]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 4.19
authorSasha Levin <sashal@kernel.org>
Sat, 14 Jan 2023 14:23:27 +0000 (09:23 -0500)
committerSasha Levin <sashal@kernel.org>
Sat, 14 Jan 2023 14:23:27 +0000 (09:23 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
29 files changed:
queue-4.19/add-acer-aspire-ethos-8951g-model-quirk.patch [new file with mode: 0644]
queue-4.19/alsa-hda-hdmi-fix-failures-at-pcm-open-on-intel-icl-.patch [new file with mode: 0644]
queue-4.19/alsa-hda-realtek-add-headset-mic-support-for-lenovo-.patch [new file with mode: 0644]
queue-4.19/alsa-hda-realtek-add-headset-mic-supported-for-hp-cp.patch [new file with mode: 0644]
queue-4.19/alsa-hda-realtek-add-quirk-for-lenovo-tianyi510pro-1.patch [new file with mode: 0644]
queue-4.19/alsa-hda-realtek-alc897-headset-mic-no-sound.patch [new file with mode: 0644]
queue-4.19/alsa-hda-realtek-enable-headset-mic-of-acer-x2660g-w.patch [new file with mode: 0644]
queue-4.19/alsa-hda-realtek-enable-the-headset-of-acer-n50-600-.patch [new file with mode: 0644]
queue-4.19/alsa-hda-realtek-fix-the-mic-type-detection-issue-fo.patch [new file with mode: 0644]
queue-4.19/alsa-hda-realtek-more-constifications.patch [new file with mode: 0644]
queue-4.19/alsa-hda-realtek-the-front-mic-on-a-hp-machine-doesn.patch [new file with mode: 0644]
queue-4.19/ext4-add-new-pending-reservation-mechanism.patch [new file with mode: 0644]
queue-4.19/ext4-fix-bug_on-in-__es_tree_search-caused-by-bad-qu.patch [new file with mode: 0644]
queue-4.19/ext4-fix-delayed-allocation-bug-in-ext4_clu_mapped-f.patch [new file with mode: 0644]
queue-4.19/ext4-fix-reserved-cluster-accounting-at-delayed-writ.patch [new file with mode: 0644]
queue-4.19/ext4-fix-uninititialized-value-in-ext4_evict_inode.patch [new file with mode: 0644]
queue-4.19/ext4-fix-use-after-free-in-ext4_orphan_cleanup.patch [new file with mode: 0644]
queue-4.19/ext4-generalize-extents-status-tree-search-functions.patch [new file with mode: 0644]
queue-4.19/ext4-lost-matching-pair-of-trace-in-ext4_truncate.patch [new file with mode: 0644]
queue-4.19/kest.pl-fix-grub2-menu-handling-for-rebooting.patch [new file with mode: 0644]
queue-4.19/ktest-add-support-for-meta-characters-in-grub_menu.patch [new file with mode: 0644]
queue-4.19/ktest-cleanup-get_grub_index.patch [new file with mode: 0644]
queue-4.19/ktest-introduce-_get_grub_index.patch [new file with mode: 0644]
queue-4.19/ktest-introduce-grub2bls-reboot_type-option.patch [new file with mode: 0644]
queue-4.19/ktest.pl-fix-incorrect-reboot-for-grub2bls.patch [new file with mode: 0644]
queue-4.19/quota-factor-out-setup-of-quota-inode.patch [new file with mode: 0644]
queue-4.19/series
queue-4.19/usb-ulpi-defer-ulpi_register-on-ulpi_read_id-timeout.patch [new file with mode: 0644]
queue-4.19/wifi-wilc1000-sdio-fix-module-autoloading.patch [new file with mode: 0644]

diff --git a/queue-4.19/add-acer-aspire-ethos-8951g-model-quirk.patch b/queue-4.19/add-acer-aspire-ethos-8951g-model-quirk.patch
new file mode 100644 (file)
index 0000000..211e231
--- /dev/null
@@ -0,0 +1,160 @@
+From 838fb58f173edcce0d175049aac2bb54ac4c481f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Sep 2019 11:33:43 +0200
+Subject: Add Acer Aspire Ethos 8951G model quirk
+
+From: Sergey Bostandzhyan <jin@mediatomb.cc>
+
+[ Upstream commit 00066e9733f629e536f6b7957de2ce11a85fe15a ]
+
+This notebook has 6 built in speakers for 5.1 surround support, however
+only two got autodetected and have also not been assigned correctly.
+
+This patch enables all speakers and also fixes muting when headphones are
+plugged in.
+
+The speaker layout is as follows:
+
+pin 0x15 Front Left / Front Right
+pin 0x18 Front Center / Subwoofer
+pin 0x1b Rear Left / Rear Right (Surround)
+
+The quirk will be enabled automatically on this hardware, but can also be
+activated manually via the model=aspire-ethos module parameter.
+
+Caveat: pin 0x1b is shared between headphones jack and surround speakers.
+When headphones are plugged in, the surround speakers get muted
+automatically by the hardware, however all other speakers remain
+unmuted. Currently it's not possible to make use of the generic automute
+function in the driver, because such shared pins are not supported.
+
+If we would change the pin settings to identify the pin as headphones,
+the surround channel and thus the ability to select 5.1 profiles would
+get lost.
+
+This quirk solves the above problem by monitoring jack state of 0x1b and
+by connecting/disconnecting all remaining speaker pins when something
+gets plugged in or unplugged from the headphones jack port.
+
+Signed-off-by: Sergey Bostandzhyan <jin@mediatomb.cc>
+Link: https://lore.kernel.org/r/20190906093343.GA7640@xn--80adja5bqm.su
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Stable-dep-of: 4bf5bf54476d ("ALSA: hda/realtek: Add quirk for Lenovo TianYi510Pro-14IOB")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/pci/hda/patch_realtek.c | 71 +++++++++++++++++++++++++++++++++++
+ 1 file changed, 71 insertions(+)
+
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index 9670db6ad1e1..fe17fb8d7f67 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -8510,6 +8510,45 @@ static void alc662_fixup_usi_headset_mic(struct hda_codec *codec,
+       }
+ }
++static void alc662_aspire_ethos_mute_speakers(struct hda_codec *codec,
++                                      struct hda_jack_callback *cb)
++{
++      /* surround speakers at 0x1b already get muted automatically when
++       * headphones are plugged in, but we have to mute/unmute the remaining
++       * channels manually:
++       * 0x15 - front left/front right
++       * 0x18 - front center/ LFE
++       */
++      if (snd_hda_jack_detect_state(codec, 0x1b) == HDA_JACK_PRESENT) {
++              snd_hda_set_pin_ctl_cache(codec, 0x15, 0);
++              snd_hda_set_pin_ctl_cache(codec, 0x18, 0);
++      } else {
++              snd_hda_set_pin_ctl_cache(codec, 0x15, PIN_OUT);
++              snd_hda_set_pin_ctl_cache(codec, 0x18, PIN_OUT);
++      }
++}
++
++static void alc662_fixup_aspire_ethos_hp(struct hda_codec *codec,
++                                      const struct hda_fixup *fix, int action)
++{
++    /* Pin 0x1b: shared headphones jack and surround speakers */
++      if (!is_jack_detectable(codec, 0x1b))
++              return;
++
++      switch (action) {
++      case HDA_FIXUP_ACT_PRE_PROBE:
++              snd_hda_jack_detect_enable_callback(codec, 0x1b,
++                              alc662_aspire_ethos_mute_speakers);
++              break;
++      case HDA_FIXUP_ACT_INIT:
++              /* Make sure to start in a correct state, i.e. if
++               * headphones have been plugged in before powering up the system
++               */
++              alc662_aspire_ethos_mute_speakers(codec, NULL);
++              break;
++      }
++}
++
+ static struct coef_fw alc668_coefs[] = {
+       WRITE_COEF(0x01, 0xbebe), WRITE_COEF(0x02, 0xaaaa), WRITE_COEF(0x03,    0x0),
+       WRITE_COEF(0x04, 0x0180), WRITE_COEF(0x06,    0x0), WRITE_COEF(0x07, 0x0f80),
+@@ -8581,6 +8620,9 @@ enum {
+       ALC662_FIXUP_USI_FUNC,
+       ALC662_FIXUP_USI_HEADSET_MODE,
+       ALC662_FIXUP_LENOVO_MULTI_CODECS,
++      ALC669_FIXUP_ACER_ASPIRE_ETHOS,
++      ALC669_FIXUP_ACER_ASPIRE_ETHOS_SUBWOOFER,
++      ALC669_FIXUP_ACER_ASPIRE_ETHOS_HEADSET,
+ };
+ static const struct hda_fixup alc662_fixups[] = {
+@@ -8907,6 +8949,33 @@ static const struct hda_fixup alc662_fixups[] = {
+               .type = HDA_FIXUP_FUNC,
+               .v.func = alc233_alc662_fixup_lenovo_dual_codecs,
+       },
++      [ALC669_FIXUP_ACER_ASPIRE_ETHOS_HEADSET] = {
++              .type = HDA_FIXUP_FUNC,
++              .v.func = alc662_fixup_aspire_ethos_hp,
++      },
++      [ALC669_FIXUP_ACER_ASPIRE_ETHOS_SUBWOOFER] = {
++              .type = HDA_FIXUP_VERBS,
++              /* subwoofer needs an extra GPIO setting to become audible */
++              .v.verbs = (const struct hda_verb[]) {
++                      {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
++                      {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
++                      {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
++                      { }
++              },
++              .chained = true,
++              .chain_id = ALC669_FIXUP_ACER_ASPIRE_ETHOS_HEADSET
++      },
++      [ALC669_FIXUP_ACER_ASPIRE_ETHOS] = {
++              .type = HDA_FIXUP_PINS,
++              .v.pins = (const struct hda_pintbl[]) {
++                      { 0x15, 0x92130110 }, /* front speakers */
++                      { 0x18, 0x99130111 }, /* center/subwoofer */
++                      { 0x1b, 0x11130012 }, /* surround plus jack for HP */
++                      { }
++              },
++              .chained = true,
++              .chain_id = ALC669_FIXUP_ACER_ASPIRE_ETHOS_SUBWOOFER
++      },
+ };
+ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
+@@ -8952,6 +9021,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
+       SND_PCI_QUIRK(0x19da, 0xa130, "Zotac Z68", ALC662_FIXUP_ZOTAC_Z68),
+       SND_PCI_QUIRK(0x1b0a, 0x01b8, "ACER Veriton", ALC662_FIXUP_ACER_VERITON),
+       SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
++      SND_PCI_QUIRK(0x1025, 0x0566, "Acer Aspire Ethos 8951G", ALC669_FIXUP_ACER_ASPIRE_ETHOS),
+ #if 0
+       /* Below is a quirk table taken from the old code.
+@@ -9044,6 +9114,7 @@ static const struct hda_model_fixup alc662_fixup_models[] = {
+       {.id = ALC892_FIXUP_ASROCK_MOBO, .name = "asrock-mobo"},
+       {.id = ALC662_FIXUP_USI_HEADSET_MODE, .name = "usi-headset"},
+       {.id = ALC662_FIXUP_LENOVO_MULTI_CODECS, .name = "dual-codecs"},
++      {.id = ALC669_FIXUP_ACER_ASPIRE_ETHOS, .name = "aspire-ethos"},
+       {}
+ };
+-- 
+2.35.1
+
diff --git a/queue-4.19/alsa-hda-hdmi-fix-failures-at-pcm-open-on-intel-icl-.patch b/queue-4.19/alsa-hda-hdmi-fix-failures-at-pcm-open-on-intel-icl-.patch
new file mode 100644 (file)
index 0000000..31ec5a7
--- /dev/null
@@ -0,0 +1,105 @@
+From 4a121175adb0c0db346f02cc9eb534800b95feee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Jul 2020 18:38:17 +0300
+Subject: ALSA: hda/hdmi: fix failures at PCM open on Intel ICL and later
+
+From: Kai Vehmanen <kai.vehmanen@linux.intel.com>
+
+[ Upstream commit 56275036d8185f92eceac7479d48b858ee3dab84 ]
+
+When HDMI PCM devices are opened in a specific order, with at least one
+HDMI/DP receiver connected, ALSA PCM open fails to -EBUSY on the
+connected monitor, on recent Intel platforms (ICL/JSL and newer). While
+this is not a typical sequence, at least Pulseaudio does this every time
+when it is started, to discover the available PCMs.
+
+The rootcause is an invalid assumption in hdmi_add_pin(), where the
+total number of converters is assumed to be known at the time the
+function is called. On older Intel platforms this held true, but after
+ICL/JSL, the order how pins and converters are in the subnode list as
+returned by snd_hda_get_sub_nodes(), was changed. As a result,
+information for some converters was not stored to per_pin->mux_nids.
+And this means some pins cannot be connected to all converters, and
+application instead gets -EBUSY instead at open.
+
+The assumption that converters are always before pins in the subnode
+list, is not really a valid one. Fix the problem in hdmi_parse_codec()
+by introducing separate loops for discovering converters and pins.
+
+BugLink: https://github.com/thesofproject/linux/issues/1978
+BugLink: https://github.com/thesofproject/linux/issues/2216
+BugLink: https://github.com/thesofproject/linux/issues/2217
+Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
+Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
+Link: https://lore.kernel.org/r/20200703153818.2808592-1-kai.vehmanen@linux.intel.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/pci/hda/patch_hdmi.c | 36 +++++++++++++++++++++++-------------
+ 1 file changed, 23 insertions(+), 13 deletions(-)
+
+diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
+index cbd5118570fd..be9f1c4295cd 100644
+--- a/sound/pci/hda/patch_hdmi.c
++++ b/sound/pci/hda/patch_hdmi.c
+@@ -1804,33 +1804,43 @@ static int hdmi_add_cvt(struct hda_codec *codec, hda_nid_t cvt_nid)
+ static int hdmi_parse_codec(struct hda_codec *codec)
+ {
+-      hda_nid_t nid;
++      hda_nid_t start_nid;
++      unsigned int caps;
+       int i, nodes;
+-      nodes = snd_hda_get_sub_nodes(codec, codec->core.afg, &nid);
+-      if (!nid || nodes < 0) {
++      nodes = snd_hda_get_sub_nodes(codec, codec->core.afg, &start_nid);
++      if (!start_nid || nodes < 0) {
+               codec_warn(codec, "HDMI: failed to get afg sub nodes\n");
+               return -EINVAL;
+       }
+-      for (i = 0; i < nodes; i++, nid++) {
+-              unsigned int caps;
+-              unsigned int type;
++      /*
++       * hdmi_add_pin() assumes total amount of converters to
++       * be known, so first discover all converters
++       */
++      for (i = 0; i < nodes; i++) {
++              hda_nid_t nid = start_nid + i;
+               caps = get_wcaps(codec, nid);
+-              type = get_wcaps_type(caps);
+               if (!(caps & AC_WCAP_DIGITAL))
+                       continue;
+-              switch (type) {
+-              case AC_WID_AUD_OUT:
++              if (get_wcaps_type(caps) == AC_WID_AUD_OUT)
+                       hdmi_add_cvt(codec, nid);
+-                      break;
+-              case AC_WID_PIN:
++      }
++
++      /* discover audio pins */
++      for (i = 0; i < nodes; i++) {
++              hda_nid_t nid = start_nid + i;
++
++              caps = get_wcaps(codec, nid);
++
++              if (!(caps & AC_WCAP_DIGITAL))
++                      continue;
++
++              if (get_wcaps_type(caps) == AC_WID_PIN)
+                       hdmi_add_pin(codec, nid);
+-                      break;
+-              }
+       }
+       return 0;
+-- 
+2.35.1
+
diff --git a/queue-4.19/alsa-hda-realtek-add-headset-mic-support-for-lenovo-.patch b/queue-4.19/alsa-hda-realtek-add-headset-mic-support-for-lenovo-.patch
new file mode 100644 (file)
index 0000000..be2be41
--- /dev/null
@@ -0,0 +1,98 @@
+From 0b4eb46f4710900534f2ed59e104c46e6d7d07d2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 Nov 2021 16:32:44 +0800
+Subject: ALSA: hda/realtek - Add headset Mic support for Lenovo ALC897
+ platform
+
+From: Kailang Yang <kailang@realtek.com>
+
+[ Upstream commit d7f32791a9fcf0dae8b073cdea9b79e29098c5f4 ]
+
+Lenovo ALC897 platform had headset Mic.
+This patch enable supported headset Mic.
+
+Signed-off-by: Kailang Yang <kailang@realtek.com>
+Cc: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/baab2c2536cb4cc18677a862c6f6d840@realtek.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Stable-dep-of: 4bf5bf54476d ("ALSA: hda/realtek: Add quirk for Lenovo TianYi510Pro-14IOB")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/pci/hda/patch_realtek.c | 40 +++++++++++++++++++++++++++++++++++
+ 1 file changed, 40 insertions(+)
+
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index 566d5ea74c62..f0cf3e23d355 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -8572,6 +8572,27 @@ static void alc671_fixup_hp_headset_mic2(struct hda_codec *codec,
+       }
+ }
++static void alc897_hp_automute_hook(struct hda_codec *codec,
++                                       struct hda_jack_callback *jack)
++{
++      struct alc_spec *spec = codec->spec;
++      int vref;
++
++      snd_hda_gen_hp_automute(codec, jack);
++      vref = spec->gen.hp_jack_present ? (PIN_HP | AC_PINCTL_VREF_100) : PIN_HP;
++      snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
++                          vref);
++}
++
++static void alc897_fixup_lenovo_headset_mic(struct hda_codec *codec,
++                                   const struct hda_fixup *fix, int action)
++{
++      struct alc_spec *spec = codec->spec;
++      if (action == HDA_FIXUP_ACT_PRE_PROBE) {
++              spec->gen.hp_automute_hook = alc897_hp_automute_hook;
++      }
++}
++
+ static const struct coef_fw alc668_coefs[] = {
+       WRITE_COEF(0x01, 0xbebe), WRITE_COEF(0x02, 0xaaaa), WRITE_COEF(0x03,    0x0),
+       WRITE_COEF(0x04, 0x0180), WRITE_COEF(0x06,    0x0), WRITE_COEF(0x07, 0x0f80),
+@@ -8652,6 +8673,8 @@ enum {
+       ALC668_FIXUP_ASUS_NO_HEADSET_MIC,
+       ALC668_FIXUP_HEADSET_MIC,
+       ALC668_FIXUP_MIC_DET_COEF,
++      ALC897_FIXUP_LENOVO_HEADSET_MIC,
++      ALC897_FIXUP_HEADSET_MIC_PIN,
+ };
+ static const struct hda_fixup alc662_fixups[] = {
+@@ -9051,6 +9074,19 @@ static const struct hda_fixup alc662_fixups[] = {
+                       {}
+               },
+       },
++      [ALC897_FIXUP_LENOVO_HEADSET_MIC] = {
++              .type = HDA_FIXUP_FUNC,
++              .v.func = alc897_fixup_lenovo_headset_mic,
++      },
++      [ALC897_FIXUP_HEADSET_MIC_PIN] = {
++              .type = HDA_FIXUP_PINS,
++              .v.pins = (const struct hda_pintbl[]) {
++                      { 0x1a, 0x03a11050 },
++                      { }
++              },
++              .chained = true,
++              .chain_id = ALC897_FIXUP_LENOVO_HEADSET_MIC
++      },
+ };
+ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
+@@ -9094,6 +9130,10 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
+       SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
+       SND_PCI_QUIRK(0x14cd, 0x5003, "USI", ALC662_FIXUP_USI_HEADSET_MODE),
+       SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC662_FIXUP_LENOVO_MULTI_CODECS),
++      SND_PCI_QUIRK(0x17aa, 0x32ca, "Lenovo ThinkCentre M80", ALC897_FIXUP_HEADSET_MIC_PIN),
++      SND_PCI_QUIRK(0x17aa, 0x32cb, "Lenovo ThinkCentre M70", ALC897_FIXUP_HEADSET_MIC_PIN),
++      SND_PCI_QUIRK(0x17aa, 0x32cf, "Lenovo ThinkCentre M950", ALC897_FIXUP_HEADSET_MIC_PIN),
++      SND_PCI_QUIRK(0x17aa, 0x32f7, "Lenovo ThinkCentre M90", ALC897_FIXUP_HEADSET_MIC_PIN),
+       SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
+       SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
+       SND_PCI_QUIRK(0x1849, 0x5892, "ASRock B150M", ALC892_FIXUP_ASROCK_MOBO),
+-- 
+2.35.1
+
diff --git a/queue-4.19/alsa-hda-realtek-add-headset-mic-supported-for-hp-cp.patch b/queue-4.19/alsa-hda-realtek-add-headset-mic-supported-for-hp-cp.patch
new file mode 100644 (file)
index 0000000..3a3a0c3
--- /dev/null
@@ -0,0 +1,99 @@
+From 50f5ff94cf283068f9d643d3276c129b3d60faf5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jan 2020 14:04:01 +0800
+Subject: ALSA: hda/realtek - Add Headset Mic supported for HP cPC
+
+From: Kailang Yang <kailang@realtek.com>
+
+[ Upstream commit 5af29028fd6db9438b5584ab7179710a0a22569d ]
+
+HP ALC671 need to support Headset Mic.
+
+Signed-off-by: Kailang Yang <kailang@realtek.com>
+Link: https://lore.kernel.org/r/06a9d2b176e14706976d6584cbe2d92a@realtek.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Stable-dep-of: 4bf5bf54476d ("ALSA: hda/realtek: Add quirk for Lenovo TianYi510Pro-14IOB")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/pci/hda/patch_realtek.c | 44 +++++++++++++++++++++++++++++++++++
+ 1 file changed, 44 insertions(+)
+
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index 3abe30eec49a..375493d3807f 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -8549,6 +8549,29 @@ static void alc662_fixup_aspire_ethos_hp(struct hda_codec *codec,
+       }
+ }
++static void alc671_fixup_hp_headset_mic2(struct hda_codec *codec,
++                                           const struct hda_fixup *fix, int action)
++{
++      struct alc_spec *spec = codec->spec;
++
++      static const struct hda_pintbl pincfgs[] = {
++              { 0x19, 0x02a11040 }, /* use as headset mic, with its own jack detect */
++              { 0x1b, 0x0181304f },
++              { }
++      };
++
++      switch (action) {
++      case HDA_FIXUP_ACT_PRE_PROBE:
++              spec->gen.mixer_nid = 0;
++              spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
++              snd_hda_apply_pincfgs(codec, pincfgs);
++              break;
++      case HDA_FIXUP_ACT_INIT:
++              alc_write_coef_idx(codec, 0x19, 0xa054);
++              break;
++      }
++}
++
+ static const struct coef_fw alc668_coefs[] = {
+       WRITE_COEF(0x01, 0xbebe), WRITE_COEF(0x02, 0xaaaa), WRITE_COEF(0x03,    0x0),
+       WRITE_COEF(0x04, 0x0180), WRITE_COEF(0x06,    0x0), WRITE_COEF(0x07, 0x0f80),
+@@ -8623,6 +8646,7 @@ enum {
+       ALC669_FIXUP_ACER_ASPIRE_ETHOS,
+       ALC669_FIXUP_ACER_ASPIRE_ETHOS_SUBWOOFER,
+       ALC669_FIXUP_ACER_ASPIRE_ETHOS_HEADSET,
++      ALC671_FIXUP_HP_HEADSET_MIC2,
+ };
+ static const struct hda_fixup alc662_fixups[] = {
+@@ -8976,6 +9000,10 @@ static const struct hda_fixup alc662_fixups[] = {
+               .chained = true,
+               .chain_id = ALC669_FIXUP_ACER_ASPIRE_ETHOS_SUBWOOFER
+       },
++      [ALC671_FIXUP_HP_HEADSET_MIC2] = {
++              .type = HDA_FIXUP_FUNC,
++              .v.func = alc671_fixup_hp_headset_mic2,
++      },
+ };
+ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
+@@ -9157,6 +9185,22 @@ static const struct snd_hda_pin_quirk alc662_pin_fixup_tbl[] = {
+               {0x12, 0x90a60130},
+               {0x14, 0x90170110},
+               {0x15, 0x0321101f}),
++      SND_HDA_PIN_QUIRK(0x10ec0671, 0x103c, "HP cPC", ALC671_FIXUP_HP_HEADSET_MIC2,
++              {0x14, 0x01014010},
++              {0x17, 0x90170150},
++              {0x1b, 0x01813030},
++              {0x21, 0x02211020}),
++      SND_HDA_PIN_QUIRK(0x10ec0671, 0x103c, "HP cPC", ALC671_FIXUP_HP_HEADSET_MIC2,
++              {0x14, 0x01014010},
++              {0x18, 0x01a19040},
++              {0x1b, 0x01813030},
++              {0x21, 0x02211020}),
++      SND_HDA_PIN_QUIRK(0x10ec0671, 0x103c, "HP cPC", ALC671_FIXUP_HP_HEADSET_MIC2,
++              {0x14, 0x01014020},
++              {0x17, 0x90170110},
++              {0x18, 0x01a19050},
++              {0x1b, 0x01813040},
++              {0x21, 0x02211030}),
+       {}
+ };
+-- 
+2.35.1
+
diff --git a/queue-4.19/alsa-hda-realtek-add-quirk-for-lenovo-tianyi510pro-1.patch b/queue-4.19/alsa-hda-realtek-add-quirk-for-lenovo-tianyi510pro-1.patch
new file mode 100644 (file)
index 0000000..1d97ab9
--- /dev/null
@@ -0,0 +1,84 @@
+From e71b599471f13a7c22ef65751c1c1257486ea353 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Dec 2022 21:32:18 +0800
+Subject: ALSA: hda/realtek: Add quirk for Lenovo TianYi510Pro-14IOB
+
+From: Edward Pacman <edward@edward-p.xyz>
+
+[ Upstream commit 4bf5bf54476dffe60e6b6d8d539f67309ff599e2 ]
+
+Lenovo TianYi510Pro-14IOB (17aa:3742)
+require quirk for enabling headset-mic
+
+Signed-off-by: Edward Pacman <edward@edward-p.xyz>
+Cc: <stable@vger.kernel.org>
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=216756
+Link: https://lore.kernel.org/r/20221207133218.18989-1-edward@edward-p.xyz
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/pci/hda/patch_realtek.c | 27 +++++++++++++++++++++++++++
+ 1 file changed, 27 insertions(+)
+
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index 0a2cf8ca2812..ed14772a8e6e 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -8593,6 +8593,17 @@ static void alc897_fixup_lenovo_headset_mic(struct hda_codec *codec,
+       }
+ }
++static void alc897_fixup_lenovo_headset_mode(struct hda_codec *codec,
++                                   const struct hda_fixup *fix, int action)
++{
++      struct alc_spec *spec = codec->spec;
++
++      if (action == HDA_FIXUP_ACT_PRE_PROBE) {
++              spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
++              spec->gen.hp_automute_hook = alc897_hp_automute_hook;
++      }
++}
++
+ static const struct coef_fw alc668_coefs[] = {
+       WRITE_COEF(0x01, 0xbebe), WRITE_COEF(0x02, 0xaaaa), WRITE_COEF(0x03,    0x0),
+       WRITE_COEF(0x04, 0x0180), WRITE_COEF(0x06,    0x0), WRITE_COEF(0x07, 0x0f80),
+@@ -8676,6 +8687,8 @@ enum {
+       ALC897_FIXUP_LENOVO_HEADSET_MIC,
+       ALC897_FIXUP_HEADSET_MIC_PIN,
+       ALC897_FIXUP_HP_HSMIC_VERB,
++      ALC897_FIXUP_LENOVO_HEADSET_MODE,
++      ALC897_FIXUP_HEADSET_MIC_PIN2,
+ };
+ static const struct hda_fixup alc662_fixups[] = {
+@@ -9095,6 +9108,19 @@ static const struct hda_fixup alc662_fixups[] = {
+                       { }
+               },
+       },
++      [ALC897_FIXUP_LENOVO_HEADSET_MODE] = {
++              .type = HDA_FIXUP_FUNC,
++              .v.func = alc897_fixup_lenovo_headset_mode,
++      },
++      [ALC897_FIXUP_HEADSET_MIC_PIN2] = {
++              .type = HDA_FIXUP_PINS,
++              .v.pins = (const struct hda_pintbl[]) {
++                      { 0x1a, 0x01a11140 }, /* use as headset mic, without its own jack detect */
++                      { }
++              },
++              .chained = true,
++              .chain_id = ALC897_FIXUP_LENOVO_HEADSET_MODE
++      },
+ };
+ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
+@@ -9143,6 +9169,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
+       SND_PCI_QUIRK(0x17aa, 0x32cb, "Lenovo ThinkCentre M70", ALC897_FIXUP_HEADSET_MIC_PIN),
+       SND_PCI_QUIRK(0x17aa, 0x32cf, "Lenovo ThinkCentre M950", ALC897_FIXUP_HEADSET_MIC_PIN),
+       SND_PCI_QUIRK(0x17aa, 0x32f7, "Lenovo ThinkCentre M90", ALC897_FIXUP_HEADSET_MIC_PIN),
++      SND_PCI_QUIRK(0x17aa, 0x3742, "Lenovo TianYi510Pro-14IOB", ALC897_FIXUP_HEADSET_MIC_PIN2),
+       SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
+       SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
+       SND_PCI_QUIRK(0x1849, 0x5892, "ASRock B150M", ALC892_FIXUP_ASROCK_MOBO),
+-- 
+2.35.1
+
diff --git a/queue-4.19/alsa-hda-realtek-alc897-headset-mic-no-sound.patch b/queue-4.19/alsa-hda-realtek-alc897-headset-mic-no-sound.patch
new file mode 100644 (file)
index 0000000..13e47ca
--- /dev/null
@@ -0,0 +1,60 @@
+From 4d69f320a26a6c6e4fc4e91f5507c3eaa012d96e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 14:57:19 +0800
+Subject: ALSA: hda/realtek - ALC897 headset MIC no sound
+
+From: Kailang Yang <kailang@realtek.com>
+
+[ Upstream commit fe6900bd8156467365bd5b976df64928fdebfeb0 ]
+
+There is not have Headset Mic verb table in BIOS default.
+So, it will have recording issue from headset MIC.
+Add the verb table value without jack detect. It will turn on Headset Mic.
+
+Signed-off-by: Kailang Yang <kailang@realtek.com>
+Cc: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/719133a27d8844a890002cb817001dfa@realtek.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Stable-dep-of: 4bf5bf54476d ("ALSA: hda/realtek: Add quirk for Lenovo TianYi510Pro-14IOB")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/pci/hda/patch_realtek.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index f0cf3e23d355..0a2cf8ca2812 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -8675,6 +8675,7 @@ enum {
+       ALC668_FIXUP_MIC_DET_COEF,
+       ALC897_FIXUP_LENOVO_HEADSET_MIC,
+       ALC897_FIXUP_HEADSET_MIC_PIN,
++      ALC897_FIXUP_HP_HSMIC_VERB,
+ };
+ static const struct hda_fixup alc662_fixups[] = {
+@@ -9087,6 +9088,13 @@ static const struct hda_fixup alc662_fixups[] = {
+               .chained = true,
+               .chain_id = ALC897_FIXUP_LENOVO_HEADSET_MIC
+       },
++      [ALC897_FIXUP_HP_HSMIC_VERB] = {
++              .type = HDA_FIXUP_PINS,
++              .v.pins = (const struct hda_pintbl[]) {
++                      { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
++                      { }
++              },
++      },
+ };
+ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
+@@ -9111,6 +9119,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
+       SND_PCI_QUIRK(0x1028, 0x0698, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
+       SND_PCI_QUIRK(0x1028, 0x069f, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
+       SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
++      SND_PCI_QUIRK(0x103c, 0x8719, "HP", ALC897_FIXUP_HP_HSMIC_VERB),
+       SND_PCI_QUIRK(0x103c, 0x873e, "HP", ALC671_FIXUP_HP_HEADSET_MIC2),
+       SND_PCI_QUIRK(0x1043, 0x1080, "Asus UX501VW", ALC668_FIXUP_HEADSET_MODE),
+       SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_ASUS_Nx50),
+-- 
+2.35.1
+
diff --git a/queue-4.19/alsa-hda-realtek-enable-headset-mic-of-acer-x2660g-w.patch b/queue-4.19/alsa-hda-realtek-enable-headset-mic-of-acer-x2660g-w.patch
new file mode 100644 (file)
index 0000000..05ce66f
--- /dev/null
@@ -0,0 +1,61 @@
+From 2dc43622b34ae832e20e81b6dc53aedbaffb8e9c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Mar 2020 16:28:07 +0800
+Subject: ALSA: hda/realtek - Enable headset mic of Acer X2660G with ALC662
+
+From: Jian-Hong Pan <jian-hong@endlessm.com>
+
+[ Upstream commit d858c706bdca97698752bd26b60c21ec07ef04f2 ]
+
+The Acer desktop X2660G with ALC662 can't detect the headset microphone
+until ALC662_FIXUP_ACER_X2660G_HEADSET_MODE quirk applied.
+
+Signed-off-by: Jian-Hong Pan <jian-hong@endlessm.com>
+Cc: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20200317082806.73194-2-jian-hong@endlessm.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Stable-dep-of: 4bf5bf54476d ("ALSA: hda/realtek: Add quirk for Lenovo TianYi510Pro-14IOB")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/pci/hda/patch_realtek.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index 375493d3807f..024a7e473e11 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -8647,6 +8647,7 @@ enum {
+       ALC669_FIXUP_ACER_ASPIRE_ETHOS_SUBWOOFER,
+       ALC669_FIXUP_ACER_ASPIRE_ETHOS_HEADSET,
+       ALC671_FIXUP_HP_HEADSET_MIC2,
++      ALC662_FIXUP_ACER_X2660G_HEADSET_MODE,
+ };
+ static const struct hda_fixup alc662_fixups[] = {
+@@ -9004,6 +9005,15 @@ static const struct hda_fixup alc662_fixups[] = {
+               .type = HDA_FIXUP_FUNC,
+               .v.func = alc671_fixup_hp_headset_mic2,
+       },
++      [ALC662_FIXUP_ACER_X2660G_HEADSET_MODE] = {
++              .type = HDA_FIXUP_PINS,
++              .v.pins = (const struct hda_pintbl[]) {
++                      { 0x1a, 0x02a1113c }, /* use as headset mic, without its own jack detect */
++                      { }
++              },
++              .chained = true,
++              .chain_id = ALC662_FIXUP_USI_FUNC
++      },
+ };
+ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
+@@ -9015,6 +9025,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
+       SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC),
+       SND_PCI_QUIRK(0x1025, 0x034a, "Gateway LT27", ALC662_FIXUP_INV_DMIC),
+       SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
++      SND_PCI_QUIRK(0x1025, 0x124e, "Acer 2660G", ALC662_FIXUP_ACER_X2660G_HEADSET_MODE),
+       SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
+       SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
+       SND_PCI_QUIRK(0x1028, 0x05fe, "Dell XPS 15", ALC668_FIXUP_DELL_XPS13),
+-- 
+2.35.1
+
diff --git a/queue-4.19/alsa-hda-realtek-enable-the-headset-of-acer-n50-600-.patch b/queue-4.19/alsa-hda-realtek-enable-the-headset-of-acer-n50-600-.patch
new file mode 100644 (file)
index 0000000..ced0462
--- /dev/null
@@ -0,0 +1,62 @@
+From 2e7fe866347afee7c46766e1e47df33430caaf65 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Mar 2020 16:28:09 +0800
+Subject: ALSA: hda/realtek - Enable the headset of Acer N50-600 with ALC662
+
+From: Jian-Hong Pan <jian-hong@endlessm.com>
+
+[ Upstream commit a124458a127ccd7629e20cd7bae3e1f758ed32aa ]
+
+A headset on the desktop like Acer N50-600 does not work, until quirk
+ALC662_FIXUP_ACER_NITRO_HEADSET_MODE is applied.
+
+Signed-off-by: Jian-Hong Pan <jian-hong@endlessm.com>
+Cc: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20200317082806.73194-3-jian-hong@endlessm.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Stable-dep-of: 4bf5bf54476d ("ALSA: hda/realtek: Add quirk for Lenovo TianYi510Pro-14IOB")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/pci/hda/patch_realtek.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index 024a7e473e11..bb0917b9e68f 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -8648,6 +8648,7 @@ enum {
+       ALC669_FIXUP_ACER_ASPIRE_ETHOS_HEADSET,
+       ALC671_FIXUP_HP_HEADSET_MIC2,
+       ALC662_FIXUP_ACER_X2660G_HEADSET_MODE,
++      ALC662_FIXUP_ACER_NITRO_HEADSET_MODE,
+ };
+ static const struct hda_fixup alc662_fixups[] = {
+@@ -9014,6 +9015,16 @@ static const struct hda_fixup alc662_fixups[] = {
+               .chained = true,
+               .chain_id = ALC662_FIXUP_USI_FUNC
+       },
++      [ALC662_FIXUP_ACER_NITRO_HEADSET_MODE] = {
++              .type = HDA_FIXUP_PINS,
++              .v.pins = (const struct hda_pintbl[]) {
++                      { 0x1a, 0x01a11140 }, /* use as headset mic, without its own jack detect */
++                      { 0x1b, 0x0221144f },
++                      { }
++              },
++              .chained = true,
++              .chain_id = ALC662_FIXUP_USI_FUNC
++      },
+ };
+ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
+@@ -9025,6 +9036,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
+       SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC),
+       SND_PCI_QUIRK(0x1025, 0x034a, "Gateway LT27", ALC662_FIXUP_INV_DMIC),
+       SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
++      SND_PCI_QUIRK(0x1025, 0x123c, "Acer Nitro N50-600", ALC662_FIXUP_ACER_NITRO_HEADSET_MODE),
+       SND_PCI_QUIRK(0x1025, 0x124e, "Acer 2660G", ALC662_FIXUP_ACER_X2660G_HEADSET_MODE),
+       SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
+       SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
+-- 
+2.35.1
+
diff --git a/queue-4.19/alsa-hda-realtek-fix-the-mic-type-detection-issue-fo.patch b/queue-4.19/alsa-hda-realtek-fix-the-mic-type-detection-issue-fo.patch
new file mode 100644 (file)
index 0000000..7cbce12
--- /dev/null
@@ -0,0 +1,88 @@
+From da632ed5ac77ffb74fa8511c3e07f25b133224da Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Oct 2021 19:47:48 +0800
+Subject: ALSA: hda/realtek: Fix the mic type detection issue for ASUS G551JW
+
+From: Hui Wang <hui.wang@canonical.com>
+
+[ Upstream commit a3fd1a986e499a06ac5ef95c3a39aa4611e7444c ]
+
+We need to define the codec pin 0x1b to be the mic, but somehow
+the mic doesn't support hot plugging detection, and Windows also has
+this issue, so we set it to phantom headset-mic.
+
+Also the determine_headset_type() often returns the omtp type by a
+mistake when we plug a ctia headset, this makes the mic can't record
+sound at all. Because most of the headset are ctia type nowadays and
+some machines have the fixed ctia type audio jack, it is possible this
+machine has the fixed ctia jack too. Here we set this mic jack to
+fixed ctia type, this could avoid the mic type detection mistake and
+make the ctia headset work stable.
+
+BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=214537
+Reported-and-tested-by: msd <msd.mmq@gmail.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Hui Wang <hui.wang@canonical.com>
+Link: https://lore.kernel.org/r/20211012114748.5238-1-hui.wang@canonical.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Stable-dep-of: 4bf5bf54476d ("ALSA: hda/realtek: Add quirk for Lenovo TianYi510Pro-14IOB")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/pci/hda/patch_realtek.c | 27 +++++++++++++++++++++++++++
+ 1 file changed, 27 insertions(+)
+
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index a3cc5cc0d668..566d5ea74c62 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -8649,6 +8649,9 @@ enum {
+       ALC671_FIXUP_HP_HEADSET_MIC2,
+       ALC662_FIXUP_ACER_X2660G_HEADSET_MODE,
+       ALC662_FIXUP_ACER_NITRO_HEADSET_MODE,
++      ALC668_FIXUP_ASUS_NO_HEADSET_MIC,
++      ALC668_FIXUP_HEADSET_MIC,
++      ALC668_FIXUP_MIC_DET_COEF,
+ };
+ static const struct hda_fixup alc662_fixups[] = {
+@@ -9025,6 +9028,29 @@ static const struct hda_fixup alc662_fixups[] = {
+               .chained = true,
+               .chain_id = ALC662_FIXUP_USI_FUNC
+       },
++      [ALC668_FIXUP_ASUS_NO_HEADSET_MIC] = {
++              .type = HDA_FIXUP_PINS,
++              .v.pins = (const struct hda_pintbl[]) {
++                      { 0x1b, 0x04a1112c },
++                      { }
++              },
++              .chained = true,
++              .chain_id = ALC668_FIXUP_HEADSET_MIC
++      },
++      [ALC668_FIXUP_HEADSET_MIC] = {
++              .type = HDA_FIXUP_FUNC,
++              .v.func = alc269_fixup_headset_mic,
++              .chained = true,
++              .chain_id = ALC668_FIXUP_MIC_DET_COEF
++      },
++      [ALC668_FIXUP_MIC_DET_COEF] = {
++              .type = HDA_FIXUP_VERBS,
++              .v.verbs = (const struct hda_verb[]) {
++                      { 0x20, AC_VERB_SET_COEF_INDEX, 0x15 },
++                      { 0x20, AC_VERB_SET_PROC_COEF, 0x0d60 },
++                      {}
++              },
++      },
+ };
+ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
+@@ -9059,6 +9085,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
+       SND_PCI_QUIRK(0x1043, 0x15a7, "ASUS UX51VZH", ALC662_FIXUP_BASS_16),
+       SND_PCI_QUIRK(0x1043, 0x177d, "ASUS N551", ALC668_FIXUP_ASUS_Nx51),
+       SND_PCI_QUIRK(0x1043, 0x17bd, "ASUS N751", ALC668_FIXUP_ASUS_Nx51),
++      SND_PCI_QUIRK(0x1043, 0x185d, "ASUS G551JW", ALC668_FIXUP_ASUS_NO_HEADSET_MIC),
+       SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71SL", ALC662_FIXUP_ASUS_MODE8),
+       SND_PCI_QUIRK(0x1043, 0x1b73, "ASUS N55SF", ALC662_FIXUP_BASS_16),
+       SND_PCI_QUIRK(0x1043, 0x1bf3, "ASUS N76VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
+-- 
+2.35.1
+
diff --git a/queue-4.19/alsa-hda-realtek-more-constifications.patch b/queue-4.19/alsa-hda-realtek-more-constifications.patch
new file mode 100644 (file)
index 0000000..61181e8
--- /dev/null
@@ -0,0 +1,480 @@
+From 6e631f1d938fd402205892d0be1a0319a7593335 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 5 Jan 2020 15:47:18 +0100
+Subject: ALSA: hda/realtek - More constifications
+
+From: Takashi Iwai <tiwai@suse.de>
+
+[ Upstream commit 6b0f95c49d890440c01a759c767dfe40e2acdbf2 ]
+
+Apply const prefix to each coef table array.
+
+Just for minor optimization and no functional changes.
+
+Link: https://lore.kernel.org/r/20200105144823.29547-4-tiwai@suse.de
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Stable-dep-of: 4bf5bf54476d ("ALSA: hda/realtek: Add quirk for Lenovo TianYi510Pro-14IOB")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/pci/hda/patch_realtek.c | 118 +++++++++++++++++-----------------
+ 1 file changed, 59 insertions(+), 59 deletions(-)
+
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index fe17fb8d7f67..3abe30eec49a 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -956,7 +956,7 @@ struct alc_codec_rename_pci_table {
+       const char *name;
+ };
+-static struct alc_codec_rename_table rename_tbl[] = {
++static const struct alc_codec_rename_table rename_tbl[] = {
+       { 0x10ec0221, 0xf00f, 0x1003, "ALC231" },
+       { 0x10ec0269, 0xfff0, 0x3010, "ALC277" },
+       { 0x10ec0269, 0xf0f0, 0x2010, "ALC259" },
+@@ -977,7 +977,7 @@ static struct alc_codec_rename_table rename_tbl[] = {
+       { } /* terminator */
+ };
+-static struct alc_codec_rename_pci_table rename_pci_tbl[] = {
++static const struct alc_codec_rename_pci_table rename_pci_tbl[] = {
+       { 0x10ec0280, 0x1028, 0, "ALC3220" },
+       { 0x10ec0282, 0x1028, 0, "ALC3221" },
+       { 0x10ec0283, 0x1028, 0, "ALC3223" },
+@@ -3115,7 +3115,7 @@ static void alc269_shutup(struct hda_codec *codec)
+       alc_shutup_pins(codec);
+ }
+-static struct coef_fw alc282_coefs[] = {
++static const struct coef_fw alc282_coefs[] = {
+       WRITE_COEF(0x03, 0x0002), /* Power Down Control */
+       UPDATE_COEF(0x05, 0xff3f, 0x0700), /* FIFO and filter clock */
+       WRITE_COEF(0x07, 0x0200), /* DMIC control */
+@@ -3227,7 +3227,7 @@ static void alc282_shutup(struct hda_codec *codec)
+       alc_write_coef_idx(codec, 0x78, coef78);
+ }
+-static struct coef_fw alc283_coefs[] = {
++static const struct coef_fw alc283_coefs[] = {
+       WRITE_COEF(0x03, 0x0002), /* Power Down Control */
+       UPDATE_COEF(0x05, 0xff3f, 0x0700), /* FIFO and filter clock */
+       WRITE_COEF(0x07, 0x0200), /* DMIC control */
+@@ -4234,7 +4234,7 @@ static void alc269_fixup_hp_line1_mic1_led(struct hda_codec *codec,
+       }
+ }
+-static struct coef_fw alc225_pre_hsmode[] = {
++static const struct coef_fw alc225_pre_hsmode[] = {
+       UPDATE_COEF(0x4a, 1<<8, 0),
+       UPDATE_COEFEX(0x57, 0x05, 1<<14, 0),
+       UPDATE_COEF(0x63, 3<<14, 3<<14),
+@@ -4247,7 +4247,7 @@ static struct coef_fw alc225_pre_hsmode[] = {
+ static void alc_headset_mode_unplugged(struct hda_codec *codec)
+ {
+-      static struct coef_fw coef0255[] = {
++      static const struct coef_fw coef0255[] = {
+               WRITE_COEF(0x1b, 0x0c0b), /* LDO and MISC control */
+               WRITE_COEF(0x45, 0xd089), /* UAJ function set to menual mode */
+               UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/
+@@ -4255,7 +4255,7 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec)
+               WRITE_COEFEX(0x57, 0x03, 0x8aa6), /* Direct Drive HP Amp control */
+               {}
+       };
+-      static struct coef_fw coef0256[] = {
++      static const struct coef_fw coef0256[] = {
+               WRITE_COEF(0x1b, 0x0c4b), /* LDO and MISC control */
+               WRITE_COEF(0x45, 0xd089), /* UAJ function set to menual mode */
+               WRITE_COEF(0x06, 0x6104), /* Set MIC2 Vref gate with HP */
+@@ -4263,7 +4263,7 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec)
+               UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/
+               {}
+       };
+-      static struct coef_fw coef0233[] = {
++      static const struct coef_fw coef0233[] = {
+               WRITE_COEF(0x1b, 0x0c0b),
+               WRITE_COEF(0x45, 0xc429),
+               UPDATE_COEF(0x35, 0x4000, 0),
+@@ -4273,7 +4273,7 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec)
+               WRITE_COEF(0x32, 0x42a3),
+               {}
+       };
+-      static struct coef_fw coef0288[] = {
++      static const struct coef_fw coef0288[] = {
+               UPDATE_COEF(0x4f, 0xfcc0, 0xc400),
+               UPDATE_COEF(0x50, 0x2000, 0x2000),
+               UPDATE_COEF(0x56, 0x0006, 0x0006),
+@@ -4281,18 +4281,18 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec)
+               UPDATE_COEF(0x67, 0x2000, 0),
+               {}
+       };
+-      static struct coef_fw coef0298[] = {
++      static const struct coef_fw coef0298[] = {
+               UPDATE_COEF(0x19, 0x1300, 0x0300),
+               {}
+       };
+-      static struct coef_fw coef0292[] = {
++      static const struct coef_fw coef0292[] = {
+               WRITE_COEF(0x76, 0x000e),
+               WRITE_COEF(0x6c, 0x2400),
+               WRITE_COEF(0x18, 0x7308),
+               WRITE_COEF(0x6b, 0xc429),
+               {}
+       };
+-      static struct coef_fw coef0293[] = {
++      static const struct coef_fw coef0293[] = {
+               UPDATE_COEF(0x10, 7<<8, 6<<8), /* SET Line1 JD to 0 */
+               UPDATE_COEFEX(0x57, 0x05, 1<<15|1<<13, 0x0), /* SET charge pump by verb */
+               UPDATE_COEFEX(0x57, 0x03, 1<<10, 1<<10), /* SET EN_OSW to 1 */
+@@ -4301,16 +4301,16 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec)
+               UPDATE_COEF(0x4a, 0x000f, 0x000e), /* Combo Jack auto detect */
+               {}
+       };
+-      static struct coef_fw coef0668[] = {
++      static const struct coef_fw coef0668[] = {
+               WRITE_COEF(0x15, 0x0d40),
+               WRITE_COEF(0xb7, 0x802b),
+               {}
+       };
+-      static struct coef_fw coef0225[] = {
++      static const struct coef_fw coef0225[] = {
+               UPDATE_COEF(0x63, 3<<14, 0),
+               {}
+       };
+-      static struct coef_fw coef0274[] = {
++      static const struct coef_fw coef0274[] = {
+               UPDATE_COEF(0x4a, 0x0100, 0),
+               UPDATE_COEFEX(0x57, 0x05, 0x4000, 0),
+               UPDATE_COEF(0x6b, 0xf000, 0x5000),
+@@ -4375,25 +4375,25 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec)
+ static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin,
+                                   hda_nid_t mic_pin)
+ {
+-      static struct coef_fw coef0255[] = {
++      static const struct coef_fw coef0255[] = {
+               WRITE_COEFEX(0x57, 0x03, 0x8aa6),
+               WRITE_COEF(0x06, 0x6100), /* Set MIC2 Vref gate to normal */
+               {}
+       };
+-      static struct coef_fw coef0256[] = {
++      static const struct coef_fw coef0256[] = {
+               UPDATE_COEFEX(0x57, 0x05, 1<<14, 1<<14), /* Direct Drive HP Amp control(Set to verb control)*/
+               WRITE_COEFEX(0x57, 0x03, 0x09a3),
+               WRITE_COEF(0x06, 0x6100), /* Set MIC2 Vref gate to normal */
+               {}
+       };
+-      static struct coef_fw coef0233[] = {
++      static const struct coef_fw coef0233[] = {
+               UPDATE_COEF(0x35, 0, 1<<14),
+               WRITE_COEF(0x06, 0x2100),
+               WRITE_COEF(0x1a, 0x0021),
+               WRITE_COEF(0x26, 0x008c),
+               {}
+       };
+-      static struct coef_fw coef0288[] = {
++      static const struct coef_fw coef0288[] = {
+               UPDATE_COEF(0x4f, 0x00c0, 0),
+               UPDATE_COEF(0x50, 0x2000, 0),
+               UPDATE_COEF(0x56, 0x0006, 0),
+@@ -4402,30 +4402,30 @@ static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin,
+               UPDATE_COEF(0x67, 0x2000, 0x2000),
+               {}
+       };
+-      static struct coef_fw coef0292[] = {
++      static const struct coef_fw coef0292[] = {
+               WRITE_COEF(0x19, 0xa208),
+               WRITE_COEF(0x2e, 0xacf0),
+               {}
+       };
+-      static struct coef_fw coef0293[] = {
++      static const struct coef_fw coef0293[] = {
+               UPDATE_COEFEX(0x57, 0x05, 0, 1<<15|1<<13), /* SET charge pump by verb */
+               UPDATE_COEFEX(0x57, 0x03, 1<<10, 0), /* SET EN_OSW to 0 */
+               UPDATE_COEF(0x1a, 1<<3, 0), /* Combo JD gating without LINE1-VREFO */
+               {}
+       };
+-      static struct coef_fw coef0688[] = {
++      static const struct coef_fw coef0688[] = {
+               WRITE_COEF(0xb7, 0x802b),
+               WRITE_COEF(0xb5, 0x1040),
+               UPDATE_COEF(0xc3, 0, 1<<12),
+               {}
+       };
+-      static struct coef_fw coef0225[] = {
++      static const struct coef_fw coef0225[] = {
+               UPDATE_COEFEX(0x57, 0x05, 1<<14, 1<<14),
+               UPDATE_COEF(0x4a, 3<<4, 2<<4),
+               UPDATE_COEF(0x63, 3<<14, 0),
+               {}
+       };
+-      static struct coef_fw coef0274[] = {
++      static const struct coef_fw coef0274[] = {
+               UPDATE_COEFEX(0x57, 0x05, 0x4000, 0x4000),
+               UPDATE_COEF(0x4a, 0x0010, 0),
+               UPDATE_COEF(0x6b, 0xf000, 0),
+@@ -4511,7 +4511,7 @@ static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin,
+ static void alc_headset_mode_default(struct hda_codec *codec)
+ {
+-      static struct coef_fw coef0225[] = {
++      static const struct coef_fw coef0225[] = {
+               UPDATE_COEF(0x45, 0x3f<<10, 0x30<<10),
+               UPDATE_COEF(0x45, 0x3f<<10, 0x31<<10),
+               UPDATE_COEF(0x49, 3<<8, 0<<8),
+@@ -4520,14 +4520,14 @@ static void alc_headset_mode_default(struct hda_codec *codec)
+               UPDATE_COEF(0x67, 0xf000, 0x3000),
+               {}
+       };
+-      static struct coef_fw coef0255[] = {
++      static const struct coef_fw coef0255[] = {
+               WRITE_COEF(0x45, 0xc089),
+               WRITE_COEF(0x45, 0xc489),
+               WRITE_COEFEX(0x57, 0x03, 0x8ea6),
+               WRITE_COEF(0x49, 0x0049),
+               {}
+       };
+-      static struct coef_fw coef0256[] = {
++      static const struct coef_fw coef0256[] = {
+               WRITE_COEF(0x45, 0xc489),
+               WRITE_COEFEX(0x57, 0x03, 0x0da3),
+               WRITE_COEF(0x49, 0x0049),
+@@ -4535,12 +4535,12 @@ static void alc_headset_mode_default(struct hda_codec *codec)
+               WRITE_COEF(0x06, 0x6100),
+               {}
+       };
+-      static struct coef_fw coef0233[] = {
++      static const struct coef_fw coef0233[] = {
+               WRITE_COEF(0x06, 0x2100),
+               WRITE_COEF(0x32, 0x4ea3),
+               {}
+       };
+-      static struct coef_fw coef0288[] = {
++      static const struct coef_fw coef0288[] = {
+               UPDATE_COEF(0x4f, 0xfcc0, 0xc400), /* Set to TRS type */
+               UPDATE_COEF(0x50, 0x2000, 0x2000),
+               UPDATE_COEF(0x56, 0x0006, 0x0006),
+@@ -4548,26 +4548,26 @@ static void alc_headset_mode_default(struct hda_codec *codec)
+               UPDATE_COEF(0x67, 0x2000, 0),
+               {}
+       };
+-      static struct coef_fw coef0292[] = {
++      static const struct coef_fw coef0292[] = {
+               WRITE_COEF(0x76, 0x000e),
+               WRITE_COEF(0x6c, 0x2400),
+               WRITE_COEF(0x6b, 0xc429),
+               WRITE_COEF(0x18, 0x7308),
+               {}
+       };
+-      static struct coef_fw coef0293[] = {
++      static const struct coef_fw coef0293[] = {
+               UPDATE_COEF(0x4a, 0x000f, 0x000e), /* Combo Jack auto detect */
+               WRITE_COEF(0x45, 0xC429), /* Set to TRS type */
+               UPDATE_COEF(0x1a, 1<<3, 0), /* Combo JD gating without LINE1-VREFO */
+               {}
+       };
+-      static struct coef_fw coef0688[] = {
++      static const struct coef_fw coef0688[] = {
+               WRITE_COEF(0x11, 0x0041),
+               WRITE_COEF(0x15, 0x0d40),
+               WRITE_COEF(0xb7, 0x802b),
+               {}
+       };
+-      static struct coef_fw coef0274[] = {
++      static const struct coef_fw coef0274[] = {
+               WRITE_COEF(0x45, 0x4289),
+               UPDATE_COEF(0x4a, 0x0010, 0x0010),
+               UPDATE_COEF(0x6b, 0x0f00, 0),
+@@ -4630,53 +4630,53 @@ static void alc_headset_mode_ctia(struct hda_codec *codec)
+ {
+       int val;
+-      static struct coef_fw coef0255[] = {
++      static const struct coef_fw coef0255[] = {
+               WRITE_COEF(0x45, 0xd489), /* Set to CTIA type */
+               WRITE_COEF(0x1b, 0x0c2b),
+               WRITE_COEFEX(0x57, 0x03, 0x8ea6),
+               {}
+       };
+-      static struct coef_fw coef0256[] = {
++      static const struct coef_fw coef0256[] = {
+               WRITE_COEF(0x45, 0xd489), /* Set to CTIA type */
+               WRITE_COEF(0x1b, 0x0e6b),
+               {}
+       };
+-      static struct coef_fw coef0233[] = {
++      static const struct coef_fw coef0233[] = {
+               WRITE_COEF(0x45, 0xd429),
+               WRITE_COEF(0x1b, 0x0c2b),
+               WRITE_COEF(0x32, 0x4ea3),
+               {}
+       };
+-      static struct coef_fw coef0288[] = {
++      static const struct coef_fw coef0288[] = {
+               UPDATE_COEF(0x50, 0x2000, 0x2000),
+               UPDATE_COEF(0x56, 0x0006, 0x0006),
+               UPDATE_COEF(0x66, 0x0008, 0),
+               UPDATE_COEF(0x67, 0x2000, 0),
+               {}
+       };
+-      static struct coef_fw coef0292[] = {
++      static const struct coef_fw coef0292[] = {
+               WRITE_COEF(0x6b, 0xd429),
+               WRITE_COEF(0x76, 0x0008),
+               WRITE_COEF(0x18, 0x7388),
+               {}
+       };
+-      static struct coef_fw coef0293[] = {
++      static const struct coef_fw coef0293[] = {
+               WRITE_COEF(0x45, 0xd429), /* Set to ctia type */
+               UPDATE_COEF(0x10, 7<<8, 7<<8), /* SET Line1 JD to 1 */
+               {}
+       };
+-      static struct coef_fw coef0688[] = {
++      static const struct coef_fw coef0688[] = {
+               WRITE_COEF(0x11, 0x0001),
+               WRITE_COEF(0x15, 0x0d60),
+               WRITE_COEF(0xc3, 0x0000),
+               {}
+       };
+-      static struct coef_fw coef0225_1[] = {
++      static const struct coef_fw coef0225_1[] = {
+               UPDATE_COEF(0x45, 0x3f<<10, 0x35<<10),
+               UPDATE_COEF(0x63, 3<<14, 2<<14),
+               {}
+       };
+-      static struct coef_fw coef0225_2[] = {
++      static const struct coef_fw coef0225_2[] = {
+               UPDATE_COEF(0x45, 0x3f<<10, 0x35<<10),
+               UPDATE_COEF(0x63, 3<<14, 1<<14),
+               {}
+@@ -4748,48 +4748,48 @@ static void alc_headset_mode_ctia(struct hda_codec *codec)
+ /* Nokia type */
+ static void alc_headset_mode_omtp(struct hda_codec *codec)
+ {
+-      static struct coef_fw coef0255[] = {
++      static const struct coef_fw coef0255[] = {
+               WRITE_COEF(0x45, 0xe489), /* Set to OMTP Type */
+               WRITE_COEF(0x1b, 0x0c2b),
+               WRITE_COEFEX(0x57, 0x03, 0x8ea6),
+               {}
+       };
+-      static struct coef_fw coef0256[] = {
++      static const struct coef_fw coef0256[] = {
+               WRITE_COEF(0x45, 0xe489), /* Set to OMTP Type */
+               WRITE_COEF(0x1b, 0x0e6b),
+               {}
+       };
+-      static struct coef_fw coef0233[] = {
++      static const struct coef_fw coef0233[] = {
+               WRITE_COEF(0x45, 0xe429),
+               WRITE_COEF(0x1b, 0x0c2b),
+               WRITE_COEF(0x32, 0x4ea3),
+               {}
+       };
+-      static struct coef_fw coef0288[] = {
++      static const struct coef_fw coef0288[] = {
+               UPDATE_COEF(0x50, 0x2000, 0x2000),
+               UPDATE_COEF(0x56, 0x0006, 0x0006),
+               UPDATE_COEF(0x66, 0x0008, 0),
+               UPDATE_COEF(0x67, 0x2000, 0),
+               {}
+       };
+-      static struct coef_fw coef0292[] = {
++      static const struct coef_fw coef0292[] = {
+               WRITE_COEF(0x6b, 0xe429),
+               WRITE_COEF(0x76, 0x0008),
+               WRITE_COEF(0x18, 0x7388),
+               {}
+       };
+-      static struct coef_fw coef0293[] = {
++      static const struct coef_fw coef0293[] = {
+               WRITE_COEF(0x45, 0xe429), /* Set to omtp type */
+               UPDATE_COEF(0x10, 7<<8, 7<<8), /* SET Line1 JD to 1 */
+               {}
+       };
+-      static struct coef_fw coef0688[] = {
++      static const struct coef_fw coef0688[] = {
+               WRITE_COEF(0x11, 0x0001),
+               WRITE_COEF(0x15, 0x0d50),
+               WRITE_COEF(0xc3, 0x0000),
+               {}
+       };
+-      static struct coef_fw coef0225[] = {
++      static const struct coef_fw coef0225[] = {
+               UPDATE_COEF(0x45, 0x3f<<10, 0x39<<10),
+               UPDATE_COEF(0x63, 3<<14, 2<<14),
+               {}
+@@ -4849,17 +4849,17 @@ static void alc_determine_headset_type(struct hda_codec *codec)
+       int val;
+       bool is_ctia = false;
+       struct alc_spec *spec = codec->spec;
+-      static struct coef_fw coef0255[] = {
++      static const struct coef_fw coef0255[] = {
+               WRITE_COEF(0x45, 0xd089), /* combo jack auto switch control(Check type)*/
+               WRITE_COEF(0x49, 0x0149), /* combo jack auto switch control(Vref
+  conteol) */
+               {}
+       };
+-      static struct coef_fw coef0288[] = {
++      static const struct coef_fw coef0288[] = {
+               UPDATE_COEF(0x4f, 0xfcc0, 0xd400), /* Check Type */
+               {}
+       };
+-      static struct coef_fw coef0298[] = {
++      static const struct coef_fw coef0298[] = {
+               UPDATE_COEF(0x50, 0x2000, 0x2000),
+               UPDATE_COEF(0x56, 0x0006, 0x0006),
+               UPDATE_COEF(0x66, 0x0008, 0),
+@@ -4867,19 +4867,19 @@ static void alc_determine_headset_type(struct hda_codec *codec)
+               UPDATE_COEF(0x19, 0x1300, 0x1300),
+               {}
+       };
+-      static struct coef_fw coef0293[] = {
++      static const struct coef_fw coef0293[] = {
+               UPDATE_COEF(0x4a, 0x000f, 0x0008), /* Combo Jack auto detect */
+               WRITE_COEF(0x45, 0xD429), /* Set to ctia type */
+               {}
+       };
+-      static struct coef_fw coef0688[] = {
++      static const struct coef_fw coef0688[] = {
+               WRITE_COEF(0x11, 0x0001),
+               WRITE_COEF(0xb7, 0x802b),
+               WRITE_COEF(0x15, 0x0d60),
+               WRITE_COEF(0xc3, 0x0c00),
+               {}
+       };
+-      static struct coef_fw coef0274[] = {
++      static const struct coef_fw coef0274[] = {
+               UPDATE_COEF(0x4a, 0x0010, 0),
+               UPDATE_COEF(0x4a, 0x8000, 0),
+               WRITE_COEF(0x45, 0xd289),
+@@ -5164,7 +5164,7 @@ static void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec,
+ static void alc255_set_default_jack_type(struct hda_codec *codec)
+ {
+       /* Set to iphone type */
+-      static struct coef_fw alc255fw[] = {
++      static const struct coef_fw alc255fw[] = {
+               WRITE_COEF(0x1b, 0x880b),
+               WRITE_COEF(0x45, 0xd089),
+               WRITE_COEF(0x1b, 0x080b),
+@@ -5172,7 +5172,7 @@ static void alc255_set_default_jack_type(struct hda_codec *codec)
+               WRITE_COEF(0x1b, 0x0c0b),
+               {}
+       };
+-      static struct coef_fw alc256fw[] = {
++      static const struct coef_fw alc256fw[] = {
+               WRITE_COEF(0x1b, 0x884b),
+               WRITE_COEF(0x45, 0xd089),
+               WRITE_COEF(0x1b, 0x084b),
+@@ -8549,7 +8549,7 @@ static void alc662_fixup_aspire_ethos_hp(struct hda_codec *codec,
+       }
+ }
+-static struct coef_fw alc668_coefs[] = {
++static const struct coef_fw alc668_coefs[] = {
+       WRITE_COEF(0x01, 0xbebe), WRITE_COEF(0x02, 0xaaaa), WRITE_COEF(0x03,    0x0),
+       WRITE_COEF(0x04, 0x0180), WRITE_COEF(0x06,    0x0), WRITE_COEF(0x07, 0x0f80),
+       WRITE_COEF(0x08, 0x0031), WRITE_COEF(0x0a, 0x0060), WRITE_COEF(0x0b,    0x0),
+-- 
+2.35.1
+
diff --git a/queue-4.19/alsa-hda-realtek-the-front-mic-on-a-hp-machine-doesn.patch b/queue-4.19/alsa-hda-realtek-the-front-mic-on-a-hp-machine-doesn.patch
new file mode 100644 (file)
index 0000000..a364d26
--- /dev/null
@@ -0,0 +1,39 @@
+From 3f997afe6915a117e99439677f69fdf9c66d1780 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Oct 2020 18:56:44 +0800
+Subject: ALSA: hda/realtek - The front Mic on a HP machine doesn't work
+
+From: Jeremy Szu <jeremy.szu@canonical.com>
+
+[ Upstream commit 148ebf548a1af366fc797fcc7d03f0bb92b12a79 ]
+
+On a HP ZCentral, the front Mic could not be detected.
+
+The codec of the HP ZCentrol is alc671 and it needs to override the pin
+configuration to enable the headset mic.
+
+Signed-off-by: Jeremy Szu <jeremy.szu@canonical.com>
+Cc: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20201008105645.65505-1-jeremy.szu@canonical.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Stable-dep-of: 4bf5bf54476d ("ALSA: hda/realtek: Add quirk for Lenovo TianYi510Pro-14IOB")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/pci/hda/patch_realtek.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index bb0917b9e68f..a3cc5cc0d668 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -9049,6 +9049,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
+       SND_PCI_QUIRK(0x1028, 0x0698, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
+       SND_PCI_QUIRK(0x1028, 0x069f, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
+       SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
++      SND_PCI_QUIRK(0x103c, 0x873e, "HP", ALC671_FIXUP_HP_HEADSET_MIC2),
+       SND_PCI_QUIRK(0x1043, 0x1080, "Asus UX501VW", ALC668_FIXUP_HEADSET_MODE),
+       SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_ASUS_Nx50),
+       SND_PCI_QUIRK(0x1043, 0x13df, "Asus N550JX", ALC662_FIXUP_BASS_1A),
+-- 
+2.35.1
+
diff --git a/queue-4.19/ext4-add-new-pending-reservation-mechanism.patch b/queue-4.19/ext4-add-new-pending-reservation-mechanism.patch
new file mode 100644 (file)
index 0000000..62f8760
--- /dev/null
@@ -0,0 +1,351 @@
+From 1e4d3f9286661240c542984257d065efdcc3afed Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 1 Oct 2018 14:17:41 -0400
+Subject: ext4: add new pending reservation mechanism
+
+From: Eric Whitney <enwlinux@gmail.com>
+
+[ Upstream commit 1dc0aa46e74a3366e12f426b7caaca477853e9c3 ]
+
+Add new pending reservation mechanism to help manage reserved cluster
+accounting.  Its primary function is to avoid the need to read extents
+from the disk when invalidating pages as a result of a truncate, punch
+hole, or collapse range operation.
+
+Signed-off-by: Eric Whitney <enwlinux@gmail.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Stable-dep-of: 131294c35ed6 ("ext4: fix delayed allocation bug in ext4_clu_mapped for bigalloc + inline")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/ext4.h           |   3 +
+ fs/ext4/extents_status.c | 187 +++++++++++++++++++++++++++++++++++++++
+ fs/ext4/extents_status.h |  51 +++++++++++
+ fs/ext4/super.c          |   8 ++
+ 4 files changed, 249 insertions(+)
+
+diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
+index 24bbfbf9a5aa..e914a0df209f 100644
+--- a/fs/ext4/ext4.h
++++ b/fs/ext4/ext4.h
+@@ -1041,6 +1041,9 @@ struct ext4_inode_info {
+       ext4_lblk_t i_da_metadata_calc_last_lblock;
+       int i_da_metadata_calc_len;
++      /* pending cluster reservations for bigalloc file systems */
++      struct ext4_pending_tree i_pending_tree;
++
+       /* on-disk additional length */
+       __u16 i_extra_isize;
+diff --git a/fs/ext4/extents_status.c b/fs/ext4/extents_status.c
+index e7503a3a3299..90e473084fd4 100644
+--- a/fs/ext4/extents_status.c
++++ b/fs/ext4/extents_status.c
+@@ -142,6 +142,7 @@
+  */
+ static struct kmem_cache *ext4_es_cachep;
++static struct kmem_cache *ext4_pending_cachep;
+ static int __es_insert_extent(struct inode *inode, struct extent_status *newes);
+ static int __es_remove_extent(struct inode *inode, ext4_lblk_t lblk,
+@@ -1363,3 +1364,189 @@ static int es_reclaim_extents(struct ext4_inode_info *ei, int *nr_to_scan)
+       ei->i_es_tree.cache_es = NULL;
+       return nr_shrunk;
+ }
++
++#ifdef ES_DEBUG__
++static void ext4_print_pending_tree(struct inode *inode)
++{
++      struct ext4_pending_tree *tree;
++      struct rb_node *node;
++      struct pending_reservation *pr;
++
++      printk(KERN_DEBUG "pending reservations for inode %lu:", inode->i_ino);
++      tree = &EXT4_I(inode)->i_pending_tree;
++      node = rb_first(&tree->root);
++      while (node) {
++              pr = rb_entry(node, struct pending_reservation, rb_node);
++              printk(KERN_DEBUG " %u", pr->lclu);
++              node = rb_next(node);
++      }
++      printk(KERN_DEBUG "\n");
++}
++#else
++#define ext4_print_pending_tree(inode)
++#endif
++
++int __init ext4_init_pending(void)
++{
++      ext4_pending_cachep = kmem_cache_create("ext4_pending_reservation",
++                                         sizeof(struct pending_reservation),
++                                         0, (SLAB_RECLAIM_ACCOUNT), NULL);
++      if (ext4_pending_cachep == NULL)
++              return -ENOMEM;
++      return 0;
++}
++
++void ext4_exit_pending(void)
++{
++      kmem_cache_destroy(ext4_pending_cachep);
++}
++
++void ext4_init_pending_tree(struct ext4_pending_tree *tree)
++{
++      tree->root = RB_ROOT;
++}
++
++/*
++ * __get_pending - retrieve a pointer to a pending reservation
++ *
++ * @inode - file containing the pending cluster reservation
++ * @lclu - logical cluster of interest
++ *
++ * Returns a pointer to a pending reservation if it's a member of
++ * the set, and NULL if not.  Must be called holding i_es_lock.
++ */
++static struct pending_reservation *__get_pending(struct inode *inode,
++                                               ext4_lblk_t lclu)
++{
++      struct ext4_pending_tree *tree;
++      struct rb_node *node;
++      struct pending_reservation *pr = NULL;
++
++      tree = &EXT4_I(inode)->i_pending_tree;
++      node = (&tree->root)->rb_node;
++
++      while (node) {
++              pr = rb_entry(node, struct pending_reservation, rb_node);
++              if (lclu < pr->lclu)
++                      node = node->rb_left;
++              else if (lclu > pr->lclu)
++                      node = node->rb_right;
++              else if (lclu == pr->lclu)
++                      return pr;
++      }
++      return NULL;
++}
++
++/*
++ * __insert_pending - adds a pending cluster reservation to the set of
++ *                    pending reservations
++ *
++ * @inode - file containing the cluster
++ * @lblk - logical block in the cluster to be added
++ *
++ * Returns 0 on successful insertion and -ENOMEM on failure.  If the
++ * pending reservation is already in the set, returns successfully.
++ */
++static int __insert_pending(struct inode *inode, ext4_lblk_t lblk)
++{
++      struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
++      struct ext4_pending_tree *tree = &EXT4_I(inode)->i_pending_tree;
++      struct rb_node **p = &tree->root.rb_node;
++      struct rb_node *parent = NULL;
++      struct pending_reservation *pr;
++      ext4_lblk_t lclu;
++      int ret = 0;
++
++      lclu = EXT4_B2C(sbi, lblk);
++      /* search to find parent for insertion */
++      while (*p) {
++              parent = *p;
++              pr = rb_entry(parent, struct pending_reservation, rb_node);
++
++              if (lclu < pr->lclu) {
++                      p = &(*p)->rb_left;
++              } else if (lclu > pr->lclu) {
++                      p = &(*p)->rb_right;
++              } else {
++                      /* pending reservation already inserted */
++                      goto out;
++              }
++      }
++
++      pr = kmem_cache_alloc(ext4_pending_cachep, GFP_ATOMIC);
++      if (pr == NULL) {
++              ret = -ENOMEM;
++              goto out;
++      }
++      pr->lclu = lclu;
++
++      rb_link_node(&pr->rb_node, parent, p);
++      rb_insert_color(&pr->rb_node, &tree->root);
++
++out:
++      return ret;
++}
++
++/*
++ * __remove_pending - removes a pending cluster reservation from the set
++ *                    of pending reservations
++ *
++ * @inode - file containing the cluster
++ * @lblk - logical block in the pending cluster reservation to be removed
++ *
++ * Returns successfully if pending reservation is not a member of the set.
++ */
++static void __remove_pending(struct inode *inode, ext4_lblk_t lblk)
++{
++      struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
++      struct pending_reservation *pr;
++      struct ext4_pending_tree *tree;
++
++      pr = __get_pending(inode, EXT4_B2C(sbi, lblk));
++      if (pr != NULL) {
++              tree = &EXT4_I(inode)->i_pending_tree;
++              rb_erase(&pr->rb_node, &tree->root);
++              kmem_cache_free(ext4_pending_cachep, pr);
++      }
++}
++
++/*
++ * ext4_remove_pending - removes a pending cluster reservation from the set
++ *                       of pending reservations
++ *
++ * @inode - file containing the cluster
++ * @lblk - logical block in the pending cluster reservation to be removed
++ *
++ * Locking for external use of __remove_pending.
++ */
++void ext4_remove_pending(struct inode *inode, ext4_lblk_t lblk)
++{
++      struct ext4_inode_info *ei = EXT4_I(inode);
++
++      write_lock(&ei->i_es_lock);
++      __remove_pending(inode, lblk);
++      write_unlock(&ei->i_es_lock);
++}
++
++/*
++ * ext4_is_pending - determine whether a cluster has a pending reservation
++ *                   on it
++ *
++ * @inode - file containing the cluster
++ * @lblk - logical block in the cluster
++ *
++ * Returns true if there's a pending reservation for the cluster in the
++ * set of pending reservations, and false if not.
++ */
++bool ext4_is_pending(struct inode *inode, ext4_lblk_t lblk)
++{
++      struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
++      struct ext4_inode_info *ei = EXT4_I(inode);
++      bool ret;
++
++      read_lock(&ei->i_es_lock);
++      ret = (bool)(__get_pending(inode, EXT4_B2C(sbi, lblk)) != NULL);
++      read_unlock(&ei->i_es_lock);
++
++      return ret;
++}
+diff --git a/fs/ext4/extents_status.h b/fs/ext4/extents_status.h
+index df9628c3ec3b..379b7171c67c 100644
+--- a/fs/ext4/extents_status.h
++++ b/fs/ext4/extents_status.h
+@@ -78,6 +78,51 @@ struct ext4_es_stats {
+       struct percpu_counter es_stats_shk_cnt;
+ };
++/*
++ * Pending cluster reservations for bigalloc file systems
++ *
++ * A cluster with a pending reservation is a logical cluster shared by at
++ * least one extent in the extents status tree with delayed and unwritten
++ * status and at least one other written or unwritten extent.  The
++ * reservation is said to be pending because a cluster reservation would
++ * have to be taken in the event all blocks in the cluster shared with
++ * written or unwritten extents were deleted while the delayed and
++ * unwritten blocks remained.
++ *
++ * The set of pending cluster reservations is an auxiliary data structure
++ * used with the extents status tree to implement reserved cluster/block
++ * accounting for bigalloc file systems.  The set is kept in memory and
++ * records all pending cluster reservations.
++ *
++ * Its primary function is to avoid the need to read extents from the
++ * disk when invalidating pages as a result of a truncate, punch hole, or
++ * collapse range operation.  Page invalidation requires a decrease in the
++ * reserved cluster count if it results in the removal of all delayed
++ * and unwritten extents (blocks) from a cluster that is not shared with a
++ * written or unwritten extent, and no decrease otherwise.  Determining
++ * whether the cluster is shared can be done by searching for a pending
++ * reservation on it.
++ *
++ * Secondarily, it provides a potentially faster method for determining
++ * whether the reserved cluster count should be increased when a physical
++ * cluster is deallocated as a result of a truncate, punch hole, or
++ * collapse range operation.  The necessary information is also present
++ * in the extents status tree, but might be more rapidly accessed in
++ * the pending reservation set in many cases due to smaller size.
++ *
++ * The pending cluster reservation set is implemented as a red-black tree
++ * with the goal of minimizing per page search time overhead.
++ */
++
++struct pending_reservation {
++      struct rb_node rb_node;
++      ext4_lblk_t lclu;
++};
++
++struct ext4_pending_tree {
++      struct rb_root root;
++};
++
+ extern int __init ext4_init_es(void);
+ extern void ext4_exit_es(void);
+ extern void ext4_es_init_tree(struct ext4_es_tree *tree);
+@@ -182,4 +227,10 @@ extern void ext4_es_unregister_shrinker(struct ext4_sb_info *sbi);
+ extern int ext4_seq_es_shrinker_info_show(struct seq_file *seq, void *v);
++extern int __init ext4_init_pending(void);
++extern void ext4_exit_pending(void);
++extern void ext4_init_pending_tree(struct ext4_pending_tree *tree);
++extern void ext4_remove_pending(struct inode *inode, ext4_lblk_t lblk);
++extern bool ext4_is_pending(struct inode *inode, ext4_lblk_t lblk);
++
+ #endif /* _EXT4_EXTENTS_STATUS_H */
+diff --git a/fs/ext4/super.c b/fs/ext4/super.c
+index e54a5be15636..73a431b6e720 100644
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -1095,6 +1095,7 @@ static struct inode *ext4_alloc_inode(struct super_block *sb)
+       ei->i_da_metadata_calc_len = 0;
+       ei->i_da_metadata_calc_last_lblock = 0;
+       spin_lock_init(&(ei->i_block_reservation_lock));
++      ext4_init_pending_tree(&ei->i_pending_tree);
+ #ifdef CONFIG_QUOTA
+       ei->i_reserved_quota = 0;
+       memset(&ei->i_dquot, 0, sizeof(ei->i_dquot));
+@@ -6189,6 +6190,10 @@ static int __init ext4_init_fs(void)
+       if (err)
+               return err;
++      err = ext4_init_pending();
++      if (err)
++              goto out6;
++
+       err = ext4_init_pageio();
+       if (err)
+               goto out5;
+@@ -6227,6 +6232,8 @@ static int __init ext4_init_fs(void)
+ out4:
+       ext4_exit_pageio();
+ out5:
++      ext4_exit_pending();
++out6:
+       ext4_exit_es();
+       return err;
+@@ -6244,6 +6251,7 @@ static void __exit ext4_exit_fs(void)
+       ext4_exit_system_zone();
+       ext4_exit_pageio();
+       ext4_exit_es();
++      ext4_exit_pending();
+ }
+ MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others");
+-- 
+2.35.1
+
diff --git a/queue-4.19/ext4-fix-bug_on-in-__es_tree_search-caused-by-bad-qu.patch b/queue-4.19/ext4-fix-bug_on-in-__es_tree_search-caused-by-bad-qu.patch
new file mode 100644 (file)
index 0000000..0f854c5
--- /dev/null
@@ -0,0 +1,114 @@
+From ca803d95c0c2b5366c817f7a9a5f8f3b01913c35 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Oct 2022 12:23:07 +0800
+Subject: ext4: fix bug_on in __es_tree_search caused by bad quota inode
+
+From: Baokun Li <libaokun1@huawei.com>
+
+[ Upstream commit d323877484765aaacbb2769b06e355c2041ed115 ]
+
+We got a issue as fllows:
+==================================================================
+ kernel BUG at fs/ext4/extents_status.c:202!
+ invalid opcode: 0000 [#1] PREEMPT SMP
+ CPU: 1 PID: 810 Comm: mount Not tainted 6.1.0-rc1-next-g9631525255e3 #352
+ RIP: 0010:__es_tree_search.isra.0+0xb8/0xe0
+ RSP: 0018:ffffc90001227900 EFLAGS: 00010202
+ RAX: 0000000000000000 RBX: 0000000077512a0f RCX: 0000000000000000
+ RDX: 0000000000000002 RSI: 0000000000002a10 RDI: ffff8881004cd0c8
+ RBP: ffff888177512ac8 R08: 47ffffffffffffff R09: 0000000000000001
+ R10: 0000000000000001 R11: 00000000000679af R12: 0000000000002a10
+ R13: ffff888177512d88 R14: 0000000077512a10 R15: 0000000000000000
+ FS: 00007f4bd76dbc40(0000)GS:ffff88842fd00000(0000)knlGS:0000000000000000
+ CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+ CR2: 00005653bf993cf8 CR3: 000000017bfdf000 CR4: 00000000000006e0
+ DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+ DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+ Call Trace:
+  <TASK>
+  ext4_es_cache_extent+0xe2/0x210
+  ext4_cache_extents+0xd2/0x110
+  ext4_find_extent+0x5d5/0x8c0
+  ext4_ext_map_blocks+0x9c/0x1d30
+  ext4_map_blocks+0x431/0xa50
+  ext4_getblk+0x82/0x340
+  ext4_bread+0x14/0x110
+  ext4_quota_read+0xf0/0x180
+  v2_read_header+0x24/0x90
+  v2_check_quota_file+0x2f/0xa0
+  dquot_load_quota_sb+0x26c/0x760
+  dquot_load_quota_inode+0xa5/0x190
+  ext4_enable_quotas+0x14c/0x300
+  __ext4_fill_super+0x31cc/0x32c0
+  ext4_fill_super+0x115/0x2d0
+  get_tree_bdev+0x1d2/0x360
+  ext4_get_tree+0x19/0x30
+  vfs_get_tree+0x26/0xe0
+  path_mount+0x81d/0xfc0
+  do_mount+0x8d/0xc0
+  __x64_sys_mount+0xc0/0x160
+  do_syscall_64+0x35/0x80
+  entry_SYSCALL_64_after_hwframe+0x63/0xcd
+  </TASK>
+==================================================================
+
+Above issue may happen as follows:
+-------------------------------------
+ext4_fill_super
+ ext4_orphan_cleanup
+  ext4_enable_quotas
+   ext4_quota_enable
+    ext4_iget --> get error inode <5>
+     ext4_ext_check_inode --> Wrong imode makes it escape inspection
+     make_bad_inode(inode) --> EXT4_BOOT_LOADER_INO set imode
+    dquot_load_quota_inode
+     vfs_setup_quota_inode --> check pass
+     dquot_load_quota_sb
+      v2_check_quota_file
+       v2_read_header
+        ext4_quota_read
+         ext4_bread
+          ext4_getblk
+           ext4_map_blocks
+            ext4_ext_map_blocks
+             ext4_find_extent
+              ext4_cache_extents
+               ext4_es_cache_extent
+                __es_tree_search.isra.0
+                 ext4_es_end --> Wrong extents trigger BUG_ON
+
+In the above issue, s_usr_quota_inum is set to 5, but inode<5> contains
+incorrect imode and disordered extents. Because 5 is EXT4_BOOT_LOADER_INO,
+the ext4_ext_check_inode check in the ext4_iget function can be bypassed,
+finally, the extents that are not checked trigger the BUG_ON in the
+__es_tree_search function. To solve this issue, check whether the inode is
+bad_inode in vfs_setup_quota_inode().
+
+Signed-off-by: Baokun Li <libaokun1@huawei.com>
+Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
+Reviewed-by: Jason Yan <yanaijie@huawei.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Link: https://lore.kernel.org/r/20221026042310.3839669-2-libaokun1@huawei.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/quota/dquot.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
+index a1d2aed0d833..770a2b143485 100644
+--- a/fs/quota/dquot.c
++++ b/fs/quota/dquot.c
+@@ -2303,6 +2303,8 @@ static int vfs_setup_quota_inode(struct inode *inode, int type)
+       struct super_block *sb = inode->i_sb;
+       struct quota_info *dqopt = sb_dqopt(sb);
++      if (is_bad_inode(inode))
++              return -EUCLEAN;
+       if (!S_ISREG(inode->i_mode))
+               return -EACCES;
+       if (IS_RDONLY(inode))
+-- 
+2.35.1
+
diff --git a/queue-4.19/ext4-fix-delayed-allocation-bug-in-ext4_clu_mapped-f.patch b/queue-4.19/ext4-fix-delayed-allocation-bug-in-ext4_clu_mapped-f.patch
new file mode 100644 (file)
index 0000000..d25b03f
--- /dev/null
@@ -0,0 +1,63 @@
+From 70a393283f87ce85b538285dfd5b6449d01eae6f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Nov 2022 10:22:07 -0500
+Subject: ext4: fix delayed allocation bug in ext4_clu_mapped for bigalloc +
+ inline
+
+From: Eric Whitney <enwlinux@gmail.com>
+
+[ Upstream commit 131294c35ed6f777bd4e79d42af13b5c41bf2775 ]
+
+When converting files with inline data to extents, delayed allocations
+made on a file system created with both the bigalloc and inline options
+can result in invalid extent status cache content, incorrect reserved
+cluster counts, kernel memory leaks, and potential kernel panics.
+
+With bigalloc, the code that determines whether a block must be
+delayed allocated searches the extent tree to see if that block maps
+to a previously allocated cluster.  If not, the block is delayed
+allocated, and otherwise, it isn't.  However, if the inline option is
+also used, and if the file containing the block is marked as able to
+store data inline, there isn't a valid extent tree associated with
+the file.  The current code in ext4_clu_mapped() calls
+ext4_find_extent() to search the non-existent tree for a previously
+allocated cluster anyway, which typically finds nothing, as desired.
+However, a side effect of the search can be to cache invalid content
+from the non-existent tree (garbage) in the extent status tree,
+including bogus entries in the pending reservation tree.
+
+To fix this, avoid searching the extent tree when allocating blocks
+for bigalloc + inline files that are being converted from inline to
+extent mapped.
+
+Signed-off-by: Eric Whitney <enwlinux@gmail.com>
+Link: https://lore.kernel.org/r/20221117152207.2424-1-enwlinux@gmail.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/extents.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
+index 0bb772cd7f88..1ad4c8eb82c1 100644
+--- a/fs/ext4/extents.c
++++ b/fs/ext4/extents.c
+@@ -5984,6 +5984,14 @@ int ext4_clu_mapped(struct inode *inode, ext4_lblk_t lclu)
+       struct ext4_extent *extent;
+       ext4_lblk_t first_lblk, first_lclu, last_lclu;
++      /*
++       * if data can be stored inline, the logical cluster isn't
++       * mapped - no physical clusters have been allocated, and the
++       * file has no extents
++       */
++      if (ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA))
++              return 0;
++
+       /* search for the extent closest to the first block in the cluster */
+       path = ext4_find_extent(inode, EXT4_C2B(sbi, lclu), NULL, 0);
+       if (IS_ERR(path)) {
+-- 
+2.35.1
+
diff --git a/queue-4.19/ext4-fix-reserved-cluster-accounting-at-delayed-writ.patch b/queue-4.19/ext4-fix-reserved-cluster-accounting-at-delayed-writ.patch
new file mode 100644 (file)
index 0000000..0ce3ee9
--- /dev/null
@@ -0,0 +1,367 @@
+From fa738f0cc8380c18b39d69f0af4eecae95cf174a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 1 Oct 2018 14:19:37 -0400
+Subject: ext4: fix reserved cluster accounting at delayed write time
+
+From: Eric Whitney <enwlinux@gmail.com>
+
+[ Upstream commit 0b02f4c0d6d9e2c611dfbdd4317193e9dca740e6 ]
+
+The code in ext4_da_map_blocks sometimes reserves space for more
+delayed allocated clusters than it should, resulting in premature
+ENOSPC, exceeded quota, and inaccurate free space reporting.
+
+Fix this by checking for written and unwritten blocks shared in the
+same cluster with the newly delayed allocated block.  A cluster
+reservation should not be made for a cluster for which physical space
+has already been allocated.
+
+Signed-off-by: Eric Whitney <enwlinux@gmail.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Stable-dep-of: 131294c35ed6 ("ext4: fix delayed allocation bug in ext4_clu_mapped for bigalloc + inline")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/ext4.h              |  1 +
+ fs/ext4/extents.c           | 79 +++++++++++++++++++++++++++++++++++++
+ fs/ext4/extents_status.c    | 53 +++++++++++++++++++++++++
+ fs/ext4/extents_status.h    | 12 ++++++
+ fs/ext4/inode.c             | 79 ++++++++++++++++++++++++++++---------
+ include/trace/events/ext4.h | 35 ++++++++++++++++
+ 6 files changed, 241 insertions(+), 18 deletions(-)
+
+diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
+index e914a0df209f..d8068c0e547d 100644
+--- a/fs/ext4/ext4.h
++++ b/fs/ext4/ext4.h
+@@ -3241,6 +3241,7 @@ extern int ext4_swap_extents(handle_t *handle, struct inode *inode1,
+                               struct inode *inode2, ext4_lblk_t lblk1,
+                            ext4_lblk_t lblk2,  ext4_lblk_t count,
+                            int mark_unwritten,int *err);
++extern int ext4_clu_mapped(struct inode *inode, ext4_lblk_t lclu);
+ /* move_extent.c */
+ extern void ext4_double_down_write_data_sem(struct inode *first,
+diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
+index c5c8326f5c25..0bb772cd7f88 100644
+--- a/fs/ext4/extents.c
++++ b/fs/ext4/extents.c
+@@ -5963,3 +5963,82 @@ ext4_swap_extents(handle_t *handle, struct inode *inode1,
+       }
+       return replaced_count;
+ }
++
++/*
++ * ext4_clu_mapped - determine whether any block in a logical cluster has
++ *                   been mapped to a physical cluster
++ *
++ * @inode - file containing the logical cluster
++ * @lclu - logical cluster of interest
++ *
++ * Returns 1 if any block in the logical cluster is mapped, signifying
++ * that a physical cluster has been allocated for it.  Otherwise,
++ * returns 0.  Can also return negative error codes.  Derived from
++ * ext4_ext_map_blocks().
++ */
++int ext4_clu_mapped(struct inode *inode, ext4_lblk_t lclu)
++{
++      struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
++      struct ext4_ext_path *path;
++      int depth, mapped = 0, err = 0;
++      struct ext4_extent *extent;
++      ext4_lblk_t first_lblk, first_lclu, last_lclu;
++
++      /* search for the extent closest to the first block in the cluster */
++      path = ext4_find_extent(inode, EXT4_C2B(sbi, lclu), NULL, 0);
++      if (IS_ERR(path)) {
++              err = PTR_ERR(path);
++              path = NULL;
++              goto out;
++      }
++
++      depth = ext_depth(inode);
++
++      /*
++       * A consistent leaf must not be empty.  This situation is possible,
++       * though, _during_ tree modification, and it's why an assert can't
++       * be put in ext4_find_extent().
++       */
++      if (unlikely(path[depth].p_ext == NULL && depth != 0)) {
++              EXT4_ERROR_INODE(inode,
++                  "bad extent address - lblock: %lu, depth: %d, pblock: %lld",
++                               (unsigned long) EXT4_C2B(sbi, lclu),
++                               depth, path[depth].p_block);
++              err = -EFSCORRUPTED;
++              goto out;
++      }
++
++      extent = path[depth].p_ext;
++
++      /* can't be mapped if the extent tree is empty */
++      if (extent == NULL)
++              goto out;
++
++      first_lblk = le32_to_cpu(extent->ee_block);
++      first_lclu = EXT4_B2C(sbi, first_lblk);
++
++      /*
++       * Three possible outcomes at this point - found extent spanning
++       * the target cluster, to the left of the target cluster, or to the
++       * right of the target cluster.  The first two cases are handled here.
++       * The last case indicates the target cluster is not mapped.
++       */
++      if (lclu >= first_lclu) {
++              last_lclu = EXT4_B2C(sbi, first_lblk +
++                                   ext4_ext_get_actual_len(extent) - 1);
++              if (lclu <= last_lclu) {
++                      mapped = 1;
++              } else {
++                      first_lblk = ext4_ext_next_allocated_block(path);
++                      first_lclu = EXT4_B2C(sbi, first_lblk);
++                      if (lclu == first_lclu)
++                              mapped = 1;
++              }
++      }
++
++out:
++      ext4_ext_drop_refs(path);
++      kfree(path);
++
++      return err ? err : mapped;
++}
+diff --git a/fs/ext4/extents_status.c b/fs/ext4/extents_status.c
+index 90e473084fd4..441ee2e747d3 100644
+--- a/fs/ext4/extents_status.c
++++ b/fs/ext4/extents_status.c
+@@ -1550,3 +1550,56 @@ bool ext4_is_pending(struct inode *inode, ext4_lblk_t lblk)
+       return ret;
+ }
++
++/*
++ * ext4_es_insert_delayed_block - adds a delayed block to the extents status
++ *                                tree, adding a pending reservation where
++ *                                needed
++ *
++ * @inode - file containing the newly added block
++ * @lblk - logical block to be added
++ * @allocated - indicates whether a physical cluster has been allocated for
++ *              the logical cluster that contains the block
++ *
++ * Returns 0 on success, negative error code on failure.
++ */
++int ext4_es_insert_delayed_block(struct inode *inode, ext4_lblk_t lblk,
++                               bool allocated)
++{
++      struct extent_status newes;
++      int err = 0;
++
++      es_debug("add [%u/1) delayed to extent status tree of inode %lu\n",
++               lblk, inode->i_ino);
++
++      newes.es_lblk = lblk;
++      newes.es_len = 1;
++      ext4_es_store_pblock_status(&newes, ~0, EXTENT_STATUS_DELAYED);
++      trace_ext4_es_insert_delayed_block(inode, &newes, allocated);
++
++      ext4_es_insert_extent_check(inode, &newes);
++
++      write_lock(&EXT4_I(inode)->i_es_lock);
++
++      err = __es_remove_extent(inode, lblk, lblk);
++      if (err != 0)
++              goto error;
++retry:
++      err = __es_insert_extent(inode, &newes);
++      if (err == -ENOMEM && __es_shrink(EXT4_SB(inode->i_sb),
++                                        128, EXT4_I(inode)))
++              goto retry;
++      if (err != 0)
++              goto error;
++
++      if (allocated)
++              __insert_pending(inode, lblk);
++
++error:
++      write_unlock(&EXT4_I(inode)->i_es_lock);
++
++      ext4_es_print_tree(inode);
++      ext4_print_pending_tree(inode);
++
++      return err;
++}
+diff --git a/fs/ext4/extents_status.h b/fs/ext4/extents_status.h
+index 379b7171c67c..9d3c676ec623 100644
+--- a/fs/ext4/extents_status.h
++++ b/fs/ext4/extents_status.h
+@@ -178,6 +178,16 @@ static inline int ext4_es_is_hole(struct extent_status *es)
+       return (ext4_es_type(es) & EXTENT_STATUS_HOLE) != 0;
+ }
++static inline int ext4_es_is_mapped(struct extent_status *es)
++{
++      return (ext4_es_is_written(es) || ext4_es_is_unwritten(es));
++}
++
++static inline int ext4_es_is_delonly(struct extent_status *es)
++{
++      return (ext4_es_is_delayed(es) && !ext4_es_is_unwritten(es));
++}
++
+ static inline void ext4_es_set_referenced(struct extent_status *es)
+ {
+       es->es_pblk |= ((ext4_fsblk_t)EXTENT_STATUS_REFERENCED) << ES_SHIFT;
+@@ -232,5 +242,7 @@ extern void ext4_exit_pending(void);
+ extern void ext4_init_pending_tree(struct ext4_pending_tree *tree);
+ extern void ext4_remove_pending(struct inode *inode, ext4_lblk_t lblk);
+ extern bool ext4_is_pending(struct inode *inode, ext4_lblk_t lblk);
++extern int ext4_es_insert_delayed_block(struct inode *inode, ext4_lblk_t lblk,
++                                      bool allocated);
+ #endif /* _EXT4_EXTENTS_STATUS_H */
+diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
+index cba27ba41834..17d120ac2010 100644
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -1823,6 +1823,65 @@ static int ext4_bh_delay_or_unwritten(handle_t *handle, struct buffer_head *bh)
+       return (buffer_delay(bh) || buffer_unwritten(bh)) && buffer_dirty(bh);
+ }
++/*
++ * ext4_insert_delayed_block - adds a delayed block to the extents status
++ *                             tree, incrementing the reserved cluster/block
++ *                             count or making a pending reservation
++ *                             where needed
++ *
++ * @inode - file containing the newly added block
++ * @lblk - logical block to be added
++ *
++ * Returns 0 on success, negative error code on failure.
++ */
++static int ext4_insert_delayed_block(struct inode *inode, ext4_lblk_t lblk)
++{
++      struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
++      int ret;
++      bool allocated = false;
++
++      /*
++       * If the cluster containing lblk is shared with a delayed,
++       * written, or unwritten extent in a bigalloc file system, it's
++       * already been accounted for and does not need to be reserved.
++       * A pending reservation must be made for the cluster if it's
++       * shared with a written or unwritten extent and doesn't already
++       * have one.  Written and unwritten extents can be purged from the
++       * extents status tree if the system is under memory pressure, so
++       * it's necessary to examine the extent tree if a search of the
++       * extents status tree doesn't get a match.
++       */
++      if (sbi->s_cluster_ratio == 1) {
++              ret = ext4_da_reserve_space(inode);
++              if (ret != 0)   /* ENOSPC */
++                      goto errout;
++      } else {   /* bigalloc */
++              if (!ext4_es_scan_clu(inode, &ext4_es_is_delonly, lblk)) {
++                      if (!ext4_es_scan_clu(inode,
++                                            &ext4_es_is_mapped, lblk)) {
++                              ret = ext4_clu_mapped(inode,
++                                                    EXT4_B2C(sbi, lblk));
++                              if (ret < 0)
++                                      goto errout;
++                              if (ret == 0) {
++                                      ret = ext4_da_reserve_space(inode);
++                                      if (ret != 0)   /* ENOSPC */
++                                              goto errout;
++                              } else {
++                                      allocated = true;
++                              }
++                      } else {
++                              allocated = true;
++                      }
++              }
++      }
++
++      ret = ext4_es_insert_delayed_block(inode, lblk, allocated);
++
++errout:
++      return ret;
++}
++
+ /*
+  * This function is grabs code from the very beginning of
+  * ext4_map_blocks, but assumes that the caller is from delayed write
+@@ -1907,25 +1966,9 @@ static int ext4_da_map_blocks(struct inode *inode, sector_t iblock,
+                * XXX: __block_prepare_write() unmaps passed block,
+                * is it OK?
+                */
+-              /*
+-               * If the block was allocated from previously allocated cluster,
+-               * then we don't need to reserve it again. However we still need
+-               * to reserve metadata for every block we're going to write.
+-               */
+-              if (EXT4_SB(inode->i_sb)->s_cluster_ratio == 1 ||
+-                  !ext4_es_scan_clu(inode,
+-                                    &ext4_es_is_delayed, map->m_lblk)) {
+-                      ret = ext4_da_reserve_space(inode);
+-                      if (ret) {
+-                              /* not enough space to reserve */
+-                              retval = ret;
+-                              goto out_unlock;
+-                      }
+-              }
+-              ret = ext4_es_insert_extent(inode, map->m_lblk, map->m_len,
+-                                          ~0, EXTENT_STATUS_DELAYED);
+-              if (ret) {
++              ret = ext4_insert_delayed_block(inode, map->m_lblk);
++              if (ret != 0) {
+                       retval = ret;
+                       goto out_unlock;
+               }
+diff --git a/include/trace/events/ext4.h b/include/trace/events/ext4.h
+index 388dc3666cc7..20c9b8e77a57 100644
+--- a/include/trace/events/ext4.h
++++ b/include/trace/events/ext4.h
+@@ -2532,6 +2532,41 @@ TRACE_EVENT(ext4_es_shrink,
+                 __entry->scan_time, __entry->nr_skipped, __entry->retried)
+ );
++TRACE_EVENT(ext4_es_insert_delayed_block,
++      TP_PROTO(struct inode *inode, struct extent_status *es,
++               bool allocated),
++
++      TP_ARGS(inode, es, allocated),
++
++      TP_STRUCT__entry(
++              __field(        dev_t,          dev             )
++              __field(        ino_t,          ino             )
++              __field(        ext4_lblk_t,    lblk            )
++              __field(        ext4_lblk_t,    len             )
++              __field(        ext4_fsblk_t,   pblk            )
++              __field(        char,           status          )
++              __field(        bool,           allocated       )
++      ),
++
++      TP_fast_assign(
++              __entry->dev            = inode->i_sb->s_dev;
++              __entry->ino            = inode->i_ino;
++              __entry->lblk           = es->es_lblk;
++              __entry->len            = es->es_len;
++              __entry->pblk           = ext4_es_pblock(es);
++              __entry->status         = ext4_es_status(es);
++              __entry->allocated      = allocated;
++      ),
++
++      TP_printk("dev %d,%d ino %lu es [%u/%u) mapped %llu status %s "
++                "allocated %d",
++                MAJOR(__entry->dev), MINOR(__entry->dev),
++                (unsigned long) __entry->ino,
++                __entry->lblk, __entry->len,
++                __entry->pblk, show_extent_status(__entry->status),
++                __entry->allocated)
++);
++
+ /* fsmap traces */
+ DECLARE_EVENT_CLASS(ext4_fsmap_class,
+       TP_PROTO(struct super_block *sb, u32 keydev, u32 agno, u64 bno, u64 len,
+-- 
+2.35.1
+
diff --git a/queue-4.19/ext4-fix-uninititialized-value-in-ext4_evict_inode.patch b/queue-4.19/ext4-fix-uninititialized-value-in-ext4_evict_inode.patch
new file mode 100644 (file)
index 0000000..96ee18a
--- /dev/null
@@ -0,0 +1,97 @@
+From d18baeee2b2eb18b38f13f083db0772fb783788f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Nov 2022 15:36:03 +0800
+Subject: ext4: fix uninititialized value in 'ext4_evict_inode'
+
+From: Ye Bin <yebin10@huawei.com>
+
+[ Upstream commit 7ea71af94eaaaf6d9aed24bc94a05b977a741cb9 ]
+
+Syzbot found the following issue:
+=====================================================
+BUG: KMSAN: uninit-value in ext4_evict_inode+0xdd/0x26b0 fs/ext4/inode.c:180
+ ext4_evict_inode+0xdd/0x26b0 fs/ext4/inode.c:180
+ evict+0x365/0x9a0 fs/inode.c:664
+ iput_final fs/inode.c:1747 [inline]
+ iput+0x985/0xdd0 fs/inode.c:1773
+ __ext4_new_inode+0xe54/0x7ec0 fs/ext4/ialloc.c:1361
+ ext4_mknod+0x376/0x840 fs/ext4/namei.c:2844
+ vfs_mknod+0x79d/0x830 fs/namei.c:3914
+ do_mknodat+0x47d/0xaa0
+ __do_sys_mknodat fs/namei.c:3992 [inline]
+ __se_sys_mknodat fs/namei.c:3989 [inline]
+ __ia32_sys_mknodat+0xeb/0x150 fs/namei.c:3989
+ do_syscall_32_irqs_on arch/x86/entry/common.c:112 [inline]
+ __do_fast_syscall_32+0xa2/0x100 arch/x86/entry/common.c:178
+ do_fast_syscall_32+0x33/0x70 arch/x86/entry/common.c:203
+ do_SYSENTER_32+0x1b/0x20 arch/x86/entry/common.c:246
+ entry_SYSENTER_compat_after_hwframe+0x70/0x82
+
+Uninit was created at:
+ __alloc_pages+0x9f1/0xe80 mm/page_alloc.c:5578
+ alloc_pages+0xaae/0xd80 mm/mempolicy.c:2285
+ alloc_slab_page mm/slub.c:1794 [inline]
+ allocate_slab+0x1b5/0x1010 mm/slub.c:1939
+ new_slab mm/slub.c:1992 [inline]
+ ___slab_alloc+0x10c3/0x2d60 mm/slub.c:3180
+ __slab_alloc mm/slub.c:3279 [inline]
+ slab_alloc_node mm/slub.c:3364 [inline]
+ slab_alloc mm/slub.c:3406 [inline]
+ __kmem_cache_alloc_lru mm/slub.c:3413 [inline]
+ kmem_cache_alloc_lru+0x6f3/0xb30 mm/slub.c:3429
+ alloc_inode_sb include/linux/fs.h:3117 [inline]
+ ext4_alloc_inode+0x5f/0x860 fs/ext4/super.c:1321
+ alloc_inode+0x83/0x440 fs/inode.c:259
+ new_inode_pseudo fs/inode.c:1018 [inline]
+ new_inode+0x3b/0x430 fs/inode.c:1046
+ __ext4_new_inode+0x2a7/0x7ec0 fs/ext4/ialloc.c:959
+ ext4_mkdir+0x4d5/0x1560 fs/ext4/namei.c:2992
+ vfs_mkdir+0x62a/0x870 fs/namei.c:4035
+ do_mkdirat+0x466/0x7b0 fs/namei.c:4060
+ __do_sys_mkdirat fs/namei.c:4075 [inline]
+ __se_sys_mkdirat fs/namei.c:4073 [inline]
+ __ia32_sys_mkdirat+0xc4/0x120 fs/namei.c:4073
+ do_syscall_32_irqs_on arch/x86/entry/common.c:112 [inline]
+ __do_fast_syscall_32+0xa2/0x100 arch/x86/entry/common.c:178
+ do_fast_syscall_32+0x33/0x70 arch/x86/entry/common.c:203
+ do_SYSENTER_32+0x1b/0x20 arch/x86/entry/common.c:246
+ entry_SYSENTER_compat_after_hwframe+0x70/0x82
+
+CPU: 1 PID: 4625 Comm: syz-executor.2 Not tainted 6.1.0-rc4-syzkaller-62821-gcb231e2f67ec #0
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/26/2022
+=====================================================
+
+Now, 'ext4_alloc_inode()' didn't init 'ei->i_flags'. If new inode failed
+before set 'ei->i_flags' in '__ext4_new_inode()', then do 'iput()'. As after
+6bc0d63dad7f commit will access 'ei->i_flags' in 'ext4_evict_inode()' which
+will lead to access uninit-value.
+To solve above issue just init 'ei->i_flags' in 'ext4_alloc_inode()'.
+
+Reported-by: syzbot+57b25da729eb0b88177d@syzkaller.appspotmail.com
+Signed-off-by: Ye Bin <yebin10@huawei.com>
+Fixes: 6bc0d63dad7f ("ext4: remove EA inode entry from mbcache on inode eviction")
+Reviewed-by: Jan Kara <jack@suse.cz>
+Reviewed-by: Eric Biggers <ebiggers@google.com>
+Link: https://lore.kernel.org/r/20221117073603.2598882-1-yebin@huaweicloud.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/super.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/fs/ext4/super.c b/fs/ext4/super.c
+index 85703a3e69e5..e54a5be15636 100644
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -1081,6 +1081,7 @@ static struct inode *ext4_alloc_inode(struct super_block *sb)
+               return NULL;
+       inode_set_iversion(&ei->vfs_inode, 1);
++      ei->i_flags = 0;
+       spin_lock_init(&ei->i_raw_lock);
+       INIT_LIST_HEAD(&ei->i_prealloc_list);
+       spin_lock_init(&ei->i_prealloc_lock);
+-- 
+2.35.1
+
diff --git a/queue-4.19/ext4-fix-use-after-free-in-ext4_orphan_cleanup.patch b/queue-4.19/ext4-fix-use-after-free-in-ext4_orphan_cleanup.patch
new file mode 100644 (file)
index 0000000..fce189a
--- /dev/null
@@ -0,0 +1,80 @@
+From c38979a0ed86a39afa58548afc86881d6960ab57 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Nov 2022 16:06:33 +0800
+Subject: ext4: fix use-after-free in ext4_orphan_cleanup
+
+From: Baokun Li <libaokun1@huawei.com>
+
+[ Upstream commit a71248b1accb2b42e4980afef4fa4a27fa0e36f5 ]
+
+I caught a issue as follows:
+==================================================================
+ BUG: KASAN: use-after-free in __list_add_valid+0x28/0x1a0
+ Read of size 8 at addr ffff88814b13f378 by task mount/710
+
+ CPU: 1 PID: 710 Comm: mount Not tainted 6.1.0-rc3-next #370
+ Call Trace:
+  <TASK>
+  dump_stack_lvl+0x73/0x9f
+  print_report+0x25d/0x759
+  kasan_report+0xc0/0x120
+  __asan_load8+0x99/0x140
+  __list_add_valid+0x28/0x1a0
+  ext4_orphan_cleanup+0x564/0x9d0 [ext4]
+  __ext4_fill_super+0x48e2/0x5300 [ext4]
+  ext4_fill_super+0x19f/0x3a0 [ext4]
+  get_tree_bdev+0x27b/0x450
+  ext4_get_tree+0x19/0x30 [ext4]
+  vfs_get_tree+0x49/0x150
+  path_mount+0xaae/0x1350
+  do_mount+0xe2/0x110
+  __x64_sys_mount+0xf0/0x190
+  do_syscall_64+0x35/0x80
+  entry_SYSCALL_64_after_hwframe+0x63/0xcd
+  </TASK>
+ [...]
+==================================================================
+
+Above issue may happen as follows:
+-------------------------------------
+ext4_fill_super
+  ext4_orphan_cleanup
+   --- loop1: assume last_orphan is 12 ---
+    list_add(&EXT4_I(inode)->i_orphan, &EXT4_SB(sb)->s_orphan)
+    ext4_truncate --> return 0
+      ext4_inode_attach_jinode --> return -ENOMEM
+    iput(inode) --> free inode<12>
+   --- loop2: last_orphan is still 12 ---
+    list_add(&EXT4_I(inode)->i_orphan, &EXT4_SB(sb)->s_orphan);
+    // use inode<12> and trigger UAF
+
+To solve this issue, we need to propagate the return value of
+ext4_inode_attach_jinode() appropriately.
+
+Signed-off-by: Baokun Li <libaokun1@huawei.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Link: https://lore.kernel.org/r/20221102080633.1630225-1-libaokun1@huawei.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/inode.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
+index 16d2b88bc66d..3c7bbdaa425a 100644
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -4568,7 +4568,8 @@ int ext4_truncate(struct inode *inode)
+       /* If we zero-out tail of the page, we have to create jinode for jbd2 */
+       if (inode->i_size & (inode->i_sb->s_blocksize - 1)) {
+-              if (ext4_inode_attach_jinode(inode) < 0)
++              err = ext4_inode_attach_jinode(inode);
++              if (err)
+                       goto out_trace;
+       }
+-- 
+2.35.1
+
diff --git a/queue-4.19/ext4-generalize-extents-status-tree-search-functions.patch b/queue-4.19/ext4-generalize-extents-status-tree-search-functions.patch
new file mode 100644 (file)
index 0000000..58193a9
--- /dev/null
@@ -0,0 +1,457 @@
+From 24d8fd52d6535265069404abafc1d2223c93db9c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 1 Oct 2018 14:10:39 -0400
+Subject: ext4: generalize extents status tree search functions
+
+From: Eric Whitney <enwlinux@gmail.com>
+
+[ Upstream commit ad431025aecda85d3ebef5e4a3aca5c1c681d0c7 ]
+
+Ext4 contains a few functions that are used to search for delayed
+extents or blocks in the extents status tree.  Rather than duplicate
+code to add new functions to search for extents with different status
+values, such as written or a combination of delayed and unwritten,
+generalize the existing code to search for caller-specified extents
+status values.  Also, move this code into extents_status.c where it
+is better associated with the data structures it operates upon, and
+where it can be more readily used to implement new extents status tree
+functions that might want a broader scope for i_es_lock.
+
+Three missing static specifiers in RFC version of patch reported and
+fixed by Fengguang Wu <fengguang.wu@intel.com>.
+
+Signed-off-by: Eric Whitney <enwlinux@gmail.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Stable-dep-of: 131294c35ed6 ("ext4: fix delayed allocation bug in ext4_clu_mapped for bigalloc + inline")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/ext4.h              |   4 -
+ fs/ext4/extents.c           |  52 +++----------
+ fs/ext4/extents_status.c    | 149 +++++++++++++++++++++++++++++++-----
+ fs/ext4/extents_status.h    |  13 +++-
+ fs/ext4/inode.c             |  17 ++--
+ include/trace/events/ext4.h |   4 +-
+ 6 files changed, 165 insertions(+), 74 deletions(-)
+
+diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
+index e58b162ad5d6..24bbfbf9a5aa 100644
+--- a/fs/ext4/ext4.h
++++ b/fs/ext4/ext4.h
+@@ -3228,10 +3228,6 @@ extern struct ext4_ext_path *ext4_find_extent(struct inode *, ext4_lblk_t,
+                                             int flags);
+ extern void ext4_ext_drop_refs(struct ext4_ext_path *);
+ extern int ext4_ext_check_inode(struct inode *inode);
+-extern int ext4_find_delalloc_range(struct inode *inode,
+-                                  ext4_lblk_t lblk_start,
+-                                  ext4_lblk_t lblk_end);
+-extern int ext4_find_delalloc_cluster(struct inode *inode, ext4_lblk_t lblk);
+ extern ext4_lblk_t ext4_ext_next_allocated_block(struct ext4_ext_path *path);
+ extern int ext4_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
+                       __u64 start, __u64 len);
+diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
+index 6c492fca60c4..c5c8326f5c25 100644
+--- a/fs/ext4/extents.c
++++ b/fs/ext4/extents.c
+@@ -2381,8 +2381,8 @@ ext4_ext_put_gap_in_cache(struct inode *inode, ext4_lblk_t hole_start,
+ {
+       struct extent_status es;
+-      ext4_es_find_delayed_extent_range(inode, hole_start,
+-                                        hole_start + hole_len - 1, &es);
++      ext4_es_find_extent_range(inode, &ext4_es_is_delayed, hole_start,
++                                hole_start + hole_len - 1, &es);
+       if (es.es_len) {
+               /* There's delayed extent containing lblock? */
+               if (es.es_lblk <= hole_start)
+@@ -3852,39 +3852,6 @@ static int check_eofblocks_fl(handle_t *handle, struct inode *inode,
+       return ext4_mark_inode_dirty(handle, inode);
+ }
+-/**
+- * ext4_find_delalloc_range: find delayed allocated block in the given range.
+- *
+- * Return 1 if there is a delalloc block in the range, otherwise 0.
+- */
+-int ext4_find_delalloc_range(struct inode *inode,
+-                           ext4_lblk_t lblk_start,
+-                           ext4_lblk_t lblk_end)
+-{
+-      struct extent_status es;
+-
+-      ext4_es_find_delayed_extent_range(inode, lblk_start, lblk_end, &es);
+-      if (es.es_len == 0)
+-              return 0; /* there is no delay extent in this tree */
+-      else if (es.es_lblk <= lblk_start &&
+-               lblk_start < es.es_lblk + es.es_len)
+-              return 1;
+-      else if (lblk_start <= es.es_lblk && es.es_lblk <= lblk_end)
+-              return 1;
+-      else
+-              return 0;
+-}
+-
+-int ext4_find_delalloc_cluster(struct inode *inode, ext4_lblk_t lblk)
+-{
+-      struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
+-      ext4_lblk_t lblk_start, lblk_end;
+-      lblk_start = EXT4_LBLK_CMASK(sbi, lblk);
+-      lblk_end = lblk_start + sbi->s_cluster_ratio - 1;
+-
+-      return ext4_find_delalloc_range(inode, lblk_start, lblk_end);
+-}
+-
+ /**
+  * Determines how many complete clusters (out of those specified by the 'map')
+  * are under delalloc and were reserved quota for.
+@@ -3943,7 +3910,8 @@ get_reserved_cluster_alloc(struct inode *inode, ext4_lblk_t lblk_start,
+               lblk_from = EXT4_LBLK_CMASK(sbi, lblk_start);
+               lblk_to = lblk_from + c_offset - 1;
+-              if (ext4_find_delalloc_range(inode, lblk_from, lblk_to))
++              if (ext4_es_scan_range(inode, &ext4_es_is_delayed, lblk_from,
++                                     lblk_to))
+                       allocated_clusters--;
+       }
+@@ -3953,7 +3921,8 @@ get_reserved_cluster_alloc(struct inode *inode, ext4_lblk_t lblk_start,
+               lblk_from = lblk_start + num_blks;
+               lblk_to = lblk_from + (sbi->s_cluster_ratio - c_offset) - 1;
+-              if (ext4_find_delalloc_range(inode, lblk_from, lblk_to))
++              if (ext4_es_scan_range(inode, &ext4_es_is_delayed, lblk_from,
++                                     lblk_to))
+                       allocated_clusters--;
+       }
+@@ -5108,8 +5077,10 @@ static int ext4_find_delayed_extent(struct inode *inode,
+       ext4_lblk_t block, next_del;
+       if (newes->es_pblk == 0) {
+-              ext4_es_find_delayed_extent_range(inode, newes->es_lblk,
+-                              newes->es_lblk + newes->es_len - 1, &es);
++              ext4_es_find_extent_range(inode, &ext4_es_is_delayed,
++                                        newes->es_lblk,
++                                        newes->es_lblk + newes->es_len - 1,
++                                        &es);
+               /*
+                * No extent in extent-tree contains block @newes->es_pblk,
+@@ -5130,7 +5101,8 @@ static int ext4_find_delayed_extent(struct inode *inode,
+       }
+       block = newes->es_lblk + newes->es_len;
+-      ext4_es_find_delayed_extent_range(inode, block, EXT_MAX_BLOCKS, &es);
++      ext4_es_find_extent_range(inode, &ext4_es_is_delayed, block,
++                                EXT_MAX_BLOCKS, &es);
+       if (es.es_len == 0)
+               next_del = EXT_MAX_BLOCKS;
+       else
+diff --git a/fs/ext4/extents_status.c b/fs/ext4/extents_status.c
+index 027c3e1b9f61..e7503a3a3299 100644
+--- a/fs/ext4/extents_status.c
++++ b/fs/ext4/extents_status.c
+@@ -233,30 +233,38 @@ static struct extent_status *__es_tree_search(struct rb_root *root,
+ }
+ /*
+- * ext4_es_find_delayed_extent_range: find the 1st delayed extent covering
+- * @es->lblk if it exists, otherwise, the next extent after @es->lblk.
++ * ext4_es_find_extent_range - find extent with specified status within block
++ *                             range or next extent following block range in
++ *                             extents status tree
+  *
+- * @inode: the inode which owns delayed extents
+- * @lblk: the offset where we start to search
+- * @end: the offset where we stop to search
+- * @es: delayed extent that we found
++ * @inode - file containing the range
++ * @matching_fn - pointer to function that matches extents with desired status
++ * @lblk - logical block defining start of range
++ * @end - logical block defining end of range
++ * @es - extent found, if any
++ *
++ * Find the first extent within the block range specified by @lblk and @end
++ * in the extents status tree that satisfies @matching_fn.  If a match
++ * is found, it's returned in @es.  If not, and a matching extent is found
++ * beyond the block range, it's returned in @es.  If no match is found, an
++ * extent is returned in @es whose es_lblk, es_len, and es_pblk components
++ * are 0.
+  */
+-void ext4_es_find_delayed_extent_range(struct inode *inode,
+-                               ext4_lblk_t lblk, ext4_lblk_t end,
+-                               struct extent_status *es)
++static void __es_find_extent_range(struct inode *inode,
++                                 int (*matching_fn)(struct extent_status *es),
++                                 ext4_lblk_t lblk, ext4_lblk_t end,
++                                 struct extent_status *es)
+ {
+       struct ext4_es_tree *tree = NULL;
+       struct extent_status *es1 = NULL;
+       struct rb_node *node;
+-      BUG_ON(es == NULL);
+-      BUG_ON(end < lblk);
+-      trace_ext4_es_find_delayed_extent_range_enter(inode, lblk);
++      WARN_ON(es == NULL);
++      WARN_ON(end < lblk);
+-      read_lock(&EXT4_I(inode)->i_es_lock);
+       tree = &EXT4_I(inode)->i_es_tree;
+-      /* find extent in cache firstly */
++      /* see if the extent has been cached */
+       es->es_lblk = es->es_len = es->es_pblk = 0;
+       if (tree->cache_es) {
+               es1 = tree->cache_es;
+@@ -271,28 +279,133 @@ void ext4_es_find_delayed_extent_range(struct inode *inode,
+       es1 = __es_tree_search(&tree->root, lblk);
+ out:
+-      if (es1 && !ext4_es_is_delayed(es1)) {
++      if (es1 && !matching_fn(es1)) {
+               while ((node = rb_next(&es1->rb_node)) != NULL) {
+                       es1 = rb_entry(node, struct extent_status, rb_node);
+                       if (es1->es_lblk > end) {
+                               es1 = NULL;
+                               break;
+                       }
+-                      if (ext4_es_is_delayed(es1))
++                      if (matching_fn(es1))
+                               break;
+               }
+       }
+-      if (es1 && ext4_es_is_delayed(es1)) {
++      if (es1 && matching_fn(es1)) {
+               tree->cache_es = es1;
+               es->es_lblk = es1->es_lblk;
+               es->es_len = es1->es_len;
+               es->es_pblk = es1->es_pblk;
+       }
++}
++
++/*
++ * Locking for __es_find_extent_range() for external use
++ */
++void ext4_es_find_extent_range(struct inode *inode,
++                             int (*matching_fn)(struct extent_status *es),
++                             ext4_lblk_t lblk, ext4_lblk_t end,
++                             struct extent_status *es)
++{
++      trace_ext4_es_find_extent_range_enter(inode, lblk);
++
++      read_lock(&EXT4_I(inode)->i_es_lock);
++      __es_find_extent_range(inode, matching_fn, lblk, end, es);
++      read_unlock(&EXT4_I(inode)->i_es_lock);
++
++      trace_ext4_es_find_extent_range_exit(inode, es);
++}
++
++/*
++ * __es_scan_range - search block range for block with specified status
++ *                   in extents status tree
++ *
++ * @inode - file containing the range
++ * @matching_fn - pointer to function that matches extents with desired status
++ * @lblk - logical block defining start of range
++ * @end - logical block defining end of range
++ *
++ * Returns true if at least one block in the specified block range satisfies
++ * the criterion specified by @matching_fn, and false if not.  If at least
++ * one extent has the specified status, then there is at least one block
++ * in the cluster with that status.  Should only be called by code that has
++ * taken i_es_lock.
++ */
++static bool __es_scan_range(struct inode *inode,
++                          int (*matching_fn)(struct extent_status *es),
++                          ext4_lblk_t start, ext4_lblk_t end)
++{
++      struct extent_status es;
++
++      __es_find_extent_range(inode, matching_fn, start, end, &es);
++      if (es.es_len == 0)
++              return false;   /* no matching extent in the tree */
++      else if (es.es_lblk <= start &&
++               start < es.es_lblk + es.es_len)
++              return true;
++      else if (start <= es.es_lblk && es.es_lblk <= end)
++              return true;
++      else
++              return false;
++}
++/*
++ * Locking for __es_scan_range() for external use
++ */
++bool ext4_es_scan_range(struct inode *inode,
++                      int (*matching_fn)(struct extent_status *es),
++                      ext4_lblk_t lblk, ext4_lblk_t end)
++{
++      bool ret;
++
++      read_lock(&EXT4_I(inode)->i_es_lock);
++      ret = __es_scan_range(inode, matching_fn, lblk, end);
++      read_unlock(&EXT4_I(inode)->i_es_lock);
++
++      return ret;
++}
++
++/*
++ * __es_scan_clu - search cluster for block with specified status in
++ *                 extents status tree
++ *
++ * @inode - file containing the cluster
++ * @matching_fn - pointer to function that matches extents with desired status
++ * @lblk - logical block in cluster to be searched
++ *
++ * Returns true if at least one extent in the cluster containing @lblk
++ * satisfies the criterion specified by @matching_fn, and false if not.  If at
++ * least one extent has the specified status, then there is at least one block
++ * in the cluster with that status.  Should only be called by code that has
++ * taken i_es_lock.
++ */
++static bool __es_scan_clu(struct inode *inode,
++                        int (*matching_fn)(struct extent_status *es),
++                        ext4_lblk_t lblk)
++{
++      struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
++      ext4_lblk_t lblk_start, lblk_end;
++
++      lblk_start = EXT4_LBLK_CMASK(sbi, lblk);
++      lblk_end = lblk_start + sbi->s_cluster_ratio - 1;
++
++      return __es_scan_range(inode, matching_fn, lblk_start, lblk_end);
++}
++
++/*
++ * Locking for __es_scan_clu() for external use
++ */
++bool ext4_es_scan_clu(struct inode *inode,
++                    int (*matching_fn)(struct extent_status *es),
++                    ext4_lblk_t lblk)
++{
++      bool ret;
++
++      read_lock(&EXT4_I(inode)->i_es_lock);
++      ret = __es_scan_clu(inode, matching_fn, lblk);
+       read_unlock(&EXT4_I(inode)->i_es_lock);
+-      trace_ext4_es_find_delayed_extent_range_exit(inode, es);
++      return ret;
+ }
+ static void ext4_es_list_add(struct inode *inode)
+diff --git a/fs/ext4/extents_status.h b/fs/ext4/extents_status.h
+index 8efdeb903d6b..df9628c3ec3b 100644
+--- a/fs/ext4/extents_status.h
++++ b/fs/ext4/extents_status.h
+@@ -90,11 +90,18 @@ extern void ext4_es_cache_extent(struct inode *inode, ext4_lblk_t lblk,
+                                unsigned int status);
+ extern int ext4_es_remove_extent(struct inode *inode, ext4_lblk_t lblk,
+                                ext4_lblk_t len);
+-extern void ext4_es_find_delayed_extent_range(struct inode *inode,
+-                                      ext4_lblk_t lblk, ext4_lblk_t end,
+-                                      struct extent_status *es);
++extern void ext4_es_find_extent_range(struct inode *inode,
++                                    int (*match_fn)(struct extent_status *es),
++                                    ext4_lblk_t lblk, ext4_lblk_t end,
++                                    struct extent_status *es);
+ extern int ext4_es_lookup_extent(struct inode *inode, ext4_lblk_t lblk,
+                                struct extent_status *es);
++extern bool ext4_es_scan_range(struct inode *inode,
++                             int (*matching_fn)(struct extent_status *es),
++                             ext4_lblk_t lblk, ext4_lblk_t end);
++extern bool ext4_es_scan_clu(struct inode *inode,
++                           int (*matching_fn)(struct extent_status *es),
++                           ext4_lblk_t lblk);
+ static inline unsigned int ext4_es_status(struct extent_status *es)
+ {
+diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
+index 3c7bbdaa425a..cba27ba41834 100644
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -600,8 +600,8 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode,
+                               EXTENT_STATUS_UNWRITTEN : EXTENT_STATUS_WRITTEN;
+               if (!(flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE) &&
+                   !(status & EXTENT_STATUS_WRITTEN) &&
+-                  ext4_find_delalloc_range(inode, map->m_lblk,
+-                                           map->m_lblk + map->m_len - 1))
++                  ext4_es_scan_range(inode, &ext4_es_is_delayed, map->m_lblk,
++                                     map->m_lblk + map->m_len - 1))
+                       status |= EXTENT_STATUS_DELAYED;
+               ret = ext4_es_insert_extent(inode, map->m_lblk,
+                                           map->m_len, map->m_pblk, status);
+@@ -724,8 +724,8 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode,
+                               EXTENT_STATUS_UNWRITTEN : EXTENT_STATUS_WRITTEN;
+               if (!(flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE) &&
+                   !(status & EXTENT_STATUS_WRITTEN) &&
+-                  ext4_find_delalloc_range(inode, map->m_lblk,
+-                                           map->m_lblk + map->m_len - 1))
++                  ext4_es_scan_range(inode, &ext4_es_is_delayed, map->m_lblk,
++                                     map->m_lblk + map->m_len - 1))
+                       status |= EXTENT_STATUS_DELAYED;
+               ret = ext4_es_insert_extent(inode, map->m_lblk, map->m_len,
+                                           map->m_pblk, status);
+@@ -1717,7 +1717,7 @@ static void ext4_da_page_release_reservation(struct page *page,
+               lblk = (page->index << (PAGE_SHIFT - inode->i_blkbits)) +
+                       ((num_clusters - 1) << sbi->s_cluster_bits);
+               if (sbi->s_cluster_ratio == 1 ||
+-                  !ext4_find_delalloc_cluster(inode, lblk))
++                  !ext4_es_scan_clu(inode, &ext4_es_is_delayed, lblk))
+                       ext4_da_release_space(inode, 1);
+               num_clusters--;
+@@ -1902,6 +1902,7 @@ static int ext4_da_map_blocks(struct inode *inode, sector_t iblock,
+ add_delayed:
+       if (retval == 0) {
+               int ret;
++
+               /*
+                * XXX: __block_prepare_write() unmaps passed block,
+                * is it OK?
+@@ -1912,7 +1913,8 @@ static int ext4_da_map_blocks(struct inode *inode, sector_t iblock,
+                * to reserve metadata for every block we're going to write.
+                */
+               if (EXT4_SB(inode->i_sb)->s_cluster_ratio == 1 ||
+-                  !ext4_find_delalloc_cluster(inode, map->m_lblk)) {
++                  !ext4_es_scan_clu(inode,
++                                    &ext4_es_is_delayed, map->m_lblk)) {
+                       ret = ext4_da_reserve_space(inode);
+                       if (ret) {
+                               /* not enough space to reserve */
+@@ -3519,7 +3521,8 @@ static int ext4_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
+                       ext4_lblk_t end = map.m_lblk + map.m_len - 1;
+                       struct extent_status es;
+-                      ext4_es_find_delayed_extent_range(inode, map.m_lblk, end, &es);
++                      ext4_es_find_extent_range(inode, &ext4_es_is_delayed,
++                                                map.m_lblk, end, &es);
+                       if (!es.es_len || es.es_lblk > end) {
+                               /* entire range is a hole */
+diff --git a/include/trace/events/ext4.h b/include/trace/events/ext4.h
+index 0dfb174f707e..388dc3666cc7 100644
+--- a/include/trace/events/ext4.h
++++ b/include/trace/events/ext4.h
+@@ -2290,7 +2290,7 @@ TRACE_EVENT(ext4_es_remove_extent,
+                 __entry->lblk, __entry->len)
+ );
+-TRACE_EVENT(ext4_es_find_delayed_extent_range_enter,
++TRACE_EVENT(ext4_es_find_extent_range_enter,
+       TP_PROTO(struct inode *inode, ext4_lblk_t lblk),
+       TP_ARGS(inode, lblk),
+@@ -2312,7 +2312,7 @@ TRACE_EVENT(ext4_es_find_delayed_extent_range_enter,
+                 (unsigned long) __entry->ino, __entry->lblk)
+ );
+-TRACE_EVENT(ext4_es_find_delayed_extent_range_exit,
++TRACE_EVENT(ext4_es_find_extent_range_exit,
+       TP_PROTO(struct inode *inode, struct extent_status *es),
+       TP_ARGS(inode, es),
+-- 
+2.35.1
+
diff --git a/queue-4.19/ext4-lost-matching-pair-of-trace-in-ext4_truncate.patch b/queue-4.19/ext4-lost-matching-pair-of-trace-in-ext4_truncate.patch
new file mode 100644 (file)
index 0000000..29b0621
--- /dev/null
@@ -0,0 +1,79 @@
+From 2c7d9deb7582867fbf82542db6612c226b15af2f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 1 Jul 2020 16:30:27 +0800
+Subject: ext4: lost matching-pair of trace in ext4_truncate
+
+From: zhengliang <zhengliang6@huawei.com>
+
+[ Upstream commit 9a5d265fed014115f35e598022c956e5d2fb863e ]
+
+It should call trace exit in all return path for ext4_truncate.
+
+Signed-off-by: zhengliang <zhengliang6@huawei.com>
+Reviewed-by: Andreas Dilger <adilger@dilger.ca>
+Reviewed-by: Ritesh Harjani <riteshh@linux.ibm.com>
+Link: https://lore.kernel.org/r/20200701083027.45996-1-zhengliang6@huawei.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Stable-dep-of: a71248b1accb ("ext4: fix use-after-free in ext4_orphan_cleanup")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/inode.c | 17 +++++++++--------
+ 1 file changed, 9 insertions(+), 8 deletions(-)
+
+diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
+index b322658ceff1..16d2b88bc66d 100644
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -4551,7 +4551,7 @@ int ext4_truncate(struct inode *inode)
+       trace_ext4_truncate_enter(inode);
+       if (!ext4_can_truncate(inode))
+-              return 0;
++              goto out_trace;
+       ext4_clear_inode_flag(inode, EXT4_INODE_EOFBLOCKS);
+@@ -4562,16 +4562,14 @@ int ext4_truncate(struct inode *inode)
+               int has_inline = 1;
+               err = ext4_inline_data_truncate(inode, &has_inline);
+-              if (err)
+-                      return err;
+-              if (has_inline)
+-                      return 0;
++              if (err || has_inline)
++                      goto out_trace;
+       }
+       /* If we zero-out tail of the page, we have to create jinode for jbd2 */
+       if (inode->i_size & (inode->i_sb->s_blocksize - 1)) {
+               if (ext4_inode_attach_jinode(inode) < 0)
+-                      return 0;
++                      goto out_trace;
+       }
+       if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))
+@@ -4580,8 +4578,10 @@ int ext4_truncate(struct inode *inode)
+               credits = ext4_blocks_for_truncate(inode);
+       handle = ext4_journal_start(inode, EXT4_HT_TRUNCATE, credits);
+-      if (IS_ERR(handle))
+-              return PTR_ERR(handle);
++      if (IS_ERR(handle)) {
++              err = PTR_ERR(handle);
++              goto out_trace;
++      }
+       if (inode->i_size & (inode->i_sb->s_blocksize - 1))
+               ext4_block_truncate_page(handle, mapping, inode->i_size);
+@@ -4630,6 +4630,7 @@ int ext4_truncate(struct inode *inode)
+       ext4_mark_inode_dirty(handle, inode);
+       ext4_journal_stop(handle);
++out_trace:
+       trace_ext4_truncate_exit(inode);
+       return err;
+ }
+-- 
+2.35.1
+
diff --git a/queue-4.19/kest.pl-fix-grub2-menu-handling-for-rebooting.patch b/queue-4.19/kest.pl-fix-grub2-menu-handling-for-rebooting.patch
new file mode 100644 (file)
index 0000000..3149f97
--- /dev/null
@@ -0,0 +1,128 @@
+From 2ef6249539ff0a94c778486d5043123e550d7c07 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Nov 2022 17:54:34 -0500
+Subject: kest.pl: Fix grub2 menu handling for rebooting
+
+From: Steven Rostedt <rostedt@goodmis.org>
+
+[ Upstream commit 26df05a8c1420ad3de314fdd407e7fc2058cc7aa ]
+
+grub2 has submenus where to use grub-reboot, it requires:
+
+  grub-reboot X>Y
+
+where X is the main index and Y is the submenu. Thus if you have:
+
+menuentry 'Debian GNU/Linux' --class debian --class gnu-linux ...
+       [...]
+}
+submenu 'Advanced options for Debian GNU/Linux' $menuentry_id_option ...
+        menuentry 'Debian GNU/Linux, with Linux 6.0.0-4-amd64' --class debian --class gnu-linux ...
+                [...]
+        }
+        menuentry 'Debian GNU/Linux, with Linux 6.0.0-4-amd64 (recovery mode)' --class debian --class gnu-linux ...
+               [...]
+        }
+        menuentry 'Debian GNU/Linux, with Linux test' --class debian --class gnu-linux ...
+                [...]
+        }
+
+And wanted to boot to the "Linux test" kernel, you need to run:
+
+ # grub-reboot 1>2
+
+As 1 is the second top menu (the submenu) and 2 is the third of the sub
+menu entries.
+
+Have the grub.cfg parsing for grub2 handle such cases.
+
+Cc: stable@vger.kernel.org
+Fixes: a15ba91361d46 ("ktest: Add support for grub2")
+Reviewed-by: John 'Warthog9' Hawley (VMware) <warthog9@eaglescrag.net>
+Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/ktest/ktest.pl | 20 +++++++++++++++-----
+ 1 file changed, 15 insertions(+), 5 deletions(-)
+
+diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl
+index 689fa4fd3d76..a0b53309c5d8 100755
+--- a/tools/testing/ktest/ktest.pl
++++ b/tools/testing/ktest/ktest.pl
+@@ -1860,7 +1860,7 @@ sub run_scp_mod {
+ sub _get_grub_index {
+-    my ($command, $target, $skip) = @_;
++    my ($command, $target, $skip, $submenu) = @_;
+     return if (defined($grub_number) && defined($last_grub_menu) &&
+              $last_grub_menu eq $grub_menu && defined($last_machine) &&
+@@ -1877,11 +1877,16 @@ sub _get_grub_index {
+     my $found = 0;
++    my $submenu_number = 0;
++
+     while (<IN>) {
+       if (/$target/) {
+           $grub_number++;
+           $found = 1;
+           last;
++      } elsif (defined($submenu) && /$submenu/) {
++              $submenu_number++;
++              $grub_number = -1;
+       } elsif (/$skip/) {
+           $grub_number++;
+       }
+@@ -1890,6 +1895,9 @@ sub _get_grub_index {
+     dodie "Could not find '$grub_menu' through $command on $machine"
+       if (!$found);
++    if ($submenu_number > 0) {
++      $grub_number = "$submenu_number>$grub_number";
++    }
+     doprint "$grub_number\n";
+     $last_grub_menu = $grub_menu;
+     $last_machine = $machine;
+@@ -1936,6 +1944,7 @@ sub get_grub_index {
+     my $command;
+     my $target;
+     my $skip;
++    my $submenu;
+     my $grub_menu_qt;
+     if ($reboot_type !~ /^grub/) {
+@@ -1950,8 +1959,9 @@ sub get_grub_index {
+       $skip = '^\s*title\s';
+     } elsif ($reboot_type eq "grub2") {
+       $command = "cat $grub_file";
+-      $target = '^menuentry.*' . $grub_menu_qt;
+-      $skip = '^menuentry\s|^submenu\s';
++      $target = '^\s*menuentry.*' . $grub_menu_qt;
++      $skip = '^\s*menuentry';
++      $submenu = '^\s*submenu\s';
+     } elsif ($reboot_type eq "grub2bls") {
+         $command = $grub_bls_get;
+         $target = '^title=.*' . $grub_menu_qt;
+@@ -1960,7 +1970,7 @@ sub get_grub_index {
+       return;
+     }
+-    _get_grub_index($command, $target, $skip);
++    _get_grub_index($command, $target, $skip, $submenu);
+ }
+ sub wait_for_input
+@@ -2024,7 +2034,7 @@ sub reboot_to {
+     if ($reboot_type eq "grub") {
+       run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch)'";
+     } elsif (($reboot_type eq "grub2") or ($reboot_type eq "grub2bls")) {
+-      run_ssh "$grub_reboot $grub_number";
++      run_ssh "$grub_reboot \"'$grub_number'\"";
+     } elsif ($reboot_type eq "syslinux") {
+       run_ssh "$syslinux --once \\\"$syslinux_label\\\" $syslinux_path";
+     } elsif (defined $reboot_script) {
+-- 
+2.35.1
+
diff --git a/queue-4.19/ktest-add-support-for-meta-characters-in-grub_menu.patch b/queue-4.19/ktest-add-support-for-meta-characters-in-grub_menu.patch
new file mode 100644 (file)
index 0000000..0794235
--- /dev/null
@@ -0,0 +1,58 @@
+From 00893dd3710e13e7ecf9a3110d31d6deb4d51674 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Apr 2019 19:58:23 -0400
+Subject: ktest: Add support for meta characters in GRUB_MENU
+
+From: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
+
+[ Upstream commit 68911069f509ba3bf0f513d9af00309e07932906 ]
+
+ktest fails if meta characters are in GRUB_MENU, for example
+GRUB_MENU = 'Fedora (test)'
+
+The failure happens because the meta characters are not escaped,
+so the menu doesn't match in any entries in GRUB_FILE.
+
+Use quotemeta() to escape the meta characters.
+
+Link: http://lkml.kernel.org/r/20190417235823.18176-1-msys.mizuma@gmail.com
+
+Signed-off-by: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
+Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
+Stable-dep-of: 26df05a8c142 ("kest.pl: Fix grub2 menu handling for rebooting")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/ktest/ktest.pl | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl
+index 92663d123be1..635121ecf543 100755
+--- a/tools/testing/ktest/ktest.pl
++++ b/tools/testing/ktest/ktest.pl
+@@ -1866,9 +1866,10 @@ sub get_grub2_index {
+       or dodie "unable to get $grub_file";
+     my $found = 0;
++    my $grub_menu_qt = quotemeta($grub_menu);
+     while (<IN>) {
+-      if (/^menuentry.*$grub_menu/) {
++      if (/^menuentry.*$grub_menu_qt/) {
+           $grub_number++;
+           $found = 1;
+           last;
+@@ -1909,9 +1910,10 @@ sub get_grub_index {
+       or dodie "unable to get menu.lst";
+     my $found = 0;
++    my $grub_menu_qt = quotemeta($grub_menu);
+     while (<IN>) {
+-      if (/^\s*title\s+$grub_menu\s*$/) {
++      if (/^\s*title\s+$grub_menu_qt\s*$/) {
+           $grub_number++;
+           $found = 1;
+           last;
+-- 
+2.35.1
+
diff --git a/queue-4.19/ktest-cleanup-get_grub_index.patch b/queue-4.19/ktest-cleanup-get_grub_index.patch
new file mode 100644 (file)
index 0000000..ede3736
--- /dev/null
@@ -0,0 +1,92 @@
+From f056a77a93c17e5c10f6b6bb3401470ef2a4b78b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 May 2019 17:36:43 -0400
+Subject: ktest: cleanup get_grub_index
+
+From: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
+
+[ Upstream commit 38891392916c42d4ba46f474d553c76d1ed329ca ]
+
+Cleanup get_grub_index().
+
+Link: http://lkml.kernel.org/r/20190509213647.6276-3-msys.mizuma@gmail.com
+
+Signed-off-by: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
+Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
+Stable-dep-of: 26df05a8c142 ("kest.pl: Fix grub2 menu handling for rebooting")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/ktest/ktest.pl | 50 ++++++++++++------------------------
+ 1 file changed, 17 insertions(+), 33 deletions(-)
+
+diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl
+index 5fa60b3c564f..a1067469ba0e 100755
+--- a/tools/testing/ktest/ktest.pl
++++ b/tools/testing/ktest/ktest.pl
+@@ -1925,46 +1925,30 @@ sub get_grub2_index {
+ sub get_grub_index {
+-    if ($reboot_type eq "grub2") {
+-      get_grub2_index;
+-      return;
+-    }
++    my $command;
++    my $target;
++    my $skip;
++    my $grub_menu_qt;
+-    if ($reboot_type ne "grub") {
++    if ($reboot_type !~ /^grub/) {
+       return;
+     }
+-    return if (defined($grub_number) && defined($last_grub_menu) &&
+-             $last_grub_menu eq $grub_menu && defined($last_machine) &&
+-             $last_machine eq $machine);
+-
+-    doprint "Find grub menu ... ";
+-    $grub_number = -1;
+-    my $ssh_grub = $ssh_exec;
+-    $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g;
+-
+-    open(IN, "$ssh_grub |")
+-      or dodie "unable to get menu.lst";
++    $grub_menu_qt = quotemeta($grub_menu);
+-    my $found = 0;
+-    my $grub_menu_qt = quotemeta($grub_menu);
+-
+-    while (<IN>) {
+-      if (/^\s*title\s+$grub_menu_qt\s*$/) {
+-          $grub_number++;
+-          $found = 1;
+-          last;
+-      } elsif (/^\s*title\s/) {
+-          $grub_number++;
+-      }
++    if ($reboot_type eq "grub") {
++      $command = "cat /boot/grub/menu.lst";
++      $target = '^\s*title\s+' . $grub_menu_qt . '\s*$';
++      $skip = '^\s*title\s';
++    } elsif ($reboot_type eq "grub2") {
++      $command = "cat $grub_file";
++      $target = '^menuentry.*' . $grub_menu_qt;
++      $skip = '^menuentry\s|^submenu\s';
++    } else {
++      return;
+     }
+-    close(IN);
+-    dodie "Could not find '$grub_menu' in /boot/grub/menu on $machine"
+-      if (!$found);
+-    doprint "$grub_number\n";
+-    $last_grub_menu = $grub_menu;
+-    $last_machine = $machine;
++    _get_grub_index($command, $target, $skip);
+ }
+ sub wait_for_input
+-- 
+2.35.1
+
diff --git a/queue-4.19/ktest-introduce-_get_grub_index.patch b/queue-4.19/ktest-introduce-_get_grub_index.patch
new file mode 100644 (file)
index 0000000..1bc1650
--- /dev/null
@@ -0,0 +1,73 @@
+From 0ccee5cb4ab817d238b06632a8af2443c69f02b8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 May 2019 17:36:42 -0400
+Subject: ktest: introduce _get_grub_index
+
+From: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
+
+[ Upstream commit f824b6866835bc5051c44ffd289134974f214e98 ]
+
+Introduce _get_grub_index() to deal with Boot Loader
+Specification (BLS) and cleanup.
+
+Link: http://lkml.kernel.org/r/20190509213647.6276-2-msys.mizuma@gmail.com
+
+Signed-off-by: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
+Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
+Stable-dep-of: 26df05a8c142 ("kest.pl: Fix grub2 menu handling for rebooting")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/ktest/ktest.pl | 37 ++++++++++++++++++++++++++++++++++++
+ 1 file changed, 37 insertions(+)
+
+diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl
+index 635121ecf543..5fa60b3c564f 100755
+--- a/tools/testing/ktest/ktest.pl
++++ b/tools/testing/ktest/ktest.pl
+@@ -1850,6 +1850,43 @@ sub run_scp_mod {
+     return run_scp($src, $dst, $cp_scp);
+ }
++sub _get_grub_index {
++
++    my ($command, $target, $skip) = @_;
++
++    return if (defined($grub_number) && defined($last_grub_menu) &&
++             $last_grub_menu eq $grub_menu && defined($last_machine) &&
++             $last_machine eq $machine);
++
++    doprint "Find $reboot_type menu ... ";
++    $grub_number = -1;
++
++    my $ssh_grub = $ssh_exec;
++    $ssh_grub =~ s,\$SSH_COMMAND,$command,g;
++
++    open(IN, "$ssh_grub |")
++      or dodie "unable to execute $command";
++
++    my $found = 0;
++
++    while (<IN>) {
++      if (/$target/) {
++          $grub_number++;
++          $found = 1;
++          last;
++      } elsif (/$skip/) {
++          $grub_number++;
++      }
++    }
++    close(IN);
++
++    dodie "Could not find '$grub_menu' through $command on $machine"
++      if (!$found);
++    doprint "$grub_number\n";
++    $last_grub_menu = $grub_menu;
++    $last_machine = $machine;
++}
++
+ sub get_grub2_index {
+     return if (defined($grub_number) && defined($last_grub_menu) &&
+-- 
+2.35.1
+
diff --git a/queue-4.19/ktest-introduce-grub2bls-reboot_type-option.patch b/queue-4.19/ktest-introduce-grub2bls-reboot_type-option.patch
new file mode 100644 (file)
index 0000000..c083352
--- /dev/null
@@ -0,0 +1,115 @@
+From 895503847551777f218c09eee0fe4c35c07bb2cd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 May 2019 17:36:44 -0400
+Subject: ktest: introduce grub2bls REBOOT_TYPE option
+
+From: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
+
+[ Upstream commit ac2466456eaa0ff9b8cf647c4c52832024bc929f ]
+
+Fedora 30 introduces Boot Loader Specification (BLS),
+it changes around grub entry configuration.
+
+kernel entries aren't in grub.cfg. We can get the entries
+by "grubby --info=ALL" command.
+
+Introduce grub2bls as REBOOT_TYPE option for BLS.
+
+Link: http://lkml.kernel.org/r/20190509213647.6276-4-msys.mizuma@gmail.com
+
+Signed-off-by: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
+Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
+Stable-dep-of: 26df05a8c142 ("kest.pl: Fix grub2 menu handling for rebooting")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/ktest/ktest.pl | 18 +++++++++++++++---
+ 1 file changed, 15 insertions(+), 3 deletions(-)
+
+diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl
+index a1067469ba0e..76468e2d619f 100755
+--- a/tools/testing/ktest/ktest.pl
++++ b/tools/testing/ktest/ktest.pl
+@@ -63,6 +63,7 @@ my %default = (
+     "STOP_TEST_AFTER"         => 600,
+     "MAX_MONITOR_WAIT"                => 1800,
+     "GRUB_REBOOT"             => "grub2-reboot",
++    "GRUB_BLS_GET"            => "grubby --info=ALL",
+     "SYSLINUX"                        => "extlinux",
+     "SYSLINUX_PATH"           => "/boot/extlinux",
+     "CONNECT_TIMEOUT"         => 25,
+@@ -123,6 +124,7 @@ my $last_grub_menu;
+ my $grub_file;
+ my $grub_number;
+ my $grub_reboot;
++my $grub_bls_get;
+ my $syslinux;
+ my $syslinux_path;
+ my $syslinux_label;
+@@ -292,6 +294,7 @@ my %option_map = (
+     "GRUB_MENU"                       => \$grub_menu,
+     "GRUB_FILE"                       => \$grub_file,
+     "GRUB_REBOOT"             => \$grub_reboot,
++    "GRUB_BLS_GET"            => \$grub_bls_get,
+     "SYSLINUX"                        => \$syslinux,
+     "SYSLINUX_PATH"           => \$syslinux_path,
+     "SYSLINUX_LABEL"          => \$syslinux_label,
+@@ -437,7 +440,7 @@ EOF
+     ;
+ $config_help{"REBOOT_TYPE"} = << "EOF"
+  Way to reboot the box to the test kernel.
+- Only valid options so far are "grub", "grub2", "syslinux", and "script".
++ Only valid options so far are "grub", "grub2", "grub2bls", "syslinux", and "script".
+  If you specify grub, it will assume grub version 1
+  and will search in /boot/grub/menu.lst for the title \$GRUB_MENU
+@@ -451,6 +454,8 @@ $config_help{"REBOOT_TYPE"} = << "EOF"
+  If you specify grub2, then you also need to specify both \$GRUB_MENU
+  and \$GRUB_FILE.
++ If you specify grub2bls, then you also need to specify \$GRUB_MENU.
++
+  If you specify syslinux, then you may use SYSLINUX to define the syslinux
+  command (defaults to extlinux), and SYSLINUX_PATH to specify the path to
+  the syslinux install (defaults to /boot/extlinux). But you have to specify
+@@ -476,6 +481,9 @@ $config_help{"GRUB_MENU"} = << "EOF"
+  menu must be a non-nested menu. Add the quotes used in the menu
+  to guarantee your selection, as the first menuentry with the content
+  of \$GRUB_MENU that is found will be used.
++
++ For grub2bls, \$GRUB_MENU is searched on the result of \$GRUB_BLS_GET
++ command for the lines that begin with "title".
+ EOF
+     ;
+ $config_help{"GRUB_FILE"} = << "EOF"
+@@ -692,7 +700,7 @@ sub get_mandatory_configs {
+       }
+     }
+-    if ($rtype eq "grub") {
++    if (($rtype eq "grub") or ($rtype eq "grub2bls")) {
+       get_mandatory_config("GRUB_MENU");
+     }
+@@ -1944,6 +1952,10 @@ sub get_grub_index {
+       $command = "cat $grub_file";
+       $target = '^menuentry.*' . $grub_menu_qt;
+       $skip = '^menuentry\s|^submenu\s';
++    } elsif ($reboot_type eq "grub2bls") {
++        $command = $grub_bls_get;
++        $target = '^title=.*' . $grub_menu_qt;
++        $skip = '^title=';
+     } else {
+       return;
+     }
+@@ -4307,7 +4319,7 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
+     if (!$buildonly) {
+       $target = "$ssh_user\@$machine";
+-      if ($reboot_type eq "grub") {
++      if (($reboot_type eq "grub") or ($reboot_type eq "grub2bls")) {
+           dodie "GRUB_MENU not defined" if (!defined($grub_menu));
+       } elsif ($reboot_type eq "grub2") {
+           dodie "GRUB_MENU not defined" if (!defined($grub_menu));
+-- 
+2.35.1
+
diff --git a/queue-4.19/ktest.pl-fix-incorrect-reboot-for-grub2bls.patch b/queue-4.19/ktest.pl-fix-incorrect-reboot-for-grub2bls.patch
new file mode 100644 (file)
index 0000000..eab0e46
--- /dev/null
@@ -0,0 +1,51 @@
+From 37af8e738417415b592907ed48bebb0b975af426 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 Nov 2020 18:12:43 -0800
+Subject: ktest.pl: Fix incorrect reboot for grub2bls
+
+From: Libo Chen <libo.chen@oracle.com>
+
+[ Upstream commit 271e0c9dce1b02a825b3cc1a7aa1fab7c381d44b ]
+
+This issue was first noticed when I was testing different kernels on
+Oracle Linux 8 which as Fedora 30+ adopts BLS as default. Even though a
+kernel entry was added successfully and the index of that kernel entry was
+retrieved correctly, ktest still wouldn't reboot the system into
+user-specified kernel.
+
+The bug was spotted in subroutine reboot_to where the if-statement never
+checks for REBOOT_TYPE "grub2bls", therefore the desired entry will not be
+set for the next boot.
+
+Add a check for "grub2bls" so that $grub_reboot $grub_number can
+be run before a reboot if REBOOT_TYPE is "grub2bls" then we can boot to
+the correct kernel.
+
+Link: https://lkml.kernel.org/r/20201121021243.1532477-1-libo.chen@oracle.com
+
+Cc: stable@vger.kernel.org
+Fixes: ac2466456eaa ("ktest: introduce grub2bls REBOOT_TYPE option")
+Signed-off-by: Libo Chen <libo.chen@oracle.com>
+Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
+Stable-dep-of: 26df05a8c142 ("kest.pl: Fix grub2 menu handling for rebooting")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/ktest/ktest.pl | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl
+index 76468e2d619f..689fa4fd3d76 100755
+--- a/tools/testing/ktest/ktest.pl
++++ b/tools/testing/ktest/ktest.pl
+@@ -2023,7 +2023,7 @@ sub reboot_to {
+     if ($reboot_type eq "grub") {
+       run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch)'";
+-    } elsif ($reboot_type eq "grub2") {
++    } elsif (($reboot_type eq "grub2") or ($reboot_type eq "grub2bls")) {
+       run_ssh "$grub_reboot $grub_number";
+     } elsif ($reboot_type eq "syslinux") {
+       run_ssh "$syslinux --once \\\"$syslinux_label\\\" $syslinux_path";
+-- 
+2.35.1
+
diff --git a/queue-4.19/quota-factor-out-setup-of-quota-inode.patch b/queue-4.19/quota-factor-out-setup-of-quota-inode.patch
new file mode 100644 (file)
index 0000000..38bc6c1
--- /dev/null
@@ -0,0 +1,192 @@
+From a99d6a0b738922dd1fcb3cf8a5d6378ec49b7a02 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Nov 2019 17:45:31 +0100
+Subject: quota: Factor out setup of quota inode
+
+From: Jan Kara <jack@suse.cz>
+
+[ Upstream commit c7d3d28360fdb3ed3a5aa0bab19315e0fdc994a1 ]
+
+Factor out setting up of quota inode and eventual error cleanup from
+vfs_load_quota_inode(). This will simplify situation for filesystems
+that don't have any quota inodes.
+
+Signed-off-by: Jan Kara <jack@suse.cz>
+Stable-dep-of: d32387748476 ("ext4: fix bug_on in __es_tree_search caused by bad quota inode")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/quota/dquot.c         | 108 ++++++++++++++++++++++++---------------
+ include/linux/quotaops.h |   2 +
+ 2 files changed, 69 insertions(+), 41 deletions(-)
+
+diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
+index ddb379abd919..a1d2aed0d833 100644
+--- a/fs/quota/dquot.c
++++ b/fs/quota/dquot.c
+@@ -2298,28 +2298,60 @@ EXPORT_SYMBOL(dquot_quota_off);
+  *    Turn quotas on on a device
+  */
+-/*
+- * Helper function to turn quotas on when we already have the inode of
+- * quota file and no quota information is loaded.
+- */
+-static int vfs_load_quota_inode(struct inode *inode, int type, int format_id,
++static int vfs_setup_quota_inode(struct inode *inode, int type)
++{
++      struct super_block *sb = inode->i_sb;
++      struct quota_info *dqopt = sb_dqopt(sb);
++
++      if (!S_ISREG(inode->i_mode))
++              return -EACCES;
++      if (IS_RDONLY(inode))
++              return -EROFS;
++      if (sb_has_quota_loaded(sb, type))
++              return -EBUSY;
++
++      dqopt->files[type] = igrab(inode);
++      if (!dqopt->files[type])
++              return -EIO;
++      if (!(dqopt->flags & DQUOT_QUOTA_SYS_FILE)) {
++              /* We don't want quota and atime on quota files (deadlocks
++               * possible) Also nobody should write to the file - we use
++               * special IO operations which ignore the immutable bit. */
++              inode_lock(inode);
++              inode->i_flags |= S_NOQUOTA;
++              inode_unlock(inode);
++              /*
++               * When S_NOQUOTA is set, remove dquot references as no more
++               * references can be added
++               */
++              __dquot_drop(inode);
++      }
++      return 0;
++}
++
++static void vfs_cleanup_quota_inode(struct super_block *sb, int type)
++{
++      struct quota_info *dqopt = sb_dqopt(sb);
++      struct inode *inode = dqopt->files[type];
++
++      if (!(dqopt->flags & DQUOT_QUOTA_SYS_FILE)) {
++              inode_lock(inode);
++              inode->i_flags &= ~S_NOQUOTA;
++              inode_unlock(inode);
++      }
++      dqopt->files[type] = NULL;
++      iput(inode);
++}
++
++int dquot_load_quota_sb(struct super_block *sb, int type, int format_id,
+       unsigned int flags)
+ {
+       struct quota_format_type *fmt = find_quota_format(format_id);
+-      struct super_block *sb = inode->i_sb;
+       struct quota_info *dqopt = sb_dqopt(sb);
+       int error;
+       if (!fmt)
+               return -ESRCH;
+-      if (!S_ISREG(inode->i_mode)) {
+-              error = -EACCES;
+-              goto out_fmt;
+-      }
+-      if (IS_RDONLY(inode)) {
+-              error = -EROFS;
+-              goto out_fmt;
+-      }
+       if (!sb->s_op->quota_write || !sb->s_op->quota_read ||
+           (type == PRJQUOTA && sb->dq_op->get_projid == NULL)) {
+               error = -EINVAL;
+@@ -2351,27 +2383,9 @@ static int vfs_load_quota_inode(struct inode *inode, int type, int format_id,
+               invalidate_bdev(sb->s_bdev);
+       }
+-      if (!(dqopt->flags & DQUOT_QUOTA_SYS_FILE)) {
+-              /* We don't want quota and atime on quota files (deadlocks
+-               * possible) Also nobody should write to the file - we use
+-               * special IO operations which ignore the immutable bit. */
+-              inode_lock(inode);
+-              inode->i_flags |= S_NOQUOTA;
+-              inode_unlock(inode);
+-              /*
+-               * When S_NOQUOTA is set, remove dquot references as no more
+-               * references can be added
+-               */
+-              __dquot_drop(inode);
+-      }
+-
+-      error = -EIO;
+-      dqopt->files[type] = igrab(inode);
+-      if (!dqopt->files[type])
+-              goto out_file_flags;
+       error = -EINVAL;
+       if (!fmt->qf_ops->check_quota_file(sb, type))
+-              goto out_file_init;
++              goto out_fmt;
+       dqopt->ops[type] = fmt->qf_ops;
+       dqopt->info[type].dqi_format = fmt;
+@@ -2379,7 +2393,7 @@ static int vfs_load_quota_inode(struct inode *inode, int type, int format_id,
+       INIT_LIST_HEAD(&dqopt->info[type].dqi_dirty_list);
+       error = dqopt->ops[type]->read_file_info(sb, type);
+       if (error < 0)
+-              goto out_file_init;
++              goto out_fmt;
+       if (dqopt->flags & DQUOT_QUOTA_SYS_FILE) {
+               spin_lock(&dq_data_lock);
+               dqopt->info[type].dqi_flags |= DQF_SYS_FILE;
+@@ -2394,18 +2408,30 @@ static int vfs_load_quota_inode(struct inode *inode, int type, int format_id,
+               dquot_disable(sb, type, flags);
+       return error;
+-out_file_init:
+-      dqopt->files[type] = NULL;
+-      iput(inode);
+-out_file_flags:
+-      inode_lock(inode);
+-      inode->i_flags &= ~S_NOQUOTA;
+-      inode_unlock(inode);
+ out_fmt:
+       put_quota_format(fmt);
+       return error; 
+ }
++EXPORT_SYMBOL(dquot_load_quota_sb);
++
++/*
++ * Helper function to turn quotas on when we already have the inode of
++ * quota file and no quota information is loaded.
++ */
++static int vfs_load_quota_inode(struct inode *inode, int type, int format_id,
++      unsigned int flags)
++{
++      int err;
++
++      err = vfs_setup_quota_inode(inode, type);
++      if (err < 0)
++              return err;
++      err = dquot_load_quota_sb(inode->i_sb, type, format_id, flags);
++      if (err < 0)
++              vfs_cleanup_quota_inode(inode->i_sb, type);
++      return err;
++}
+ /* Reenable quotas on remount RW */
+ int dquot_resume(struct super_block *sb, int type)
+diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h
+index 91e0b7624053..ec10897f7f60 100644
+--- a/include/linux/quotaops.h
++++ b/include/linux/quotaops.h
+@@ -99,6 +99,8 @@ int dquot_file_open(struct inode *inode, struct file *file);
+ int dquot_enable(struct inode *inode, int type, int format_id,
+       unsigned int flags);
++int dquot_load_quota_sb(struct super_block *sb, int type, int format_id,
++      unsigned int flags);
+ int dquot_quota_on(struct super_block *sb, int type, int format_id,
+       const struct path *path);
+ int dquot_quota_on_mount(struct super_block *sb, char *qf_name,
+-- 
+2.35.1
+
index 616ba7d1c50646d35e59ce2c3c5b6f95d8b9744f..22fff145982e4f9bbf721570ba008aed4017aa60 100644 (file)
@@ -468,3 +468,31 @@ perf-auxtrace-fix-address-filter-duplicate-symbol-selection.patch
 s390-percpu-add-read_once-to-arch_this_cpu_to_op_simple.patch
 net-ulp-prevent-ulp-without-clone-op-from-entering-the-listen-status.patch
 alsa-pcm-move-rwsem-lock-inside-snd_ctl_elem_read-to-prevent-uaf.patch
+wifi-wilc1000-sdio-fix-module-autoloading.patch
+alsa-hda-hdmi-fix-failures-at-pcm-open-on-intel-icl-.patch
+add-acer-aspire-ethos-8951g-model-quirk.patch
+alsa-hda-realtek-more-constifications.patch
+alsa-hda-realtek-add-headset-mic-supported-for-hp-cp.patch
+alsa-hda-realtek-enable-headset-mic-of-acer-x2660g-w.patch
+alsa-hda-realtek-enable-the-headset-of-acer-n50-600-.patch
+alsa-hda-realtek-the-front-mic-on-a-hp-machine-doesn.patch
+alsa-hda-realtek-fix-the-mic-type-detection-issue-fo.patch
+alsa-hda-realtek-add-headset-mic-support-for-lenovo-.patch
+alsa-hda-realtek-alc897-headset-mic-no-sound.patch
+alsa-hda-realtek-add-quirk-for-lenovo-tianyi510pro-1.patch
+ktest-add-support-for-meta-characters-in-grub_menu.patch
+ktest-introduce-_get_grub_index.patch
+ktest-cleanup-get_grub_index.patch
+ktest-introduce-grub2bls-reboot_type-option.patch
+ktest.pl-fix-incorrect-reboot-for-grub2bls.patch
+kest.pl-fix-grub2-menu-handling-for-rebooting.patch
+usb-ulpi-defer-ulpi_register-on-ulpi_read_id-timeout.patch
+quota-factor-out-setup-of-quota-inode.patch
+ext4-fix-bug_on-in-__es_tree_search-caused-by-bad-qu.patch
+ext4-lost-matching-pair-of-trace-in-ext4_truncate.patch
+ext4-fix-use-after-free-in-ext4_orphan_cleanup.patch
+ext4-fix-uninititialized-value-in-ext4_evict_inode.patch
+ext4-generalize-extents-status-tree-search-functions.patch
+ext4-add-new-pending-reservation-mechanism.patch
+ext4-fix-reserved-cluster-accounting-at-delayed-writ.patch
+ext4-fix-delayed-allocation-bug-in-ext4_clu_mapped-f.patch
diff --git a/queue-4.19/usb-ulpi-defer-ulpi_register-on-ulpi_read_id-timeout.patch b/queue-4.19/usb-ulpi-defer-ulpi_register-on-ulpi_read_id-timeout.patch
new file mode 100644 (file)
index 0000000..214ccfc
--- /dev/null
@@ -0,0 +1,49 @@
+From 85a42569f5edafb3142250de260797938db4f826 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 Dec 2022 21:15:26 +0100
+Subject: usb: ulpi: defer ulpi_register on ulpi_read_id timeout
+
+From: Ferry Toth <ftoth@exalondelft.nl>
+
+[ Upstream commit 8a7b31d545d3a15f0e6f5984ae16f0ca4fd76aac ]
+
+Since commit 0f0101719138 ("usb: dwc3: Don't switch OTG -> peripheral
+if extcon is present") Dual Role support on Intel Merrifield platform
+broke due to rearranging the call to dwc3_get_extcon().
+
+It appears to be caused by ulpi_read_id() on the first test write failing
+with -ETIMEDOUT. Currently ulpi_read_id() expects to discover the phy via
+DT when the test write fails and returns 0 in that case, even if DT does not
+provide the phy. As a result usb probe completes without phy.
+
+Make ulpi_read_id() return -ETIMEDOUT to its user if the first test write
+fails. The user should then handle it appropriately. A follow up patch
+will make dwc3_core_init() set -EPROBE_DEFER in this case and bail out.
+
+Fixes: ef6a7bcfb01c ("usb: ulpi: Support device discovery via DT")
+Cc: stable@vger.kernel.org
+Acked-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Signed-off-by: Ferry Toth <ftoth@exalondelft.nl>
+Link: https://lore.kernel.org/r/20221205201527.13525-2-ftoth@exalondelft.nl
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/common/ulpi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/common/ulpi.c b/drivers/usb/common/ulpi.c
+index c42c152bbc33..94700c1d2f6e 100644
+--- a/drivers/usb/common/ulpi.c
++++ b/drivers/usb/common/ulpi.c
+@@ -207,7 +207,7 @@ static int ulpi_read_id(struct ulpi *ulpi)
+       /* Test the interface */
+       ret = ulpi_write(ulpi, ULPI_SCRATCH, 0xaa);
+       if (ret < 0)
+-              goto err;
++              return ret;
+       ret = ulpi_read(ulpi, ULPI_SCRATCH);
+       if (ret < 0)
+-- 
+2.35.1
+
diff --git a/queue-4.19/wifi-wilc1000-sdio-fix-module-autoloading.patch b/queue-4.19/wifi-wilc1000-sdio-fix-module-autoloading.patch
new file mode 100644 (file)
index 0000000..d8450f3
--- /dev/null
@@ -0,0 +1,36 @@
+From 3f6ef7bc16eca5d3b22f708134e5dfe0a440a6b1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Oct 2022 19:12:21 +0200
+Subject: wifi: wilc1000: sdio: fix module autoloading
+
+From: Michael Walle <michael@walle.cc>
+
+[ Upstream commit 57d545b5a3d6ce3a8fb6b093f02bfcbb908973f3 ]
+
+There are no SDIO module aliases included in the driver, therefore,
+module autoloading isn't working. Add the proper MODULE_DEVICE_TABLE().
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Michael Walle <michael@walle.cc>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20221027171221.491937-1-michael@walle.cc
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/wilc1000/wilc_sdio.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/staging/wilc1000/wilc_sdio.c b/drivers/staging/wilc1000/wilc_sdio.c
+index e52c3bdeaf04..b4d456f3fb1b 100644
+--- a/drivers/staging/wilc1000/wilc_sdio.c
++++ b/drivers/staging/wilc1000/wilc_sdio.c
+@@ -18,6 +18,7 @@ static const struct sdio_device_id wilc_sdio_ids[] = {
+       { SDIO_DEVICE(SDIO_VENDOR_ID_WILC, SDIO_DEVICE_ID_WILC) },
+       { },
+ };
++MODULE_DEVICE_TABLE(sdio, wilc_sdio_ids);
+ #define WILC_SDIO_BLOCK_SIZE 512
+-- 
+2.35.1
+