--- /dev/null
+From 2dee54b289fbc810669a1b2b8a0887fa1c9a14d7 Mon Sep 17 00:00:00 2001
+From: Colin Ian King <colin.i.king@gmail.com>
+Date: Sun, 12 Dec 2021 17:20:25 +0000
+Subject: ALSA: drivers: opl3: Fix incorrect use of vp->state
+
+From: Colin Ian King <colin.i.king@gmail.com>
+
+commit 2dee54b289fbc810669a1b2b8a0887fa1c9a14d7 upstream.
+
+Static analysis with scan-build has found an assignment to vp2 that is
+never used. It seems that the check on vp->state > 0 should be actually
+on vp2->state instead. Fix this.
+
+This dates back to 2002, I found the offending commit from the git
+history git://git.kernel.org/pub/scm/linux/kernel/git/tglx/history.git,
+commit 91e39521bbf6 ("[PATCH] ALSA patch for 2.5.4")
+
+Signed-off-by: Colin Ian King <colin.i.king@gmail.com>
+Cc: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20211212172025.470367-1-colin.i.king@gmail.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/drivers/opl3/opl3_midi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/sound/drivers/opl3/opl3_midi.c
++++ b/sound/drivers/opl3/opl3_midi.c
+@@ -398,7 +398,7 @@ void snd_opl3_note_on(void *p, int note,
+ }
+ if (instr_4op) {
+ vp2 = &opl3->voices[voice + 3];
+- if (vp->state > 0) {
++ if (vp2->state > 0) {
+ opl3_reg = reg_side | (OPL3_REG_KEYON_BLOCK +
+ voice_offset + 3);
+ reg_val = vp->keyon_reg & ~OPL3_KEYON_BIT;
--- /dev/null
+From aa72394667e5cea3547e4c41ddff7ca8c632d764 Mon Sep 17 00:00:00 2001
+From: Bradley Scott <bscott@teksavvy.com>
+Date: Mon, 13 Dec 2021 11:22:47 -0500
+Subject: ALSA: hda/realtek: Add new alc285-hp-amp-init model
+
+From: Bradley Scott <bscott@teksavvy.com>
+
+commit aa72394667e5cea3547e4c41ddff7ca8c632d764 upstream.
+
+Adds a new "alc285-hp-amp-init" model that can be used to apply the ALC285
+HP speaker amplifier initialization fixup to devices that are not already
+known by passing "hda_model=alc285-hp-amp-init" to the
+snd-sof-intel-hda-common module or "model=alc285-hp-amp-init" to the
+snd-hda-intel module, depending on which is being used.
+
+Signed-off-by: Bradley Scott <bscott@teksavvy.com>
+Cc: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20211213162246.506838-1-bscott@teksavvy.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ Documentation/sound/hd-audio/models.rst | 2 ++
+ sound/pci/hda/patch_realtek.c | 1 +
+ 2 files changed, 3 insertions(+)
+
+--- a/Documentation/sound/hd-audio/models.rst
++++ b/Documentation/sound/hd-audio/models.rst
+@@ -326,6 +326,8 @@ usi-headset
+ Headset support on USI machines
+ dual-codecs
+ Lenovo laptops with dual codecs
++alc285-hp-amp-init
++ HP laptops which require speaker amplifier initialization (ALC285)
+
+ ALC680
+ ======
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -9061,6 +9061,7 @@ static const struct hda_model_fixup alc2
+ {.id = ALC287_FIXUP_IDEAPAD_BASS_SPK_AMP, .name = "alc287-ideapad-bass-spk-amp"},
+ {.id = ALC623_FIXUP_LENOVO_THINKSTATION_P340, .name = "alc623-lenovo-thinkstation-p340"},
+ {.id = ALC255_FIXUP_ACER_HEADPHONE_AND_MIC, .name = "alc255-acer-headphone-and-mic"},
++ {.id = ALC285_FIXUP_HP_GPIO_AMP_INIT, .name = "alc285-hp-amp-init"},
+ {}
+ };
+ #define ALC225_STANDARD_PINS \
--- /dev/null
+From d296a74b7b59ff9116236c17edb25f26935dbf70 Mon Sep 17 00:00:00 2001
+From: Bradley Scott <Bradley.Scott@zebra.com>
+Date: Mon, 13 Dec 2021 10:49:39 -0500
+Subject: ALSA: hda/realtek: Amp init fixup for HP ZBook 15 G6
+
+From: Bradley Scott <Bradley.Scott@zebra.com>
+
+commit d296a74b7b59ff9116236c17edb25f26935dbf70 upstream.
+
+HP ZBook 15 G6 (SSID 103c:860f) needs the same speaker amplifier
+initialization as used on several other HP laptops using ALC285.
+
+Signed-off-by: Bradley Scott <Bradley.Scott@zebra.com>
+Cc: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20211213154938.503201-1-Bradley.Scott@zebra.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/pci/hda/patch_realtek.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -8599,6 +8599,7 @@ static const struct snd_pci_quirk alc269
+ SND_PCI_QUIRK(0x103c, 0x84da, "HP OMEN dc0019-ur", ALC295_FIXUP_HP_OMEN),
+ SND_PCI_QUIRK(0x103c, 0x84e7, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3),
+ SND_PCI_QUIRK(0x103c, 0x8519, "HP Spectre x360 15-df0xxx", ALC285_FIXUP_HP_SPECTRE_X360),
++ SND_PCI_QUIRK(0x103c, 0x860f, "HP ZBook 15 G6", ALC285_FIXUP_HP_GPIO_AMP_INIT),
+ SND_PCI_QUIRK(0x103c, 0x861f, "HP Elite Dragonfly G1", ALC285_FIXUP_HP_GPIO_AMP_INIT),
+ SND_PCI_QUIRK(0x103c, 0x869d, "HP", ALC236_FIXUP_HP_MUTE_LED),
+ SND_PCI_QUIRK(0x103c, 0x86c7, "HP Envy AiO 32", ALC274_FIXUP_HP_ENVY_GPIO),
--- /dev/null
+From edca7cc4b0accfa69dc032442fe0684e59c691b8 Mon Sep 17 00:00:00 2001
+From: Werner Sembach <wse@tuxedocomputers.com>
+Date: Wed, 15 Dec 2021 20:16:46 +0100
+Subject: ALSA: hda/realtek: Fix quirk for Clevo NJ51CU
+
+From: Werner Sembach <wse@tuxedocomputers.com>
+
+commit edca7cc4b0accfa69dc032442fe0684e59c691b8 upstream.
+
+The Clevo NJ51CU comes either with the ALC293 or the ALC256 codec, but uses
+the 0x8686 subproduct id in both cases. The ALC256 codec needs a different
+quirk for the headset microphone working and and edditional quirk for sound
+working after suspend and resume.
+
+When waking up from s3 suspend the Coef 0x10 is set to 0x0220 instead of
+0x0020 on the ALC256 codec. Setting the value manually makes the sound
+work again. This patch does this automatically.
+
+[ minor coding style fix by tiwai ]
+
+Signed-off-by: Werner Sembach <wse@tuxedocomputers.com>
+Fixes: b5acfe152abaa ("ALSA: hda/realtek: Add some Clove SSID in the ALC293(ALC1220)")
+Cc: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20211215191646.844644-1-wse@tuxedocomputers.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/pci/hda/patch_realtek.c | 26 +++++++++++++++++++++++++-
+ 1 file changed, 25 insertions(+), 1 deletion(-)
+
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -6492,6 +6492,23 @@ static void alc233_fixup_no_audio_jack(s
+ alc_process_coef_fw(codec, alc233_fixup_no_audio_jack_coefs);
+ }
+
++static void alc256_fixup_mic_no_presence_and_resume(struct hda_codec *codec,
++ const struct hda_fixup *fix,
++ int action)
++{
++ /*
++ * The Clevo NJ51CU comes either with the ALC293 or the ALC256 codec,
++ * but uses the 0x8686 subproduct id in both cases. The ALC256 codec
++ * needs an additional quirk for sound working after suspend and resume.
++ */
++ if (codec->core.vendor_id == 0x10ec0256) {
++ alc_update_coef_idx(codec, 0x10, 1<<9, 0);
++ snd_hda_codec_set_pincfg(codec, 0x19, 0x04a11120);
++ } else {
++ snd_hda_codec_set_pincfg(codec, 0x1a, 0x04a1113c);
++ }
++}
++
+ enum {
+ ALC269_FIXUP_GPIO2,
+ ALC269_FIXUP_SONY_VAIO,
+@@ -6711,6 +6728,7 @@ enum {
+ ALC256_FIXUP_SET_COEF_DEFAULTS,
+ ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE,
+ ALC233_FIXUP_NO_AUDIO_JACK,
++ ALC256_FIXUP_MIC_NO_PRESENCE_AND_RESUME,
+ };
+
+ static const struct hda_fixup alc269_fixups[] = {
+@@ -8429,6 +8447,12 @@ static const struct hda_fixup alc269_fix
+ .type = HDA_FIXUP_FUNC,
+ .v.func = alc233_fixup_no_audio_jack,
+ },
++ [ALC256_FIXUP_MIC_NO_PRESENCE_AND_RESUME] = {
++ .type = HDA_FIXUP_FUNC,
++ .v.func = alc256_fixup_mic_no_presence_and_resume,
++ .chained = true,
++ .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
++ },
+ };
+
+ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+@@ -8767,7 +8791,7 @@ static const struct snd_pci_quirk alc269
+ SND_PCI_QUIRK(0x1558, 0x8562, "Clevo NH[5|7][0-9]RZ[Q]", ALC269_FIXUP_DMIC),
+ SND_PCI_QUIRK(0x1558, 0x8668, "Clevo NP50B[BE]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
+ SND_PCI_QUIRK(0x1558, 0x8680, "Clevo NJ50LU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
+- SND_PCI_QUIRK(0x1558, 0x8686, "Clevo NH50[CZ]U", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
++ SND_PCI_QUIRK(0x1558, 0x8686, "Clevo NH50[CZ]U", ALC256_FIXUP_MIC_NO_PRESENCE_AND_RESUME),
+ SND_PCI_QUIRK(0x1558, 0x8a20, "Clevo NH55DCQ-Y", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
+ SND_PCI_QUIRK(0x1558, 0x8a51, "Clevo NH70RCQ-Y", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
+ SND_PCI_QUIRK(0x1558, 0x8d50, "Clevo NH55RCQ-M", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
--- /dev/null
+From c01c1db1dc632edafb0dff32d40daf4f9c1a4e19 Mon Sep 17 00:00:00 2001
+From: Xiaoke Wang <xkernel.wang@foxmail.com>
+Date: Mon, 13 Dec 2021 15:39:31 +0800
+Subject: ALSA: jack: Check the return value of kstrdup()
+
+From: Xiaoke Wang <xkernel.wang@foxmail.com>
+
+commit c01c1db1dc632edafb0dff32d40daf4f9c1a4e19 upstream.
+
+kstrdup() can return NULL, it is better to check the return value of it.
+
+Signed-off-by: Xiaoke Wang <xkernel.wang@foxmail.com>
+Cc: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/tencent_094816F3522E0DC704056C789352EBBF0606@qq.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/core/jack.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/sound/core/jack.c
++++ b/sound/core/jack.c
+@@ -220,6 +220,10 @@ int snd_jack_new(struct snd_card *card,
+ return -ENOMEM;
+
+ jack->id = kstrdup(id, GFP_KERNEL);
++ if (jack->id == NULL) {
++ kfree(jack);
++ return -ENOMEM;
++ }
+
+ /* don't creat input device for phantom jack */
+ if (!phantom_jack) {
--- /dev/null
+From ee907afb0c39a41ee74b862882cfe12820c74b98 Mon Sep 17 00:00:00 2001
+From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Date: Mon, 6 Dec 2021 22:08:04 +0100
+Subject: ASoC: meson: aiu: Move AIU_I2S_MISC hold setting to aiu-fifo-i2s
+
+From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+
+commit ee907afb0c39a41ee74b862882cfe12820c74b98 upstream.
+
+The out-of-tree vendor driver uses the following approach to set the
+AIU_I2S_MISC register:
+1) write AIU_MEM_I2S_START_PTR and AIU_MEM_I2S_RD_PTR
+2) configure AIU_I2S_MUTE_SWAP[15:0]
+3) write AIU_MEM_I2S_END_PTR
+4) set AIU_I2S_MISC[2] to 1 (documented as: "put I2S interface in hold
+ mode")
+5) set AIU_I2S_MISC[4] to 1 (depending on the driver revision it always
+ stays at 1 while for older drivers this bit is unset in step 4)
+6) set AIU_I2S_MISC[2] to 0
+7) write AIU_MEM_I2S_MASKS
+8) toggle AIU_MEM_I2S_CONTROL[0]
+9) toggle AIU_MEM_I2S_BUF_CNTL[0]
+
+Move setting the AIU_I2S_MISC[2] bit to aiu_fifo_i2s_hw_params() so it
+resembles the flow in the vendor kernel more closely. While here also
+configure AIU_I2S_MISC[4] (documented as: "force each audio data to
+left or right according to the bit attached with the audio data")
+similar to how the vendor driver does this. This fixes the infamous and
+long-standing "machine gun noise" issue (a buffer underrun issue).
+
+Fixes: 6ae9ca9ce986bf ("ASoC: meson: aiu: add i2s and spdif support")
+Reported-by: Christian Hewitt <christianshewitt@gmail.com>
+Reported-by: Geraldo Nascimento <geraldogabriel@gmail.com>
+Tested-by: Christian Hewitt <christianshewitt@gmail.com>
+Tested-by: Geraldo Nascimento <geraldogabriel@gmail.com>
+Acked-by: Jerome Brunet <jbrunet@baylibre.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Link: https://lore.kernel.org/r/20211206210804.2512999-3-martin.blumenstingl@googlemail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/soc/meson/aiu-encoder-i2s.c | 33 ---------------------------------
+ sound/soc/meson/aiu-fifo-i2s.c | 19 +++++++++++++++++++
+ 2 files changed, 19 insertions(+), 33 deletions(-)
+
+--- a/sound/soc/meson/aiu-encoder-i2s.c
++++ b/sound/soc/meson/aiu-encoder-i2s.c
+@@ -18,7 +18,6 @@
+ #define AIU_RST_SOFT_I2S_FAST BIT(0)
+
+ #define AIU_I2S_DAC_CFG_MSB_FIRST BIT(2)
+-#define AIU_I2S_MISC_HOLD_EN BIT(2)
+ #define AIU_CLK_CTRL_I2S_DIV_EN BIT(0)
+ #define AIU_CLK_CTRL_I2S_DIV GENMASK(3, 2)
+ #define AIU_CLK_CTRL_AOCLK_INVERT BIT(6)
+@@ -36,37 +35,6 @@ static void aiu_encoder_i2s_divider_enab
+ enable ? AIU_CLK_CTRL_I2S_DIV_EN : 0);
+ }
+
+-static void aiu_encoder_i2s_hold(struct snd_soc_component *component,
+- bool enable)
+-{
+- snd_soc_component_update_bits(component, AIU_I2S_MISC,
+- AIU_I2S_MISC_HOLD_EN,
+- enable ? AIU_I2S_MISC_HOLD_EN : 0);
+-}
+-
+-static int aiu_encoder_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
+- struct snd_soc_dai *dai)
+-{
+- struct snd_soc_component *component = dai->component;
+-
+- switch (cmd) {
+- case SNDRV_PCM_TRIGGER_START:
+- case SNDRV_PCM_TRIGGER_RESUME:
+- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+- aiu_encoder_i2s_hold(component, false);
+- return 0;
+-
+- case SNDRV_PCM_TRIGGER_STOP:
+- case SNDRV_PCM_TRIGGER_SUSPEND:
+- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+- aiu_encoder_i2s_hold(component, true);
+- return 0;
+-
+- default:
+- return -EINVAL;
+- }
+-}
+-
+ static int aiu_encoder_i2s_setup_desc(struct snd_soc_component *component,
+ struct snd_pcm_hw_params *params)
+ {
+@@ -353,7 +321,6 @@ static void aiu_encoder_i2s_shutdown(str
+ }
+
+ const struct snd_soc_dai_ops aiu_encoder_i2s_dai_ops = {
+- .trigger = aiu_encoder_i2s_trigger,
+ .hw_params = aiu_encoder_i2s_hw_params,
+ .hw_free = aiu_encoder_i2s_hw_free,
+ .set_fmt = aiu_encoder_i2s_set_fmt,
+--- a/sound/soc/meson/aiu-fifo-i2s.c
++++ b/sound/soc/meson/aiu-fifo-i2s.c
+@@ -20,6 +20,8 @@
+ #define AIU_MEM_I2S_CONTROL_MODE_16BIT BIT(6)
+ #define AIU_MEM_I2S_BUF_CNTL_INIT BIT(0)
+ #define AIU_RST_SOFT_I2S_FAST BIT(0)
++#define AIU_I2S_MISC_HOLD_EN BIT(2)
++#define AIU_I2S_MISC_FORCE_LEFT_RIGHT BIT(4)
+
+ #define AIU_FIFO_I2S_BLOCK 256
+
+@@ -90,6 +92,10 @@ static int aiu_fifo_i2s_hw_params(struct
+ unsigned int val;
+ int ret;
+
++ snd_soc_component_update_bits(component, AIU_I2S_MISC,
++ AIU_I2S_MISC_HOLD_EN,
++ AIU_I2S_MISC_HOLD_EN);
++
+ ret = aiu_fifo_hw_params(substream, params, dai);
+ if (ret)
+ return ret;
+@@ -117,6 +123,19 @@ static int aiu_fifo_i2s_hw_params(struct
+ snd_soc_component_update_bits(component, AIU_MEM_I2S_MASKS,
+ AIU_MEM_I2S_MASKS_IRQ_BLOCK, val);
+
++ /*
++ * Most (all?) supported SoCs have this bit set by default. The vendor
++ * driver however sets it manually (depending on the version either
++ * while un-setting AIU_I2S_MISC_HOLD_EN or right before that). Follow
++ * the same approach for consistency with the vendor driver.
++ */
++ snd_soc_component_update_bits(component, AIU_I2S_MISC,
++ AIU_I2S_MISC_FORCE_LEFT_RIGHT,
++ AIU_I2S_MISC_FORCE_LEFT_RIGHT);
++
++ snd_soc_component_update_bits(component, AIU_I2S_MISC,
++ AIU_I2S_MISC_HOLD_EN, 0);
++
+ return 0;
+ }
+
--- /dev/null
+From 12f247ab590a08856441efdbd351cf2cc8f60a2d Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Jos=C3=A9=20Exp=C3=B3sito?= <jose.exposito89@gmail.com>
+Date: Sun, 12 Dec 2021 21:01:49 -0800
+Subject: Input: atmel_mxt_ts - fix double free in mxt_read_info_block
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: José Expósito <jose.exposito89@gmail.com>
+
+commit 12f247ab590a08856441efdbd351cf2cc8f60a2d upstream.
+
+The "id_buf" buffer is stored in "data->raw_info_block" and freed by
+"mxt_free_object_table" in case of error.
+
+Return instead of jumping to avoid a double free.
+
+Addresses-Coverity-ID: 1474582 ("Double free")
+Fixes: 068bdb67ef74 ("Input: atmel_mxt_ts - fix the firmware update")
+Signed-off-by: José Expósito <jose.exposito89@gmail.com>
+Link: https://lore.kernel.org/r/20211212194257.68879-1-jose.exposito89@gmail.com
+Cc: stable@vger.kernel.org
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -1839,7 +1839,7 @@ static int mxt_read_info_block(struct mx
+ if (error) {
+ dev_err(&client->dev, "Error %d parsing object table\n", error);
+ mxt_free_object_table(data);
+- goto err_free_mem;
++ return error;
+ }
+
+ data->object_table = (struct mxt_object *)(id_buf + MXT_OBJECT_START);
--- /dev/null
+From 2b5160b12091285c5aca45980f100a9294af7b04 Mon Sep 17 00:00:00 2001
+From: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
+Date: Fri, 17 Dec 2021 12:44:09 -0300
+Subject: ipmi: bail out if init_srcu_struct fails
+
+From: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
+
+commit 2b5160b12091285c5aca45980f100a9294af7b04 upstream.
+
+In case, init_srcu_struct fails (because of memory allocation failure), we
+might proceed with the driver initialization despite srcu_struct not being
+entirely initialized.
+
+Fixes: 913a89f009d9 ("ipmi: Don't initialize anything in the core until something uses it")
+Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
+Cc: Corey Minyard <cminyard@mvista.com>
+Cc: stable@vger.kernel.org
+Message-Id: <20211217154410.1228673-1-cascardo@canonical.com>
+Signed-off-by: Corey Minyard <cminyard@mvista.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/char/ipmi/ipmi_msghandler.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/char/ipmi/ipmi_msghandler.c
++++ b/drivers/char/ipmi/ipmi_msghandler.c
+@@ -5161,7 +5161,9 @@ static int ipmi_init_msghandler(void)
+ if (initialized)
+ goto out;
+
+- init_srcu_struct(&ipmi_interfaces_srcu);
++ rv = init_srcu_struct(&ipmi_interfaces_srcu);
++ if (rv)
++ goto out;
+
+ timer_setup(&ipmi_timer, ipmi_timeout, 0);
+ mod_timer(&ipmi_timer, jiffies + IPMI_TIMEOUT_JIFFIES);
--- /dev/null
+From 75d70d76cb7b927cace2cb34265d68ebb3306b13 Mon Sep 17 00:00:00 2001
+From: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
+Date: Fri, 17 Dec 2021 12:44:10 -0300
+Subject: ipmi: fix initialization when workqueue allocation fails
+
+From: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
+
+commit 75d70d76cb7b927cace2cb34265d68ebb3306b13 upstream.
+
+If the workqueue allocation fails, the driver is marked as not initialized,
+and timer and panic_notifier will be left registered.
+
+Instead of removing those when workqueue allocation fails, do the workqueue
+initialization before doing it, and cleanup srcu_struct if it fails.
+
+Fixes: 1d49eb91e86e ("ipmi: Move remove_work to dedicated workqueue")
+Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
+Cc: Corey Minyard <cminyard@mvista.com>
+Cc: Ioanna Alifieraki <ioanna-maria.alifieraki@canonical.com>
+Cc: stable@vger.kernel.org
+Message-Id: <20211217154410.1228673-2-cascardo@canonical.com>
+Signed-off-by: Corey Minyard <cminyard@mvista.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/char/ipmi/ipmi_msghandler.c | 15 +++++++++------
+ 1 file changed, 9 insertions(+), 6 deletions(-)
+
+--- a/drivers/char/ipmi/ipmi_msghandler.c
++++ b/drivers/char/ipmi/ipmi_msghandler.c
+@@ -5165,20 +5165,23 @@ static int ipmi_init_msghandler(void)
+ if (rv)
+ goto out;
+
+- timer_setup(&ipmi_timer, ipmi_timeout, 0);
+- mod_timer(&ipmi_timer, jiffies + IPMI_TIMEOUT_JIFFIES);
+-
+- atomic_notifier_chain_register(&panic_notifier_list, &panic_block);
+-
+ remove_work_wq = create_singlethread_workqueue("ipmi-msghandler-remove-wq");
+ if (!remove_work_wq) {
+ pr_err("unable to create ipmi-msghandler-remove-wq workqueue");
+ rv = -ENOMEM;
+- goto out;
++ goto out_wq;
+ }
+
++ timer_setup(&ipmi_timer, ipmi_timeout, 0);
++ mod_timer(&ipmi_timer, jiffies + IPMI_TIMEOUT_JIFFIES);
++
++ atomic_notifier_chain_register(&panic_notifier_list, &panic_block);
++
+ initialized = true;
+
++out_wq:
++ if (rv)
++ cleanup_srcu_struct(&ipmi_interfaces_srcu);
+ out:
+ mutex_unlock(&ipmi_interfaces_mutex);
+ return rv;
--- /dev/null
+From 34f35f8f14bc406efc06ee4ff73202c6fd245d15 Mon Sep 17 00:00:00 2001
+From: Mian Yousaf Kaukab <ykaukab@suse.de>
+Date: Wed, 8 Dec 2021 10:32:39 +0100
+Subject: ipmi: ssif: initialize ssif_info->client early
+
+From: Mian Yousaf Kaukab <ykaukab@suse.de>
+
+commit 34f35f8f14bc406efc06ee4ff73202c6fd245d15 upstream.
+
+During probe ssif_info->client is dereferenced in error path. However,
+it is set when some of the error checking has already been done. This
+causes following kernel crash if an error path is taken:
+
+[ 30.645593][ T674] ipmi_ssif 0-000e: ipmi_ssif: Not probing, Interface already present
+[ 30.657616][ T674] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000088
+...
+[ 30.657723][ T674] pc : __dev_printk+0x28/0xa0
+[ 30.657732][ T674] lr : _dev_err+0x7c/0xa0
+...
+[ 30.657772][ T674] Call trace:
+[ 30.657775][ T674] __dev_printk+0x28/0xa0
+[ 30.657778][ T674] _dev_err+0x7c/0xa0
+[ 30.657781][ T674] ssif_probe+0x548/0x900 [ipmi_ssif 62ce4b08badc1458fd896206d9ef69a3c31f3d3e]
+[ 30.657791][ T674] i2c_device_probe+0x37c/0x3c0
+...
+
+Initialize ssif_info->client before any error path can be taken. Clear
+i2c_client data in the error path to prevent the dangling pointer from
+leaking.
+
+Fixes: c4436c9149c5 ("ipmi_ssif: avoid registering duplicate ssif interface")
+Cc: stable@vger.kernel.org # 5.4.x
+Suggested-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Mian Yousaf Kaukab <ykaukab@suse.de>
+Message-Id: <20211208093239.4432-1-ykaukab@suse.de>
+Signed-off-by: Corey Minyard <cminyard@mvista.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/char/ipmi/ipmi_ssif.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+--- a/drivers/char/ipmi/ipmi_ssif.c
++++ b/drivers/char/ipmi/ipmi_ssif.c
+@@ -1700,6 +1700,9 @@ static int ssif_probe(struct i2c_client
+ }
+ }
+
++ ssif_info->client = client;
++ i2c_set_clientdata(client, ssif_info);
++
+ rv = ssif_check_and_remove(client, ssif_info);
+ /* If rv is 0 and addr source is not SI_ACPI, continue probing */
+ if (!rv && ssif_info->addr_source == SI_ACPI) {
+@@ -1720,9 +1723,6 @@ static int ssif_probe(struct i2c_client
+ ipmi_addr_src_to_str(ssif_info->addr_source),
+ client->addr, client->adapter->name, slave_addr);
+
+- ssif_info->client = client;
+- i2c_set_clientdata(client, ssif_info);
+-
+ /* Now check for system interface capabilities */
+ msg[0] = IPMI_NETFN_APP_REQUEST << 2;
+ msg[1] = IPMI_GET_SYSTEM_INTERFACE_CAPABILITIES_CMD;
+@@ -1922,6 +1922,7 @@ static int ssif_probe(struct i2c_client
+
+ dev_err(&ssif_info->client->dev,
+ "Unable to start IPMI SSIF: %d\n", rv);
++ i2c_set_clientdata(client, NULL);
+ kfree(ssif_info);
+ }
+ kfree(resp);
--- /dev/null
+From fdba608f15e2427419997b0898750a49a735afcb Mon Sep 17 00:00:00 2001
+From: Sean Christopherson <seanjc@google.com>
+Date: Tue, 21 Dec 2021 10:37:00 -0500
+Subject: KVM: VMX: Wake vCPU when delivering posted IRQ even if vCPU == this vCPU
+
+From: Sean Christopherson <seanjc@google.com>
+
+commit fdba608f15e2427419997b0898750a49a735afcb upstream.
+
+Drop a check that guards triggering a posted interrupt on the currently
+running vCPU, and more importantly guards waking the target vCPU if
+triggering a posted interrupt fails because the vCPU isn't IN_GUEST_MODE.
+If a vIRQ is delivered from asynchronous context, the target vCPU can be
+the currently running vCPU and can also be blocking, in which case
+skipping kvm_vcpu_wake_up() is effectively dropping what is supposed to
+be a wake event for the vCPU.
+
+The "do nothing" logic when "vcpu == running_vcpu" mostly works only
+because the majority of calls to ->deliver_posted_interrupt(), especially
+when using posted interrupts, come from synchronous KVM context. But if
+a device is exposed to the guest using vfio-pci passthrough, the VFIO IRQ
+and vCPU are bound to the same pCPU, and the IRQ is _not_ configured to
+use posted interrupts, wake events from the device will be delivered to
+KVM from IRQ context, e.g.
+
+ vfio_msihandler()
+ |
+ |-> eventfd_signal()
+ |
+ |-> ...
+ |
+ |-> irqfd_wakeup()
+ |
+ |->kvm_arch_set_irq_inatomic()
+ |
+ |-> kvm_irq_delivery_to_apic_fast()
+ |
+ |-> kvm_apic_set_irq()
+
+This also aligns the non-nested and nested usage of triggering posted
+interrupts, and will allow for additional cleanups.
+
+Fixes: 379a3c8ee444 ("KVM: VMX: Optimize posted-interrupt delivery for timer fastpath")
+Cc: stable@vger.kernel.org
+Reported-by: Longpeng (Mike) <longpeng2@huawei.com>
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
+Message-Id: <20211208015236.1616697-18-seanjc@google.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/kvm/vmx/vmx.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/arch/x86/kvm/vmx/vmx.c
++++ b/arch/x86/kvm/vmx/vmx.c
+@@ -4007,8 +4007,7 @@ static int vmx_deliver_posted_interrupt(
+ if (pi_test_and_set_on(&vmx->pi_desc))
+ return 0;
+
+- if (vcpu != kvm_get_running_vcpu() &&
+- !kvm_vcpu_trigger_posted_interrupt(vcpu, false))
++ if (!kvm_vcpu_trigger_posted_interrupt(vcpu, false))
+ kvm_vcpu_kick(vcpu);
+
+ return 0;
--- /dev/null
+From 8f66fce0f46560b9e910787ff7ad0974441c4f9c Mon Sep 17 00:00:00 2001
+From: John David Anglin <dave.anglin@bell.net>
+Date: Tue, 21 Dec 2021 13:21:22 -0500
+Subject: parisc: Correct completer in lws start
+
+From: John David Anglin <dave.anglin@bell.net>
+
+commit 8f66fce0f46560b9e910787ff7ad0974441c4f9c upstream.
+
+The completer in the "or,ev %r1,%r30,%r30" instruction is reversed, so we are
+not clipping the LWS number when we are called from a 32-bit process (W=0).
+We need to nulify the following depdi instruction when the least-significant
+bit of %r30 is 1.
+
+If the %r20 register is not clipped, a user process could perform a LWS call
+that would branch to an undefined location in the kernel and potentially crash
+the machine.
+
+Signed-off-by: John David Anglin <dave.anglin@bell.net>
+Cc: stable@vger.kernel.org # 4.19+
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/parisc/kernel/syscall.S | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/parisc/kernel/syscall.S
++++ b/arch/parisc/kernel/syscall.S
+@@ -478,7 +478,7 @@ lws_start:
+ extrd,u %r1,PSW_W_BIT,1,%r1
+ /* sp must be aligned on 4, so deposit the W bit setting into
+ * the bottom of sp temporarily */
+- or,ev %r1,%r30,%r30
++ or,od %r1,%r30,%r30
+
+ /* Clip LWS number to a 32-bit value for 32-bit processes */
+ depdi 0, 31, 32, %r20
--- /dev/null
+From d3a5a68cff47f6eead84504c3c28376b85053242 Mon Sep 17 00:00:00 2001
+From: John David Anglin <dave.anglin@bell.net>
+Date: Tue, 21 Dec 2021 13:33:16 -0500
+Subject: parisc: Fix mask used to select futex spinlock
+
+From: John David Anglin <dave.anglin@bell.net>
+
+commit d3a5a68cff47f6eead84504c3c28376b85053242 upstream.
+
+The address bits used to select the futex spinlock need to match those used in
+the LWS code in syscall.S. The mask 0x3f8 only selects 7 bits. It should
+select 8 bits.
+
+This change fixes the glibc nptl/tst-cond24 and nptl/tst-cond25 tests.
+
+Signed-off-by: John David Anglin <dave.anglin@bell.net>
+Fixes: 53a42b6324b8 ("parisc: Switch to more fine grained lws locks")
+Cc: stable@vger.kernel.org # 5.10+
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/parisc/include/asm/futex.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/arch/parisc/include/asm/futex.h
++++ b/arch/parisc/include/asm/futex.h
+@@ -16,7 +16,7 @@ static inline void
+ _futex_spin_lock_irqsave(u32 __user *uaddr, unsigned long int *flags)
+ {
+ extern u32 lws_lock_start[];
+- long index = ((long)uaddr & 0x3f8) >> 1;
++ long index = ((long)uaddr & 0x7f8) >> 1;
+ arch_spinlock_t *s = (arch_spinlock_t *)&lws_lock_start[index];
+ local_irq_save(*flags);
+ arch_spin_lock(s);
+@@ -26,7 +26,7 @@ static inline void
+ _futex_spin_unlock_irqrestore(u32 __user *uaddr, unsigned long int *flags)
+ {
+ extern u32 lws_lock_start[];
+- long index = ((long)uaddr & 0x3f8) >> 1;
++ long index = ((long)uaddr & 0x7f8) >> 1;
+ arch_spinlock_t *s = (arch_spinlock_t *)&lws_lock_start[index];
+ arch_spin_unlock(s);
+ local_irq_restore(*flags);
--- /dev/null
+From 26a8b09437804fabfb1db080d676b96c0de68e7c Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Wed, 22 Dec 2021 11:50:23 +0100
+Subject: platform/x86: intel_pmc_core: fix memleak on registration failure
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 26a8b09437804fabfb1db080d676b96c0de68e7c upstream.
+
+In case device registration fails during module initialisation, the
+platform device structure needs to be freed using platform_device_put()
+to properly free all resources (e.g. the device name).
+
+Fixes: 938835aa903a ("platform/x86: intel_pmc_core: do not create a static struct device")
+Cc: stable@vger.kernel.org # 5.9
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Link: https://lore.kernel.org/r/20211222105023.6205-1-johan@kernel.org
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/platform/x86/intel_pmc_core_pltdrv.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/platform/x86/intel_pmc_core_pltdrv.c
++++ b/drivers/platform/x86/intel_pmc_core_pltdrv.c
+@@ -65,7 +65,7 @@ static int __init pmc_core_platform_init
+
+ retval = platform_device_register(pmc_core_device);
+ if (retval)
+- kfree(pmc_core_device);
++ platform_device_put(pmc_core_device);
+
+ return retval;
+ }
hwmon-lm90-add-basic-support-for-ti-tmp461.patch
hwmon-lm90-introduce-flag-indicating-extended-temper.patch
hwmon-lm90-drop-critical-attribute-support-for-max66.patch
+alsa-jack-check-the-return-value-of-kstrdup.patch
+alsa-drivers-opl3-fix-incorrect-use-of-vp-state.patch
+alsa-hda-realtek-amp-init-fixup-for-hp-zbook-15-g6.patch
+alsa-hda-realtek-add-new-alc285-hp-amp-init-model.patch
+alsa-hda-realtek-fix-quirk-for-clevo-nj51cu.patch
+asoc-meson-aiu-move-aiu_i2s_misc-hold-setting-to-aiu-fifo-i2s.patch
+input-atmel_mxt_ts-fix-double-free-in-mxt_read_info_block.patch
+ipmi-bail-out-if-init_srcu_struct-fails.patch
+ipmi-ssif-initialize-ssif_info-client-early.patch
+ipmi-fix-initialization-when-workqueue-allocation-fails.patch
+parisc-correct-completer-in-lws-start.patch
+parisc-fix-mask-used-to-select-futex-spinlock.patch
+tee-handle-lookup-of-shm-with-reference-count-0.patch
+x86-pkey-fix-undefined-behaviour-with-pkru_wd_bit.patch
+platform-x86-intel_pmc_core-fix-memleak-on-registration-failure.patch
+kvm-vmx-wake-vcpu-when-delivering-posted-irq-even-if-vcpu-this-vcpu.patch
--- /dev/null
+From dfd0743f1d9ea76931510ed150334d571fbab49d Mon Sep 17 00:00:00 2001
+From: Jens Wiklander <jens.wiklander@linaro.org>
+Date: Thu, 9 Dec 2021 15:59:37 +0100
+Subject: tee: handle lookup of shm with reference count 0
+
+From: Jens Wiklander <jens.wiklander@linaro.org>
+
+commit dfd0743f1d9ea76931510ed150334d571fbab49d upstream.
+
+Since the tee subsystem does not keep a strong reference to its idle
+shared memory buffers, it races with other threads that try to destroy a
+shared memory through a close of its dma-buf fd or by unmapping the
+memory.
+
+In tee_shm_get_from_id() when a lookup in teedev->idr has been
+successful, it is possible that the tee_shm is in the dma-buf teardown
+path, but that path is blocked by the teedev mutex. Since we don't have
+an API to tell if the tee_shm is in the dma-buf teardown path or not we
+must find another way of detecting this condition.
+
+Fix this by doing the reference counting directly on the tee_shm using a
+new refcount_t refcount field. dma-buf is replaced by using
+anon_inode_getfd() instead, this separates the life-cycle of the
+underlying file from the tee_shm. tee_shm_put() is updated to hold the
+mutex when decreasing the refcount to 0 and then remove the tee_shm from
+teedev->idr before releasing the mutex. This means that the tee_shm can
+never be found unless it has a refcount larger than 0.
+
+Fixes: 967c9cca2cc5 ("tee: generic TEE subsystem")
+Cc: stable@vger.kernel.org
+Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Reviewed-by: Lars Persson <larper@axis.com>
+Reviewed-by: Sumit Garg <sumit.garg@linaro.org>
+Reported-by: Patrik Lantz <patrik.lantz@axis.com>
+Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tee/tee_shm.c | 171 ++++++++++++++++++------------------------------
+ include/linux/tee_drv.h | 4 -
+ 2 files changed, 68 insertions(+), 107 deletions(-)
+
+--- a/drivers/tee/tee_shm.c
++++ b/drivers/tee/tee_shm.c
+@@ -1,11 +1,11 @@
+ // SPDX-License-Identifier: GPL-2.0-only
+ /*
+- * Copyright (c) 2015-2016, Linaro Limited
++ * Copyright (c) 2015-2017, 2019-2021 Linaro Limited
+ */
++#include <linux/anon_inodes.h>
+ #include <linux/device.h>
+-#include <linux/dma-buf.h>
+-#include <linux/fdtable.h>
+ #include <linux/idr.h>
++#include <linux/mm.h>
+ #include <linux/sched.h>
+ #include <linux/slab.h>
+ #include <linux/tee_drv.h>
+@@ -28,16 +28,8 @@ static void release_registered_pages(str
+ }
+ }
+
+-static void tee_shm_release(struct tee_shm *shm)
++static void tee_shm_release(struct tee_device *teedev, struct tee_shm *shm)
+ {
+- struct tee_device *teedev = shm->ctx->teedev;
+-
+- if (shm->flags & TEE_SHM_DMA_BUF) {
+- mutex_lock(&teedev->mutex);
+- idr_remove(&teedev->idr, shm->id);
+- mutex_unlock(&teedev->mutex);
+- }
+-
+ if (shm->flags & TEE_SHM_POOL) {
+ struct tee_shm_pool_mgr *poolm;
+
+@@ -64,45 +56,6 @@ static void tee_shm_release(struct tee_s
+ tee_device_put(teedev);
+ }
+
+-static struct sg_table *tee_shm_op_map_dma_buf(struct dma_buf_attachment
+- *attach, enum dma_data_direction dir)
+-{
+- return NULL;
+-}
+-
+-static void tee_shm_op_unmap_dma_buf(struct dma_buf_attachment *attach,
+- struct sg_table *table,
+- enum dma_data_direction dir)
+-{
+-}
+-
+-static void tee_shm_op_release(struct dma_buf *dmabuf)
+-{
+- struct tee_shm *shm = dmabuf->priv;
+-
+- tee_shm_release(shm);
+-}
+-
+-static int tee_shm_op_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma)
+-{
+- struct tee_shm *shm = dmabuf->priv;
+- size_t size = vma->vm_end - vma->vm_start;
+-
+- /* Refuse sharing shared memory provided by application */
+- if (shm->flags & TEE_SHM_USER_MAPPED)
+- return -EINVAL;
+-
+- return remap_pfn_range(vma, vma->vm_start, shm->paddr >> PAGE_SHIFT,
+- size, vma->vm_page_prot);
+-}
+-
+-static const struct dma_buf_ops tee_shm_dma_buf_ops = {
+- .map_dma_buf = tee_shm_op_map_dma_buf,
+- .unmap_dma_buf = tee_shm_op_unmap_dma_buf,
+- .release = tee_shm_op_release,
+- .mmap = tee_shm_op_mmap,
+-};
+-
+ struct tee_shm *tee_shm_alloc(struct tee_context *ctx, size_t size, u32 flags)
+ {
+ struct tee_device *teedev = ctx->teedev;
+@@ -137,6 +90,7 @@ struct tee_shm *tee_shm_alloc(struct tee
+ goto err_dev_put;
+ }
+
++ refcount_set(&shm->refcount, 1);
+ shm->flags = flags | TEE_SHM_POOL;
+ shm->ctx = ctx;
+ if (flags & TEE_SHM_DMA_BUF)
+@@ -150,10 +104,7 @@ struct tee_shm *tee_shm_alloc(struct tee
+ goto err_kfree;
+ }
+
+-
+ if (flags & TEE_SHM_DMA_BUF) {
+- DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
+-
+ mutex_lock(&teedev->mutex);
+ shm->id = idr_alloc(&teedev->idr, shm, 1, 0, GFP_KERNEL);
+ mutex_unlock(&teedev->mutex);
+@@ -161,28 +112,11 @@ struct tee_shm *tee_shm_alloc(struct tee
+ ret = ERR_PTR(shm->id);
+ goto err_pool_free;
+ }
+-
+- exp_info.ops = &tee_shm_dma_buf_ops;
+- exp_info.size = shm->size;
+- exp_info.flags = O_RDWR;
+- exp_info.priv = shm;
+-
+- shm->dmabuf = dma_buf_export(&exp_info);
+- if (IS_ERR(shm->dmabuf)) {
+- ret = ERR_CAST(shm->dmabuf);
+- goto err_rem;
+- }
+ }
+
+ teedev_ctx_get(ctx);
+
+ return shm;
+-err_rem:
+- if (flags & TEE_SHM_DMA_BUF) {
+- mutex_lock(&teedev->mutex);
+- idr_remove(&teedev->idr, shm->id);
+- mutex_unlock(&teedev->mutex);
+- }
+ err_pool_free:
+ poolm->ops->free(poolm, shm);
+ err_kfree:
+@@ -243,6 +177,7 @@ struct tee_shm *tee_shm_register(struct
+ goto err;
+ }
+
++ refcount_set(&shm->refcount, 1);
+ shm->flags = flags | TEE_SHM_REGISTER;
+ shm->ctx = ctx;
+ shm->id = -1;
+@@ -303,22 +238,6 @@ struct tee_shm *tee_shm_register(struct
+ goto err;
+ }
+
+- if (flags & TEE_SHM_DMA_BUF) {
+- DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
+-
+- exp_info.ops = &tee_shm_dma_buf_ops;
+- exp_info.size = shm->size;
+- exp_info.flags = O_RDWR;
+- exp_info.priv = shm;
+-
+- shm->dmabuf = dma_buf_export(&exp_info);
+- if (IS_ERR(shm->dmabuf)) {
+- ret = ERR_CAST(shm->dmabuf);
+- teedev->desc->ops->shm_unregister(ctx, shm);
+- goto err;
+- }
+- }
+-
+ return shm;
+ err:
+ if (shm) {
+@@ -336,6 +255,35 @@ err:
+ }
+ EXPORT_SYMBOL_GPL(tee_shm_register);
+
++static int tee_shm_fop_release(struct inode *inode, struct file *filp)
++{
++ tee_shm_put(filp->private_data);
++ return 0;
++}
++
++static int tee_shm_fop_mmap(struct file *filp, struct vm_area_struct *vma)
++{
++ struct tee_shm *shm = filp->private_data;
++ size_t size = vma->vm_end - vma->vm_start;
++
++ /* Refuse sharing shared memory provided by application */
++ if (shm->flags & TEE_SHM_USER_MAPPED)
++ return -EINVAL;
++
++ /* check for overflowing the buffer's size */
++ if (vma->vm_pgoff + vma_pages(vma) > shm->size >> PAGE_SHIFT)
++ return -EINVAL;
++
++ return remap_pfn_range(vma, vma->vm_start, shm->paddr >> PAGE_SHIFT,
++ size, vma->vm_page_prot);
++}
++
++static const struct file_operations tee_shm_fops = {
++ .owner = THIS_MODULE,
++ .release = tee_shm_fop_release,
++ .mmap = tee_shm_fop_mmap,
++};
++
+ /**
+ * tee_shm_get_fd() - Increase reference count and return file descriptor
+ * @shm: Shared memory handle
+@@ -348,10 +296,11 @@ int tee_shm_get_fd(struct tee_shm *shm)
+ if (!(shm->flags & TEE_SHM_DMA_BUF))
+ return -EINVAL;
+
+- get_dma_buf(shm->dmabuf);
+- fd = dma_buf_fd(shm->dmabuf, O_CLOEXEC);
++ /* matched by tee_shm_put() in tee_shm_op_release() */
++ refcount_inc(&shm->refcount);
++ fd = anon_inode_getfd("tee_shm", &tee_shm_fops, shm, O_RDWR);
+ if (fd < 0)
+- dma_buf_put(shm->dmabuf);
++ tee_shm_put(shm);
+ return fd;
+ }
+
+@@ -361,17 +310,7 @@ int tee_shm_get_fd(struct tee_shm *shm)
+ */
+ void tee_shm_free(struct tee_shm *shm)
+ {
+- /*
+- * dma_buf_put() decreases the dmabuf reference counter and will
+- * call tee_shm_release() when the last reference is gone.
+- *
+- * In the case of driver private memory we call tee_shm_release
+- * directly instead as it doesn't have a reference counter.
+- */
+- if (shm->flags & TEE_SHM_DMA_BUF)
+- dma_buf_put(shm->dmabuf);
+- else
+- tee_shm_release(shm);
++ tee_shm_put(shm);
+ }
+ EXPORT_SYMBOL_GPL(tee_shm_free);
+
+@@ -478,10 +417,15 @@ struct tee_shm *tee_shm_get_from_id(stru
+ teedev = ctx->teedev;
+ mutex_lock(&teedev->mutex);
+ shm = idr_find(&teedev->idr, id);
++ /*
++ * If the tee_shm was found in the IDR it must have a refcount
++ * larger than 0 due to the guarantee in tee_shm_put() below. So
++ * it's safe to use refcount_inc().
++ */
+ if (!shm || shm->ctx != ctx)
+ shm = ERR_PTR(-EINVAL);
+- else if (shm->flags & TEE_SHM_DMA_BUF)
+- get_dma_buf(shm->dmabuf);
++ else
++ refcount_inc(&shm->refcount);
+ mutex_unlock(&teedev->mutex);
+ return shm;
+ }
+@@ -493,7 +437,24 @@ EXPORT_SYMBOL_GPL(tee_shm_get_from_id);
+ */
+ void tee_shm_put(struct tee_shm *shm)
+ {
+- if (shm->flags & TEE_SHM_DMA_BUF)
+- dma_buf_put(shm->dmabuf);
++ struct tee_device *teedev = shm->ctx->teedev;
++ bool do_release = false;
++
++ mutex_lock(&teedev->mutex);
++ if (refcount_dec_and_test(&shm->refcount)) {
++ /*
++ * refcount has reached 0, we must now remove it from the
++ * IDR before releasing the mutex. This will guarantee that
++ * the refcount_inc() in tee_shm_get_from_id() never starts
++ * from 0.
++ */
++ if (shm->flags & TEE_SHM_DMA_BUF)
++ idr_remove(&teedev->idr, shm->id);
++ do_release = true;
++ }
++ mutex_unlock(&teedev->mutex);
++
++ if (do_release)
++ tee_shm_release(teedev, shm);
+ }
+ EXPORT_SYMBOL_GPL(tee_shm_put);
+--- a/include/linux/tee_drv.h
++++ b/include/linux/tee_drv.h
+@@ -195,7 +195,7 @@ int tee_session_calc_client_uuid(uuid_t
+ * @offset: offset of buffer in user space
+ * @pages: locked pages from userspace
+ * @num_pages: number of locked pages
+- * @dmabuf: dmabuf used to for exporting to user space
++ * @refcount: reference counter
+ * @flags: defined by TEE_SHM_* in tee_drv.h
+ * @id: unique id of a shared memory object on this device
+ *
+@@ -210,7 +210,7 @@ struct tee_shm {
+ unsigned int offset;
+ struct page **pages;
+ size_t num_pages;
+- struct dma_buf *dmabuf;
++ refcount_t refcount;
+ u32 flags;
+ int id;
+ };
--- /dev/null
+From 57690554abe135fee81d6ac33cc94d75a7e224bb Mon Sep 17 00:00:00 2001
+From: Andrew Cooper <andrew.cooper3@citrix.com>
+Date: Thu, 16 Dec 2021 00:08:56 +0000
+Subject: x86/pkey: Fix undefined behaviour with PKRU_WD_BIT
+
+From: Andrew Cooper <andrew.cooper3@citrix.com>
+
+commit 57690554abe135fee81d6ac33cc94d75a7e224bb upstream.
+
+Both __pkru_allows_write() and arch_set_user_pkey_access() shift
+PKRU_WD_BIT (a signed constant) by up to 30 bits, hitting the
+sign bit.
+
+Use unsigned constants instead.
+
+Clearly pkey 15 has not been used in combination with UBSAN yet.
+
+Noticed by code inspection only. I can't actually provoke the
+compiler into generating incorrect logic as far as this shift is
+concerned.
+
+[
+ dhansen: add stable@ tag, plus minor changelog massaging,
+
+ For anyone doing backports, these #defines were in
+ arch/x86/include/asm/pgtable.h before 784a46618f6.
+]
+
+Fixes: 33a709b25a76 ("mm/gup, x86/mm/pkeys: Check VMAs and PTEs for protection keys")
+Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
+Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Cc: stable@vger.kernel.org
+Link: https://lkml.kernel.org/r/20211216000856.4480-1-andrew.cooper3@citrix.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/include/asm/pgtable.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/arch/x86/include/asm/pgtable.h
++++ b/arch/x86/include/asm/pgtable.h
+@@ -1360,8 +1360,8 @@ static inline pmd_t pmd_swp_clear_uffd_w
+ }
+ #endif /* CONFIG_HAVE_ARCH_USERFAULTFD_WP */
+
+-#define PKRU_AD_BIT 0x1
+-#define PKRU_WD_BIT 0x2
++#define PKRU_AD_BIT 0x1u
++#define PKRU_WD_BIT 0x2u
+ #define PKRU_BITS_PER_PKEY 2
+
+ #ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS