From: Sasha Levin Date: Mon, 1 Jun 2020 02:48:45 +0000 (-0400) Subject: Fixes for 5.6 X-Git-Tag: v4.4.226~46 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=48f91063ee413a27bfa3812f586a05609e001981;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 5.6 Signed-off-by: Sasha Levin --- diff --git a/queue-5.6/alsa-hda-realtek-add-a-model-for-thinkpad-t570-witho.patch b/queue-5.6/alsa-hda-realtek-add-a-model-for-thinkpad-t570-witho.patch new file mode 100644 index 00000000000..317511319cb --- /dev/null +++ b/queue-5.6/alsa-hda-realtek-add-a-model-for-thinkpad-t570-witho.patch @@ -0,0 +1,124 @@ +From f9dc85363bb6107e2d1e2e2a70ec63960dfa7655 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 26 May 2020 08:24:06 +0200 +Subject: ALSA: hda/realtek - Add a model for Thinkpad T570 without DAC + workaround + +From: Takashi Iwai + +[ Upstream commit 399c01aa49e548c82d40f8161915a5941dd3c60e ] + +We fixed the regression of the speaker volume for some Thinkpad models +(e.g. T570) by the commit 54947cd64c1b ("ALSA: hda/realtek - Fix +speaker output regression on Thinkpad T570"). Essentially it fixes +the DAC / pin pairing by a static table. It was confirmed and merged +to stable kernel later. + +Now, interestingly, we got another regression report for the very same +model (T570) about the similar problem, and the commit above was the +culprit. That is, by some reason, there are devices that prefer the +DAC1, and another device DAC2! + +Unfortunately those have the same ID and we have no idea what can +differentiate, in this patch, a new fixup model "tpt470-dock-fix" is +provided, so that users with such a machine can apply it manually. +When model=tpt470-dock-fix option is passed to snd-hda-intel module, +it avoids the fixed DAC pairing and the DAC1 is assigned to the +speaker like the earlier versions. + +Fixes: 54947cd64c1b ("ALSA: hda/realtek - Fix speaker output regression on Thinkpad T570") +BugLink: https://apibugzilla.suse.com/show_bug.cgi?id=1172017 +Cc: +Link: https://lore.kernel.org/r/20200526062406.9799-1-tiwai@suse.de +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/pci/hda/patch_realtek.c | 36 +++++++++++++++++++++++++---------- + 1 file changed, 26 insertions(+), 10 deletions(-) + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 041d2a32059b..92c6e58c3862 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -5484,18 +5484,9 @@ static void alc_fixup_tpt470_dock(struct hda_codec *codec, + { 0x19, 0x21a11010 }, /* dock mic */ + { } + }; +- /* Assure the speaker pin to be coupled with DAC NID 0x03; otherwise +- * the speaker output becomes too low by some reason on Thinkpads with +- * ALC298 codec +- */ +- static const hda_nid_t preferred_pairs[] = { +- 0x14, 0x03, 0x17, 0x02, 0x21, 0x02, +- 0 +- }; + struct alc_spec *spec = codec->spec; + + if (action == HDA_FIXUP_ACT_PRE_PROBE) { +- spec->gen.preferred_dacs = preferred_pairs; + spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP; + snd_hda_apply_pincfgs(codec, pincfgs); + } else if (action == HDA_FIXUP_ACT_INIT) { +@@ -5508,6 +5499,23 @@ static void alc_fixup_tpt470_dock(struct hda_codec *codec, + } + } + ++static void alc_fixup_tpt470_dacs(struct hda_codec *codec, ++ const struct hda_fixup *fix, int action) ++{ ++ /* Assure the speaker pin to be coupled with DAC NID 0x03; otherwise ++ * the speaker output becomes too low by some reason on Thinkpads with ++ * ALC298 codec ++ */ ++ static const hda_nid_t preferred_pairs[] = { ++ 0x14, 0x03, 0x17, 0x02, 0x21, 0x02, ++ 0 ++ }; ++ struct alc_spec *spec = codec->spec; ++ ++ if (action == HDA_FIXUP_ACT_PRE_PROBE) ++ spec->gen.preferred_dacs = preferred_pairs; ++} ++ + static void alc_shutup_dell_xps13(struct hda_codec *codec) + { + struct alc_spec *spec = codec->spec; +@@ -6063,6 +6071,7 @@ enum { + ALC700_FIXUP_INTEL_REFERENCE, + ALC274_FIXUP_DELL_BIND_DACS, + ALC274_FIXUP_DELL_AIO_LINEOUT_VERB, ++ ALC298_FIXUP_TPT470_DOCK_FIX, + ALC298_FIXUP_TPT470_DOCK, + ALC255_FIXUP_DUMMY_LINEOUT_VERB, + ALC255_FIXUP_DELL_HEADSET_MIC, +@@ -6994,12 +7003,18 @@ static const struct hda_fixup alc269_fixups[] = { + .chained = true, + .chain_id = ALC274_FIXUP_DELL_BIND_DACS + }, +- [ALC298_FIXUP_TPT470_DOCK] = { ++ [ALC298_FIXUP_TPT470_DOCK_FIX] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc_fixup_tpt470_dock, + .chained = true, + .chain_id = ALC293_FIXUP_LENOVO_SPK_NOISE + }, ++ [ALC298_FIXUP_TPT470_DOCK] = { ++ .type = HDA_FIXUP_FUNC, ++ .v.func = alc_fixup_tpt470_dacs, ++ .chained = true, ++ .chain_id = ALC298_FIXUP_TPT470_DOCK_FIX ++ }, + [ALC255_FIXUP_DUMMY_LINEOUT_VERB] = { + .type = HDA_FIXUP_PINS, + .v.pins = (const struct hda_pintbl[]) { +@@ -7638,6 +7653,7 @@ static const struct hda_model_fixup alc269_fixup_models[] = { + {.id = ALC292_FIXUP_TPT440_DOCK, .name = "tpt440-dock"}, + {.id = ALC292_FIXUP_TPT440, .name = "tpt440"}, + {.id = ALC292_FIXUP_TPT460, .name = "tpt460"}, ++ {.id = ALC298_FIXUP_TPT470_DOCK_FIX, .name = "tpt470-dock-fix"}, + {.id = ALC298_FIXUP_TPT470_DOCK, .name = "tpt470-dock"}, + {.id = ALC233_FIXUP_LENOVO_MULTI_CODECS, .name = "dual-codecs"}, + {.id = ALC700_FIXUP_INTEL_REFERENCE, .name = "alc700-ref"}, +-- +2.25.1 + diff --git a/queue-5.6/alsa-hda-realtek-add-new-codec-supported-for-alc287.patch b/queue-5.6/alsa-hda-realtek-add-new-codec-supported-for-alc287.patch new file mode 100644 index 00000000000..60d11b3a0b1 --- /dev/null +++ b/queue-5.6/alsa-hda-realtek-add-new-codec-supported-for-alc287.patch @@ -0,0 +1,51 @@ +From b3bb985fbcb1da558c251443c76478e9f4972db7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 27 May 2020 14:10:26 +0800 +Subject: ALSA: hda/realtek - Add new codec supported for ALC287 + +From: Kailang Yang + +[ Upstream commit 630e36126e420e1756378b3427b42711ce0b9ddd ] + +Enable new codec supported for ALC287. + +Signed-off-by: Kailang Yang +Cc: +Link: https://lore.kernel.org/r/dcf5ce5507104d0589a917cbb71dc3c6@realtek.com +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/pci/hda/patch_realtek.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 92c6e58c3862..e62d58872b6e 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -384,6 +384,7 @@ static void alc_fill_eapd_coef(struct hda_codec *codec) + case 0x10ec0282: + case 0x10ec0283: + case 0x10ec0286: ++ case 0x10ec0287: + case 0x10ec0288: + case 0x10ec0285: + case 0x10ec0298: +@@ -8292,6 +8293,7 @@ static int patch_alc269(struct hda_codec *codec) + case 0x10ec0215: + case 0x10ec0245: + case 0x10ec0285: ++ case 0x10ec0287: + case 0x10ec0289: + spec->codec_variant = ALC269_TYPE_ALC215; + spec->shutup = alc225_shutup; +@@ -9570,6 +9572,7 @@ static const struct hda_device_id snd_hda_id_realtek[] = { + HDA_CODEC_ENTRY(0x10ec0284, "ALC284", patch_alc269), + HDA_CODEC_ENTRY(0x10ec0285, "ALC285", patch_alc269), + HDA_CODEC_ENTRY(0x10ec0286, "ALC286", patch_alc269), ++ HDA_CODEC_ENTRY(0x10ec0287, "ALC287", patch_alc269), + HDA_CODEC_ENTRY(0x10ec0288, "ALC288", patch_alc269), + HDA_CODEC_ENTRY(0x10ec0289, "ALC289", patch_alc269), + HDA_CODEC_ENTRY(0x10ec0290, "ALC290", patch_alc269), +-- +2.25.1 + diff --git a/queue-5.6/alsa-hwdep-fix-a-left-shifting-1-by-31-ub-bug.patch b/queue-5.6/alsa-hwdep-fix-a-left-shifting-1-by-31-ub-bug.patch new file mode 100644 index 00000000000..75704468fde --- /dev/null +++ b/queue-5.6/alsa-hwdep-fix-a-left-shifting-1-by-31-ub-bug.patch @@ -0,0 +1,45 @@ +From 176135900d85e4bcc4ff693bae987794effc960f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 26 May 2020 00:39:21 +0000 +Subject: ALSA: hwdep: fix a left shifting 1 by 31 UB bug + +From: Changming Liu + +[ Upstream commit fb8cd6481ffd126f35e9e146a0dcf0c4e8899f2e ] + +The "info.index" variable can be 31 in "1 << info.index". +This might trigger an undefined behavior since 1 is signed. + +Fix this by casting 1 to 1u just to be sure "1u << 31" is defined. + +Signed-off-by: Changming Liu +Cc: +Link: https://lore.kernel.org/r/BL0PR06MB4548170B842CB055C9AF695DE5B00@BL0PR06MB4548.namprd06.prod.outlook.com +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/core/hwdep.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/sound/core/hwdep.c b/sound/core/hwdep.c +index b412d3b3d5ff..21edb8ac95eb 100644 +--- a/sound/core/hwdep.c ++++ b/sound/core/hwdep.c +@@ -216,12 +216,12 @@ static int snd_hwdep_dsp_load(struct snd_hwdep *hw, + if (info.index >= 32) + return -EINVAL; + /* check whether the dsp was already loaded */ +- if (hw->dsp_loaded & (1 << info.index)) ++ if (hw->dsp_loaded & (1u << info.index)) + return -EBUSY; + err = hw->ops.dsp_load(hw, &info); + if (err < 0) + return err; +- hw->dsp_loaded |= (1 << info.index); ++ hw->dsp_loaded |= (1u << info.index); + return 0; + } + +-- +2.25.1 + diff --git a/queue-5.6/alsa-usb-audio-mixer-volume-quirk-for-ess-technology.patch b/queue-5.6/alsa-usb-audio-mixer-volume-quirk-for-ess-technology.patch new file mode 100644 index 00000000000..5a503447d90 --- /dev/null +++ b/queue-5.6/alsa-usb-audio-mixer-volume-quirk-for-ess-technology.patch @@ -0,0 +1,52 @@ +From ad37b737e762a132c203df02d16902119116ef84 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 26 May 2020 14:26:13 +0800 +Subject: ALSA: usb-audio: mixer: volume quirk for ESS Technology Asus USB DAC + +From: Chris Chiu + +[ Upstream commit 4020d1ccbe55bdf67b31d718d2400506eaf4b43f ] + +The Asus USB DAC is a USB type-C audio dongle for connecting to +the headset and headphone. The volume minimum value -23040 which +is 0xa600 in hexadecimal with the resolution value 1 indicates +this should be endianness issue caused by the firmware bug. Add +a volume quirk to fix the volume control problem. + +Also fixes this warning: + Warning! Unlikely big volume range (=23040), cval->res is probably wrong. + [5] FU [Headset Capture Volume] ch = 1, val = -23040/0/1 + Warning! Unlikely big volume range (=23040), cval->res is probably wrong. + [7] FU [Headset Playback Volume] ch = 1, val = -23040/0/1 + +Signed-off-by: Chris Chiu +Cc: +Link: https://lore.kernel.org/r/20200526062613.55401-1-chiu@endlessm.com +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/usb/mixer.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c +index 7a2961ad60de..68fefe55e5c0 100644 +--- a/sound/usb/mixer.c ++++ b/sound/usb/mixer.c +@@ -1171,6 +1171,14 @@ static void volume_control_quirks(struct usb_mixer_elem_info *cval, + cval->res = 384; + } + break; ++ case USB_ID(0x0495, 0x3042): /* ESS Technology Asus USB DAC */ ++ if ((strstr(kctl->id.name, "Playback Volume") != NULL) || ++ strstr(kctl->id.name, "Capture Volume") != NULL) { ++ cval->min >>= 8; ++ cval->max = 0; ++ cval->res = 1; ++ } ++ break; + } + } + +-- +2.25.1 + diff --git a/queue-5.6/alsa-usb-audio-quirks-for-gigabyte-trx40-aorus-maste.patch b/queue-5.6/alsa-usb-audio-quirks-for-gigabyte-trx40-aorus-maste.patch new file mode 100644 index 00000000000..d5ea92c4bd9 --- /dev/null +++ b/queue-5.6/alsa-usb-audio-quirks-for-gigabyte-trx40-aorus-maste.patch @@ -0,0 +1,119 @@ +From 464e5f32ad0f8afa63b3bd817e442570e92bec29 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 26 May 2020 10:28:10 +0200 +Subject: ALSA: usb-audio: Quirks for Gigabyte TRX40 Aorus Master onboard audio + +From: Takashi Iwai + +[ Upstream commit 7f5ad9c9003425175f46c94df380e8c9e558cfb5 ] + +Gigabyte TRX40 Aorus Master is equipped with two USB-audio devices, +a Realtek ALC1220-VB codec (USB ID 0414:a001) and an ESS SABRE9218 DAC +(USB ID 0414:a000). The latter serves solely for the headphone output +on the front panel while the former serves for the rest I/Os (mostly +for the I/Os in the rear panel but also including the front mic). + +Both chips do work more or less with the unmodified USB-audio driver, +but there are a few glitches. The ALC1220-VB returns an error for an +inquiry to some jacks, as already seen on other TRX40-based mobos. +However this machine has a slightly incompatible configuration, hence +the existing mapping cannot be used as is. + +Meanwhile the ESS chip seems working without any quirk. But since +both audio devices don't provide any specific names, both cards appear +as "USB-Audio", and it's quite confusing for users. + +This patch is an attempt to overcome those issues: + +- The specific mapping table for ALC1220-VB is provided, reducing the + non-working nodes and renaming the badly chosen controls. + The connector map isn't needed here unlike other TRX40 quirks. + +- For both USB IDs (0414:a000 and 0414:a001), provide specific card + name strings, so that user-space can identify more easily; and more + importantly, UCM profile can be applied to each. + +Reported-by: Linus Torvalds +Cc: +Link: https://lore.kernel.org/r/20200526082810.29506-1-tiwai@suse.de +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/usb/mixer_maps.c | 19 +++++++++++++++++++ + sound/usb/quirks-table.h | 25 +++++++++++++++++++++++++ + 2 files changed, 44 insertions(+) + +diff --git a/sound/usb/mixer_maps.c b/sound/usb/mixer_maps.c +index bfdc6ad52785..9af7aa93f6fa 100644 +--- a/sound/usb/mixer_maps.c ++++ b/sound/usb/mixer_maps.c +@@ -397,6 +397,21 @@ static const struct usbmix_connector_map trx40_mobo_connector_map[] = { + {} + }; + ++/* Rear panel + front mic on Gigabyte TRX40 Aorus Master with ALC1220-VB */ ++static const struct usbmix_name_map aorus_master_alc1220vb_map[] = { ++ { 17, NULL }, /* OT, IEC958?, disabled */ ++ { 19, NULL, 12 }, /* FU, Input Gain Pad - broken response, disabled */ ++ { 16, "Line Out" }, /* OT */ ++ { 22, "Line Out Playback" }, /* FU */ ++ { 7, "Line" }, /* IT */ ++ { 19, "Line Capture" }, /* FU */ ++ { 8, "Mic" }, /* IT */ ++ { 20, "Mic Capture" }, /* FU */ ++ { 9, "Front Mic" }, /* IT */ ++ { 21, "Front Mic Capture" }, /* FU */ ++ {} ++}; ++ + /* + * Control map entries + */ +@@ -526,6 +541,10 @@ static const struct usbmix_ctl_map usbmix_ctl_maps[] = { + .id = USB_ID(0x1b1c, 0x0a42), + .map = corsair_virtuoso_map, + }, ++ { /* Gigabyte TRX40 Aorus Master (rear panel + front mic) */ ++ .id = USB_ID(0x0414, 0xa001), ++ .map = aorus_master_alc1220vb_map, ++ }, + { /* Gigabyte TRX40 Aorus Pro WiFi */ + .id = USB_ID(0x0414, 0xa002), + .map = trx40_mobo_map, +diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h +index aa4c16ce0e57..bbae11605a4c 100644 +--- a/sound/usb/quirks-table.h ++++ b/sound/usb/quirks-table.h +@@ -3650,4 +3650,29 @@ ALC1220_VB_DESKTOP(0x0db0, 0x543d), /* MSI TRX40 */ + ALC1220_VB_DESKTOP(0x26ce, 0x0a01), /* Asrock TRX40 Creator */ + #undef ALC1220_VB_DESKTOP + ++/* Two entries for Gigabyte TRX40 Aorus Master: ++ * TRX40 Aorus Master has two USB-audio devices, one for the front headphone ++ * with ESS SABRE9218 DAC chip, while another for the rest I/O (the rear ++ * panel and the front mic) with Realtek ALC1220-VB. ++ * Here we provide two distinct names for making UCM profiles easier. ++ */ ++{ ++ USB_DEVICE(0x0414, 0xa000), ++ .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { ++ .vendor_name = "Gigabyte", ++ .product_name = "Aorus Master Front Headphone", ++ .profile_name = "Gigabyte-Aorus-Master-Front-Headphone", ++ .ifnum = QUIRK_NO_INTERFACE ++ } ++}, ++{ ++ USB_DEVICE(0x0414, 0xa001), ++ .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { ++ .vendor_name = "Gigabyte", ++ .product_name = "Aorus Master Main Audio", ++ .profile_name = "Gigabyte-Aorus-Master-Main-Audio", ++ .ifnum = QUIRK_NO_INTERFACE ++ } ++}, ++ + #undef USB_DEVICE_VENDOR_SPEC +-- +2.25.1 + diff --git a/queue-5.6/arm-8970-1-decompressor-increase-tag-size.patch b/queue-5.6/arm-8970-1-decompressor-increase-tag-size.patch new file mode 100644 index 00000000000..d0501ec6cdb --- /dev/null +++ b/queue-5.6/arm-8970-1-decompressor-increase-tag-size.patch @@ -0,0 +1,39 @@ +From 5e06d3c8b49d643f3ecfc2f9ef8d19910b63cba3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 Apr 2020 20:36:11 +0100 +Subject: ARM: 8970/1: decompressor: increase tag size +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Łukasz Stelmach + +[ Upstream commit 2c962369d72f286659e6446919f88d69b943cb4d ] + +The size field of the tag header structure is supposed to be set to the +size of a tag structure including the header. + +Fixes: c772568788b5f0 ("ARM: add additional table to compressed kernel") +Signed-off-by: Łukasz Stelmach +Signed-off-by: Russell King +Signed-off-by: Sasha Levin +--- + arch/arm/boot/compressed/vmlinux.lds.S | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm/boot/compressed/vmlinux.lds.S b/arch/arm/boot/compressed/vmlinux.lds.S +index fc7ed03d8b93..51b078604978 100644 +--- a/arch/arm/boot/compressed/vmlinux.lds.S ++++ b/arch/arm/boot/compressed/vmlinux.lds.S +@@ -43,7 +43,7 @@ SECTIONS + } + .table : ALIGN(4) { + _table_start = .; +- LONG(ZIMAGE_MAGIC(2)) ++ LONG(ZIMAGE_MAGIC(4)) + LONG(ZIMAGE_MAGIC(0x5a534c4b)) + LONG(ZIMAGE_MAGIC(__piggy_size_addr - _start)) + LONG(ZIMAGE_MAGIC(_kernel_bss_size)) +-- +2.25.1 + diff --git a/queue-5.6/arm-dts-bcm-hr2-fix-ppi-interrupt-types.patch b/queue-5.6/arm-dts-bcm-hr2-fix-ppi-interrupt-types.patch new file mode 100644 index 00000000000..7f29fa552bf --- /dev/null +++ b/queue-5.6/arm-dts-bcm-hr2-fix-ppi-interrupt-types.patch @@ -0,0 +1,62 @@ +From d9eae0356157b0e6acd431ad689b0dc0254fdb82 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 20 May 2020 16:30:42 +1200 +Subject: ARM: dts: bcm: HR2: Fix PPI interrupt types + +From: Hamish Martin + +[ Upstream commit be0ec060b54f0481fb95d59086c1484a949c903c ] + +These error messages are output when booting on a BCM HR2 system: + GIC: PPI11 is secure or misconfigured + GIC: PPI13 is secure or misconfigured + +Per ARM documentation these interrupts are triggered on a rising edge. +See ARM Cortex A-9 MPCore Technical Reference Manual, Revision r4p1, +Section 3.3.8 Interrupt Configuration Registers. + +The same issue was resolved for NSP systems in commit 5f1aa51c7a1e +("ARM: dts: NSP: Fix PPI interrupt types"). + +Fixes: b9099ec754b5 ("ARM: dts: Add Broadcom Hurricane 2 DTS include file") +Signed-off-by: Hamish Martin +Signed-off-by: Florian Fainelli +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/bcm-hr2.dtsi | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/arch/arm/boot/dts/bcm-hr2.dtsi b/arch/arm/boot/dts/bcm-hr2.dtsi +index 6142c672811e..5e5f5ca3c86f 100644 +--- a/arch/arm/boot/dts/bcm-hr2.dtsi ++++ b/arch/arm/boot/dts/bcm-hr2.dtsi +@@ -75,7 +75,7 @@ + timer@20200 { + compatible = "arm,cortex-a9-global-timer"; + reg = <0x20200 0x100>; +- interrupts = ; ++ interrupts = ; + clocks = <&periph_clk>; + }; + +@@ -83,7 +83,7 @@ + compatible = "arm,cortex-a9-twd-timer"; + reg = <0x20600 0x20>; + interrupts = ; ++ IRQ_TYPE_EDGE_RISING)>; + clocks = <&periph_clk>; + }; + +@@ -91,7 +91,7 @@ + compatible = "arm,cortex-a9-twd-wdt"; + reg = <0x20620 0x20>; + interrupts = ; ++ IRQ_TYPE_EDGE_RISING)>; + clocks = <&periph_clk>; + }; + +-- +2.25.1 + diff --git a/queue-5.6/arm-dts-bcm2835-rpi-zero-w-fix-led-polarity.patch b/queue-5.6/arm-dts-bcm2835-rpi-zero-w-fix-led-polarity.patch new file mode 100644 index 00000000000..a326c749e2f --- /dev/null +++ b/queue-5.6/arm-dts-bcm2835-rpi-zero-w-fix-led-polarity.patch @@ -0,0 +1,46 @@ +From b5bc18b5d18dbe5669b36682c6207807fb912033 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 18 Apr 2020 14:35:22 +0200 +Subject: ARM: dts: bcm2835-rpi-zero-w: Fix led polarity +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Vincent Stehlé + +[ Upstream commit 58bb90ab415562eededb932455046924e65df342 ] + +The status "ACT" led on the Raspberry Pi Zero W is on when GPIO 47 is low. + +This has been verified on a board and somewhat confirmed by both the GPIO +name ("STATUS_LED_N") and the reduced schematics [1]. + +[1]: https://www.raspberrypi.org/documentation/hardware/raspberrypi/schematics/rpi_SCH_ZeroW_1p1_reduced.pdf + +Fixes: 2c7c040c73e9 ("ARM: dts: bcm2835: Add Raspberry Pi Zero W") +Signed-off-by: Vincent Stehlé +Cc: Stefan Wahren +Cc: Florian Fainelli +Tested-by: Stefan Wahren +Signed-off-by: Florian Fainelli +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/bcm2835-rpi-zero-w.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/bcm2835-rpi-zero-w.dts b/arch/arm/boot/dts/bcm2835-rpi-zero-w.dts +index 4c3f606e5b8d..f65448c01e31 100644 +--- a/arch/arm/boot/dts/bcm2835-rpi-zero-w.dts ++++ b/arch/arm/boot/dts/bcm2835-rpi-zero-w.dts +@@ -24,7 +24,7 @@ + + leds { + act { +- gpios = <&gpio 47 GPIO_ACTIVE_HIGH>; ++ gpios = <&gpio 47 GPIO_ACTIVE_LOW>; + }; + }; + +-- +2.25.1 + diff --git a/queue-5.6/arm-dts-imx6q-bx50v3-set-display-interface-clock-par.patch b/queue-5.6/arm-dts-imx6q-bx50v3-set-display-interface-clock-par.patch new file mode 100644 index 00000000000..4352d27f73d --- /dev/null +++ b/queue-5.6/arm-dts-imx6q-bx50v3-set-display-interface-clock-par.patch @@ -0,0 +1,122 @@ +From df47379ff14db625fdbbed05ec0776b108713a32 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 14 May 2020 19:02:37 +0200 +Subject: ARM: dts/imx6q-bx50v3: Set display interface clock parents + +From: Robert Beckett + +[ Upstream commit 665e7c73a7724a393b4ec92d1ae1e029925ef2b7 ] + +Avoid LDB and IPU DI clocks both using the same parent. LDB requires +pasthrough clock to avoid breaking timing while IPU DI does not. + +Force IPU DI clocks to use IMX6QDL_CLK_PLL2_PFD0_352M as parent +and LDB to use IMX6QDL_CLK_PLL5_VIDEO_DIV. + +This fixes an issue where attempting atomic modeset while using +HDMI and display port at the same time causes LDB clock programming +to destroy the programming of HDMI that was done during the same +modeset. + +Cc: stable@vger.kernel.org +Signed-off-by: Robert Beckett +[Use IMX6QDL_CLK_PLL2_PFD0_352M instead of IMX6QDL_CLK_PLL2_PFD2_396M + originally chosen by Robert Beckett to avoid affecting eMMC clock + by DRM atomic updates] +Signed-off-by: Ian Ray +[Squash Robert's and Ian's commits for bisectability, update patch + description and add stable tag] +Signed-off-by: Sebastian Reichel +Signed-off-by: Shawn Guo +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/imx6q-b450v3.dts | 7 ------- + arch/arm/boot/dts/imx6q-b650v3.dts | 7 ------- + arch/arm/boot/dts/imx6q-b850v3.dts | 11 ----------- + arch/arm/boot/dts/imx6q-bx50v3.dtsi | 15 +++++++++++++++ + 4 files changed, 15 insertions(+), 25 deletions(-) + +diff --git a/arch/arm/boot/dts/imx6q-b450v3.dts b/arch/arm/boot/dts/imx6q-b450v3.dts +index 95b8f2d71821..fb0980190aa0 100644 +--- a/arch/arm/boot/dts/imx6q-b450v3.dts ++++ b/arch/arm/boot/dts/imx6q-b450v3.dts +@@ -65,13 +65,6 @@ + }; + }; + +-&clks { +- assigned-clocks = <&clks IMX6QDL_CLK_LDB_DI0_SEL>, +- <&clks IMX6QDL_CLK_LDB_DI1_SEL>; +- assigned-clock-parents = <&clks IMX6QDL_CLK_PLL3_USB_OTG>, +- <&clks IMX6QDL_CLK_PLL3_USB_OTG>; +-}; +- + &ldb { + status = "okay"; + +diff --git a/arch/arm/boot/dts/imx6q-b650v3.dts b/arch/arm/boot/dts/imx6q-b650v3.dts +index 611cb7ae7e55..8f762d9c5ae9 100644 +--- a/arch/arm/boot/dts/imx6q-b650v3.dts ++++ b/arch/arm/boot/dts/imx6q-b650v3.dts +@@ -65,13 +65,6 @@ + }; + }; + +-&clks { +- assigned-clocks = <&clks IMX6QDL_CLK_LDB_DI0_SEL>, +- <&clks IMX6QDL_CLK_LDB_DI1_SEL>; +- assigned-clock-parents = <&clks IMX6QDL_CLK_PLL3_USB_OTG>, +- <&clks IMX6QDL_CLK_PLL3_USB_OTG>; +-}; +- + &ldb { + status = "okay"; + +diff --git a/arch/arm/boot/dts/imx6q-b850v3.dts b/arch/arm/boot/dts/imx6q-b850v3.dts +index e4cb118f88c6..1ea64ecf4291 100644 +--- a/arch/arm/boot/dts/imx6q-b850v3.dts ++++ b/arch/arm/boot/dts/imx6q-b850v3.dts +@@ -53,17 +53,6 @@ + }; + }; + +-&clks { +- assigned-clocks = <&clks IMX6QDL_CLK_LDB_DI0_SEL>, +- <&clks IMX6QDL_CLK_LDB_DI1_SEL>, +- <&clks IMX6QDL_CLK_IPU1_DI0_PRE_SEL>, +- <&clks IMX6QDL_CLK_IPU2_DI0_PRE_SEL>; +- assigned-clock-parents = <&clks IMX6QDL_CLK_PLL5_VIDEO_DIV>, +- <&clks IMX6QDL_CLK_PLL5_VIDEO_DIV>, +- <&clks IMX6QDL_CLK_PLL2_PFD2_396M>, +- <&clks IMX6QDL_CLK_PLL2_PFD2_396M>; +-}; +- + &ldb { + fsl,dual-channel; + status = "okay"; +diff --git a/arch/arm/boot/dts/imx6q-bx50v3.dtsi b/arch/arm/boot/dts/imx6q-bx50v3.dtsi +index fa27dcdf06f1..1938b04199c4 100644 +--- a/arch/arm/boot/dts/imx6q-bx50v3.dtsi ++++ b/arch/arm/boot/dts/imx6q-bx50v3.dtsi +@@ -377,3 +377,18 @@ + #interrupt-cells = <1>; + }; + }; ++ ++&clks { ++ assigned-clocks = <&clks IMX6QDL_CLK_LDB_DI0_SEL>, ++ <&clks IMX6QDL_CLK_LDB_DI1_SEL>, ++ <&clks IMX6QDL_CLK_IPU1_DI0_PRE_SEL>, ++ <&clks IMX6QDL_CLK_IPU1_DI1_PRE_SEL>, ++ <&clks IMX6QDL_CLK_IPU2_DI0_PRE_SEL>, ++ <&clks IMX6QDL_CLK_IPU2_DI1_PRE_SEL>; ++ assigned-clock-parents = <&clks IMX6QDL_CLK_PLL5_VIDEO_DIV>, ++ <&clks IMX6QDL_CLK_PLL5_VIDEO_DIV>, ++ <&clks IMX6QDL_CLK_PLL2_PFD0_352M>, ++ <&clks IMX6QDL_CLK_PLL2_PFD0_352M>, ++ <&clks IMX6QDL_CLK_PLL2_PFD0_352M>, ++ <&clks IMX6QDL_CLK_PLL2_PFD0_352M>; ++}; +-- +2.25.1 + diff --git a/queue-5.6/arm-dts-mmp3-dell-ariel-fix-the-spi-devices.patch b/queue-5.6/arm-dts-mmp3-dell-ariel-fix-the-spi-devices.patch new file mode 100644 index 00000000000..0e20a29189f --- /dev/null +++ b/queue-5.6/arm-dts-mmp3-dell-ariel-fix-the-spi-devices.patch @@ -0,0 +1,59 @@ +From 58f959ae77ddaf44bf4d65037854de85c947c82b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 19 Apr 2020 19:11:57 +0200 +Subject: ARM: dts: mmp3-dell-ariel: Fix the SPI devices + +From: Lubomir Rintel + +[ Upstream commit 233cbffaa0b9ca874731efee67a11f005da1f87c ] + +I've managed to get about everything wrong while digging these out of +OEM's board file. + +Correct the bus numbers, the exact model of the NOR flash, polarity of +the chip selects and align the SPI frequency with the data sheet. + +Tested that it works now, with a slight fix to the PXA SSP driver. + +Link: https://lore.kernel.org/r/20200419171157.672999-16-lkundrak@v3.sk +Signed-off-by: Lubomir Rintel +Cc: +Signed-off-by: Arnd Bergmann +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/mmp3-dell-ariel.dts | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/arch/arm/boot/dts/mmp3-dell-ariel.dts b/arch/arm/boot/dts/mmp3-dell-ariel.dts +index 15449c72c042..b0ec14c42164 100644 +--- a/arch/arm/boot/dts/mmp3-dell-ariel.dts ++++ b/arch/arm/boot/dts/mmp3-dell-ariel.dts +@@ -98,19 +98,19 @@ + status = "okay"; + }; + +-&ssp3 { ++&ssp1 { + status = "okay"; +- cs-gpios = <&gpio 46 GPIO_ACTIVE_HIGH>; ++ cs-gpios = <&gpio 46 GPIO_ACTIVE_LOW>; + + firmware-flash@0 { +- compatible = "st,m25p80", "jedec,spi-nor"; ++ compatible = "winbond,w25q32", "jedec,spi-nor"; + reg = <0>; +- spi-max-frequency = <40000000>; ++ spi-max-frequency = <104000000>; + m25p,fast-read; + }; + }; + +-&ssp4 { +- cs-gpios = <&gpio 56 GPIO_ACTIVE_HIGH>; ++&ssp2 { ++ cs-gpios = <&gpio 56 GPIO_ACTIVE_LOW>; + status = "okay"; + }; +-- +2.25.1 + diff --git a/queue-5.6/arm-dts-mmp3-drop-usb-nop-xceiv-from-hsic-phy.patch b/queue-5.6/arm-dts-mmp3-drop-usb-nop-xceiv-from-hsic-phy.patch new file mode 100644 index 00000000000..77ced4bd5f7 --- /dev/null +++ b/queue-5.6/arm-dts-mmp3-drop-usb-nop-xceiv-from-hsic-phy.patch @@ -0,0 +1,51 @@ +From 4c9913e8152e53a46a1f6bbf3f4370698f456f51 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 19 Apr 2020 19:11:55 +0200 +Subject: ARM: dts: mmp3: Drop usb-nop-xceiv from HSIC phy + +From: Lubomir Rintel + +[ Upstream commit 24cf6eef79a7e85cfd2ef9dea52f769c9192fc6e ] + +"usb-nop-xceiv" is good enough if we don't lose the configuration done +by the firmware, but we'd really prefer a real driver. + +Unfortunately, the PHY core is odd in that when the node is compatible +with "usb-nop-xceiv", it ignores the other compatible strings. Let's +just remove it. + +Signed-off-by: Lubomir Rintel +Cc: +Signed-off-by: Arnd Bergmann +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/mmp3.dtsi | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/arch/arm/boot/dts/mmp3.dtsi b/arch/arm/boot/dts/mmp3.dtsi +index 3e28f0dc9df4..1e25bf998ab5 100644 +--- a/arch/arm/boot/dts/mmp3.dtsi ++++ b/arch/arm/boot/dts/mmp3.dtsi +@@ -202,8 +202,7 @@ + }; + + hsic_phy0: hsic-phy@f0001800 { +- compatible = "marvell,mmp3-hsic-phy", +- "usb-nop-xceiv"; ++ compatible = "marvell,mmp3-hsic-phy"; + reg = <0xf0001800 0x40>; + #phy-cells = <0>; + status = "disabled"; +@@ -224,8 +223,7 @@ + }; + + hsic_phy1: hsic-phy@f0002800 { +- compatible = "marvell,mmp3-hsic-phy", +- "usb-nop-xceiv"; ++ compatible = "marvell,mmp3-hsic-phy"; + reg = <0xf0002800 0x40>; + #phy-cells = <0>; + status = "disabled"; +-- +2.25.1 + diff --git a/queue-5.6/arm-dts-mmp3-use-the-mmp3-compatible-string-for-cloc.patch b/queue-5.6/arm-dts-mmp3-use-the-mmp3-compatible-string-for-cloc.patch new file mode 100644 index 00000000000..79c8d151fa2 --- /dev/null +++ b/queue-5.6/arm-dts-mmp3-use-the-mmp3-compatible-string-for-cloc.patch @@ -0,0 +1,38 @@ +From 83343ca00e89e68fd21d1a462406ab692254abf1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 19 Apr 2020 19:11:56 +0200 +Subject: ARM: dts: mmp3: Use the MMP3 compatible string for /clocks + +From: Lubomir Rintel + +[ Upstream commit ec7d12faf81de983efce8ff23f41c5d1bff14c41 ] + +Clocks are in fact slightly different on MMP3. In particular, PLL2 is +fixed to a different frequency, there's an extra PLL3, and the GPU +clocks are configured differently. + +Link: https://lore.kernel.org/r/20200419171157.672999-15-lkundrak@v3.sk +Signed-off-by: Lubomir Rintel +Cc: +Signed-off-by: Arnd Bergmann +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/mmp3.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/mmp3.dtsi b/arch/arm/boot/dts/mmp3.dtsi +index 59a108e49b41..3e28f0dc9df4 100644 +--- a/arch/arm/boot/dts/mmp3.dtsi ++++ b/arch/arm/boot/dts/mmp3.dtsi +@@ -531,7 +531,7 @@ + }; + + soc_clocks: clocks@d4050000 { +- compatible = "marvell,mmp2-clock"; ++ compatible = "marvell,mmp3-clock"; + reg = <0xd4050000 0x1000>, + <0xd4282800 0x400>, + <0xd4015000 0x1000>; +-- +2.25.1 + diff --git a/queue-5.6/arm-uaccess-consolidate-uaccess-asm-to-asm-uaccess-a.patch b/queue-5.6/arm-uaccess-consolidate-uaccess-asm-to-asm-uaccess-a.patch new file mode 100644 index 00000000000..d3b0c4a08ac --- /dev/null +++ b/queue-5.6/arm-uaccess-consolidate-uaccess-asm-to-asm-uaccess-a.patch @@ -0,0 +1,302 @@ +From 00d3e8ccc37b1bcfb070d20d5b7a81e1afd242bb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 3 May 2020 13:03:54 +0100 +Subject: ARM: uaccess: consolidate uaccess asm to asm/uaccess-asm.h + +From: Russell King + +[ Upstream commit 747ffc2fcf969eff9309d7f2d1d61cb8b9e1bb40 ] + +Consolidate the user access assembly code to asm/uaccess-asm.h. This +moves the csdb, check_uaccess, uaccess_mask_range_ptr, uaccess_enable, +uaccess_disable, uaccess_save, uaccess_restore macros, and creates two +new ones for exception entry and exit - uaccess_entry and uaccess_exit. + +This makes the uaccess_save and uaccess_restore macros private to +asm/uaccess-asm.h. + +Signed-off-by: Russell King +Signed-off-by: Sasha Levin +--- + arch/arm/include/asm/assembler.h | 75 +------------------- + arch/arm/include/asm/uaccess-asm.h | 106 +++++++++++++++++++++++++++++ + arch/arm/kernel/entry-armv.S | 11 +-- + arch/arm/kernel/entry-header.S | 9 +-- + 4 files changed, 112 insertions(+), 89 deletions(-) + create mode 100644 arch/arm/include/asm/uaccess-asm.h + +diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h +index 99929122dad7..3546d294d55f 100644 +--- a/arch/arm/include/asm/assembler.h ++++ b/arch/arm/include/asm/assembler.h +@@ -18,11 +18,11 @@ + #endif + + #include +-#include + #include + #include + #include + #include ++#include + + #define IOMEM(x) (x) + +@@ -446,79 +446,6 @@ THUMB( orr \reg , \reg , #PSR_T_BIT ) + .size \name , . - \name + .endm + +- .macro csdb +-#ifdef CONFIG_THUMB2_KERNEL +- .inst.w 0xf3af8014 +-#else +- .inst 0xe320f014 +-#endif +- .endm +- +- .macro check_uaccess, addr:req, size:req, limit:req, tmp:req, bad:req +-#ifndef CONFIG_CPU_USE_DOMAINS +- adds \tmp, \addr, #\size - 1 +- sbcscc \tmp, \tmp, \limit +- bcs \bad +-#ifdef CONFIG_CPU_SPECTRE +- movcs \addr, #0 +- csdb +-#endif +-#endif +- .endm +- +- .macro uaccess_mask_range_ptr, addr:req, size:req, limit:req, tmp:req +-#ifdef CONFIG_CPU_SPECTRE +- sub \tmp, \limit, #1 +- subs \tmp, \tmp, \addr @ tmp = limit - 1 - addr +- addhs \tmp, \tmp, #1 @ if (tmp >= 0) { +- subshs \tmp, \tmp, \size @ tmp = limit - (addr + size) } +- movlo \addr, #0 @ if (tmp < 0) addr = NULL +- csdb +-#endif +- .endm +- +- .macro uaccess_disable, tmp, isb=1 +-#ifdef CONFIG_CPU_SW_DOMAIN_PAN +- /* +- * Whenever we re-enter userspace, the domains should always be +- * set appropriately. +- */ +- mov \tmp, #DACR_UACCESS_DISABLE +- mcr p15, 0, \tmp, c3, c0, 0 @ Set domain register +- .if \isb +- instr_sync +- .endif +-#endif +- .endm +- +- .macro uaccess_enable, tmp, isb=1 +-#ifdef CONFIG_CPU_SW_DOMAIN_PAN +- /* +- * Whenever we re-enter userspace, the domains should always be +- * set appropriately. +- */ +- mov \tmp, #DACR_UACCESS_ENABLE +- mcr p15, 0, \tmp, c3, c0, 0 +- .if \isb +- instr_sync +- .endif +-#endif +- .endm +- +- .macro uaccess_save, tmp +-#ifdef CONFIG_CPU_SW_DOMAIN_PAN +- mrc p15, 0, \tmp, c3, c0, 0 +- str \tmp, [sp, #SVC_DACR] +-#endif +- .endm +- +- .macro uaccess_restore +-#ifdef CONFIG_CPU_SW_DOMAIN_PAN +- ldr r0, [sp, #SVC_DACR] +- mcr p15, 0, r0, c3, c0, 0 +-#endif +- .endm +- + .irp c,,eq,ne,cs,cc,mi,pl,vs,vc,hi,ls,ge,lt,gt,le,hs,lo + .macro ret\c, reg + #if __LINUX_ARM_ARCH__ < 6 +diff --git a/arch/arm/include/asm/uaccess-asm.h b/arch/arm/include/asm/uaccess-asm.h +new file mode 100644 +index 000000000000..d475e3e8145d +--- /dev/null ++++ b/arch/arm/include/asm/uaccess-asm.h +@@ -0,0 +1,106 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++ ++#ifndef __ASM_UACCESS_ASM_H__ ++#define __ASM_UACCESS_ASM_H__ ++ ++#include ++#include ++#include ++#include ++ ++ .macro csdb ++#ifdef CONFIG_THUMB2_KERNEL ++ .inst.w 0xf3af8014 ++#else ++ .inst 0xe320f014 ++#endif ++ .endm ++ ++ .macro check_uaccess, addr:req, size:req, limit:req, tmp:req, bad:req ++#ifndef CONFIG_CPU_USE_DOMAINS ++ adds \tmp, \addr, #\size - 1 ++ sbcscc \tmp, \tmp, \limit ++ bcs \bad ++#ifdef CONFIG_CPU_SPECTRE ++ movcs \addr, #0 ++ csdb ++#endif ++#endif ++ .endm ++ ++ .macro uaccess_mask_range_ptr, addr:req, size:req, limit:req, tmp:req ++#ifdef CONFIG_CPU_SPECTRE ++ sub \tmp, \limit, #1 ++ subs \tmp, \tmp, \addr @ tmp = limit - 1 - addr ++ addhs \tmp, \tmp, #1 @ if (tmp >= 0) { ++ subshs \tmp, \tmp, \size @ tmp = limit - (addr + size) } ++ movlo \addr, #0 @ if (tmp < 0) addr = NULL ++ csdb ++#endif ++ .endm ++ ++ .macro uaccess_disable, tmp, isb=1 ++#ifdef CONFIG_CPU_SW_DOMAIN_PAN ++ /* ++ * Whenever we re-enter userspace, the domains should always be ++ * set appropriately. ++ */ ++ mov \tmp, #DACR_UACCESS_DISABLE ++ mcr p15, 0, \tmp, c3, c0, 0 @ Set domain register ++ .if \isb ++ instr_sync ++ .endif ++#endif ++ .endm ++ ++ .macro uaccess_enable, tmp, isb=1 ++#ifdef CONFIG_CPU_SW_DOMAIN_PAN ++ /* ++ * Whenever we re-enter userspace, the domains should always be ++ * set appropriately. ++ */ ++ mov \tmp, #DACR_UACCESS_ENABLE ++ mcr p15, 0, \tmp, c3, c0, 0 ++ .if \isb ++ instr_sync ++ .endif ++#endif ++ .endm ++ ++ .macro uaccess_save, tmp ++#ifdef CONFIG_CPU_SW_DOMAIN_PAN ++ mrc p15, 0, \tmp, c3, c0, 0 ++ str \tmp, [sp, #SVC_DACR] ++#endif ++ .endm ++ ++ .macro uaccess_restore ++#ifdef CONFIG_CPU_SW_DOMAIN_PAN ++ ldr r0, [sp, #SVC_DACR] ++ mcr p15, 0, r0, c3, c0, 0 ++#endif ++ .endm ++ ++ /* ++ * Save the address limit on entry to a privileged exception and ++ * if using PAN, save and disable usermode access. ++ */ ++ .macro uaccess_entry, tsk, tmp0, tmp1, tmp2, disable ++ ldr \tmp0, [\tsk, #TI_ADDR_LIMIT] ++ mov \tmp1, #TASK_SIZE ++ str \tmp1, [\tsk, #TI_ADDR_LIMIT] ++ str \tmp0, [sp, #SVC_ADDR_LIMIT] ++ uaccess_save \tmp0 ++ .if \disable ++ uaccess_disable \tmp0 ++ .endif ++ .endm ++ ++ /* Restore the user access state previously saved by uaccess_entry */ ++ .macro uaccess_exit, tsk, tmp0, tmp1 ++ ldr \tmp1, [sp, #SVC_ADDR_LIMIT] ++ uaccess_restore ++ str \tmp1, [\tsk, #TI_ADDR_LIMIT] ++ .endm ++ ++#endif /* __ASM_UACCESS_ASM_H__ */ +diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S +index 77f54830554c..55a47df04773 100644 +--- a/arch/arm/kernel/entry-armv.S ++++ b/arch/arm/kernel/entry-armv.S +@@ -27,6 +27,7 @@ + #include + #include + #include ++#include + + #include "entry-header.S" + #include +@@ -179,15 +180,7 @@ ENDPROC(__und_invalid) + stmia r7, {r2 - r6} + + get_thread_info tsk +- ldr r0, [tsk, #TI_ADDR_LIMIT] +- mov r1, #TASK_SIZE +- str r1, [tsk, #TI_ADDR_LIMIT] +- str r0, [sp, #SVC_ADDR_LIMIT] +- +- uaccess_save r0 +- .if \uaccess +- uaccess_disable r0 +- .endif ++ uaccess_entry tsk, r0, r1, r2, \uaccess + + .if \trace + #ifdef CONFIG_TRACE_IRQFLAGS +diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S +index 32051ec5b33f..40db0f9188b6 100644 +--- a/arch/arm/kernel/entry-header.S ++++ b/arch/arm/kernel/entry-header.S +@@ -6,6 +6,7 @@ + #include + #include + #include ++#include + #include + + @ Bad Abort numbers +@@ -217,9 +218,7 @@ + blne trace_hardirqs_off + #endif + .endif +- ldr r1, [sp, #SVC_ADDR_LIMIT] +- uaccess_restore +- str r1, [tsk, #TI_ADDR_LIMIT] ++ uaccess_exit tsk, r0, r1 + + #ifndef CONFIG_THUMB2_KERNEL + @ ARM mode SVC restore +@@ -263,9 +262,7 @@ + @ on the stack remains correct). + @ + .macro svc_exit_via_fiq +- ldr r1, [sp, #SVC_ADDR_LIMIT] +- uaccess_restore +- str r1, [tsk, #TI_ADDR_LIMIT] ++ uaccess_exit tsk, r0, r1 + #ifndef CONFIG_THUMB2_KERNEL + @ ARM mode restore + mov r0, sp +-- +2.25.1 + diff --git a/queue-5.6/arm-uaccess-fix-dacr-mismatch-with-nested-exceptions.patch b/queue-5.6/arm-uaccess-fix-dacr-mismatch-with-nested-exceptions.patch new file mode 100644 index 00000000000..2c006ca8a01 --- /dev/null +++ b/queue-5.6/arm-uaccess-fix-dacr-mismatch-with-nested-exceptions.patch @@ -0,0 +1,120 @@ +From ad64e482e0fca4e5a56d512af07184f93889fd1e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 3 May 2020 13:24:07 +0100 +Subject: ARM: uaccess: fix DACR mismatch with nested exceptions + +From: Russell King + +[ Upstream commit 71f8af1110101facfad68989ff91f88f8e2c3e22 ] + +Tomas Paukrt reports that his SAM9X60 based system (ARM926, ARMv5TJ) +fails to fix up alignment faults, eventually resulting in a kernel +oops. + +The problem occurs when using CONFIG_CPU_USE_DOMAINS with commit +e6978e4bf181 ("ARM: save and reset the address limit when entering an +exception"). This is because the address limit is set back to +TASK_SIZE on exception entry, and, although it is restored on exception +exit, the domain register is not. + +Hence, this sequence can occur: + + interrupt + pt_regs->addr_limit = addr_limit // USER_DS + addr_limit = USER_DS + alignment exception + __probe_kernel_read() + old_fs = get_fs() // USER_DS + set_fs(KERNEL_DS) + addr_limit = KERNEL_DS + dacr.kernel = DOMAIN_MANAGER + interrupt + pt_regs->addr_limit = addr_limit // KERNEL_DS + addr_limit = USER_DS + alignment exception + __probe_kernel_read() + old_fs = get_fs() // USER_DS + set_fs(KERNEL_DS) + addr_limit = KERNEL_DS + dacr.kernel = DOMAIN_MANAGER + ... + set_fs(old_fs) + addr_limit = USER_DS + dacr.kernel = DOMAIN_CLIENT + ... + addr_limit = pt_regs->addr_limit // KERNEL_DS + interrupt returns + +At this point, addr_limit is correctly restored to KERNEL_DS for +__probe_kernel_read() to continue execution, but dacr.kernel is not, +it has been reset by the set_fs(old_fs) to DOMAIN_CLIENT. + +This would not have happened prior to the mentioned commit, because +addr_limit would remain KERNEL_DS, so get_fs() would have returned +KERNEL_DS, and so would correctly nest. + +This commit fixes the problem by also saving the DACR on exception +entry if either CONFIG_CPU_SW_DOMAIN_PAN or CONFIG_CPU_USE_DOMAINS are +enabled, and resetting the DACR appropriately on exception entry to +match addr_limit and PAN settings. + +Fixes: e6978e4bf181 ("ARM: save and reset the address limit when entering an exception") +Reported-by: Tomas Paukrt +Signed-off-by: Russell King +Signed-off-by: Sasha Levin +--- + arch/arm/include/asm/uaccess-asm.h | 25 ++++++++++++++++++++----- + 1 file changed, 20 insertions(+), 5 deletions(-) + +diff --git a/arch/arm/include/asm/uaccess-asm.h b/arch/arm/include/asm/uaccess-asm.h +index e46468b91eaa..907571fd05c6 100644 +--- a/arch/arm/include/asm/uaccess-asm.h ++++ b/arch/arm/include/asm/uaccess-asm.h +@@ -67,15 +67,21 @@ + #endif + .endm + +-#ifdef CONFIG_CPU_SW_DOMAIN_PAN ++#if defined(CONFIG_CPU_SW_DOMAIN_PAN) || defined(CONFIG_CPU_USE_DOMAINS) + #define DACR(x...) x + #else + #define DACR(x...) + #endif + + /* +- * Save the address limit on entry to a privileged exception and +- * if using PAN, save and disable usermode access. ++ * Save the address limit on entry to a privileged exception. ++ * ++ * If we are using the DACR for kernel access by the user accessors ++ * (CONFIG_CPU_USE_DOMAINS=y), always reset the DACR kernel domain ++ * back to client mode, whether or not \disable is set. ++ * ++ * If we are using SW PAN, set the DACR user domain to no access ++ * if \disable is set. + */ + .macro uaccess_entry, tsk, tmp0, tmp1, tmp2, disable + ldr \tmp1, [\tsk, #TI_ADDR_LIMIT] +@@ -84,8 +90,17 @@ + DACR( mrc p15, 0, \tmp0, c3, c0, 0) + DACR( str \tmp0, [sp, #SVC_DACR]) + str \tmp1, [sp, #SVC_ADDR_LIMIT] +- .if \disable +- uaccess_disable \tmp0 ++ .if \disable && IS_ENABLED(CONFIG_CPU_SW_DOMAIN_PAN) ++ /* kernel=client, user=no access */ ++ mov \tmp2, #DACR_UACCESS_DISABLE ++ mcr p15, 0, \tmp2, c3, c0, 0 ++ instr_sync ++ .elseif IS_ENABLED(CONFIG_CPU_USE_DOMAINS) ++ /* kernel=client */ ++ bic \tmp2, \tmp0, #domain_mask(DOMAIN_KERNEL) ++ orr \tmp2, \tmp2, #domain_val(DOMAIN_KERNEL, DOMAIN_CLIENT) ++ mcr p15, 0, \tmp2, c3, c0, 0 ++ instr_sync + .endif + .endm + +-- +2.25.1 + diff --git a/queue-5.6/arm-uaccess-integrate-uaccess_save-and-uaccess_resto.patch b/queue-5.6/arm-uaccess-integrate-uaccess_save-and-uaccess_resto.patch new file mode 100644 index 00000000000..168bb4d2ac5 --- /dev/null +++ b/queue-5.6/arm-uaccess-integrate-uaccess_save-and-uaccess_resto.patch @@ -0,0 +1,78 @@ +From 4d39644715dae3cae13dd0a04888285c28a2f202 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 3 May 2020 13:14:09 +0100 +Subject: ARM: uaccess: integrate uaccess_save and uaccess_restore + +From: Russell King + +[ Upstream commit 8ede890b0bcebe8c760aacfe20e934d98c3dc6aa ] + +Integrate uaccess_save / uaccess_restore macros into the new +uaccess_entry / uaccess_exit macros respectively. + +Signed-off-by: Russell King +Signed-off-by: Sasha Levin +--- + arch/arm/include/asm/uaccess-asm.h | 30 +++++++++++++----------------- + 1 file changed, 13 insertions(+), 17 deletions(-) + +diff --git a/arch/arm/include/asm/uaccess-asm.h b/arch/arm/include/asm/uaccess-asm.h +index d475e3e8145d..e46468b91eaa 100644 +--- a/arch/arm/include/asm/uaccess-asm.h ++++ b/arch/arm/include/asm/uaccess-asm.h +@@ -67,30 +67,23 @@ + #endif + .endm + +- .macro uaccess_save, tmp + #ifdef CONFIG_CPU_SW_DOMAIN_PAN +- mrc p15, 0, \tmp, c3, c0, 0 +- str \tmp, [sp, #SVC_DACR] +-#endif +- .endm +- +- .macro uaccess_restore +-#ifdef CONFIG_CPU_SW_DOMAIN_PAN +- ldr r0, [sp, #SVC_DACR] +- mcr p15, 0, r0, c3, c0, 0 ++#define DACR(x...) x ++#else ++#define DACR(x...) + #endif +- .endm + + /* + * Save the address limit on entry to a privileged exception and + * if using PAN, save and disable usermode access. + */ + .macro uaccess_entry, tsk, tmp0, tmp1, tmp2, disable +- ldr \tmp0, [\tsk, #TI_ADDR_LIMIT] +- mov \tmp1, #TASK_SIZE +- str \tmp1, [\tsk, #TI_ADDR_LIMIT] +- str \tmp0, [sp, #SVC_ADDR_LIMIT] +- uaccess_save \tmp0 ++ ldr \tmp1, [\tsk, #TI_ADDR_LIMIT] ++ mov \tmp2, #TASK_SIZE ++ str \tmp2, [\tsk, #TI_ADDR_LIMIT] ++ DACR( mrc p15, 0, \tmp0, c3, c0, 0) ++ DACR( str \tmp0, [sp, #SVC_DACR]) ++ str \tmp1, [sp, #SVC_ADDR_LIMIT] + .if \disable + uaccess_disable \tmp0 + .endif +@@ -99,8 +92,11 @@ + /* Restore the user access state previously saved by uaccess_entry */ + .macro uaccess_exit, tsk, tmp0, tmp1 + ldr \tmp1, [sp, #SVC_ADDR_LIMIT] +- uaccess_restore ++ DACR( ldr \tmp0, [sp, #SVC_DACR]) + str \tmp1, [\tsk, #TI_ADDR_LIMIT] ++ DACR( mcr p15, 0, \tmp0, c3, c0, 0) + .endm + ++#undef DACR ++ + #endif /* __ASM_UACCESS_ASM_H__ */ +-- +2.25.1 + diff --git a/queue-5.6/arm64-dts-mt8173-fix-vcodec-enc-clock.patch b/queue-5.6/arm64-dts-mt8173-fix-vcodec-enc-clock.patch new file mode 100644 index 00000000000..452fbcdea90 --- /dev/null +++ b/queue-5.6/arm64-dts-mt8173-fix-vcodec-enc-clock.patch @@ -0,0 +1,54 @@ +From a247be97635bff677663be2fee53036e994f76b5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 4 May 2020 20:44:43 +0800 +Subject: arm64: dts: mt8173: fix vcodec-enc clock + +From: Hsin-Yi Wang + +[ Upstream commit 3b1f6c5e4dfaf767f6f2f120cd93b347b5a9f1aa ] + +Fix the assigned-clock-parents to higher frequency clock to avoid h264 +encode timeout: + +[ 134.763465] mtk_vpu 10020000.vpu: vpu ipi 4 ack time out ! +[ 134.769008] [MTK_VCODEC][ERROR][18]: vpu_enc_send_msg() vpu_ipi_send msg_id c002 len 32 fail -5 +[ 134.777707] [MTK_VCODEC][ERROR][18]: vpu_enc_encode() AP_IPIMSG_ENC_ENCODE 0 fail + +venc_sel is the clock used by h264 encoder, and venclt_sel is the clock +used by vp8 encoder. Assign venc_sel to vcodecpll_ck and venclt_sel to +vcodecpll_370p5. + + vcodecpll 1482000000 + vcodecpll_ck 494000000 + venc_sel 494000000 +... + vcodecpll_370p5 370500000 + venclt_sel 370500000 + +Fixes: fbbad0287cec ("arm64: dts: Using standard CCF interface to set vcodec clk") +Signed-off-by: Hsin-Yi Wang +Link: https://lore.kernel.org/r/20200504124442.208004-1-hsinyi@chromium.org +Signed-off-by: Matthias Brugger +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/mediatek/mt8173.dtsi | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi +index 8b4e806d5119..125c78321ab4 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi +@@ -1401,8 +1401,8 @@ + "venc_lt_sel"; + assigned-clocks = <&topckgen CLK_TOP_VENC_SEL>, + <&topckgen CLK_TOP_VENC_LT_SEL>; +- assigned-clock-parents = <&topckgen CLK_TOP_VENCPLL_D2>, +- <&topckgen CLK_TOP_UNIVPLL1_D2>; ++ assigned-clock-parents = <&topckgen CLK_TOP_VCODECPLL>, ++ <&topckgen CLK_TOP_VCODECPLL_370P5>; + }; + + jpegdec: jpegdec@18004000 { +-- +2.25.1 + diff --git a/queue-5.6/ceph-flush-release-queue-when-handling-caps-for-unkn.patch b/queue-5.6/ceph-flush-release-queue-when-handling-caps-for-unkn.patch new file mode 100644 index 00000000000..1e3a0baa5d3 --- /dev/null +++ b/queue-5.6/ceph-flush-release-queue-when-handling-caps-for-unkn.patch @@ -0,0 +1,48 @@ +From 63e5f3ee7e0a24eb72c22a98c388e5514d29d5a6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 20 May 2020 10:36:07 -0400 +Subject: ceph: flush release queue when handling caps for unknown inode +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Jeff Layton + +[ Upstream commit fb33c114d3ed5bdac230716f5b0a93b56b92a90d ] + +It's possible for the VFS to completely forget about an inode, but for +it to still be sitting on the cap release queue. If the MDS sends the +client a cap message for such an inode, it just ignores it today, which +can lead to a stall of up to 5s until the cap release queue is flushed. + +If we get a cap message for an inode that can't be located, then go +ahead and flush the cap release queue. + +Cc: stable@vger.kernel.org +URL: https://tracker.ceph.com/issues/45532 +Fixes: 1e9c2eb6811e ("ceph: delete stale dentry when last reference is dropped") +Reported-and-Tested-by: Andrej Filipčič +Suggested-by: Yan, Zheng +Signed-off-by: Jeff Layton +Signed-off-by: Ilya Dryomov +Signed-off-by: Sasha Levin +--- + fs/ceph/caps.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c +index f50204380a65..3ae88ca03ccd 100644 +--- a/fs/ceph/caps.c ++++ b/fs/ceph/caps.c +@@ -3952,7 +3952,7 @@ void ceph_handle_caps(struct ceph_mds_session *session, + __ceph_queue_cap_release(session, cap); + spin_unlock(&session->s_cap_lock); + } +- goto done; ++ goto flush_cap_releases; + } + + /* these will work even if we don't have a cap yet */ +-- +2.25.1 + diff --git a/queue-5.6/clk-qcom-gcc-fix-parent-for-gpll0_out_even.patch b/queue-5.6/clk-qcom-gcc-fix-parent-for-gpll0_out_even.patch new file mode 100644 index 00000000000..412f92e8654 --- /dev/null +++ b/queue-5.6/clk-qcom-gcc-fix-parent-for-gpll0_out_even.patch @@ -0,0 +1,40 @@ +From 044276ff233c78d6ab18c67d186ddb453cd6002e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 May 2020 10:57:28 +0530 +Subject: clk: qcom: gcc: Fix parent for gpll0_out_even + +From: Vinod Koul + +[ Upstream commit a76f274182f054481182c81cd62bb8794a5450a6 ] + +Documentation says that gpll0 is parent of gpll0_out_even, somehow +driver coded that as bi_tcxo, so fix it + +Fixes: 2a1d7eb854bb ("clk: qcom: gcc: Add global clock controller driver for SM8150") +Reported-by: Jonathan Marek +Signed-off-by: Vinod Koul +Link: https://lkml.kernel.org/r/20200521052728.2141377-1-vkoul@kernel.org +Reviewed-by: Bjorn Andersson +Signed-off-by: Stephen Boyd +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/gcc-sm8150.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/clk/qcom/gcc-sm8150.c b/drivers/clk/qcom/gcc-sm8150.c +index 20877214acff..e3959ff5cb55 100644 +--- a/drivers/clk/qcom/gcc-sm8150.c ++++ b/drivers/clk/qcom/gcc-sm8150.c +@@ -75,8 +75,7 @@ static struct clk_alpha_pll_postdiv gpll0_out_even = { + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpll0_out_even", + .parent_data = &(const struct clk_parent_data){ +- .fw_name = "bi_tcxo", +- .name = "bi_tcxo", ++ .hw = &gpll0.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_trion_pll_postdiv_ops, +-- +2.25.1 + diff --git a/queue-5.6/drm-amd-display-added-locking-for-atomic-update-stre.patch b/queue-5.6/drm-amd-display-added-locking-for-atomic-update-stre.patch new file mode 100644 index 00000000000..32eef4aa7e0 --- /dev/null +++ b/queue-5.6/drm-amd-display-added-locking-for-atomic-update-stre.patch @@ -0,0 +1,638 @@ +From 545cd043164d6d42093818f169acd4d2ce8e8b72 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Jan 2020 17:04:24 -0500 +Subject: drm/amd/display: Added locking for atomic update stream and update + planes + +From: Anthony Koo + +[ Upstream commit 009114f6df84150a567b05537aa29b9d660e419b ] + +[Why] +Screen flickering when HDR switches between FP16 and ARGB2101010 + +[How] +Moved pipe_control_lock so stream update and plane update occur atomically + +Signed-off-by: Anthony Koo +Signed-off-by: Lucy Li +Reviewed-by: Aric Cyr +Acked-by: Bhawanpreet Lakha +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/dc/core/dc.c | 87 +++++++++++---- + .../display/dc/dce110/dce110_hw_sequencer.c | 23 +--- + .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 32 +----- + .../amd/display/dc/dcn10/dcn10_hw_sequencer.h | 4 + + .../gpu/drm/amd/display/dc/dcn10/dcn10_init.c | 1 + + .../drm/amd/display/dc/dcn20/dcn20_hwseq.c | 101 ++++++++---------- + .../drm/amd/display/dc/dcn20/dcn20_hwseq.h | 4 - + .../gpu/drm/amd/display/dc/dcn20/dcn20_init.c | 2 +- + .../gpu/drm/amd/display/dc/dcn21/dcn21_init.c | 2 +- + .../gpu/drm/amd/display/dc/inc/hw_sequencer.h | 4 +- + 10 files changed, 125 insertions(+), 135 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c +index 2667691ba2aa..32a07665863f 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c +@@ -763,6 +763,29 @@ static bool disable_all_writeback_pipes_for_stream( + return true; + } + ++void apply_ctx_interdependent_lock(struct dc *dc, struct dc_state *context, struct dc_stream_state *stream, bool lock) ++{ ++ int i = 0; ++ ++ /* Checks if interdependent update function pointer is NULL or not, takes care of DCE110 case */ ++ if (dc->hwss.interdependent_update_lock) ++ dc->hwss.interdependent_update_lock(dc, context, lock); ++ else { ++ for (i = 0; i < dc->res_pool->pipe_count; i++) { ++ struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; ++ struct pipe_ctx *old_pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i]; ++ ++ // Copied conditions that were previously in dce110_apply_ctx_for_surface ++ if (stream == pipe_ctx->stream) { ++ if (!pipe_ctx->top_pipe && ++ (pipe_ctx->plane_state || old_pipe_ctx->plane_state)) ++ dc->hwss.pipe_control_lock(dc, pipe_ctx, lock); ++ break; ++ } ++ } ++ } ++} ++ + static void disable_dangling_plane(struct dc *dc, struct dc_state *context) + { + int i, j; +@@ -788,12 +811,17 @@ static void disable_dangling_plane(struct dc *dc, struct dc_state *context) + if (should_disable && old_stream) { + dc_rem_all_planes_for_stream(dc, old_stream, dangling_context); + disable_all_writeback_pipes_for_stream(dc, old_stream, dangling_context); ++ + if (dc->hwss.apply_ctx_for_surface) { ++ apply_ctx_interdependent_lock(dc, dc->current_state, old_stream, true); + dc->hwss.apply_ctx_for_surface(dc, old_stream, 0, dangling_context); ++ apply_ctx_interdependent_lock(dc, dc->current_state, old_stream, false); + dc->hwss.post_unlock_program_front_end(dc, dangling_context); + } + if (dc->hwss.program_front_end_for_ctx) { ++ dc->hwss.interdependent_update_lock(dc, dc->current_state, true); + dc->hwss.program_front_end_for_ctx(dc, dangling_context); ++ dc->hwss.interdependent_update_lock(dc, dc->current_state, false); + dc->hwss.post_unlock_program_front_end(dc, dangling_context); + } + } +@@ -1215,17 +1243,19 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c + /* re-program planes for existing stream, in case we need to + * free up plane resource for later use + */ +- if (dc->hwss.apply_ctx_for_surface) ++ if (dc->hwss.apply_ctx_for_surface) { + for (i = 0; i < context->stream_count; i++) { + if (context->streams[i]->mode_changed) + continue; +- ++ apply_ctx_interdependent_lock(dc, context, context->streams[i], true); + dc->hwss.apply_ctx_for_surface( + dc, context->streams[i], + context->stream_status[i].plane_count, + context); /* use new pipe config in new context */ ++ apply_ctx_interdependent_lock(dc, context, context->streams[i], false); + dc->hwss.post_unlock_program_front_end(dc, context); + } ++ } + + /* Program hardware */ + for (i = 0; i < dc->res_pool->pipe_count; i++) { +@@ -1245,10 +1275,11 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c + + /* Program all planes within new context*/ + if (dc->hwss.program_front_end_for_ctx) { ++ dc->hwss.interdependent_update_lock(dc, context, true); + dc->hwss.program_front_end_for_ctx(dc, context); ++ dc->hwss.interdependent_update_lock(dc, context, false); + dc->hwss.post_unlock_program_front_end(dc, context); + } +- + for (i = 0; i < context->stream_count; i++) { + const struct dc_link *link = context->streams[i]->link; + +@@ -1256,10 +1287,12 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c + continue; + + if (dc->hwss.apply_ctx_for_surface) { ++ apply_ctx_interdependent_lock(dc, context, context->streams[i], true); + dc->hwss.apply_ctx_for_surface( + dc, context->streams[i], + context->stream_status[i].plane_count, + context); ++ apply_ctx_interdependent_lock(dc, context, context->streams[i], false); + dc->hwss.post_unlock_program_front_end(dc, context); + } + +@@ -2112,15 +2145,10 @@ static void commit_planes_do_stream_update(struct dc *dc, + if (update_type == UPDATE_TYPE_FAST) + continue; + +- if (stream_update->dsc_config && dc->hwss.pipe_control_lock_global) { +- dc->hwss.pipe_control_lock_global(dc, pipe_ctx, true); ++ if (stream_update->dsc_config) + dp_update_dsc_config(pipe_ctx); +- dc->hwss.pipe_control_lock_global(dc, pipe_ctx, false); +- } + + if (stream_update->dpms_off) { +- dc->hwss.pipe_control_lock(dc, pipe_ctx, true); +- + if (*stream_update->dpms_off) { + core_link_disable_stream(pipe_ctx); + /* for dpms, keep acquired resources*/ +@@ -2134,8 +2162,6 @@ static void commit_planes_do_stream_update(struct dc *dc, + + core_link_enable_stream(dc->current_state, pipe_ctx); + } +- +- dc->hwss.pipe_control_lock(dc, pipe_ctx, false); + } + + if (stream_update->abm_level && pipe_ctx->stream_res.abm) { +@@ -2191,6 +2217,27 @@ static void commit_planes_for_stream(struct dc *dc, + context_clock_trace(dc, context); + } + ++ for (j = 0; j < dc->res_pool->pipe_count; j++) { ++ struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j]; ++ ++ if (!pipe_ctx->top_pipe && ++ !pipe_ctx->prev_odm_pipe && ++ pipe_ctx->stream && ++ pipe_ctx->stream == stream) { ++ top_pipe_to_program = pipe_ctx; ++ } ++ } ++ ++ if ((update_type != UPDATE_TYPE_FAST) && dc->hwss.interdependent_update_lock) ++ dc->hwss.interdependent_update_lock(dc, context, true); ++ else ++ /* Lock the top pipe while updating plane addrs, since freesync requires ++ * plane addr update event triggers to be synchronized. ++ * top_pipe_to_program is expected to never be NULL ++ */ ++ dc->hwss.pipe_control_lock(dc, top_pipe_to_program, true); ++ ++ + // Stream updates + if (stream_update) + commit_planes_do_stream_update(dc, stream, stream_update, update_type, context); +@@ -2205,6 +2252,11 @@ static void commit_planes_for_stream(struct dc *dc, + if (dc->hwss.program_front_end_for_ctx) + dc->hwss.program_front_end_for_ctx(dc, context); + ++ if ((update_type != UPDATE_TYPE_FAST) && dc->hwss.interdependent_update_lock) ++ dc->hwss.interdependent_update_lock(dc, context, false); ++ else ++ dc->hwss.pipe_control_lock(dc, top_pipe_to_program, false); ++ + dc->hwss.post_unlock_program_front_end(dc, context); + return; + } +@@ -2241,8 +2293,6 @@ static void commit_planes_for_stream(struct dc *dc, + pipe_ctx->stream == stream) { + struct dc_stream_status *stream_status = NULL; + +- top_pipe_to_program = pipe_ctx; +- + if (!pipe_ctx->plane_state) + continue; + +@@ -2287,12 +2337,6 @@ static void commit_planes_for_stream(struct dc *dc, + + // Update Type FAST, Surface updates + if (update_type == UPDATE_TYPE_FAST) { +- /* Lock the top pipe while updating plane addrs, since freesync requires +- * plane addr update event triggers to be synchronized. +- * top_pipe_to_program is expected to never be NULL +- */ +- dc->hwss.pipe_control_lock(dc, top_pipe_to_program, true); +- + if (dc->hwss.set_flip_control_gsl) + for (i = 0; i < surface_count; i++) { + struct dc_plane_state *plane_state = srf_updates[i].surface; +@@ -2334,9 +2378,12 @@ static void commit_planes_for_stream(struct dc *dc, + dc->hwss.update_plane_addr(dc, pipe_ctx); + } + } ++ } + ++ if ((update_type != UPDATE_TYPE_FAST) && dc->hwss.interdependent_update_lock) ++ dc->hwss.interdependent_update_lock(dc, context, false); ++ else + dc->hwss.pipe_control_lock(dc, top_pipe_to_program, false); +- } + + if (update_type != UPDATE_TYPE_FAST) + dc->hwss.post_unlock_program_front_end(dc, context); +diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +index a961b94aefd9..56d4ec7bdad7 100644 +--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c ++++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +@@ -2574,17 +2574,6 @@ static void dce110_apply_ctx_for_surface( + if (dc->fbc_compressor) + dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor); + +- for (i = 0; i < dc->res_pool->pipe_count; i++) { +- struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; +- struct pipe_ctx *old_pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i]; +- +- if (stream == pipe_ctx->stream) { +- if (!pipe_ctx->top_pipe && +- (pipe_ctx->plane_state || old_pipe_ctx->plane_state)) +- dc->hwss.pipe_control_lock(dc, pipe_ctx, true); +- } +- } +- + for (i = 0; i < dc->res_pool->pipe_count; i++) { + struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; + +@@ -2607,16 +2596,6 @@ static void dce110_apply_ctx_for_surface( + + } + +- for (i = 0; i < dc->res_pool->pipe_count; i++) { +- struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; +- struct pipe_ctx *old_pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i]; +- +- if ((stream == pipe_ctx->stream) && +- (!pipe_ctx->top_pipe) && +- (pipe_ctx->plane_state || old_pipe_ctx->plane_state)) +- dc->hwss.pipe_control_lock(dc, pipe_ctx, false); +- } +- + if (dc->fbc_compressor) + enable_fbc(dc, context); + } +@@ -2626,6 +2605,7 @@ static void dce110_post_unlock_program_front_end( + struct dc_state *context) + { + } ++ + static void dce110_power_down_fe(struct dc *dc, struct pipe_ctx *pipe_ctx) + { + struct dce_hwseq *hws = dc->hwseq; +@@ -2742,6 +2722,7 @@ static const struct hw_sequencer_funcs dce110_funcs = { + .disable_audio_stream = dce110_disable_audio_stream, + .disable_plane = dce110_power_down_fe, + .pipe_control_lock = dce_pipe_control_lock, ++ .interdependent_update_lock = NULL, + .prepare_bandwidth = dce110_prepare_bandwidth, + .optimize_bandwidth = dce110_optimize_bandwidth, + .set_drr = set_drr, +diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +index a9a5a13d5edf..7fc559acffcd 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +@@ -82,7 +82,7 @@ void print_microsec(struct dc_context *dc_ctx, + us_x10 % frac); + } + +-static void dcn10_lock_all_pipes(struct dc *dc, ++void dcn10_lock_all_pipes(struct dc *dc, + struct dc_state *context, + bool lock) + { +@@ -93,6 +93,7 @@ static void dcn10_lock_all_pipes(struct dc *dc, + for (i = 0; i < dc->res_pool->pipe_count; i++) { + pipe_ctx = &context->res_ctx.pipe_ctx[i]; + tg = pipe_ctx->stream_res.tg; ++ + /* + * Only lock the top pipe's tg to prevent redundant + * (un)locking. Also skip if pipe is disabled. +@@ -103,9 +104,9 @@ static void dcn10_lock_all_pipes(struct dc *dc, + continue; + + if (lock) +- tg->funcs->lock(tg); ++ dc->hwss.pipe_control_lock(dc, pipe_ctx, true); + else +- tg->funcs->unlock(tg); ++ dc->hwss.pipe_control_lock(dc, pipe_ctx, false); + } + } + +@@ -1576,7 +1577,7 @@ void dcn10_pipe_control_lock( + /* use TG master update lock to lock everything on the TG + * therefore only top pipe need to lock + */ +- if (pipe->top_pipe) ++ if (!pipe || pipe->top_pipe) + return; + + if (dc->debug.sanity_checks) +@@ -2530,11 +2531,6 @@ void dcn10_apply_ctx_for_surface( + if (underflow_check_delay_us != 0xFFFFFFFF && hws->funcs.did_underflow_occur) + ASSERT(hws->funcs.did_underflow_occur(dc, top_pipe_to_program)); + +- if (interdependent_update) +- dcn10_lock_all_pipes(dc, context, true); +- else +- dcn10_pipe_control_lock(dc, top_pipe_to_program, true); +- + if (underflow_check_delay_us != 0xFFFFFFFF) + udelay(underflow_check_delay_us); + +@@ -2554,19 +2550,6 @@ void dcn10_apply_ctx_for_surface( + + pipe_ctx->update_flags.raw = 0; + +- /* +- * Powergate reused pipes that are not powergated +- * fairly hacky right now, using opp_id as indicator +- * TODO: After move dc_post to dc_update, this will +- * be removed. +- */ +- if (pipe_ctx->plane_state && !old_pipe_ctx->plane_state) { +- if (old_pipe_ctx->stream_res.tg == tg && +- old_pipe_ctx->plane_res.hubp && +- old_pipe_ctx->plane_res.hubp->opp_id != OPP_ID_INVALID) +- dc->hwss.disable_plane(dc, old_pipe_ctx); +- } +- + if ((!pipe_ctx->plane_state || + pipe_ctx->stream_res.tg != old_pipe_ctx->stream_res.tg) && + old_pipe_ctx->plane_state && +@@ -2599,11 +2582,6 @@ void dcn10_apply_ctx_for_surface( + &pipe_ctx->dlg_regs, + &pipe_ctx->ttu_regs); + } +- +- if (interdependent_update) +- dcn10_lock_all_pipes(dc, context, false); +- else +- dcn10_pipe_control_lock(dc, top_pipe_to_program, false); + } + + void dcn10_post_unlock_program_front_end( +diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h +index b523f0b8dc23..16a50e05ffbf 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h ++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h +@@ -70,6 +70,10 @@ void dcn10_reset_hw_ctx_wrap( + struct dc *dc, + struct dc_state *context); + void dcn10_disable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx); ++void dcn10_lock_all_pipes( ++ struct dc *dc, ++ struct dc_state *context, ++ bool lock); + void dcn10_apply_ctx_for_surface( + struct dc *dc, + const struct dc_stream_state *stream, +diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_init.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_init.c +index 681db997a532..b88ef9703b2b 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_init.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_init.c +@@ -50,6 +50,7 @@ static const struct hw_sequencer_funcs dcn10_funcs = { + .disable_audio_stream = dce110_disable_audio_stream, + .disable_plane = dcn10_disable_plane, + .pipe_control_lock = dcn10_pipe_control_lock, ++ .interdependent_update_lock = dcn10_lock_all_pipes, + .prepare_bandwidth = dcn10_prepare_bandwidth, + .optimize_bandwidth = dcn10_optimize_bandwidth, + .set_drr = dcn10_set_drr, +diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +index 0c4a8c37ce84..611dac544bfe 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +@@ -1088,40 +1088,18 @@ void dcn20_enable_plane( + // } + } + +- +-void dcn20_pipe_control_lock_global( +- struct dc *dc, +- struct pipe_ctx *pipe, +- bool lock) +-{ +- if (lock) { +- pipe->stream_res.tg->funcs->lock_doublebuffer_enable( +- pipe->stream_res.tg); +- pipe->stream_res.tg->funcs->lock(pipe->stream_res.tg); +- } else { +- pipe->stream_res.tg->funcs->unlock(pipe->stream_res.tg); +- pipe->stream_res.tg->funcs->wait_for_state(pipe->stream_res.tg, +- CRTC_STATE_VACTIVE); +- pipe->stream_res.tg->funcs->wait_for_state(pipe->stream_res.tg, +- CRTC_STATE_VBLANK); +- pipe->stream_res.tg->funcs->wait_for_state(pipe->stream_res.tg, +- CRTC_STATE_VACTIVE); +- pipe->stream_res.tg->funcs->lock_doublebuffer_disable( +- pipe->stream_res.tg); +- } +-} +- + void dcn20_pipe_control_lock( + struct dc *dc, + struct pipe_ctx *pipe, + bool lock) + { + bool flip_immediate = false; ++ bool dig_update_required = false; + + /* use TG master update lock to lock everything on the TG + * therefore only top pipe need to lock + */ +- if (pipe->top_pipe) ++ if (!pipe || pipe->top_pipe) + return; + + if (pipe->plane_state != NULL) +@@ -1154,6 +1132,19 @@ void dcn20_pipe_control_lock( + (!flip_immediate && pipe->stream_res.gsl_group > 0)) + dcn20_setup_gsl_group_as_lock(dc, pipe, flip_immediate); + ++ if (pipe->stream && pipe->stream->update_flags.bits.dsc_changed) ++ dig_update_required = true; ++ ++ /* Need double buffer lock mode in order to synchronize front end pipe ++ * updates with dig updates. ++ */ ++ if (dig_update_required) { ++ if (lock) { ++ pipe->stream_res.tg->funcs->lock_doublebuffer_enable( ++ pipe->stream_res.tg); ++ } ++ } ++ + if (pipe->plane_state != NULL && pipe->plane_state->triplebuffer_flips) { + if (lock) + pipe->stream_res.tg->funcs->triplebuffer_lock(pipe->stream_res.tg); +@@ -1165,6 +1156,19 @@ void dcn20_pipe_control_lock( + else + pipe->stream_res.tg->funcs->unlock(pipe->stream_res.tg); + } ++ ++ if (dig_update_required) { ++ if (!lock) { ++ pipe->stream_res.tg->funcs->wait_for_state(pipe->stream_res.tg, ++ CRTC_STATE_VACTIVE); ++ pipe->stream_res.tg->funcs->wait_for_state(pipe->stream_res.tg, ++ CRTC_STATE_VBLANK); ++ pipe->stream_res.tg->funcs->wait_for_state(pipe->stream_res.tg, ++ CRTC_STATE_VACTIVE); ++ pipe->stream_res.tg->funcs->lock_doublebuffer_disable( ++ pipe->stream_res.tg); ++ } ++ } + } + + static void dcn20_detect_pipe_changes(struct pipe_ctx *old_pipe, struct pipe_ctx *new_pipe) +@@ -1536,26 +1540,28 @@ static void dcn20_program_pipe( + } + } + +-static bool does_pipe_need_lock(struct pipe_ctx *pipe) +-{ +- if ((pipe->plane_state && pipe->plane_state->update_flags.raw) +- || pipe->update_flags.raw) +- return true; +- if (pipe->bottom_pipe) +- return does_pipe_need_lock(pipe->bottom_pipe); +- +- return false; +-} +- + void dcn20_program_front_end_for_ctx( + struct dc *dc, + struct dc_state *context) + { + int i; + struct dce_hwseq *hws = dc->hwseq; +- bool pipe_locked[MAX_PIPES] = {false}; + DC_LOGGER_INIT(dc->ctx->logger); + ++ for (i = 0; i < dc->res_pool->pipe_count; i++) { ++ struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; ++ ++ if (!pipe_ctx->top_pipe && !pipe_ctx->prev_odm_pipe && pipe_ctx->plane_state) { ++ ASSERT(!pipe_ctx->plane_state->triplebuffer_flips); ++ if (dc->hwss.program_triplebuffer != NULL && ++ !dc->debug.disable_tri_buf) { ++ /*turn off triple buffer for full update*/ ++ dc->hwss.program_triplebuffer( ++ dc, pipe_ctx, pipe_ctx->plane_state->triplebuffer_flips); ++ } ++ } ++ } ++ + /* Carry over GSL groups in case the context is changing. */ + for (i = 0; i < dc->res_pool->pipe_count; i++) + if (context->res_ctx.pipe_ctx[i].stream == dc->current_state->res_ctx.pipe_ctx[i].stream) +@@ -1566,17 +1572,6 @@ void dcn20_program_front_end_for_ctx( + for (i = 0; i < dc->res_pool->pipe_count; i++) + dcn20_detect_pipe_changes(&dc->current_state->res_ctx.pipe_ctx[i], + &context->res_ctx.pipe_ctx[i]); +- for (i = 0; i < dc->res_pool->pipe_count; i++) +- if (!context->res_ctx.pipe_ctx[i].top_pipe && +- does_pipe_need_lock(&context->res_ctx.pipe_ctx[i])) { +- struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; +- +- if (pipe_ctx->update_flags.bits.tg_changed || pipe_ctx->update_flags.bits.enable) +- dc->hwss.pipe_control_lock(dc, pipe_ctx, true); +- if (!pipe_ctx->update_flags.bits.enable) +- dc->hwss.pipe_control_lock(dc, &dc->current_state->res_ctx.pipe_ctx[i], true); +- pipe_locked[i] = true; +- } + + /* OTG blank before disabling all front ends */ + for (i = 0; i < dc->res_pool->pipe_count; i++) +@@ -1614,17 +1609,6 @@ void dcn20_program_front_end_for_ctx( + hws->funcs.program_all_writeback_pipes_in_tree(dc, pipe->stream, context); + } + } +- +- /* Unlock all locked pipes */ +- for (i = 0; i < dc->res_pool->pipe_count; i++) +- if (pipe_locked[i]) { +- struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; +- +- if (pipe_ctx->update_flags.bits.tg_changed || pipe_ctx->update_flags.bits.enable) +- dc->hwss.pipe_control_lock(dc, pipe_ctx, false); +- if (!pipe_ctx->update_flags.bits.enable) +- dc->hwss.pipe_control_lock(dc, &dc->current_state->res_ctx.pipe_ctx[i], false); +- } + } + + void dcn20_post_unlock_program_front_end( +@@ -1664,7 +1648,6 @@ void dcn20_post_unlock_program_front_end( + dc->res_pool->hubbub->funcs->apply_DEDCN21_147_wa(dc->res_pool->hubbub); + } + +- + void dcn20_prepare_bandwidth( + struct dc *dc, + struct dc_state *context) +diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.h b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.h +index 80f192b8b3a2..63ce763f148e 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.h ++++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.h +@@ -61,10 +61,6 @@ void dcn20_pipe_control_lock( + struct dc *dc, + struct pipe_ctx *pipe, + bool lock); +-void dcn20_pipe_control_lock_global( +- struct dc *dc, +- struct pipe_ctx *pipe, +- bool lock); + void dcn20_prepare_bandwidth( + struct dc *dc, + struct dc_state *context); +diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_init.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_init.c +index c0a7cf1ba3a0..1642bf546ceb 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_init.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_init.c +@@ -51,7 +51,7 @@ static const struct hw_sequencer_funcs dcn20_funcs = { + .disable_audio_stream = dce110_disable_audio_stream, + .disable_plane = dcn20_disable_plane, + .pipe_control_lock = dcn20_pipe_control_lock, +- .pipe_control_lock_global = dcn20_pipe_control_lock_global, ++ .interdependent_update_lock = dcn10_lock_all_pipes, + .prepare_bandwidth = dcn20_prepare_bandwidth, + .optimize_bandwidth = dcn20_optimize_bandwidth, + .update_bandwidth = dcn20_update_bandwidth, +diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c +index bb8309513964..8b91445389df 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c +@@ -52,7 +52,7 @@ static const struct hw_sequencer_funcs dcn21_funcs = { + .disable_audio_stream = dce110_disable_audio_stream, + .disable_plane = dcn20_disable_plane, + .pipe_control_lock = dcn20_pipe_control_lock, +- .pipe_control_lock_global = dcn20_pipe_control_lock_global, ++ .interdependent_update_lock = dcn10_lock_all_pipes, + .prepare_bandwidth = dcn20_prepare_bandwidth, + .optimize_bandwidth = dcn20_optimize_bandwidth, + .update_bandwidth = dcn20_update_bandwidth, +diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +index 63919866ba38..d4c1fb242c63 100644 +--- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h ++++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +@@ -80,10 +80,10 @@ struct hw_sequencer_funcs { + void (*update_pending_status)(struct pipe_ctx *pipe_ctx); + + /* Pipe Lock Related */ +- void (*pipe_control_lock_global)(struct dc *dc, +- struct pipe_ctx *pipe, bool lock); + void (*pipe_control_lock)(struct dc *dc, + struct pipe_ctx *pipe, bool lock); ++ void (*interdependent_update_lock)(struct dc *dc, ++ struct dc_state *context, bool lock); + void (*set_flip_control_gsl)(struct pipe_ctx *pipe_ctx, + bool flip_immediate); + +-- +2.25.1 + diff --git a/queue-5.6/drm-amd-display-defer-cursor-lock-until-after-vupdat.patch b/queue-5.6/drm-amd-display-defer-cursor-lock-until-after-vupdat.patch new file mode 100644 index 00000000000..9d9653681bf --- /dev/null +++ b/queue-5.6/drm-amd-display-defer-cursor-lock-until-after-vupdat.patch @@ -0,0 +1,222 @@ +From cdd5637e4686b028aa2b788f07a780e84e481dc3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 4 May 2020 16:49:28 -0400 +Subject: drm/amd/display: Defer cursor lock until after VUPDATE + +From: Nicholas Kazlauskas + +[ Upstream commit 31ecebee9c36d5e5e113a357a655d993fa916174 ] + +[Why] +We dropped the delay after changed the cursor functions locking the +entire pipe to locking just the CURSOR registers to fix page flip +stuttering - this introduced cursor stuttering instead, and an underflow +issue. + +The cursor update can be delayed indefinitely if the cursor update +repeatedly happens right around VUPDATE. + +The underflow issue can happen if we do a viewport update on a pipe +on the same frame where a cursor update happens around VUPDATE - the +old cursor registers are retained which can be in an invalid position. + +This can cause a pipe hang and indefinite underflow. + +[How] +The complex, ideal solution to the problem would be a software +triple buffering mechanism from the DM layer to program only one cursor +update per frame just before VUPDATE. + +The simple workaround until we have that infrastructure in place is +this change - bring back the delay until VUPDATE before locking, but +with some corrections to the calculations. + +This didn't work for all timings before because the calculation for +VUPDATE was wrong - it was using the offset from VSTARTUP instead and +didn't correctly handle the case where VUPDATE could be in the back +porch. + +Add a new hardware sequencer function to use the existing helper to +calculate the real VUPDATE start and VUPDATE end - VUPDATE can last +multiple lines after all. + +Change the udelay to incorporate the width of VUPDATE as well. + +Signed-off-by: Nicholas Kazlauskas +Reviewed-by: Aric Cyr +Acked-by: Rodrigo Siqueira +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 69 ++++++++++++++++++- + .../amd/display/dc/dcn10/dcn10_hw_sequencer.h | 5 ++ + .../gpu/drm/amd/display/dc/dcn10/dcn10_init.c | 1 + + .../gpu/drm/amd/display/dc/dcn20/dcn20_init.c | 1 + + .../gpu/drm/amd/display/dc/dcn21/dcn21_init.c | 1 + + .../gpu/drm/amd/display/dc/inc/hw_sequencer.h | 5 ++ + 6 files changed, 81 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +index 97a820b90541..60cea910759b 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +@@ -1592,12 +1592,79 @@ void dcn10_pipe_control_lock( + hws->funcs.verify_allow_pstate_change_high(dc); + } + ++/** ++ * delay_cursor_until_vupdate() - Delay cursor update if too close to VUPDATE. ++ * ++ * Software keepout workaround to prevent cursor update locking from stalling ++ * out cursor updates indefinitely or from old values from being retained in ++ * the case where the viewport changes in the same frame as the cursor. ++ * ++ * The idea is to calculate the remaining time from VPOS to VUPDATE. If it's ++ * too close to VUPDATE, then stall out until VUPDATE finishes. ++ * ++ * TODO: Optimize cursor programming to be once per frame before VUPDATE ++ * to avoid the need for this workaround. ++ */ ++static void delay_cursor_until_vupdate(struct dc *dc, struct pipe_ctx *pipe_ctx) ++{ ++ struct dc_stream_state *stream = pipe_ctx->stream; ++ struct crtc_position position; ++ uint32_t vupdate_start, vupdate_end; ++ unsigned int lines_to_vupdate, us_to_vupdate, vpos; ++ unsigned int us_per_line, us_vupdate; ++ ++ if (!dc->hwss.calc_vupdate_position || !dc->hwss.get_position) ++ return; ++ ++ if (!pipe_ctx->stream_res.stream_enc || !pipe_ctx->stream_res.tg) ++ return; ++ ++ dc->hwss.calc_vupdate_position(dc, pipe_ctx, &vupdate_start, ++ &vupdate_end); ++ ++ dc->hwss.get_position(&pipe_ctx, 1, &position); ++ vpos = position.vertical_count; ++ ++ /* Avoid wraparound calculation issues */ ++ vupdate_start += stream->timing.v_total; ++ vupdate_end += stream->timing.v_total; ++ vpos += stream->timing.v_total; ++ ++ if (vpos <= vupdate_start) { ++ /* VPOS is in VACTIVE or back porch. */ ++ lines_to_vupdate = vupdate_start - vpos; ++ } else if (vpos > vupdate_end) { ++ /* VPOS is in the front porch. */ ++ return; ++ } else { ++ /* VPOS is in VUPDATE. */ ++ lines_to_vupdate = 0; ++ } ++ ++ /* Calculate time until VUPDATE in microseconds. */ ++ us_per_line = ++ stream->timing.h_total * 10000u / stream->timing.pix_clk_100hz; ++ us_to_vupdate = lines_to_vupdate * us_per_line; ++ ++ /* 70 us is a conservative estimate of cursor update time*/ ++ if (us_to_vupdate > 70) ++ return; ++ ++ /* Stall out until the cursor update completes. */ ++ us_vupdate = (vupdate_end - vupdate_start + 1) * us_per_line; ++ udelay(us_to_vupdate + us_vupdate); ++} ++ + void dcn10_cursor_lock(struct dc *dc, struct pipe_ctx *pipe, bool lock) + { + /* cursor lock is per MPCC tree, so only need to lock one pipe per stream */ + if (!pipe || pipe->top_pipe) + return; + ++ /* Prevent cursor lock from stalling out cursor updates. */ ++ if (lock) ++ delay_cursor_until_vupdate(dc, pipe); ++ + dc->res_pool->mpc->funcs->cursor_lock(dc->res_pool->mpc, + pipe->stream_res.opp->inst, lock); + } +@@ -3142,7 +3209,7 @@ int dcn10_get_vupdate_offset_from_vsync(struct pipe_ctx *pipe_ctx) + return vertical_line_start; + } + +-static void dcn10_calc_vupdate_position( ++void dcn10_calc_vupdate_position( + struct dc *dc, + struct pipe_ctx *pipe_ctx, + uint32_t *start_line, +diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h +index af51424315d5..42b6e016d71e 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h ++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h +@@ -34,6 +34,11 @@ struct dc; + void dcn10_hw_sequencer_construct(struct dc *dc); + + int dcn10_get_vupdate_offset_from_vsync(struct pipe_ctx *pipe_ctx); ++void dcn10_calc_vupdate_position( ++ struct dc *dc, ++ struct pipe_ctx *pipe_ctx, ++ uint32_t *start_line, ++ uint32_t *end_line); + void dcn10_setup_vupdate_interrupt(struct dc *dc, struct pipe_ctx *pipe_ctx); + enum dc_status dcn10_enable_stream_timing( + struct pipe_ctx *pipe_ctx, +diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_init.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_init.c +index 4a8e4b797bea..0900c861204f 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_init.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_init.c +@@ -72,6 +72,7 @@ static const struct hw_sequencer_funcs dcn10_funcs = { + .set_clock = dcn10_set_clock, + .get_clock = dcn10_get_clock, + .get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync, ++ .calc_vupdate_position = dcn10_calc_vupdate_position, + }; + + static const struct hwseq_private_funcs dcn10_private_funcs = { +diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_init.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_init.c +index 0cae0c2f84c4..71bfde2cf646 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_init.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_init.c +@@ -83,6 +83,7 @@ static const struct hw_sequencer_funcs dcn20_funcs = { + .init_vm_ctx = dcn20_init_vm_ctx, + .set_flip_control_gsl = dcn20_set_flip_control_gsl, + .get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync, ++ .calc_vupdate_position = dcn10_calc_vupdate_position, + }; + + static const struct hwseq_private_funcs dcn20_private_funcs = { +diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c +index 8fe8ec7c0882..7f53bf724fce 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c +@@ -86,6 +86,7 @@ static const struct hw_sequencer_funcs dcn21_funcs = { + .optimize_pwr_state = dcn21_optimize_pwr_state, + .exit_optimized_pwr_state = dcn21_exit_optimized_pwr_state, + .get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync, ++ .calc_vupdate_position = dcn10_calc_vupdate_position, + .set_cursor_position = dcn10_set_cursor_position, + .set_cursor_attribute = dcn10_set_cursor_attribute, + .set_cursor_sdr_white_level = dcn10_set_cursor_sdr_white_level, +diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +index e57467d99d66..08307f3796e3 100644 +--- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h ++++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +@@ -92,6 +92,11 @@ struct hw_sequencer_funcs { + void (*get_position)(struct pipe_ctx **pipe_ctx, int num_pipes, + struct crtc_position *position); + int (*get_vupdate_offset_from_vsync)(struct pipe_ctx *pipe_ctx); ++ void (*calc_vupdate_position)( ++ struct dc *dc, ++ struct pipe_ctx *pipe_ctx, ++ uint32_t *start_line, ++ uint32_t *end_line); + void (*enable_per_frame_crtc_position_reset)(struct dc *dc, + int group_size, struct pipe_ctx *grouped_pipes[]); + void (*enable_timing_synchronization)(struct dc *dc, +-- +2.25.1 + diff --git a/queue-5.6/drm-amd-display-drop-cursor-position-check-in-atomic.patch b/queue-5.6/drm-amd-display-drop-cursor-position-check-in-atomic.patch new file mode 100644 index 00000000000..051d47ccdc3 --- /dev/null +++ b/queue-5.6/drm-amd-display-drop-cursor-position-check-in-atomic.patch @@ -0,0 +1,45 @@ +From 8d581d4297677b8b5221592c971d6a1ff66f5c92 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 23 May 2020 11:53:41 +0000 +Subject: drm/amd/display: drop cursor position check in atomic test + +From: Simon Ser + +[ Upstream commit f7d5991b92ff824798693ddf231cf814c9d5a88b ] + +get_cursor_position already handles the case where the cursor has +negative off-screen coordinates by not setting +dc_cursor_position.enabled. + +Signed-off-by: Simon Ser +Fixes: 626bf90fe03f ("drm/amd/display: add basic atomic check for cursor plane") +Cc: Alex Deucher +Cc: Nicholas Kazlauskas +Signed-off-by: Alex Deucher +Cc: stable@vger.kernel.org +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 7 ------- + 1 file changed, 7 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +index 0cd11d3d4cf4..8e7cffe10cc5 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -7746,13 +7746,6 @@ static int dm_update_plane_state(struct dc *dc, + return -EINVAL; + } + +- if (new_plane_state->crtc_x <= -new_acrtc->max_cursor_width || +- new_plane_state->crtc_y <= -new_acrtc->max_cursor_height) { +- DRM_DEBUG_ATOMIC("Bad cursor position %d, %d\n", +- new_plane_state->crtc_x, new_plane_state->crtc_y); +- return -EINVAL; +- } +- + return 0; + } + +-- +2.25.1 + diff --git a/queue-5.6/drm-amd-display-fix-potential-integer-wraparound-res.patch b/queue-5.6/drm-amd-display-fix-potential-integer-wraparound-res.patch new file mode 100644 index 00000000000..84e14b7e3bc --- /dev/null +++ b/queue-5.6/drm-amd-display-fix-potential-integer-wraparound-res.patch @@ -0,0 +1,42 @@ +From 43ce1afda87fc2ceedc277b09d02e82dec0f48c2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 12 May 2020 11:48:48 -0400 +Subject: drm/amd/display: Fix potential integer wraparound resulting in a hang + +From: Aric Cyr + +[ Upstream commit 4e5183200d9b66695c754ef214933402056e7b95 ] + +[Why] +If VUPDATE_END is before VUPDATE_START the delay calculated can become +very large, causing a soft hang. + +[How] +Take the absolute value of the difference between START and END. + +Signed-off-by: Aric Cyr +Reviewed-by: Nicholas Kazlauskas +Acked-by: Qingqing Zhuo +Signed-off-by: Alex Deucher +Cc: stable@vger.kernel.org +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +index 60cea910759b..0c987b5d68e2 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +@@ -1651,6 +1651,8 @@ static void delay_cursor_until_vupdate(struct dc *dc, struct pipe_ctx *pipe_ctx) + return; + + /* Stall out until the cursor update completes. */ ++ if (vupdate_end < vupdate_start) ++ vupdate_end += stream->timing.v_total; + us_vupdate = (vupdate_end - vupdate_start + 1) * us_per_line; + udelay(us_to_vupdate + us_vupdate); + } +-- +2.25.1 + diff --git a/queue-5.6/drm-amd-display-indicate-dsc-updates-explicitly.patch b/queue-5.6/drm-amd-display-indicate-dsc-updates-explicitly.patch new file mode 100644 index 00000000000..5714ebda52f --- /dev/null +++ b/queue-5.6/drm-amd-display-indicate-dsc-updates-explicitly.patch @@ -0,0 +1,96 @@ +From ac56f2b4125bfc6514350c06db398c79894f8944 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Jan 2020 17:02:09 -0500 +Subject: drm/amd/display: Indicate dsc updates explicitly + +From: Anthony Koo + +[ Upstream commit acdac228c4d1b9ff8ac778835719d3381c198aad ] + +[Why] +DSC updates only set type to FULL UPDATE, but doesn't +flag the change + +[How] +Add DSC flag update flag + +Signed-off-by: Anthony Koo +Reviewed-by: Aric Cyr +Acked-by: Bhawanpreet Lakha +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/dc/core/dc.c | 19 ++++++++++++------- + drivers/gpu/drm/amd/display/dc/dc_stream.h | 1 + + 2 files changed, 13 insertions(+), 7 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c +index 66be2920fab0..2667691ba2aa 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c +@@ -1745,14 +1745,15 @@ static enum surface_update_type check_update_surfaces_for_stream( + + if (stream_update->wb_update) + su_flags->bits.wb_update = 1; ++ ++ if (stream_update->dsc_config) ++ su_flags->bits.dsc_changed = 1; ++ + if (su_flags->raw != 0) + overall_type = UPDATE_TYPE_FULL; + + if (stream_update->output_csc_transform || stream_update->output_color_space) + su_flags->bits.out_csc = 1; +- +- if (stream_update->dsc_config) +- overall_type = UPDATE_TYPE_FULL; + } + + for (i = 0 ; i < surface_count; i++) { +@@ -1787,8 +1788,11 @@ enum surface_update_type dc_check_update_surfaces_for_stream( + + type = check_update_surfaces_for_stream(dc, updates, surface_count, stream_update, stream_status); + if (type == UPDATE_TYPE_FULL) { +- if (stream_update) ++ if (stream_update) { ++ uint32_t dsc_changed = stream_update->stream->update_flags.bits.dsc_changed; + stream_update->stream->update_flags.raw = 0xFFFFFFFF; ++ stream_update->stream->update_flags.bits.dsc_changed = dsc_changed; ++ } + for (i = 0; i < surface_count; i++) + updates[i].surface->update_flags.raw = 0xFFFFFFFF; + } +@@ -2104,14 +2108,15 @@ static void commit_planes_do_stream_update(struct dc *dc, + } + } + ++ /* Full fe update*/ ++ if (update_type == UPDATE_TYPE_FAST) ++ continue; ++ + if (stream_update->dsc_config && dc->hwss.pipe_control_lock_global) { + dc->hwss.pipe_control_lock_global(dc, pipe_ctx, true); + dp_update_dsc_config(pipe_ctx); + dc->hwss.pipe_control_lock_global(dc, pipe_ctx, false); + } +- /* Full fe update*/ +- if (update_type == UPDATE_TYPE_FAST) +- continue; + + if (stream_update->dpms_off) { + dc->hwss.pipe_control_lock(dc, pipe_ctx, true); +diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h +index 92096de79dec..a5c7ef47b8d3 100644 +--- a/drivers/gpu/drm/amd/display/dc/dc_stream.h ++++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h +@@ -118,6 +118,7 @@ union stream_update_flags { + uint32_t dpms_off:1; + uint32_t gamut_remap:1; + uint32_t wb_update:1; ++ uint32_t dsc_changed : 1; + } bits; + + uint32_t raw; +-- +2.25.1 + diff --git a/queue-5.6/drm-amd-display-split-program-front-end-part-that-oc.patch b/queue-5.6/drm-amd-display-split-program-front-end-part-that-oc.patch new file mode 100644 index 00000000000..d3fc32ba96a --- /dev/null +++ b/queue-5.6/drm-amd-display-split-program-front-end-part-that-oc.patch @@ -0,0 +1,321 @@ +From fdade97ca8671f9c80c04dfba15a158a8a2f0ef8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Jan 2020 16:23:31 -0500 +Subject: drm/amd/display: Split program front end part that occur outside lock + +From: Anthony Koo + +[ Upstream commit bbf5f6c3f83bedd71006473849138a446ad4d9a3 ] + +[Why] +Eventually want to lock at a higher level in stack. +To do this, we need to be able to isolate the parts that need to be done +after pipe unlock. + +[How] +Split out programming that is done post unlock. + +Signed-off-by: Anthony Koo +Reviewed-by: Aric Cyr +Acked-by: Bhawanpreet Lakha +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/dc/core/dc.c | 24 +++++++++--- + .../display/dc/dce110/dce110_hw_sequencer.c | 6 +++ + .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 39 ++++++++++++++++--- + .../amd/display/dc/dcn10/dcn10_hw_sequencer.h | 3 ++ + .../gpu/drm/amd/display/dc/dcn10/dcn10_init.c | 1 + + .../drm/amd/display/dc/dcn20/dcn20_hwseq.c | 11 +++++- + .../drm/amd/display/dc/dcn20/dcn20_hwseq.h | 3 ++ + .../gpu/drm/amd/display/dc/dcn20/dcn20_init.c | 1 + + .../gpu/drm/amd/display/dc/dcn21/dcn21_init.c | 1 + + .../gpu/drm/amd/display/dc/inc/hw_sequencer.h | 2 + + 10 files changed, 79 insertions(+), 12 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c +index b3987124183a..66be2920fab0 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c +@@ -788,11 +788,15 @@ static void disable_dangling_plane(struct dc *dc, struct dc_state *context) + if (should_disable && old_stream) { + dc_rem_all_planes_for_stream(dc, old_stream, dangling_context); + disable_all_writeback_pipes_for_stream(dc, old_stream, dangling_context); +- if (dc->hwss.apply_ctx_for_surface) ++ if (dc->hwss.apply_ctx_for_surface) { + dc->hwss.apply_ctx_for_surface(dc, old_stream, 0, dangling_context); ++ dc->hwss.post_unlock_program_front_end(dc, dangling_context); ++ } ++ if (dc->hwss.program_front_end_for_ctx) { ++ dc->hwss.program_front_end_for_ctx(dc, dangling_context); ++ dc->hwss.post_unlock_program_front_end(dc, dangling_context); ++ } + } +- if (dc->hwss.program_front_end_for_ctx) +- dc->hwss.program_front_end_for_ctx(dc, dangling_context); + } + + current_ctx = dc->current_state; +@@ -1220,6 +1224,7 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c + dc, context->streams[i], + context->stream_status[i].plane_count, + context); /* use new pipe config in new context */ ++ dc->hwss.post_unlock_program_front_end(dc, context); + } + + /* Program hardware */ +@@ -1239,19 +1244,24 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c + } + + /* Program all planes within new context*/ +- if (dc->hwss.program_front_end_for_ctx) ++ if (dc->hwss.program_front_end_for_ctx) { + dc->hwss.program_front_end_for_ctx(dc, context); ++ dc->hwss.post_unlock_program_front_end(dc, context); ++ } ++ + for (i = 0; i < context->stream_count; i++) { + const struct dc_link *link = context->streams[i]->link; + + if (!context->streams[i]->mode_changed) + continue; + +- if (dc->hwss.apply_ctx_for_surface) ++ if (dc->hwss.apply_ctx_for_surface) { + dc->hwss.apply_ctx_for_surface( + dc, context->streams[i], + context->stream_status[i].plane_count, + context); ++ dc->hwss.post_unlock_program_front_end(dc, context); ++ } + + /* + * enable stereo +@@ -2190,6 +2200,7 @@ static void commit_planes_for_stream(struct dc *dc, + if (dc->hwss.program_front_end_for_ctx) + dc->hwss.program_front_end_for_ctx(dc, context); + ++ dc->hwss.post_unlock_program_front_end(dc, context); + return; + } + +@@ -2322,6 +2333,9 @@ static void commit_planes_for_stream(struct dc *dc, + dc->hwss.pipe_control_lock(dc, top_pipe_to_program, false); + } + ++ if (update_type != UPDATE_TYPE_FAST) ++ dc->hwss.post_unlock_program_front_end(dc, context); ++ + // Fire manual trigger only when bottom plane is flipped + for (j = 0; j < dc->res_pool->pipe_count; j++) { + struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j]; +diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +index 5b689273ff44..a961b94aefd9 100644 +--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c ++++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +@@ -2621,6 +2621,11 @@ static void dce110_apply_ctx_for_surface( + enable_fbc(dc, context); + } + ++static void dce110_post_unlock_program_front_end( ++ struct dc *dc, ++ struct dc_state *context) ++{ ++} + static void dce110_power_down_fe(struct dc *dc, struct pipe_ctx *pipe_ctx) + { + struct dce_hwseq *hws = dc->hwseq; +@@ -2722,6 +2727,7 @@ static const struct hw_sequencer_funcs dce110_funcs = { + .init_hw = init_hw, + .apply_ctx_to_hw = dce110_apply_ctx_to_hw, + .apply_ctx_for_surface = dce110_apply_ctx_for_surface, ++ .post_unlock_program_front_end = dce110_post_unlock_program_front_end, + .update_plane_addr = update_plane_addr, + .update_pending_status = dce110_update_pending_status, + .enable_accelerated_mode = dce110_enable_accelerated_mode, +diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +index 1008ac8a0f2a..a9a5a13d5edf 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +@@ -2512,7 +2512,6 @@ void dcn10_apply_ctx_for_surface( + int i; + struct timing_generator *tg; + uint32_t underflow_check_delay_us; +- bool removed_pipe[4] = { false }; + bool interdependent_update = false; + struct pipe_ctx *top_pipe_to_program = + dcn10_find_top_pipe_for_stream(dc, context, stream); +@@ -2552,6 +2551,9 @@ void dcn10_apply_ctx_for_surface( + struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; + struct pipe_ctx *old_pipe_ctx = + &dc->current_state->res_ctx.pipe_ctx[i]; ++ ++ pipe_ctx->update_flags.raw = 0; ++ + /* + * Powergate reused pipes that are not powergated + * fairly hacky right now, using opp_id as indicator +@@ -2571,7 +2573,7 @@ void dcn10_apply_ctx_for_surface( + old_pipe_ctx->stream_res.tg == tg) { + + hws->funcs.plane_atomic_disconnect(dc, old_pipe_ctx); +- removed_pipe[i] = true; ++ pipe_ctx->update_flags.bits.disable = 1; + + DC_LOG_DC("Reset mpcc for pipe %d\n", + old_pipe_ctx->pipe_idx); +@@ -2602,16 +2604,41 @@ void dcn10_apply_ctx_for_surface( + dcn10_lock_all_pipes(dc, context, false); + else + dcn10_pipe_control_lock(dc, top_pipe_to_program, false); ++} ++ ++void dcn10_post_unlock_program_front_end( ++ struct dc *dc, ++ struct dc_state *context) ++{ ++ int i, j; ++ ++ DC_LOGGER_INIT(dc->ctx->logger); + +- if (num_planes == 0) +- false_optc_underflow_wa(dc, stream, tg); ++ for (i = 0; i < dc->res_pool->pipe_count; i++) { ++ struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; ++ ++ if (!pipe_ctx->top_pipe && ++ !pipe_ctx->prev_odm_pipe && ++ pipe_ctx->stream) { ++ struct dc_stream_status *stream_status = NULL; ++ struct timing_generator *tg = pipe_ctx->stream_res.tg; ++ ++ for (j = 0; j < context->stream_count; j++) { ++ if (pipe_ctx->stream == context->streams[j]) ++ stream_status = &context->stream_status[j]; ++ } ++ ++ if (context->stream_status[i].plane_count == 0) ++ false_optc_underflow_wa(dc, pipe_ctx->stream, tg); ++ } ++ } + + for (i = 0; i < dc->res_pool->pipe_count; i++) +- if (removed_pipe[i]) ++ if (context->res_ctx.pipe_ctx[i].update_flags.bits.disable) + dc->hwss.disable_plane(dc, &dc->current_state->res_ctx.pipe_ctx[i]); + + for (i = 0; i < dc->res_pool->pipe_count; i++) +- if (removed_pipe[i]) { ++ if (context->res_ctx.pipe_ctx[i].update_flags.bits.disable) { + dc->hwss.optimize_bandwidth(dc, context); + break; + } +diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h +index 4d20f6586bb5..b523f0b8dc23 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h ++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h +@@ -75,6 +75,9 @@ void dcn10_apply_ctx_for_surface( + const struct dc_stream_state *stream, + int num_planes, + struct dc_state *context); ++void dcn10_post_unlock_program_front_end( ++ struct dc *dc, ++ struct dc_state *context); + void dcn10_hubp_pg_control( + struct dce_hwseq *hws, + unsigned int hubp_inst, +diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_init.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_init.c +index e7e5352ec424..681db997a532 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_init.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_init.c +@@ -32,6 +32,7 @@ static const struct hw_sequencer_funcs dcn10_funcs = { + .init_hw = dcn10_init_hw, + .apply_ctx_to_hw = dce110_apply_ctx_to_hw, + .apply_ctx_for_surface = dcn10_apply_ctx_for_surface, ++ .post_unlock_program_front_end = dcn10_post_unlock_program_front_end, + .update_plane_addr = dcn10_update_plane_addr, + .update_dchub = dcn10_update_dchub, + .update_pending_status = dcn10_update_pending_status, +diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +index ad422e00f9fe..0c4a8c37ce84 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +@@ -1551,7 +1551,6 @@ void dcn20_program_front_end_for_ctx( + struct dc *dc, + struct dc_state *context) + { +- const unsigned int TIMEOUT_FOR_PIPE_ENABLE_MS = 100; + int i; + struct dce_hwseq *hws = dc->hwseq; + bool pipe_locked[MAX_PIPES] = {false}; +@@ -1626,6 +1625,16 @@ void dcn20_program_front_end_for_ctx( + if (!pipe_ctx->update_flags.bits.enable) + dc->hwss.pipe_control_lock(dc, &dc->current_state->res_ctx.pipe_ctx[i], false); + } ++} ++ ++void dcn20_post_unlock_program_front_end( ++ struct dc *dc, ++ struct dc_state *context) ++{ ++ int i; ++ const unsigned int TIMEOUT_FOR_PIPE_ENABLE_MS = 100; ++ ++ DC_LOGGER_INIT(dc->ctx->logger); + + for (i = 0; i < dc->res_pool->pipe_count; i++) + if (context->res_ctx.pipe_ctx[i].update_flags.bits.disable) +diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.h b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.h +index 02c9be5ebd47..80f192b8b3a2 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.h ++++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.h +@@ -35,6 +35,9 @@ bool dcn20_set_shaper_3dlut( + void dcn20_program_front_end_for_ctx( + struct dc *dc, + struct dc_state *context); ++void dcn20_post_unlock_program_front_end( ++ struct dc *dc, ++ struct dc_state *context); + void dcn20_update_plane_addr(const struct dc *dc, struct pipe_ctx *pipe_ctx); + void dcn20_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx); + bool dcn20_set_input_transfer_func(struct dc *dc, struct pipe_ctx *pipe_ctx, +diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_init.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_init.c +index 5e640f17d3d4..c0a7cf1ba3a0 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_init.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_init.c +@@ -33,6 +33,7 @@ static const struct hw_sequencer_funcs dcn20_funcs = { + .apply_ctx_to_hw = dce110_apply_ctx_to_hw, + .apply_ctx_for_surface = NULL, + .program_front_end_for_ctx = dcn20_program_front_end_for_ctx, ++ .post_unlock_program_front_end = dcn20_post_unlock_program_front_end, + .update_plane_addr = dcn20_update_plane_addr, + .update_dchub = dcn10_update_dchub, + .update_pending_status = dcn10_update_pending_status, +diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c +index fddbd59bf4f9..bb8309513964 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c +@@ -34,6 +34,7 @@ static const struct hw_sequencer_funcs dcn21_funcs = { + .apply_ctx_to_hw = dce110_apply_ctx_to_hw, + .apply_ctx_for_surface = NULL, + .program_front_end_for_ctx = dcn20_program_front_end_for_ctx, ++ .post_unlock_program_front_end = dcn20_post_unlock_program_front_end, + .update_plane_addr = dcn20_update_plane_addr, + .update_dchub = dcn10_update_dchub, + .update_pending_status = dcn10_update_pending_status, +diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +index 209118f9f193..63919866ba38 100644 +--- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h ++++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +@@ -66,6 +66,8 @@ struct hw_sequencer_funcs { + int num_planes, struct dc_state *context); + void (*program_front_end_for_ctx)(struct dc *dc, + struct dc_state *context); ++ void (*post_unlock_program_front_end)(struct dc *dc, ++ struct dc_state *context); + void (*update_plane_addr)(const struct dc *dc, + struct pipe_ctx *pipe_ctx); + void (*update_dchub)(struct dce_hwseq *hws, +-- +2.25.1 + diff --git a/queue-5.6/drm-amd-display-use-cursor-locking-to-prevent-flip-d.patch b/queue-5.6/drm-amd-display-use-cursor-locking-to-prevent-flip-d.patch new file mode 100644 index 00000000000..b3a36839812 --- /dev/null +++ b/queue-5.6/drm-amd-display-use-cursor-locking-to-prevent-flip-d.patch @@ -0,0 +1,461 @@ +From 7e6c002946aaa186e9b9c6397abf87159c84d03a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 22 Apr 2020 18:08:03 -0400 +Subject: drm/amd/display: Use cursor locking to prevent flip delays + +From: Aric Cyr + +[ Upstream commit b2a7b0ce0773bfa4406bc0a78e41979532a1edd7 ] + +[Why] +Current locking scheme for cursor can result in a flip missing +its vsync, deferring it for one or more vsyncs. Result is a +potential for stuttering when cursor is moved. + +[How] +Use cursor update lock so that flips are not blocked while cursor +is being programmed. + +Signed-off-by: Aric Cyr +Reviewed-by: Nicholas Kazlauskas +Acked-by: Aurabindo Pillai +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + .../gpu/drm/amd/display/dc/core/dc_stream.c | 40 ++----------------- + .../display/dc/dce110/dce110_hw_sequencer.c | 1 + + .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 10 +++++ + .../amd/display/dc/dcn10/dcn10_hw_sequencer.h | 1 + + .../gpu/drm/amd/display/dc/dcn10/dcn10_init.c | 1 + + .../gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c | 15 +++++++ + .../gpu/drm/amd/display/dc/dcn10/dcn10_mpc.h | 20 +++++++--- + .../drm/amd/display/dc/dcn10/dcn10_resource.c | 14 ++++++- + .../gpu/drm/amd/display/dc/dcn20/dcn20_init.c | 1 + + .../gpu/drm/amd/display/dc/dcn20/dcn20_mpc.c | 1 + + .../gpu/drm/amd/display/dc/dcn20/dcn20_mpc.h | 3 +- + .../drm/amd/display/dc/dcn20/dcn20_resource.c | 4 ++ + .../gpu/drm/amd/display/dc/dcn21/dcn21_init.c | 1 + + .../drm/amd/display/dc/dcn21/dcn21_resource.c | 4 ++ + drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h | 16 ++++++++ + .../gpu/drm/amd/display/dc/inc/hw_sequencer.h | 1 + + 16 files changed, 88 insertions(+), 45 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +index 8c20e9e907b2..4f0e7203dba4 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +@@ -231,34 +231,6 @@ struct dc_stream_status *dc_stream_get_status( + return dc_stream_get_status_from_state(dc->current_state, stream); + } + +-static void delay_cursor_until_vupdate(struct pipe_ctx *pipe_ctx, struct dc *dc) +-{ +-#if defined(CONFIG_DRM_AMD_DC_DCN) +- unsigned int vupdate_line; +- unsigned int lines_to_vupdate, us_to_vupdate, vpos, nvpos; +- struct dc_stream_state *stream = pipe_ctx->stream; +- unsigned int us_per_line; +- +- if (!dc->hwss.get_vupdate_offset_from_vsync) +- return; +- +- vupdate_line = dc->hwss.get_vupdate_offset_from_vsync(pipe_ctx); +- if (!dc_stream_get_crtc_position(dc, &stream, 1, &vpos, &nvpos)) +- return; +- +- if (vpos >= vupdate_line) +- return; +- +- us_per_line = +- stream->timing.h_total * 10000 / stream->timing.pix_clk_100hz; +- lines_to_vupdate = vupdate_line - vpos; +- us_to_vupdate = lines_to_vupdate * us_per_line; +- +- /* 70 us is a conservative estimate of cursor update time*/ +- if (us_to_vupdate < 70) +- udelay(us_to_vupdate); +-#endif +-} + + /** + * dc_stream_set_cursor_attributes() - Update cursor attributes and set cursor surface address +@@ -298,9 +270,7 @@ bool dc_stream_set_cursor_attributes( + + if (!pipe_to_program) { + pipe_to_program = pipe_ctx; +- +- delay_cursor_until_vupdate(pipe_ctx, dc); +- dc->hwss.pipe_control_lock(dc, pipe_to_program, true); ++ dc->hwss.cursor_lock(dc, pipe_to_program, true); + } + + dc->hwss.set_cursor_attribute(pipe_ctx); +@@ -309,7 +279,7 @@ bool dc_stream_set_cursor_attributes( + } + + if (pipe_to_program) +- dc->hwss.pipe_control_lock(dc, pipe_to_program, false); ++ dc->hwss.cursor_lock(dc, pipe_to_program, false); + + return true; + } +@@ -349,16 +319,14 @@ bool dc_stream_set_cursor_position( + + if (!pipe_to_program) { + pipe_to_program = pipe_ctx; +- +- delay_cursor_until_vupdate(pipe_ctx, dc); +- dc->hwss.pipe_control_lock(dc, pipe_to_program, true); ++ dc->hwss.cursor_lock(dc, pipe_to_program, true); + } + + dc->hwss.set_cursor_position(pipe_ctx); + } + + if (pipe_to_program) +- dc->hwss.pipe_control_lock(dc, pipe_to_program, false); ++ dc->hwss.cursor_lock(dc, pipe_to_program, false); + + return true; + } +diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +index 56d4ec7bdad7..454a123b92fc 100644 +--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c ++++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +@@ -2723,6 +2723,7 @@ static const struct hw_sequencer_funcs dce110_funcs = { + .disable_plane = dce110_power_down_fe, + .pipe_control_lock = dce_pipe_control_lock, + .interdependent_update_lock = NULL, ++ .cursor_lock = dce_pipe_control_lock, + .prepare_bandwidth = dce110_prepare_bandwidth, + .optimize_bandwidth = dce110_optimize_bandwidth, + .set_drr = set_drr, +diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +index 7fc559acffcd..97a820b90541 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +@@ -1592,6 +1592,16 @@ void dcn10_pipe_control_lock( + hws->funcs.verify_allow_pstate_change_high(dc); + } + ++void dcn10_cursor_lock(struct dc *dc, struct pipe_ctx *pipe, bool lock) ++{ ++ /* cursor lock is per MPCC tree, so only need to lock one pipe per stream */ ++ if (!pipe || pipe->top_pipe) ++ return; ++ ++ dc->res_pool->mpc->funcs->cursor_lock(dc->res_pool->mpc, ++ pipe->stream_res.opp->inst, lock); ++} ++ + static bool wait_for_reset_trigger_to_occur( + struct dc_context *dc_ctx, + struct timing_generator *tg) +diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h +index 16a50e05ffbf..af51424315d5 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h ++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h +@@ -49,6 +49,7 @@ void dcn10_pipe_control_lock( + struct dc *dc, + struct pipe_ctx *pipe, + bool lock); ++void dcn10_cursor_lock(struct dc *dc, struct pipe_ctx *pipe, bool lock); + void dcn10_blank_pixel_data( + struct dc *dc, + struct pipe_ctx *pipe_ctx, +diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_init.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_init.c +index b88ef9703b2b..4a8e4b797bea 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_init.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_init.c +@@ -50,6 +50,7 @@ static const struct hw_sequencer_funcs dcn10_funcs = { + .disable_audio_stream = dce110_disable_audio_stream, + .disable_plane = dcn10_disable_plane, + .pipe_control_lock = dcn10_pipe_control_lock, ++ .cursor_lock = dcn10_cursor_lock, + .interdependent_update_lock = dcn10_lock_all_pipes, + .prepare_bandwidth = dcn10_prepare_bandwidth, + .optimize_bandwidth = dcn10_optimize_bandwidth, +diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c +index 04f863499cfb..3fcd408e9103 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c +@@ -223,6 +223,9 @@ struct mpcc *mpc1_insert_plane( + REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, dpp_id); + REG_SET(MPCC_OPP_ID[mpcc_id], 0, MPCC_OPP_ID, tree->opp_id); + ++ /* Configure VUPDATE lock set for this MPCC to map to the OPP */ ++ REG_SET(MPCC_UPDATE_LOCK_SEL[mpcc_id], 0, MPCC_UPDATE_LOCK_SEL, tree->opp_id); ++ + /* update mpc tree mux setting */ + if (tree->opp_list == insert_above_mpcc) { + /* insert the toppest mpcc */ +@@ -318,6 +321,7 @@ void mpc1_remove_mpcc( + REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, 0xf); + REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_SEL, 0xf); + REG_SET(MPCC_OPP_ID[mpcc_id], 0, MPCC_OPP_ID, 0xf); ++ REG_SET(MPCC_UPDATE_LOCK_SEL[mpcc_id], 0, MPCC_UPDATE_LOCK_SEL, 0xf); + + /* mark this mpcc as not in use */ + mpc10->mpcc_in_use_mask &= ~(1 << mpcc_id); +@@ -328,6 +332,7 @@ void mpc1_remove_mpcc( + REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, 0xf); + REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_SEL, 0xf); + REG_SET(MPCC_OPP_ID[mpcc_id], 0, MPCC_OPP_ID, 0xf); ++ REG_SET(MPCC_UPDATE_LOCK_SEL[mpcc_id], 0, MPCC_UPDATE_LOCK_SEL, 0xf); + } + } + +@@ -361,6 +366,7 @@ void mpc1_mpc_init(struct mpc *mpc) + REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, 0xf); + REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_SEL, 0xf); + REG_SET(MPCC_OPP_ID[mpcc_id], 0, MPCC_OPP_ID, 0xf); ++ REG_SET(MPCC_UPDATE_LOCK_SEL[mpcc_id], 0, MPCC_UPDATE_LOCK_SEL, 0xf); + + mpc1_init_mpcc(&(mpc->mpcc_array[mpcc_id]), mpcc_id); + } +@@ -381,6 +387,7 @@ void mpc1_mpc_init_single_inst(struct mpc *mpc, unsigned int mpcc_id) + REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, 0xf); + REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_SEL, 0xf); + REG_SET(MPCC_OPP_ID[mpcc_id], 0, MPCC_OPP_ID, 0xf); ++ REG_SET(MPCC_UPDATE_LOCK_SEL[mpcc_id], 0, MPCC_UPDATE_LOCK_SEL, 0xf); + + mpc1_init_mpcc(&(mpc->mpcc_array[mpcc_id]), mpcc_id); + +@@ -453,6 +460,13 @@ void mpc1_read_mpcc_state( + MPCC_BUSY, &s->busy); + } + ++void mpc1_cursor_lock(struct mpc *mpc, int opp_id, bool lock) ++{ ++ struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc); ++ ++ REG_SET(CUR[opp_id], 0, CUR_VUPDATE_LOCK_SET, lock ? 1 : 0); ++} ++ + static const struct mpc_funcs dcn10_mpc_funcs = { + .read_mpcc_state = mpc1_read_mpcc_state, + .insert_plane = mpc1_insert_plane, +@@ -464,6 +478,7 @@ static const struct mpc_funcs dcn10_mpc_funcs = { + .assert_mpcc_idle_before_connect = mpc1_assert_mpcc_idle_before_connect, + .init_mpcc_list_from_hw = mpc1_init_mpcc_list_from_hw, + .update_blending = mpc1_update_blending, ++ .cursor_lock = mpc1_cursor_lock, + .set_denorm = NULL, + .set_denorm_clamp = NULL, + .set_output_csc = NULL, +diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.h +index 962a68e322ee..66a4719c22a0 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.h ++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.h +@@ -39,11 +39,12 @@ + SRII(MPCC_BG_G_Y, MPCC, inst),\ + SRII(MPCC_BG_R_CR, MPCC, inst),\ + SRII(MPCC_BG_B_CB, MPCC, inst),\ +- SRII(MPCC_BG_B_CB, MPCC, inst),\ +- SRII(MPCC_SM_CONTROL, MPCC, inst) ++ SRII(MPCC_SM_CONTROL, MPCC, inst),\ ++ SRII(MPCC_UPDATE_LOCK_SEL, MPCC, inst) + + #define MPC_OUT_MUX_COMMON_REG_LIST_DCN1_0(inst) \ +- SRII(MUX, MPC_OUT, inst) ++ SRII(MUX, MPC_OUT, inst),\ ++ VUPDATE_SRII(CUR, VUPDATE_LOCK_SET, inst) + + #define MPC_COMMON_REG_VARIABLE_LIST \ + uint32_t MPCC_TOP_SEL[MAX_MPCC]; \ +@@ -55,7 +56,9 @@ + uint32_t MPCC_BG_R_CR[MAX_MPCC]; \ + uint32_t MPCC_BG_B_CB[MAX_MPCC]; \ + uint32_t MPCC_SM_CONTROL[MAX_MPCC]; \ +- uint32_t MUX[MAX_OPP]; ++ uint32_t MUX[MAX_OPP]; \ ++ uint32_t MPCC_UPDATE_LOCK_SEL[MAX_MPCC]; \ ++ uint32_t CUR[MAX_OPP]; + + #define MPC_COMMON_MASK_SH_LIST_DCN1_0(mask_sh)\ + SF(MPCC0_MPCC_TOP_SEL, MPCC_TOP_SEL, mask_sh),\ +@@ -78,7 +81,8 @@ + SF(MPCC0_MPCC_SM_CONTROL, MPCC_SM_FIELD_ALT, mask_sh),\ + SF(MPCC0_MPCC_SM_CONTROL, MPCC_SM_FORCE_NEXT_FRAME_POL, mask_sh),\ + SF(MPCC0_MPCC_SM_CONTROL, MPCC_SM_FORCE_NEXT_TOP_POL, mask_sh),\ +- SF(MPC_OUT0_MUX, MPC_OUT_MUX, mask_sh) ++ SF(MPC_OUT0_MUX, MPC_OUT_MUX, mask_sh),\ ++ SF(MPCC0_MPCC_UPDATE_LOCK_SEL, MPCC_UPDATE_LOCK_SEL, mask_sh) + + #define MPC_REG_FIELD_LIST(type) \ + type MPCC_TOP_SEL;\ +@@ -101,7 +105,9 @@ + type MPCC_SM_FIELD_ALT;\ + type MPCC_SM_FORCE_NEXT_FRAME_POL;\ + type MPCC_SM_FORCE_NEXT_TOP_POL;\ +- type MPC_OUT_MUX; ++ type MPC_OUT_MUX;\ ++ type MPCC_UPDATE_LOCK_SEL;\ ++ type CUR_VUPDATE_LOCK_SET; + + struct dcn_mpc_registers { + MPC_COMMON_REG_VARIABLE_LIST +@@ -192,4 +198,6 @@ void mpc1_read_mpcc_state( + int mpcc_inst, + struct mpcc_state *s); + ++void mpc1_cursor_lock(struct mpc *mpc, int opp_id, bool lock); ++ + #endif +diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c +index 3b71898e859e..e3c4c06ac191 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c +@@ -181,6 +181,14 @@ enum dcn10_clk_src_array_id { + .reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ + mm ## block ## id ## _ ## reg_name + ++#define VUPDATE_SRII(reg_name, block, id)\ ++ .reg_name[id] = BASE(mm ## reg_name ## 0 ## _ ## block ## id ## _BASE_IDX) + \ ++ mm ## reg_name ## 0 ## _ ## block ## id ++ ++/* set field/register/bitfield name */ ++#define SFRB(field_name, reg_name, bitfield, post_fix)\ ++ .field_name = reg_name ## __ ## bitfield ## post_fix ++ + /* NBIO */ + #define NBIO_BASE_INNER(seg) \ + NBIF_BASE__INST0_SEG ## seg +@@ -419,11 +427,13 @@ static const struct dcn_mpc_registers mpc_regs = { + }; + + static const struct dcn_mpc_shift mpc_shift = { +- MPC_COMMON_MASK_SH_LIST_DCN1_0(__SHIFT) ++ MPC_COMMON_MASK_SH_LIST_DCN1_0(__SHIFT),\ ++ SFRB(CUR_VUPDATE_LOCK_SET, CUR0_VUPDATE_LOCK_SET0, CUR0_VUPDATE_LOCK_SET, __SHIFT) + }; + + static const struct dcn_mpc_mask mpc_mask = { +- MPC_COMMON_MASK_SH_LIST_DCN1_0(_MASK), ++ MPC_COMMON_MASK_SH_LIST_DCN1_0(_MASK),\ ++ SFRB(CUR_VUPDATE_LOCK_SET, CUR0_VUPDATE_LOCK_SET0, CUR0_VUPDATE_LOCK_SET, _MASK) + }; + + #define tg_regs(id)\ +diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_init.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_init.c +index 1642bf546ceb..0cae0c2f84c4 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_init.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_init.c +@@ -52,6 +52,7 @@ static const struct hw_sequencer_funcs dcn20_funcs = { + .disable_plane = dcn20_disable_plane, + .pipe_control_lock = dcn20_pipe_control_lock, + .interdependent_update_lock = dcn10_lock_all_pipes, ++ .cursor_lock = dcn10_cursor_lock, + .prepare_bandwidth = dcn20_prepare_bandwidth, + .optimize_bandwidth = dcn20_optimize_bandwidth, + .update_bandwidth = dcn20_update_bandwidth, +diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mpc.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mpc.c +index de9c857ab3e9..570dfd9a243f 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mpc.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mpc.c +@@ -545,6 +545,7 @@ const struct mpc_funcs dcn20_mpc_funcs = { + .mpc_init = mpc1_mpc_init, + .mpc_init_single_inst = mpc1_mpc_init_single_inst, + .update_blending = mpc2_update_blending, ++ .cursor_lock = mpc1_cursor_lock, + .get_mpcc_for_dpp = mpc2_get_mpcc_for_dpp, + .wait_for_idle = mpc2_assert_idle_mpcc, + .assert_mpcc_idle_before_connect = mpc2_assert_mpcc_idle_before_connect, +diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mpc.h b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mpc.h +index c78fd5123497..496658f420db 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mpc.h ++++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mpc.h +@@ -179,7 +179,8 @@ + SF(MPC_OUT0_DENORM_CLAMP_G_Y, MPC_OUT_DENORM_CLAMP_MAX_G_Y, mask_sh),\ + SF(MPC_OUT0_DENORM_CLAMP_G_Y, MPC_OUT_DENORM_CLAMP_MIN_G_Y, mask_sh),\ + SF(MPC_OUT0_DENORM_CLAMP_B_CB, MPC_OUT_DENORM_CLAMP_MAX_B_CB, mask_sh),\ +- SF(MPC_OUT0_DENORM_CLAMP_B_CB, MPC_OUT_DENORM_CLAMP_MIN_B_CB, mask_sh) ++ SF(MPC_OUT0_DENORM_CLAMP_B_CB, MPC_OUT_DENORM_CLAMP_MIN_B_CB, mask_sh),\ ++ SF(CUR_VUPDATE_LOCK_SET0, CUR_VUPDATE_LOCK_SET, mask_sh) + + /* + * DCN2 MPC_OCSC debug status register: +diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c +index 1b0bca9587d0..1ba47f3a6857 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c +@@ -506,6 +506,10 @@ enum dcn20_clk_src_array_id { + .block ## _ ## reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ + mm ## block ## id ## _ ## reg_name + ++#define VUPDATE_SRII(reg_name, block, id)\ ++ .reg_name[id] = BASE(mm ## reg_name ## _ ## block ## id ## _BASE_IDX) + \ ++ mm ## reg_name ## _ ## block ## id ++ + /* NBIO */ + #define NBIO_BASE_INNER(seg) \ + NBIO_BASE__INST0_SEG ## seg +diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c +index 8b91445389df..8fe8ec7c0882 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c +@@ -53,6 +53,7 @@ static const struct hw_sequencer_funcs dcn21_funcs = { + .disable_plane = dcn20_disable_plane, + .pipe_control_lock = dcn20_pipe_control_lock, + .interdependent_update_lock = dcn10_lock_all_pipes, ++ .cursor_lock = dcn10_cursor_lock, + .prepare_bandwidth = dcn20_prepare_bandwidth, + .optimize_bandwidth = dcn20_optimize_bandwidth, + .update_bandwidth = dcn20_update_bandwidth, +diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c +index 122d3e734c59..5286cc7d1261 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c +@@ -306,6 +306,10 @@ struct _vcs_dpi_soc_bounding_box_st dcn2_1_soc = { + .block ## _ ## reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ + mm ## block ## id ## _ ## reg_name + ++#define VUPDATE_SRII(reg_name, block, id)\ ++ .reg_name[id] = BASE(mm ## reg_name ## _ ## block ## id ## _BASE_IDX) + \ ++ mm ## reg_name ## _ ## block ## id ++ + /* NBIO */ + #define NBIO_BASE_INNER(seg) \ + NBIF0_BASE__INST0_SEG ## seg +diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h +index 094afc4c8173..50ee8aa7ec3b 100644 +--- a/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h ++++ b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h +@@ -210,6 +210,22 @@ struct mpc_funcs { + struct mpcc_blnd_cfg *blnd_cfg, + int mpcc_id); + ++ /* ++ * Lock cursor updates for the specified OPP. ++ * OPP defines the set of MPCC that are locked together for cursor. ++ * ++ * Parameters: ++ * [in] mpc - MPC context. ++ * [in] opp_id - The OPP to lock cursor updates on ++ * [in] lock - lock/unlock the OPP ++ * ++ * Return: void ++ */ ++ void (*cursor_lock)( ++ struct mpc *mpc, ++ int opp_id, ++ bool lock); ++ + struct mpcc* (*get_mpcc_for_dpp)( + struct mpc_tree *tree, + int dpp_id); +diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +index d4c1fb242c63..e57467d99d66 100644 +--- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h ++++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +@@ -86,6 +86,7 @@ struct hw_sequencer_funcs { + struct dc_state *context, bool lock); + void (*set_flip_control_gsl)(struct pipe_ctx *pipe_ctx, + bool flip_immediate); ++ void (*cursor_lock)(struct dc *dc, struct pipe_ctx *pipe, bool lock); + + /* Timing Related */ + void (*get_position)(struct pipe_ctx **pipe_ctx, int num_pipes, +-- +2.25.1 + diff --git a/queue-5.6/exec-always-set-cap_ambient-in-cap_bprm_set_creds.patch b/queue-5.6/exec-always-set-cap_ambient-in-cap_bprm_set_creds.patch new file mode 100644 index 00000000000..ca4acefe5d9 --- /dev/null +++ b/queue-5.6/exec-always-set-cap_ambient-in-cap_bprm_set_creds.patch @@ -0,0 +1,52 @@ +From cf76cc3e0fba55277bced9d2b870f9fec905b66a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 25 May 2020 12:56:15 -0500 +Subject: exec: Always set cap_ambient in cap_bprm_set_creds + +From: Eric W. Biederman + +[ Upstream commit a4ae32c71fe90794127b32d26d7ad795813b502e ] + +An invariant of cap_bprm_set_creds is that every field in the new cred +structure that cap_bprm_set_creds might set, needs to be set every +time to ensure the fields does not get a stale value. + +The field cap_ambient is not set every time cap_bprm_set_creds is +called, which means that if there is a suid or sgid script with an +interpreter that has neither the suid nor the sgid bits set the +interpreter should be able to accept ambient credentials. +Unfortuantely because cap_ambient is not reset to it's original value +the interpreter can not accept ambient credentials. + +Given that the ambient capability set is expected to be controlled by +the caller, I don't think this is particularly serious. But it is +definitely worth fixing so the code works correctly. + +I have tested to verify my reading of the code is correct and the +interpreter of a sgid can receive ambient capabilities with this +change and cannot receive ambient capabilities without this change. + +Cc: stable@vger.kernel.org +Cc: Andy Lutomirski +Fixes: 58319057b784 ("capabilities: ambient capabilities") +Signed-off-by: "Eric W. Biederman" +Signed-off-by: Sasha Levin +--- + security/commoncap.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/security/commoncap.c b/security/commoncap.c +index f4ee0ae106b2..0ca31c8bc0b1 100644 +--- a/security/commoncap.c ++++ b/security/commoncap.c +@@ -812,6 +812,7 @@ int cap_bprm_set_creds(struct linux_binprm *bprm) + int ret; + kuid_t root_uid; + ++ new->cap_ambient = old->cap_ambient; + if (WARN_ON(!cap_ambient_invariant_ok(old))) + return -EPERM; + +-- +2.25.1 + diff --git a/queue-5.6/fs-binfmt_elf.c-allocate-initialized-memory-in-fill_.patch b/queue-5.6/fs-binfmt_elf.c-allocate-initialized-memory-in-fill_.patch new file mode 100644 index 00000000000..41e1801bc2a --- /dev/null +++ b/queue-5.6/fs-binfmt_elf.c-allocate-initialized-memory-in-fill_.patch @@ -0,0 +1,45 @@ +From 8f62a413c6c9c853b81ada65886311d7845f9416 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 27 May 2020 22:20:52 -0700 +Subject: fs/binfmt_elf.c: allocate initialized memory in + fill_thread_core_info() + +From: Alexander Potapenko + +[ Upstream commit 1d605416fb7175e1adf094251466caa52093b413 ] + +KMSAN reported uninitialized data being written to disk when dumping +core. As a result, several kilobytes of kmalloc memory may be written +to the core file and then read by a non-privileged user. + +Reported-by: sam +Signed-off-by: Alexander Potapenko +Signed-off-by: Andrew Morton +Acked-by: Kees Cook +Cc: Al Viro +Cc: Alexey Dobriyan +Cc: +Link: http://lkml.kernel.org/r/20200419100848.63472-1-glider@google.com +Link: https://github.com/google/kmsan/issues/76 +Signed-off-by: Linus Torvalds +Signed-off-by: Sasha Levin +--- + fs/binfmt_elf.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c +index f4713ea76e82..54f888ddb8cc 100644 +--- a/fs/binfmt_elf.c ++++ b/fs/binfmt_elf.c +@@ -1733,7 +1733,7 @@ static int fill_thread_core_info(struct elf_thread_core_info *t, + (!regset->active || regset->active(t->task, regset) > 0)) { + int ret; + size_t size = regset_size(t->task, regset); +- void *data = kmalloc(size, GFP_KERNEL); ++ void *data = kzalloc(size, GFP_KERNEL); + if (unlikely(!data)) + return 0; + ret = regset->get(t->task, regset, +-- +2.25.1 + diff --git a/queue-5.6/gpio-bcm-kona-fix-return-value-of-bcm_kona_gpio_prob.patch b/queue-5.6/gpio-bcm-kona-fix-return-value-of-bcm_kona_gpio_prob.patch new file mode 100644 index 00000000000..2db98ef3be3 --- /dev/null +++ b/queue-5.6/gpio-bcm-kona-fix-return-value-of-bcm_kona_gpio_prob.patch @@ -0,0 +1,37 @@ +From ca18ab35cfabf2774d765784f5437057bcbfbb42 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 22 May 2020 12:12:18 +0800 +Subject: gpio: bcm-kona: Fix return value of bcm_kona_gpio_probe() + +From: Tiezhu Yang + +[ Upstream commit 98f7d1b15e87c84488b30ecc4ec753b0690b9dbf ] + +Propagate the error code returned by devm_platform_ioremap_resource() +out of probe() instead of overwriting it. + +Fixes: 72d8cb715477 ("drivers: gpio: bcm-kona: use devm_platform_ioremap_resource()") +Signed-off-by: Tiezhu Yang +[Bartosz: tweaked the commit message] +Signed-off-by: Bartosz Golaszewski +Signed-off-by: Sasha Levin +--- + drivers/gpio/gpio-bcm-kona.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpio/gpio-bcm-kona.c b/drivers/gpio/gpio-bcm-kona.c +index baee8c3f06ad..cf3687a7925f 100644 +--- a/drivers/gpio/gpio-bcm-kona.c ++++ b/drivers/gpio/gpio-bcm-kona.c +@@ -625,7 +625,7 @@ static int bcm_kona_gpio_probe(struct platform_device *pdev) + + kona_gpio->reg_base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(kona_gpio->reg_base)) { +- ret = -ENXIO; ++ ret = PTR_ERR(kona_gpio->reg_base); + goto err_irq_domain; + } + +-- +2.25.1 + diff --git a/queue-5.6/gpio-exar-fix-bad-handling-for-ida_simple_get-error-.patch b/queue-5.6/gpio-exar-fix-bad-handling-for-ida_simple_get-error-.patch new file mode 100644 index 00000000000..68bae553ad2 --- /dev/null +++ b/queue-5.6/gpio-exar-fix-bad-handling-for-ida_simple_get-error-.patch @@ -0,0 +1,55 @@ +From 02ec3c306e6eb431d55023c6a8b24f4242cbf30e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Apr 2020 15:56:54 +0200 +Subject: gpio: exar: Fix bad handling for ida_simple_get error path + +From: Takashi Iwai + +[ Upstream commit 333830aa149a87cabeb5d30fbcf12eecc8040d2c ] + +The commit 7ecced0934e5 ("gpio: exar: add a check for the return value +of ida_simple_get fails") added a goto jump to the common error +handler for ida_simple_get() error, but this is wrong in two ways: +it doesn't set the proper return code and, more badly, it invokes +ida_simple_remove() with a negative index that shall lead to a kernel +panic via BUG_ON(). + +This patch addresses those two issues. + +Fixes: 7ecced0934e5 ("gpio: exar: add a check for the return value of ida_simple_get fails") +Cc: +Signed-off-by: Takashi Iwai +Signed-off-by: Bartosz Golaszewski +Signed-off-by: Sasha Levin +--- + drivers/gpio/gpio-exar.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpio/gpio-exar.c b/drivers/gpio/gpio-exar.c +index da1ef0b1c291..b1accfba017d 100644 +--- a/drivers/gpio/gpio-exar.c ++++ b/drivers/gpio/gpio-exar.c +@@ -148,8 +148,10 @@ static int gpio_exar_probe(struct platform_device *pdev) + mutex_init(&exar_gpio->lock); + + index = ida_simple_get(&ida_index, 0, 0, GFP_KERNEL); +- if (index < 0) +- goto err_destroy; ++ if (index < 0) { ++ ret = index; ++ goto err_mutex_destroy; ++ } + + sprintf(exar_gpio->name, "exar_gpio%d", index); + exar_gpio->gpio_chip.label = exar_gpio->name; +@@ -176,6 +178,7 @@ static int gpio_exar_probe(struct platform_device *pdev) + + err_destroy: + ida_simple_remove(&ida_index, index); ++err_mutex_destroy: + mutex_destroy(&exar_gpio->lock); + return ret; + } +-- +2.25.1 + diff --git a/queue-5.6/gpio-fix-locking-open-drain-irq-lines.patch b/queue-5.6/gpio-fix-locking-open-drain-irq-lines.patch new file mode 100644 index 00000000000..39429ade68d --- /dev/null +++ b/queue-5.6/gpio-fix-locking-open-drain-irq-lines.patch @@ -0,0 +1,61 @@ +From 246d630914c648b772fce191a6b9c35f34cad7ea Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 27 May 2020 16:07:58 +0200 +Subject: gpio: fix locking open drain IRQ lines + +From: Linus Walleij + +[ Upstream commit e9bdf7e655b9ee81ee912fae1d59df48ce7311b6 ] + +We provided the right semantics on open drain lines being +by definition output but incidentally the irq set up function +would only allow IRQs on lines that were "not output". + +Fix the semantics to allow output open drain lines to be used +for IRQs. + +Reported-by: Hans Verkuil +Signed-off-by: Linus Walleij +Signed-off-by: Hans Verkuil +Tested-by: Hans Verkuil +Cc: Russell King +Cc: stable@vger.kernel.org # v5.3+ +Link: https://lore.kernel.org/r/20200527140758.162280-1-linus.walleij@linaro.org +Signed-off-by: Linus Walleij +Signed-off-by: Sasha Levin +--- + drivers/gpio/gpiolib.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c +index 00fb91feba70..2f350e3df965 100644 +--- a/drivers/gpio/gpiolib.c ++++ b/drivers/gpio/gpiolib.c +@@ -4025,7 +4025,9 @@ int gpiochip_lock_as_irq(struct gpio_chip *chip, unsigned int offset) + } + } + +- if (test_bit(FLAG_IS_OUT, &desc->flags)) { ++ /* To be valid for IRQ the line needs to be input or open drain */ ++ if (test_bit(FLAG_IS_OUT, &desc->flags) && ++ !test_bit(FLAG_OPEN_DRAIN, &desc->flags)) { + chip_err(chip, + "%s: tried to flag a GPIO set as output for IRQ\n", + __func__); +@@ -4088,7 +4090,12 @@ void gpiochip_enable_irq(struct gpio_chip *chip, unsigned int offset) + + if (!IS_ERR(desc) && + !WARN_ON(!test_bit(FLAG_USED_AS_IRQ, &desc->flags))) { +- WARN_ON(test_bit(FLAG_IS_OUT, &desc->flags)); ++ /* ++ * We must not be output when using IRQ UNLESS we are ++ * open drain. ++ */ ++ WARN_ON(test_bit(FLAG_IS_OUT, &desc->flags) && ++ !test_bit(FLAG_OPEN_DRAIN, &desc->flags)); + set_bit(FLAG_IRQ_IS_ENABLED, &desc->flags); + } + } +-- +2.25.1 + diff --git a/queue-5.6/gpio-mvebu-fix-probing-for-chips-without-pwm.patch b/queue-5.6/gpio-mvebu-fix-probing-for-chips-without-pwm.patch new file mode 100644 index 00000000000..1c761d22bc9 --- /dev/null +++ b/queue-5.6/gpio-mvebu-fix-probing-for-chips-without-pwm.patch @@ -0,0 +1,66 @@ +From b06934c8631ec7e93d2c5fbaf09a6dd83da910d8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Apr 2020 11:21:57 +0200 +Subject: gpio: mvebu: Fix probing for chips without PWM + +From: Sascha Hauer + +[ Upstream commit 19c26d90ff4ca08ef2a2fef23cc9c13cfbfd891e ] + +The PWM iomem resource is optional and its presence indicates whether +the GPIO chip has a PWM or not, which is why mvebu_pwm_probe() returned +successfully when the PWM resource was not present. With f51b18d92b66 +the driver switched to devm_platform_ioremap_resource_byname() and +its error return is propagated to the caller, so now a missing PWM resource +leads to a probe error in the driver. + +To fix this explicitly test for the presence of the PWM resource and +return successfully when it's not there. Do this check before the check +for the clock is done (which GPIO chips without a PWM do not have). Also +move the existing comment why the PWM resource is optional up to the +actual check. + +Fixes: f51b18d92b66 ("gpio: mvebu: use devm_platform_ioremap_resource_byname()") +Signed-off-by: Sascha Hauer +Signed-off-by: Bartosz Golaszewski +Signed-off-by: Sasha Levin +--- + drivers/gpio/gpio-mvebu.c | 15 +++++++++------ + 1 file changed, 9 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c +index d2b999c7987f..f0c5433a327f 100644 +--- a/drivers/gpio/gpio-mvebu.c ++++ b/drivers/gpio/gpio-mvebu.c +@@ -782,6 +782,15 @@ static int mvebu_pwm_probe(struct platform_device *pdev, + "marvell,armada-370-gpio")) + return 0; + ++ /* ++ * There are only two sets of PWM configuration registers for ++ * all the GPIO lines on those SoCs which this driver reserves ++ * for the first two GPIO chips. So if the resource is missing ++ * we can't treat it as an error. ++ */ ++ if (!platform_get_resource_byname(pdev, IORESOURCE_MEM, "pwm")) ++ return 0; ++ + if (IS_ERR(mvchip->clk)) + return PTR_ERR(mvchip->clk); + +@@ -804,12 +813,6 @@ static int mvebu_pwm_probe(struct platform_device *pdev, + mvchip->mvpwm = mvpwm; + mvpwm->mvchip = mvchip; + +- /* +- * There are only two sets of PWM configuration registers for +- * all the GPIO lines on those SoCs which this driver reserves +- * for the first two GPIO chips. So if the resource is missing +- * we can't treat it as an error. +- */ + mvpwm->membase = devm_platform_ioremap_resource_byname(pdev, "pwm"); + if (IS_ERR(mvpwm->membase)) + return PTR_ERR(mvpwm->membase); +-- +2.25.1 + diff --git a/queue-5.6/gpio-pxa-fix-return-value-of-pxa_gpio_probe.patch b/queue-5.6/gpio-pxa-fix-return-value-of-pxa_gpio_probe.patch new file mode 100644 index 00000000000..e4c246f5244 --- /dev/null +++ b/queue-5.6/gpio-pxa-fix-return-value-of-pxa_gpio_probe.patch @@ -0,0 +1,38 @@ +From 9e5e61c8c620cc07adbd8bdf2c5576b881040edc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 22 May 2020 12:12:19 +0800 +Subject: gpio: pxa: Fix return value of pxa_gpio_probe() + +From: Tiezhu Yang + +[ Upstream commit 558ab2e8155e5f42ca0a6407957cd4173dc166cc ] + +When call function devm_platform_ioremap_resource(), we should use IS_ERR() +to check the return value and return PTR_ERR() if failed. + +Fixes: 542c25b7a209 ("drivers: gpio: pxa: use devm_platform_ioremap_resource()") +Signed-off-by: Tiezhu Yang +Signed-off-by: Bartosz Golaszewski +Signed-off-by: Sasha Levin +--- + drivers/gpio/gpio-pxa.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c +index 9888b62f37af..432c487f77b4 100644 +--- a/drivers/gpio/gpio-pxa.c ++++ b/drivers/gpio/gpio-pxa.c +@@ -663,8 +663,8 @@ static int pxa_gpio_probe(struct platform_device *pdev) + pchip->irq1 = irq1; + + gpio_reg_base = devm_platform_ioremap_resource(pdev, 0); +- if (!gpio_reg_base) +- return -EINVAL; ++ if (IS_ERR(gpio_reg_base)) ++ return PTR_ERR(gpio_reg_base); + + clk = clk_get(&pdev->dev, NULL); + if (IS_ERR(clk)) { +-- +2.25.1 + diff --git a/queue-5.6/gpu-drm-ingenic-fix-bogus-crtc_atomic_check-callback.patch b/queue-5.6/gpu-drm-ingenic-fix-bogus-crtc_atomic_check-callback.patch new file mode 100644 index 00000000000..96eb23f8e3d --- /dev/null +++ b/queue-5.6/gpu-drm-ingenic-fix-bogus-crtc_atomic_check-callback.patch @@ -0,0 +1,40 @@ +From ec96fb35caf69bf417565bca405dd994970d50fe Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 16 May 2020 23:50:49 +0200 +Subject: gpu/drm: ingenic: Fix bogus crtc_atomic_check callback + +From: Paul Cercueil + +[ Upstream commit a53bcc19876498bdd3b4ef796c787295dcc498b4 ] + +The code was comparing the SoC's maximum height with the mode's width, +and vice-versa. D'oh. + +Cc: stable@vger.kernel.org # v5.6 +Fixes: a7c909b7c037 ("gpu/drm: ingenic: Check for display size in CRTC atomic check") +Signed-off-by: Paul Cercueil +Link: https://patchwork.freedesktop.org/patch/msgid/20200516215057.392609-4-paul@crapouillou.net +Acked-by: Sam Ravnborg +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/ingenic/ingenic-drm.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/ingenic/ingenic-drm.c b/drivers/gpu/drm/ingenic/ingenic-drm.c +index bcba2f024842..8f5077370a52 100644 +--- a/drivers/gpu/drm/ingenic/ingenic-drm.c ++++ b/drivers/gpu/drm/ingenic/ingenic-drm.c +@@ -328,8 +328,8 @@ static int ingenic_drm_crtc_atomic_check(struct drm_crtc *crtc, + if (!drm_atomic_crtc_needs_modeset(state)) + return 0; + +- if (state->mode.hdisplay > priv->soc_info->max_height || +- state->mode.vdisplay > priv->soc_info->max_width) ++ if (state->mode.hdisplay > priv->soc_info->max_width || ++ state->mode.vdisplay > priv->soc_info->max_height) + return -EINVAL; + + rate = clk_round_rate(priv->pix_clk, +-- +2.25.1 + diff --git a/queue-5.6/gpu-drm-ingenic-fix-opaque-pointer-casted-to-wrong-t.patch b/queue-5.6/gpu-drm-ingenic-fix-opaque-pointer-casted-to-wrong-t.patch new file mode 100644 index 00000000000..bb675470444 --- /dev/null +++ b/queue-5.6/gpu-drm-ingenic-fix-opaque-pointer-casted-to-wrong-t.patch @@ -0,0 +1,42 @@ +From 8a211e1c56cdbe6af12e37e01021644dc6846182 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 16 May 2020 23:50:50 +0200 +Subject: gpu/drm: Ingenic: Fix opaque pointer casted to wrong type + +From: Paul Cercueil + +[ Upstream commit abf56fadf0e208abfb13ad1ac0094416058da0ad ] + +The opaque pointer passed to the IRQ handler is a pointer to the +drm_device, not a pointer to our ingenic_drm structure. + +It still worked, because our ingenic_drm structure contains the +drm_device as its first field, so the pointer received had the same +value, but this was not semantically correct. + +Cc: stable@vger.kernel.org # v5.3 +Fixes: 90b86fcc47b4 ("DRM: Add KMS driver for the Ingenic JZ47xx SoCs") +Signed-off-by: Paul Cercueil +Link: https://patchwork.freedesktop.org/patch/msgid/20200516215057.392609-5-paul@crapouillou.net +Acked-by: Sam Ravnborg +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/ingenic/ingenic-drm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/ingenic/ingenic-drm.c b/drivers/gpu/drm/ingenic/ingenic-drm.c +index 8f5077370a52..e9900e078d51 100644 +--- a/drivers/gpu/drm/ingenic/ingenic-drm.c ++++ b/drivers/gpu/drm/ingenic/ingenic-drm.c +@@ -474,7 +474,7 @@ static int ingenic_drm_encoder_atomic_check(struct drm_encoder *encoder, + + static irqreturn_t ingenic_drm_irq_handler(int irq, void *arg) + { +- struct ingenic_drm *priv = arg; ++ struct ingenic_drm *priv = drm_device_get_priv(arg); + unsigned int state; + + regmap_read(priv->map, JZ_REG_LCD_STATE, &state); +-- +2.25.1 + diff --git a/queue-5.6/ib-ipoib-fix-double-free-of-skb-in-case-of-multicast.patch b/queue-5.6/ib-ipoib-fix-double-free-of-skb-in-case-of-multicast.patch new file mode 100644 index 00000000000..d200837df65 --- /dev/null +++ b/queue-5.6/ib-ipoib-fix-double-free-of-skb-in-case-of-multicast.patch @@ -0,0 +1,243 @@ +From c932576c6324b94462adaa3398d13b3ccf9d8b42 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 27 May 2020 16:47:05 +0300 +Subject: IB/ipoib: Fix double free of skb in case of multicast traffic in CM + mode + +From: Valentine Fatiev + +[ Upstream commit 1acba6a817852d4aa7916d5c4f2c82f702ee9224 ] + +When connected mode is set, and we have connected and datagram traffic in +parallel, ipoib might crash with double free of datagram skb. + +The current mechanism assumes that the order in the completion queue is +the same as the order of sent packets for all QPs. Order is kept only for +specific QP, in case of mixed UD and CM traffic we have few QPs (one UD and +few CM's) in parallel. + +The problem: +---------------------------------------------------------- + +Transmit queue: +----------------- +UD skb pointer kept in queue itself, CM skb kept in spearate queue and +uses transmit queue as a placeholder to count the number of total +transmitted packets. + +0 1 2 3 4 5 6 7 8 9 10 11 12 13 .........127 +------------------------------------------------------------ +NL ud1 UD2 CM1 ud3 cm2 cm3 ud4 cm4 ud5 NL NL NL ........... +------------------------------------------------------------ + ^ ^ + tail head + +Completion queue (problematic scenario) - the order not the same as in +the transmit queue: + + 1 2 3 4 5 6 7 8 9 +------------------------------------ + ud1 CM1 UD2 ud3 cm2 cm3 ud4 cm4 ud5 +------------------------------------ + +1. CM1 'wc' processing + - skb freed in cm separate ring. + - tx_tail of transmit queue increased although UD2 is not freed. + Now driver assumes UD2 index is already freed and it could be used for + new transmitted skb. + +0 1 2 3 4 5 6 7 8 9 10 11 12 13 .........127 +------------------------------------------------------------ +NL NL UD2 CM1 ud3 cm2 cm3 ud4 cm4 ud5 NL NL NL ........... +------------------------------------------------------------ + ^ ^ ^ + (Bad)tail head +(Bad - Could be used for new SKB) + +In this case (due to heavy load) UD2 skb pointer could be replaced by new +transmitted packet UD_NEW, as the driver assumes its free. At this point +we will have to process two 'wc' with same index but we have only one +pointer to free. + +During second attempt to free the same skb we will have NULL pointer +exception. + +2. UD2 'wc' processing + - skb freed according the index we got from 'wc', but it was already + overwritten by mistake. So actually the skb that was released is the + skb of the new transmitted packet and not the original one. + +3. UD_NEW 'wc' processing + - attempt to free already freed skb. NUll pointer exception. + +The fix: +----------------------------------------------------------------------- + +The fix is to stop using the UD ring as a placeholder for CM packets, the +cyclic ring variables tx_head and tx_tail will manage the UD tx_ring, a +new cyclic variables global_tx_head and global_tx_tail are introduced for +managing and counting the overall outstanding sent packets, then the send +queue will be stopped and waken based on these variables only. + +Note that no locking is needed since global_tx_head is updated in the xmit +flow and global_tx_tail is updated in the NAPI flow only. A previous +attempt tried to use one variable to count the outstanding sent packets, +but it did not work since xmit and NAPI flows can run at the same time and +the counter will be updated wrongly. Thus, we use the same simple cyclic +head and tail scheme that we have today for the UD tx_ring. + +Fixes: 2c104ea68350 ("IB/ipoib: Get rid of the tx_outstanding variable in all modes") +Link: https://lore.kernel.org/r/20200527134705.480068-1-leon@kernel.org +Signed-off-by: Valentine Fatiev +Signed-off-by: Alaa Hleihel +Signed-off-by: Leon Romanovsky +Acked-by: Doug Ledford +Signed-off-by: Jason Gunthorpe +Signed-off-by: Sasha Levin +--- + drivers/infiniband/ulp/ipoib/ipoib.h | 4 ++++ + drivers/infiniband/ulp/ipoib/ipoib_cm.c | 15 +++++++++------ + drivers/infiniband/ulp/ipoib/ipoib_ib.c | 9 +++++++-- + drivers/infiniband/ulp/ipoib/ipoib_main.c | 10 ++++++---- + 4 files changed, 26 insertions(+), 12 deletions(-) + +diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h +index 2aa3457a30ce..0e5f27caf2b2 100644 +--- a/drivers/infiniband/ulp/ipoib/ipoib.h ++++ b/drivers/infiniband/ulp/ipoib/ipoib.h +@@ -377,8 +377,12 @@ struct ipoib_dev_priv { + struct ipoib_rx_buf *rx_ring; + + struct ipoib_tx_buf *tx_ring; ++ /* cyclic ring variables for managing tx_ring, for UD only */ + unsigned int tx_head; + unsigned int tx_tail; ++ /* cyclic ring variables for counting overall outstanding send WRs */ ++ unsigned int global_tx_head; ++ unsigned int global_tx_tail; + struct ib_sge tx_sge[MAX_SKB_FRAGS + 1]; + struct ib_ud_wr tx_wr; + struct ib_wc send_wc[MAX_SEND_CQE]; +diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c +index c59e00a0881f..9bf0fa30df28 100644 +--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c ++++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c +@@ -756,7 +756,8 @@ void ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_ + return; + } + +- if ((priv->tx_head - priv->tx_tail) == ipoib_sendq_size - 1) { ++ if ((priv->global_tx_head - priv->global_tx_tail) == ++ ipoib_sendq_size - 1) { + ipoib_dbg(priv, "TX ring 0x%x full, stopping kernel net queue\n", + tx->qp->qp_num); + netif_stop_queue(dev); +@@ -786,7 +787,7 @@ void ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_ + } else { + netif_trans_update(dev); + ++tx->tx_head; +- ++priv->tx_head; ++ ++priv->global_tx_head; + } + } + +@@ -820,10 +821,11 @@ void ipoib_cm_handle_tx_wc(struct net_device *dev, struct ib_wc *wc) + netif_tx_lock(dev); + + ++tx->tx_tail; +- ++priv->tx_tail; ++ ++priv->global_tx_tail; + + if (unlikely(netif_queue_stopped(dev) && +- (priv->tx_head - priv->tx_tail) <= ipoib_sendq_size >> 1 && ++ ((priv->global_tx_head - priv->global_tx_tail) <= ++ ipoib_sendq_size >> 1) && + test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags))) + netif_wake_queue(dev); + +@@ -1232,8 +1234,9 @@ timeout: + dev_kfree_skb_any(tx_req->skb); + netif_tx_lock_bh(p->dev); + ++p->tx_tail; +- ++priv->tx_tail; +- if (unlikely(priv->tx_head - priv->tx_tail == ipoib_sendq_size >> 1) && ++ ++priv->global_tx_tail; ++ if (unlikely((priv->global_tx_head - priv->global_tx_tail) <= ++ ipoib_sendq_size >> 1) && + netif_queue_stopped(p->dev) && + test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags)) + netif_wake_queue(p->dev); +diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c +index c332b4761816..da3c5315bbb5 100644 +--- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c ++++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c +@@ -407,9 +407,11 @@ static void ipoib_ib_handle_tx_wc(struct net_device *dev, struct ib_wc *wc) + dev_kfree_skb_any(tx_req->skb); + + ++priv->tx_tail; ++ ++priv->global_tx_tail; + + if (unlikely(netif_queue_stopped(dev) && +- ((priv->tx_head - priv->tx_tail) <= ipoib_sendq_size >> 1) && ++ ((priv->global_tx_head - priv->global_tx_tail) <= ++ ipoib_sendq_size >> 1) && + test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags))) + netif_wake_queue(dev); + +@@ -634,7 +636,8 @@ int ipoib_send(struct net_device *dev, struct sk_buff *skb, + else + priv->tx_wr.wr.send_flags &= ~IB_SEND_IP_CSUM; + /* increase the tx_head after send success, but use it for queue state */ +- if (priv->tx_head - priv->tx_tail == ipoib_sendq_size - 1) { ++ if ((priv->global_tx_head - priv->global_tx_tail) == ++ ipoib_sendq_size - 1) { + ipoib_dbg(priv, "TX ring full, stopping kernel net queue\n"); + netif_stop_queue(dev); + } +@@ -662,6 +665,7 @@ int ipoib_send(struct net_device *dev, struct sk_buff *skb, + + rc = priv->tx_head; + ++priv->tx_head; ++ ++priv->global_tx_head; + } + return rc; + } +@@ -807,6 +811,7 @@ int ipoib_ib_dev_stop_default(struct net_device *dev) + ipoib_dma_unmap_tx(priv, tx_req); + dev_kfree_skb_any(tx_req->skb); + ++priv->tx_tail; ++ ++priv->global_tx_tail; + } + + for (i = 0; i < ipoib_recvq_size; ++i) { +diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c +index 4a0d3a9e72e1..70d6d476ba90 100644 +--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c ++++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c +@@ -1188,9 +1188,11 @@ static void ipoib_timeout(struct net_device *dev, unsigned int txqueue) + + ipoib_warn(priv, "transmit timeout: latency %d msecs\n", + jiffies_to_msecs(jiffies - dev_trans_start(dev))); +- ipoib_warn(priv, "queue stopped %d, tx_head %u, tx_tail %u\n", +- netif_queue_stopped(dev), +- priv->tx_head, priv->tx_tail); ++ ipoib_warn(priv, ++ "queue stopped %d, tx_head %u, tx_tail %u, global_tx_head %u, global_tx_tail %u\n", ++ netif_queue_stopped(dev), priv->tx_head, priv->tx_tail, ++ priv->global_tx_head, priv->global_tx_tail); ++ + /* XXX reset QP, etc. */ + } + +@@ -1705,7 +1707,7 @@ static int ipoib_dev_init_default(struct net_device *dev) + goto out_rx_ring_cleanup; + } + +- /* priv->tx_head, tx_tail & tx_outstanding are already 0 */ ++ /* priv->tx_head, tx_tail and global_tx_tail/head are already 0 */ + + if (ipoib_transport_dev_init(dev, priv->ca)) { + pr_warn("%s: ipoib_transport_dev_init failed\n", +-- +2.25.1 + diff --git a/queue-5.6/ib-qib-call-kobject_put-when-kobject_init_and_add-fa.patch b/queue-5.6/ib-qib-call-kobject_put-when-kobject_init_and_add-fa.patch new file mode 100644 index 00000000000..5513064a06c --- /dev/null +++ b/queue-5.6/ib-qib-call-kobject_put-when-kobject_init_and_add-fa.patch @@ -0,0 +1,82 @@ +From 5d83256a66d3b7c0111f9354a7cfca185e7f4184 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 11 May 2020 23:13:28 -0400 +Subject: IB/qib: Call kobject_put() when kobject_init_and_add() fails + +From: Kaike Wan + +[ Upstream commit a35cd6447effd5c239b564c80fa109d05ff3d114 ] + +When kobject_init_and_add() returns an error in the function +qib_create_port_files(), the function kobject_put() is not called for the +corresponding kobject, which potentially leads to memory leak. + +This patch fixes the issue by calling kobject_put() even if +kobject_init_and_add() fails. In addition, the ppd->diagc_kobj is released +along with other kobjects when the sysfs is unregistered. + +Fixes: f931551bafe1 ("IB/qib: Add new qib driver for QLogic PCIe InfiniBand adapters") +Link: https://lore.kernel.org/r/20200512031328.189865.48627.stgit@awfm-01.aw.intel.com +Cc: +Suggested-by: Lin Yi +Reviewed-by: Mike Marciniszyn +Signed-off-by: Kaike Wan +Signed-off-by: Dennis Dalessandro +Reviewed-by: Leon Romanovsky +Signed-off-by: Jason Gunthorpe +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/qib/qib_sysfs.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/drivers/infiniband/hw/qib/qib_sysfs.c b/drivers/infiniband/hw/qib/qib_sysfs.c +index 568b21eb6ea1..021df0654ba7 100644 +--- a/drivers/infiniband/hw/qib/qib_sysfs.c ++++ b/drivers/infiniband/hw/qib/qib_sysfs.c +@@ -760,7 +760,7 @@ int qib_create_port_files(struct ib_device *ibdev, u8 port_num, + qib_dev_err(dd, + "Skipping linkcontrol sysfs info, (err %d) port %u\n", + ret, port_num); +- goto bail; ++ goto bail_link; + } + kobject_uevent(&ppd->pport_kobj, KOBJ_ADD); + +@@ -770,7 +770,7 @@ int qib_create_port_files(struct ib_device *ibdev, u8 port_num, + qib_dev_err(dd, + "Skipping sl2vl sysfs info, (err %d) port %u\n", + ret, port_num); +- goto bail_link; ++ goto bail_sl; + } + kobject_uevent(&ppd->sl2vl_kobj, KOBJ_ADD); + +@@ -780,7 +780,7 @@ int qib_create_port_files(struct ib_device *ibdev, u8 port_num, + qib_dev_err(dd, + "Skipping diag_counters sysfs info, (err %d) port %u\n", + ret, port_num); +- goto bail_sl; ++ goto bail_diagc; + } + kobject_uevent(&ppd->diagc_kobj, KOBJ_ADD); + +@@ -793,7 +793,7 @@ int qib_create_port_files(struct ib_device *ibdev, u8 port_num, + qib_dev_err(dd, + "Skipping Congestion Control sysfs info, (err %d) port %u\n", + ret, port_num); +- goto bail_diagc; ++ goto bail_cc; + } + + kobject_uevent(&ppd->pport_cc_kobj, KOBJ_ADD); +@@ -854,6 +854,7 @@ void qib_verbs_unregister_sysfs(struct qib_devdata *dd) + &cc_table_bin_attr); + kobject_put(&ppd->pport_cc_kobj); + } ++ kobject_put(&ppd->diagc_kobj); + kobject_put(&ppd->sl2vl_kobj); + kobject_put(&ppd->pport_kobj); + } +-- +2.25.1 + diff --git a/queue-5.6/include-asm-generic-topology.h-guard-cpumask_of_node.patch b/queue-5.6/include-asm-generic-topology.h-guard-cpumask_of_node.patch new file mode 100644 index 00000000000..eae0bce987f --- /dev/null +++ b/queue-5.6/include-asm-generic-topology.h-guard-cpumask_of_node.patch @@ -0,0 +1,48 @@ +From 42a5a77f107e21ba47a1b3b1cc49bf6132e01059 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 27 May 2020 22:20:55 -0700 +Subject: include/asm-generic/topology.h: guard cpumask_of_node() macro + argument + +From: Arnd Bergmann + +[ Upstream commit 4377748c7b5187c3342a60fa2ceb60c8a57a8488 ] + +drivers/hwmon/amd_energy.c:195:15: error: invalid operands to binary expression ('void' and 'int') + (channel - data->nr_cpus)); + ~~~~~~~~~^~~~~~~~~~~~~~~~~ +include/asm-generic/topology.h:51:42: note: expanded from macro 'cpumask_of_node' + #define cpumask_of_node(node) ((void)node, cpu_online_mask) + ^~~~ +include/linux/cpumask.h:618:72: note: expanded from macro 'cpumask_first_and' + #define cpumask_first_and(src1p, src2p) cpumask_next_and(-1, (src1p), (src2p)) + ^~~~~ + +Fixes: f0b848ce6fe9 ("cpumask: Introduce cpumask_of_{node,pcibus} to replace {node,pcibus}_to_cpumask") +Fixes: 8abee9566b7e ("hwmon: Add amd_energy driver to report energy counters") +Signed-off-by: Arnd Bergmann +Signed-off-by: Andrew Morton +Acked-by: Guenter Roeck +Link: http://lkml.kernel.org/r/20200527134623.930247-1-arnd@arndb.de +Signed-off-by: Linus Torvalds +Signed-off-by: Sasha Levin +--- + include/asm-generic/topology.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/asm-generic/topology.h b/include/asm-generic/topology.h +index 238873739550..5aa8705df87e 100644 +--- a/include/asm-generic/topology.h ++++ b/include/asm-generic/topology.h +@@ -48,7 +48,7 @@ + #ifdef CONFIG_NEED_MULTIPLE_NODES + #define cpumask_of_node(node) ((node) == 0 ? cpu_online_mask : cpu_none_mask) + #else +- #define cpumask_of_node(node) ((void)node, cpu_online_mask) ++ #define cpumask_of_node(node) ((void)(node), cpu_online_mask) + #endif + #endif + #ifndef pcibus_to_node +-- +2.25.1 + diff --git a/queue-5.6/input-dlink-dir685-touchkeys-fix-a-typo-in-driver-na.patch b/queue-5.6/input-dlink-dir685-touchkeys-fix-a-typo-in-driver-na.patch new file mode 100644 index 00000000000..7b486e7841f --- /dev/null +++ b/queue-5.6/input-dlink-dir685-touchkeys-fix-a-typo-in-driver-na.patch @@ -0,0 +1,38 @@ +From 5eb2caf672513b1fa270e84ab90c0ed124d871a2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 22 Apr 2020 13:58:42 -0700 +Subject: Input: dlink-dir685-touchkeys - fix a typo in driver name + +From: Christophe JAILLET + +[ Upstream commit 38347374ae3f1ec4df56dd688bd603a64e79a0ed ] + +According to the file name and Kconfig, a 'k' is missing in this driver +name. It should be "dlink-dir685-touchkeys". + +Fixes: 131b3de7016b ("Input: add D-Link DIR-685 touchkeys driver") +Signed-off-by: Christophe JAILLET +Reviewed-by: Linus Walleij +Link: https://lore.kernel.org/r/20200412213937.5287-1-christophe.jaillet@wanadoo.fr +Signed-off-by: Dmitry Torokhov +Signed-off-by: Sasha Levin +--- + drivers/input/keyboard/dlink-dir685-touchkeys.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/input/keyboard/dlink-dir685-touchkeys.c b/drivers/input/keyboard/dlink-dir685-touchkeys.c +index b0ead7199c40..a69dcc3bd30c 100644 +--- a/drivers/input/keyboard/dlink-dir685-touchkeys.c ++++ b/drivers/input/keyboard/dlink-dir685-touchkeys.c +@@ -143,7 +143,7 @@ MODULE_DEVICE_TABLE(of, dir685_tk_of_match); + + static struct i2c_driver dir685_tk_i2c_driver = { + .driver = { +- .name = "dlin-dir685-touchkeys", ++ .name = "dlink-dir685-touchkeys", + .of_match_table = of_match_ptr(dir685_tk_of_match), + }, + .probe = dir685_tk_probe, +-- +2.25.1 + diff --git a/queue-5.6/input-evdev-call-input_flush_device-on-release-not-f.patch b/queue-5.6/input-evdev-call-input_flush_device-on-release-not-f.patch new file mode 100644 index 00000000000..e3dcfca903d --- /dev/null +++ b/queue-5.6/input-evdev-call-input_flush_device-on-release-not-f.patch @@ -0,0 +1,75 @@ +From ca54547f3dd4d7506e63e058f0476ada907c9ce9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 22 Apr 2020 13:45:12 -0700 +Subject: Input: evdev - call input_flush_device() on release(), not flush() + +From: Brendan Shanks + +[ Upstream commit 09264098ff153f60866039d60b31d39b66f55a31 ] + +input_flush_device() should only be called once the struct file is being +released and no open descriptors remain, but evdev_flush() was calling +it whenever a file descriptor was closed. + +This caused uploaded force-feedback effects to be erased when a process +did a dup()/close() on the event FD, called system(), etc. + +Call input_flush_device() from evdev_release() instead. + +Reported-by: Mathieu Maret +Signed-off-by: Brendan Shanks +Link: https://lore.kernel.org/r/20200421231003.7935-1-bshanks@codeweavers.com +Cc: stable@vger.kernel.org +Signed-off-by: Dmitry Torokhov +Signed-off-by: Sasha Levin +--- + drivers/input/evdev.c | 19 ++++--------------- + 1 file changed, 4 insertions(+), 15 deletions(-) + +diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c +index cb6e3a5f509c..0d57e51b8ba1 100644 +--- a/drivers/input/evdev.c ++++ b/drivers/input/evdev.c +@@ -326,20 +326,6 @@ static int evdev_fasync(int fd, struct file *file, int on) + return fasync_helper(fd, file, on, &client->fasync); + } + +-static int evdev_flush(struct file *file, fl_owner_t id) +-{ +- struct evdev_client *client = file->private_data; +- struct evdev *evdev = client->evdev; +- +- mutex_lock(&evdev->mutex); +- +- if (evdev->exist && !client->revoked) +- input_flush_device(&evdev->handle, file); +- +- mutex_unlock(&evdev->mutex); +- return 0; +-} +- + static void evdev_free(struct device *dev) + { + struct evdev *evdev = container_of(dev, struct evdev, dev); +@@ -453,6 +439,10 @@ static int evdev_release(struct inode *inode, struct file *file) + unsigned int i; + + mutex_lock(&evdev->mutex); ++ ++ if (evdev->exist && !client->revoked) ++ input_flush_device(&evdev->handle, file); ++ + evdev_ungrab(evdev, client); + mutex_unlock(&evdev->mutex); + +@@ -1310,7 +1300,6 @@ static const struct file_operations evdev_fops = { + .compat_ioctl = evdev_ioctl_compat, + #endif + .fasync = evdev_fasync, +- .flush = evdev_flush, + .llseek = no_llseek, + }; + +-- +2.25.1 + diff --git a/queue-5.6/input-i8042-add-thinkpad-s230u-to-i8042-nomux-list.patch b/queue-5.6/input-i8042-add-thinkpad-s230u-to-i8042-nomux-list.patch new file mode 100644 index 00000000000..34773589d44 --- /dev/null +++ b/queue-5.6/input-i8042-add-thinkpad-s230u-to-i8042-nomux-list.patch @@ -0,0 +1,63 @@ +From 69f7eb7cb74c30cd5fab202ebef0e1fbd93448fd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 20 Apr 2020 10:02:19 -0700 +Subject: Input: i8042 - add ThinkPad S230u to i8042 nomux list + +From: Kevin Locke + +[ Upstream commit 18931506465a762ffd3f4803d36a18d336a67da9 ] + +On the Lenovo ThinkPad Twist S230u (3347-4HU) with BIOS version +"GDETC1WW (1.81 ) 06/27/2019", whether booted in UEFI or Legacy/CSM mode +the keyboard, Synaptics TouchPad, and TrackPoint either do not function +or stop functioning a few minutes after boot. This problem has been +noted before, perhaps only occurring on BIOS 1.57 and +later.[1][2][3][4][5] + +This model does not have an external PS/2 port, so mux does not appear +to be useful. + +Odds of a BIOS fix appear to be low: 1.57 was released over 6 years ago +and although the [BIOS changelog] notes "Fixed an issue of UEFI +touchpad/trackpoint/keyboard/touchscreen" in 1.58, it appears to be +insufficient. + +Adding 33474HU to the nomux list avoids the issue on my system. + +[1]: https://bugs.launchpad.net/bugs/1210748 +[2]: https://bbs.archlinux.org/viewtopic.php?pid=1360425 +[3]: https://forums.linuxmint.com/viewtopic.php?f=46&t=41200 +[4]: https://forums.linuxmint.com/viewtopic.php?f=49&t=157115 +[5]: https://forums.lenovo.com/topic/findpost/27/1337119 +[BIOS changelog]: https://download.lenovo.com/pccbbs/mobiles/gduj33uc.txt + +Signed-off-by: Kevin Locke +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/feb8a8339a67025dab3850e6377eb6f3a0e782ba.1587400635.git.kevin@kevinlocke.name +Signed-off-by: Dmitry Torokhov +Signed-off-by: Sasha Levin +--- + drivers/input/serio/i8042-x86ia64io.h | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h +index 08e919dbeb5d..5bbc9152731d 100644 +--- a/drivers/input/serio/i8042-x86ia64io.h ++++ b/drivers/input/serio/i8042-x86ia64io.h +@@ -541,6 +541,13 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = { + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5738"), + }, + }, ++ { ++ /* Lenovo ThinkPad Twist S230u */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "33474HU"), ++ }, ++ }, + { } + }; + +-- +2.25.1 + diff --git a/queue-5.6/input-i8042-add-thinkpad-s230u-to-i8042-reset-list.patch b/queue-5.6/input-i8042-add-thinkpad-s230u-to-i8042-reset-list.patch new file mode 100644 index 00000000000..d88ecda8f03 --- /dev/null +++ b/queue-5.6/input-i8042-add-thinkpad-s230u-to-i8042-reset-list.patch @@ -0,0 +1,60 @@ +From c2c8467706acdc2e9b91d58c75f070c6a999f075 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 Apr 2020 18:07:20 -0700 +Subject: Input: i8042 - add ThinkPad S230u to i8042 reset list + +From: Kevin Locke + +[ Upstream commit 2712c91a54a1058d55c284152b4d93c979b67be6 ] + +On the Lenovo ThinkPad Twist S230u (3347-4HU) with BIOS version +"GDETC1WW (1.81 ) 06/27/2019", the keyboard, Synaptics TouchPad, and +TrackPoint either do not function or stop functioning a few minutes +after boot. This problem has been noted before, perhaps only occurring +with BIOS 1.57 and later.[1][2][3][4][5] + +Odds of a BIOS fix appear to be low: 1.57 was released over 6 years ago +and although the [BIOS changelog] notes "Fixed an issue of UEFI +touchpad/trackpoint/keyboard/touchscreen" in 1.58, it appears to be +insufficient. + +Setting i8042.reset=1 or adding 33474HU to the reset list avoids the +issue on my system from either warm or cold boot. + +[1]: https://bugs.launchpad.net/bugs/1210748 +[2]: https://bbs.archlinux.org/viewtopic.php?pid=1360425 +[3]: https://forums.linuxmint.com/viewtopic.php?f=46&t=41200 +[4]: https://forums.linuxmint.com/viewtopic.php?f=49&t=157115 +[5]: https://forums.lenovo.com/topic/findpost/27/1337119 +[BIOS changelog]: https://download.lenovo.com/pccbbs/mobiles/gduj33uc.txt + +Signed-off-by: Kevin Locke +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/94f384b0f75f90f71425d7dce7ac82c59ddb87a8.1587702636.git.kevin@kevinlocke.name +Signed-off-by: Dmitry Torokhov +Signed-off-by: Sasha Levin +--- + drivers/input/serio/i8042-x86ia64io.h | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h +index 5bbc9152731d..c47800176534 100644 +--- a/drivers/input/serio/i8042-x86ia64io.h ++++ b/drivers/input/serio/i8042-x86ia64io.h +@@ -669,6 +669,13 @@ static const struct dmi_system_id __initconst i8042_dmi_reset_table[] = { + DMI_MATCH(DMI_PRODUCT_NAME, "P65xRP"), + }, + }, ++ { ++ /* Lenovo ThinkPad Twist S230u */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "33474HU"), ++ }, ++ }, + { } + }; + +-- +2.25.1 + diff --git a/queue-5.6/input-synaptics-rmi4-fix-error-return-code-in-rmi_dr.patch b/queue-5.6/input-synaptics-rmi4-fix-error-return-code-in-rmi_dr.patch new file mode 100644 index 00000000000..57c3803e8c5 --- /dev/null +++ b/queue-5.6/input-synaptics-rmi4-fix-error-return-code-in-rmi_dr.patch @@ -0,0 +1,38 @@ +From b27ec813c747de93c47611e9caa3dea1af4508c7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 Apr 2020 16:09:53 -0700 +Subject: Input: synaptics-rmi4 - fix error return code in rmi_driver_probe() + +From: Wei Yongjun + +[ Upstream commit 5caab2da63207d6d631007f592f5219459e3454d ] + +Fix to return a negative error code from the input_register_device() +error handling case instead of 0, as done elsewhere in this function. + +Signed-off-by: Wei Yongjun +Link: https://lore.kernel.org/r/20200428134948.78343-1-weiyongjun1@huawei.com +Cc: stable@vger.kernel.org +Signed-off-by: Dmitry Torokhov +Signed-off-by: Sasha Levin +--- + drivers/input/rmi4/rmi_driver.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c +index c18e1a25bca6..258d5fe3d395 100644 +--- a/drivers/input/rmi4/rmi_driver.c ++++ b/drivers/input/rmi4/rmi_driver.c +@@ -1210,7 +1210,8 @@ static int rmi_driver_probe(struct device *dev) + if (data->input) { + rmi_driver_set_input_name(rmi_dev, data->input); + if (!rmi_dev->xport->input) { +- if (input_register_device(data->input)) { ++ retval = input_register_device(data->input); ++ if (retval) { + dev_err(dev, "%s: Failed to register input device.\n", + __func__); + goto err_destroy_functions; +-- +2.25.1 + diff --git a/queue-5.6/input-synaptics-rmi4-really-fix-attn_data-use-after-.patch b/queue-5.6/input-synaptics-rmi4-really-fix-attn_data-use-after-.patch new file mode 100644 index 00000000000..478a09c8a8f --- /dev/null +++ b/queue-5.6/input-synaptics-rmi4-really-fix-attn_data-use-after-.patch @@ -0,0 +1,49 @@ +From e8bf01530e6ce83e8528aeb1faabc57b10c86227 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 Apr 2020 18:08:58 -0700 +Subject: Input: synaptics-rmi4 - really fix attn_data use-after-free + +From: Evan Green + +[ Upstream commit d5a5e5b5fa7b86c05bf073acc0ba98fa280174ec ] + +Fix a use-after-free noticed by running with KASAN enabled. If +rmi_irq_fn() is run twice in a row, then rmi_f11_attention() (among +others) will end up reading from drvdata->attn_data.data, which was +freed and left dangling in rmi_irq_fn(). + +Commit 55edde9fff1a ("Input: synaptics-rmi4 - prevent UAF reported by +KASAN") correctly identified and analyzed this bug. However the attempted +fix only NULLed out a local variable, missing the fact that +drvdata->attn_data is a struct, not a pointer. + +NULL out the correct pointer in the driver data to prevent the attention +functions from copying from it. + +Fixes: 55edde9fff1a ("Input: synaptics-rmi4 - prevent UAF reported by KASAN") +Fixes: b908d3cd812a ("Input: synaptics-rmi4 - allow to add attention data") +Signed-off-by: Evan Green +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20200427145537.1.Ic8f898e0147beeee2c005ee7b20f1aebdef1e7eb@changeid +Signed-off-by: Dmitry Torokhov +Signed-off-by: Sasha Levin +--- + drivers/input/rmi4/rmi_driver.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c +index 190b9974526b..c18e1a25bca6 100644 +--- a/drivers/input/rmi4/rmi_driver.c ++++ b/drivers/input/rmi4/rmi_driver.c +@@ -205,7 +205,7 @@ static irqreturn_t rmi_irq_fn(int irq, void *dev_id) + + if (count) { + kfree(attn_data.data); +- attn_data.data = NULL; ++ drvdata->attn_data.data = NULL; + } + + if (!kfifo_is_empty(&drvdata->attn_fifo)) +-- +2.25.1 + diff --git a/queue-5.6/input-usbtouchscreen-add-support-for-bonxeon-tp.patch b/queue-5.6/input-usbtouchscreen-add-support-for-bonxeon-tp.patch new file mode 100644 index 00000000000..0463dd79e93 --- /dev/null +++ b/queue-5.6/input-usbtouchscreen-add-support-for-bonxeon-tp.patch @@ -0,0 +1,37 @@ +From 9e92656c9defa27e01483b1fdf85cb10c2d02c71 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 18 Apr 2020 21:17:12 -0700 +Subject: Input: usbtouchscreen - add support for BonXeon TP + +From: James Hilliard + +[ Upstream commit e3b4f94ef52ae1592cbe199bd38dbdc0d58b2217 ] + +Based on available information this uses the singletouch irtouch +protocol. This is tested and confirmed to be fully functional on +the BonXeon TP hardware I have. + +Signed-off-by: James Hilliard +Link: https://lore.kernel.org/r/20200413184217.55700-1-james.hilliard1@gmail.com +Cc: stable@vger.kernel.org +Signed-off-by: Dmitry Torokhov +Signed-off-by: Sasha Levin +--- + drivers/input/touchscreen/usbtouchscreen.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c +index 16d70201de4a..397cb1d3f481 100644 +--- a/drivers/input/touchscreen/usbtouchscreen.c ++++ b/drivers/input/touchscreen/usbtouchscreen.c +@@ -182,6 +182,7 @@ static const struct usb_device_id usbtouch_devices[] = { + #endif + + #ifdef CONFIG_TOUCHSCREEN_USB_IRTOUCH ++ {USB_DEVICE(0x255e, 0x0001), .driver_info = DEVTYPE_IRTOUCH}, + {USB_DEVICE(0x595a, 0x0001), .driver_info = DEVTYPE_IRTOUCH}, + {USB_DEVICE(0x6615, 0x0001), .driver_info = DEVTYPE_IRTOUCH}, + {USB_DEVICE(0x6615, 0x0012), .driver_info = DEVTYPE_IRTOUCH_HIRES}, +-- +2.25.1 + diff --git a/queue-5.6/input-xpad-add-custom-init-packet-for-xbox-one-s-con.patch b/queue-5.6/input-xpad-add-custom-init-packet-for-xbox-one-s-con.patch new file mode 100644 index 00000000000..c4020de0e29 --- /dev/null +++ b/queue-5.6/input-xpad-add-custom-init-packet-for-xbox-one-s-con.patch @@ -0,0 +1,59 @@ +From 354b611648a844be9052d41f78e7285942bc9dcc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 22 Apr 2020 14:13:09 -0700 +Subject: Input: xpad - add custom init packet for Xbox One S controllers +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Łukasz Patron + +[ Upstream commit 764f7f911bf72450c51eb74cbb262ad9933741d8 ] + +Sending [ 0x05, 0x20, 0x00, 0x0f, 0x06 ] packet for Xbox One S controllers +fixes an issue where controller is stuck in Bluetooth mode and not sending +any inputs. + +Signed-off-by: Łukasz Patron +Reviewed-by: Cameron Gutman +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20200422075206.18229-1-priv.luk@gmail.com +Signed-off-by: Dmitry Torokhov +Signed-off-by: Sasha Levin +--- + drivers/input/joystick/xpad.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c +index 6b40a1c68f9f..c77cdb3b62b5 100644 +--- a/drivers/input/joystick/xpad.c ++++ b/drivers/input/joystick/xpad.c +@@ -458,6 +458,16 @@ static const u8 xboxone_fw2015_init[] = { + 0x05, 0x20, 0x00, 0x01, 0x00 + }; + ++/* ++ * This packet is required for Xbox One S (0x045e:0x02ea) ++ * and Xbox One Elite Series 2 (0x045e:0x0b00) pads to ++ * initialize the controller that was previously used in ++ * Bluetooth mode. ++ */ ++static const u8 xboxone_s_init[] = { ++ 0x05, 0x20, 0x00, 0x0f, 0x06 ++}; ++ + /* + * This packet is required for the Titanfall 2 Xbox One pads + * (0x0e6f:0x0165) to finish initialization and for Hori pads +@@ -516,6 +526,8 @@ static const struct xboxone_init_packet xboxone_init_packets[] = { + XBOXONE_INIT_PKT(0x0e6f, 0x0165, xboxone_hori_init), + XBOXONE_INIT_PKT(0x0f0d, 0x0067, xboxone_hori_init), + XBOXONE_INIT_PKT(0x0000, 0x0000, xboxone_fw2015_init), ++ XBOXONE_INIT_PKT(0x045e, 0x02ea, xboxone_s_init), ++ XBOXONE_INIT_PKT(0x045e, 0x0b00, xboxone_s_init), + XBOXONE_INIT_PKT(0x0e6f, 0x0000, xboxone_pdp_init1), + XBOXONE_INIT_PKT(0x0e6f, 0x0000, xboxone_pdp_init2), + XBOXONE_INIT_PKT(0x24c6, 0x541a, xboxone_rumblebegin_init), +-- +2.25.1 + diff --git a/queue-5.6/iommu-fix-reference-count-leak-in-iommu_group_alloc.patch b/queue-5.6/iommu-fix-reference-count-leak-in-iommu_group_alloc.patch new file mode 100644 index 00000000000..b1292d2b8e2 --- /dev/null +++ b/queue-5.6/iommu-fix-reference-count-leak-in-iommu_group_alloc.patch @@ -0,0 +1,38 @@ +From cfaa9bfc52e7eaf9df45d33382ab9c61bdfb910f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 27 May 2020 16:00:19 -0500 +Subject: iommu: Fix reference count leak in iommu_group_alloc. + +From: Qiushi Wu + +[ Upstream commit 7cc31613734c4870ae32f5265d576ef296621343 ] + +kobject_init_and_add() takes reference even when it fails. +Thus, when kobject_init_and_add() returns an error, +kobject_put() must be called to properly clean up the kobject. + +Fixes: d72e31c93746 ("iommu: IOMMU Groups") +Signed-off-by: Qiushi Wu +Link: https://lore.kernel.org/r/20200527210020.6522-1-wu000273@umn.edu +Signed-off-by: Joerg Roedel +Signed-off-by: Sasha Levin +--- + drivers/iommu/iommu.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c +index 22b28076d48e..b09de25df02e 100644 +--- a/drivers/iommu/iommu.c ++++ b/drivers/iommu/iommu.c +@@ -509,7 +509,7 @@ struct iommu_group *iommu_group_alloc(void) + NULL, "%d", group->id); + if (ret) { + ida_simple_remove(&iommu_group_ida, group->id); +- kfree(group); ++ kobject_put(&group->kobj); + return ERR_PTR(ret); + } + +-- +2.25.1 + diff --git a/queue-5.6/libceph-ignore-pool-overlay-and-cache-logic-on-redir.patch b/queue-5.6/libceph-ignore-pool-overlay-and-cache-logic-on-redir.patch new file mode 100644 index 00000000000..c0ed7052f4b --- /dev/null +++ b/queue-5.6/libceph-ignore-pool-overlay-and-cache-logic-on-redir.patch @@ -0,0 +1,49 @@ +From 1edc269a84a4d7c2769e609bc0e42c5393dc97f8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 18 May 2020 16:03:09 +0800 +Subject: libceph: ignore pool overlay and cache logic on redirects + +From: Jerry Lee + +[ Upstream commit 890bd0f8997ae6ac0a367dd5146154a3963306dd ] + +OSD client should ignore cache/overlay flag if got redirect reply. +Otherwise, the client hangs when the cache tier is in forward mode. + +[ idryomov: Redirects are effectively deprecated and no longer + used or tested. The original tiering modes based on redirects + are inherently flawed because redirects can race and reorder, + potentially resulting in data corruption. The new proxy and + readproxy tiering modes should be used instead of forward and + readforward. Still marking for stable as obviously correct, + though. ] + +Cc: stable@vger.kernel.org +URL: https://tracker.ceph.com/issues/23296 +URL: https://tracker.ceph.com/issues/36406 +Signed-off-by: Jerry Lee +Reviewed-by: Ilya Dryomov +Signed-off-by: Ilya Dryomov +Signed-off-by: Sasha Levin +--- + net/ceph/osd_client.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c +index af868d3923b9..834019dbc6b1 100644 +--- a/net/ceph/osd_client.c ++++ b/net/ceph/osd_client.c +@@ -3652,7 +3652,9 @@ static void handle_reply(struct ceph_osd *osd, struct ceph_msg *msg) + * supported. + */ + req->r_t.target_oloc.pool = m.redirect.oloc.pool; +- req->r_flags |= CEPH_OSD_FLAG_REDIRECTED; ++ req->r_flags |= CEPH_OSD_FLAG_REDIRECTED | ++ CEPH_OSD_FLAG_IGNORE_OVERLAY | ++ CEPH_OSD_FLAG_IGNORE_CACHE; + req->r_tid = 0; + __submit_request(req, false); + goto out_unlock_osdc; +-- +2.25.1 + diff --git a/queue-5.6/mm-remove-vm_bug_on-pageslab-from-page_mapcount.patch b/queue-5.6/mm-remove-vm_bug_on-pageslab-from-page_mapcount.patch new file mode 100644 index 00000000000..b55f7e0bf80 --- /dev/null +++ b/queue-5.6/mm-remove-vm_bug_on-pageslab-from-page_mapcount.patch @@ -0,0 +1,99 @@ +From b8f1c4e4b18edf273fc72fbd6253afd0c7c46ff5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 27 May 2020 22:20:47 -0700 +Subject: mm: remove VM_BUG_ON(PageSlab()) from page_mapcount() + +From: Konstantin Khlebnikov + +[ Upstream commit 6988f31d558aa8c744464a7f6d91d34ada48ad12 ] + +Replace superfluous VM_BUG_ON() with comment about correct usage. + +Technically reverts commit 1d148e218a0d ("mm: add VM_BUG_ON_PAGE() to +page_mapcount()"), but context lines have changed. + +Function isolate_migratepages_block() runs some checks out of lru_lock +when choose pages for migration. After checking PageLRU() it checks +extra page references by comparing page_count() and page_mapcount(). +Between these two checks page could be removed from lru, freed and taken +by slab. + +As a result this race triggers VM_BUG_ON(PageSlab()) in page_mapcount(). +Race window is tiny. For certain workload this happens around once a +year. + + page:ffffea0105ca9380 count:1 mapcount:0 mapping:ffff88ff7712c180 index:0x0 compound_mapcount: 0 + flags: 0x500000000008100(slab|head) + raw: 0500000000008100 dead000000000100 dead000000000200 ffff88ff7712c180 + raw: 0000000000000000 0000000080200020 00000001ffffffff 0000000000000000 + page dumped because: VM_BUG_ON_PAGE(PageSlab(page)) + ------------[ cut here ]------------ + kernel BUG at ./include/linux/mm.h:628! + invalid opcode: 0000 [#1] SMP NOPTI + CPU: 77 PID: 504 Comm: kcompactd1 Tainted: G W 4.19.109-27 #1 + Hardware name: Yandex T175-N41-Y3N/MY81-EX0-Y3N, BIOS R05 06/20/2019 + RIP: 0010:isolate_migratepages_block+0x986/0x9b0 + +The code in isolate_migratepages_block() was added in commit +119d6d59dcc0 ("mm, compaction: avoid isolating pinned pages") before +adding VM_BUG_ON into page_mapcount(). + +This race has been predicted in 2015 by Vlastimil Babka (see link +below). + +[akpm@linux-foundation.org: comment tweaks, per Hugh] +Fixes: 1d148e218a0d ("mm: add VM_BUG_ON_PAGE() to page_mapcount()") +Signed-off-by: Konstantin Khlebnikov +Signed-off-by: Andrew Morton +Acked-by: Hugh Dickins +Acked-by: Kirill A. Shutemov +Acked-by: Vlastimil Babka +Cc: David Rientjes +Cc: +Link: http://lkml.kernel.org/r/159032779896.957378.7852761411265662220.stgit@buzz +Link: https://lore.kernel.org/lkml/557710E1.6060103@suse.cz/ +Link: https://lore.kernel.org/linux-mm/158937872515.474360.5066096871639561424.stgit@buzz/T/ (v1) +Signed-off-by: Linus Torvalds +Signed-off-by: Sasha Levin +--- + include/linux/mm.h | 15 +++++++++++++-- + 1 file changed, 13 insertions(+), 2 deletions(-) + +diff --git a/include/linux/mm.h b/include/linux/mm.h +index c54fb96cb1e6..96deeecd9179 100644 +--- a/include/linux/mm.h ++++ b/include/linux/mm.h +@@ -670,6 +670,11 @@ static inline void *kvcalloc(size_t n, size_t size, gfp_t flags) + + extern void kvfree(const void *addr); + ++/* ++ * Mapcount of compound page as a whole, does not include mapped sub-pages. ++ * ++ * Must be called only for compound pages or any their tail sub-pages. ++ */ + static inline int compound_mapcount(struct page *page) + { + VM_BUG_ON_PAGE(!PageCompound(page), page); +@@ -689,10 +694,16 @@ static inline void page_mapcount_reset(struct page *page) + + int __page_mapcount(struct page *page); + ++/* ++ * Mapcount of 0-order page; when compound sub-page, includes ++ * compound_mapcount(). ++ * ++ * Result is undefined for pages which cannot be mapped into userspace. ++ * For example SLAB or special types of pages. See function page_has_type(). ++ * They use this place in struct page differently. ++ */ + static inline int page_mapcount(struct page *page) + { +- VM_BUG_ON_PAGE(PageSlab(page), page); +- + if (unlikely(PageCompound(page))) + return __page_mapcount(page); + return atomic_read(&page->_mapcount) + 1; +-- +2.25.1 + diff --git a/queue-5.6/mm-thp-stop-leaking-unreleased-file-pages.patch b/queue-5.6/mm-thp-stop-leaking-unreleased-file-pages.patch new file mode 100644 index 00000000000..bfcabe91226 --- /dev/null +++ b/queue-5.6/mm-thp-stop-leaking-unreleased-file-pages.patch @@ -0,0 +1,44 @@ +From 471652e9929ad6dfa04c6361da8afc125f6aea67 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 27 May 2020 22:20:43 -0700 +Subject: mm,thp: stop leaking unreleased file pages + +From: Hugh Dickins + +[ Upstream commit 2f33a706027c94cd4f70fcd3e3f4a17c1ce4ea4b ] + +When collapse_file() calls try_to_release_page(), it has already isolated +the page: so if releasing buffers happens to fail (as it sometimes does), +remember to putback_lru_page(): otherwise that page is left unreclaimable +and unfreeable, and the file extent uncollapsible. + +Fixes: 99cb0dbd47a1 ("mm,thp: add read-only THP support for (non-shmem) FS") +Signed-off-by: Hugh Dickins +Signed-off-by: Andrew Morton +Acked-by: Song Liu +Acked-by: Kirill A. Shutemov +Acked-by: Johannes Weiner +Cc: Rik van Riel +Cc: [5.4+] +Link: http://lkml.kernel.org/r/alpine.LSU.2.11.2005231837500.1766@eggly.anvils +Signed-off-by: Linus Torvalds +Signed-off-by: Sasha Levin +--- + mm/khugepaged.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/mm/khugepaged.c b/mm/khugepaged.c +index b679908743cb..ba059e68cf50 100644 +--- a/mm/khugepaged.c ++++ b/mm/khugepaged.c +@@ -1673,6 +1673,7 @@ static void collapse_file(struct mm_struct *mm, + if (page_has_private(page) && + !try_to_release_page(page, GFP_KERNEL)) { + result = SCAN_PAGE_HAS_PRIVATE; ++ putback_lru_page(page); + goto out_unlock; + } + +-- +2.25.1 + diff --git a/queue-5.6/mmc-block-fix-use-after-free-issue-for-rpmb.patch b/queue-5.6/mmc-block-fix-use-after-free-issue-for-rpmb.patch new file mode 100644 index 00000000000..dbfe6eb961d --- /dev/null +++ b/queue-5.6/mmc-block-fix-use-after-free-issue-for-rpmb.patch @@ -0,0 +1,43 @@ +From 8f4a216e62e7ee7dc7cd5d1d4f5629d27738dac7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 22 May 2020 09:29:25 +0000 +Subject: mmc: block: Fix use-after-free issue for rpmb +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Peng Hao + +[ Upstream commit 202500d21654874aa03243e91f96de153ec61860 ] + +The data structure member “rpmb->md” was passed to a call of the function +“mmc_blk_put” after a call of the function “put_device”. Reorder these +function calls to keep the data accesses consistent. + +Fixes: 1c87f7357849 ("mmc: block: Fix bug when removing RPMB chardev ") +Signed-off-by: Peng Hao +Cc: stable@vger.kernel.org +[Uffe: Fixed up mangled patch and updated commit message] +Signed-off-by: Ulf Hansson +Signed-off-by: Sasha Levin +--- + drivers/mmc/core/block.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c +index 32db16f6debc..2d19291ebc84 100644 +--- a/drivers/mmc/core/block.c ++++ b/drivers/mmc/core/block.c +@@ -2475,8 +2475,8 @@ static int mmc_rpmb_chrdev_release(struct inode *inode, struct file *filp) + struct mmc_rpmb_data *rpmb = container_of(inode->i_cdev, + struct mmc_rpmb_data, chrdev); + +- put_device(&rpmb->dev); + mmc_blk_put(rpmb->md); ++ put_device(&rpmb->dev); + + return 0; + } +-- +2.25.1 + diff --git a/queue-5.6/parisc-fix-kernel-panic-in-mem_init.patch b/queue-5.6/parisc-fix-kernel-panic-in-mem_init.patch new file mode 100644 index 00000000000..1f79bd32510 --- /dev/null +++ b/queue-5.6/parisc-fix-kernel-panic-in-mem_init.patch @@ -0,0 +1,52 @@ +From 7879fed38a959e6d29aa1b10003c9aad9e57c326 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 28 May 2020 22:29:25 +0200 +Subject: parisc: Fix kernel panic in mem_init() + +From: Helge Deller + +[ Upstream commit bf71bc16e02162388808949b179d59d0b571b965 ] + +The Debian kernel v5.6 triggers this kernel panic: + + Kernel panic - not syncing: Bad Address (null pointer deref?) + Bad Address (null pointer deref?): Code=26 (Data memory access rights trap) at addr 0000000000000000 + CPU: 0 PID: 0 Comm: swapper Not tainted 5.6.0-2-parisc64 #1 Debian 5.6.14-1 + IAOQ[0]: mem_init+0xb0/0x150 + IAOQ[1]: mem_init+0xb4/0x150 + RP(r2): start_kernel+0x6c8/0x1190 + Backtrace: + [<0000000040101ab4>] start_kernel+0x6c8/0x1190 + [<0000000040108574>] start_parisc+0x158/0x1b8 + +on a HP-PARISC rp3440 machine with this memory layout: + Memory Ranges: + 0) Start 0x0000000000000000 End 0x000000003fffffff Size 1024 MB + 1) Start 0x0000004040000000 End 0x00000040ffdfffff Size 3070 MB + +Fix the crash by avoiding virt_to_page() and similar functions in +mem_init() until the memory zones have been fully set up. + +Signed-off-by: Helge Deller +Cc: stable@vger.kernel.org # v5.0+ +Signed-off-by: Sasha Levin +--- + arch/parisc/mm/init.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c +index 5224fb38d766..01d7071b23f7 100644 +--- a/arch/parisc/mm/init.c ++++ b/arch/parisc/mm/init.c +@@ -562,7 +562,7 @@ void __init mem_init(void) + > BITS_PER_LONG); + + high_memory = __va((max_pfn << PAGE_SHIFT)); +- set_max_mapnr(page_to_pfn(virt_to_page(high_memory - 1)) + 1); ++ set_max_mapnr(max_low_pfn); + memblock_free_all(); + + #ifdef CONFIG_PA11 +-- +2.25.1 + diff --git a/queue-5.6/rdma-core-fix-double-destruction-of-uobject.patch b/queue-5.6/rdma-core-fix-double-destruction-of-uobject.patch new file mode 100644 index 00000000000..14da07b967f --- /dev/null +++ b/queue-5.6/rdma-core-fix-double-destruction-of-uobject.patch @@ -0,0 +1,148 @@ +From f7ba6f3e0224d04dbced723fb4d7ef2ad6f50c19 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 27 May 2020 16:55:34 +0300 +Subject: RDMA/core: Fix double destruction of uobject + +From: Jason Gunthorpe + +[ Upstream commit c85f4abe66bea0b5db8d28d55da760c4fe0a0301 ] + +Fix use after free when user user space request uobject concurrently for +the same object, within the RCU grace period. + +In that case, remove_handle_idr_uobject() is called twice and we will have +an extra put on the uobject which cause use after free. Fix it by leaving +the uobject write locked after it was removed from the idr. + +Call to rdma_lookup_put_uobject with UVERBS_LOOKUP_DESTROY instead of +UVERBS_LOOKUP_WRITE will do the work. + + refcount_t: underflow; use-after-free. + WARNING: CPU: 0 PID: 1381 at lib/refcount.c:28 refcount_warn_saturate+0xfe/0x1a0 + Kernel panic - not syncing: panic_on_warn set ... + CPU: 0 PID: 1381 Comm: syz-executor.0 Not tainted 5.5.0-rc3 #8 + Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.1-0-ga5cab58e9a3f-prebuilt.qemu.org 04/01/2014 + Call Trace: + dump_stack+0x94/0xce + panic+0x234/0x56f + __warn+0x1cc/0x1e1 + report_bug+0x200/0x310 + fixup_bug.part.11+0x32/0x80 + do_error_trap+0xd3/0x100 + do_invalid_op+0x31/0x40 + invalid_op+0x1e/0x30 + RIP: 0010:refcount_warn_saturate+0xfe/0x1a0 + Code: 0f 0b eb 9b e8 23 f6 6d ff 80 3d 6c d4 19 03 00 75 8d e8 15 f6 6d ff 48 c7 c7 c0 02 55 bd c6 05 57 d4 19 03 01 e8 a2 58 49 ff <0f> 0b e9 6e ff ff ff e8 f6 f5 6d ff 80 3d 42 d4 19 03 00 0f 85 5c + RSP: 0018:ffffc90002df7b98 EFLAGS: 00010282 + RAX: 0000000000000000 RBX: ffff88810f6a193c RCX: ffffffffba649009 + RDX: 0000000000000000 RSI: 0000000000000008 RDI: ffff88811b0283cc + RBP: 0000000000000003 R08: ffffed10236060e3 R09: ffffed10236060e3 + R10: 0000000000000001 R11: ffffed10236060e2 R12: ffff88810f6a193c + R13: ffffc90002df7d60 R14: 0000000000000000 R15: ffff888116ae6a08 + uverbs_uobject_put+0xfd/0x140 + __uobj_perform_destroy+0x3d/0x60 + ib_uverbs_close_xrcd+0x148/0x170 + ib_uverbs_write+0xaa5/0xdf0 + __vfs_write+0x7c/0x100 + vfs_write+0x168/0x4a0 + ksys_write+0xc8/0x200 + do_syscall_64+0x9c/0x390 + entry_SYSCALL_64_after_hwframe+0x44/0xa9 + RIP: 0033:0x465b49 + Code: f7 d8 64 89 02 b8 ff ff ff ff c3 66 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 bc ff ff ff f7 d8 64 89 01 48 + RSP: 002b:00007f759d122c58 EFLAGS: 00000246 ORIG_RAX: 0000000000000001 + RAX: ffffffffffffffda RBX: 000000000073bfa8 RCX: 0000000000465b49 + RDX: 000000000000000c RSI: 0000000020000080 RDI: 0000000000000003 + RBP: 0000000000000003 R08: 0000000000000000 R09: 0000000000000000 + R10: 0000000000000000 R11: 0000000000000246 R12: 00007f759d1236bc + R13: 00000000004ca27c R14: 000000000070de40 R15: 00000000ffffffff + Dumping ftrace buffer: + (ftrace buffer empty) + Kernel Offset: 0x39400000 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffffbfffffff) + +Fixes: 7452a3c745a2 ("IB/uverbs: Allow RDMA_REMOVE_DESTROY to work concurrently with disassociate") +Link: https://lore.kernel.org/r/20200527135534.482279-1-leon@kernel.org +Signed-off-by: Maor Gottlieb +Signed-off-by: Leon Romanovsky +Signed-off-by: Jason Gunthorpe +Signed-off-by: Sasha Levin +--- + drivers/infiniband/core/rdma_core.c | 20 +++++++++++++------- + include/rdma/uverbs_std_types.h | 2 +- + 2 files changed, 14 insertions(+), 8 deletions(-) + +diff --git a/drivers/infiniband/core/rdma_core.c b/drivers/infiniband/core/rdma_core.c +index bf8e149d3191..e0a5e897e4b1 100644 +--- a/drivers/infiniband/core/rdma_core.c ++++ b/drivers/infiniband/core/rdma_core.c +@@ -153,9 +153,9 @@ static int uverbs_destroy_uobject(struct ib_uobject *uobj, + uobj->context = NULL; + + /* +- * For DESTROY the usecnt is held write locked, the caller is expected +- * to put it unlock and put the object when done with it. Only DESTROY +- * can remove the IDR handle. ++ * For DESTROY the usecnt is not changed, the caller is expected to ++ * manage it via uobj_put_destroy(). Only DESTROY can remove the IDR ++ * handle. + */ + if (reason != RDMA_REMOVE_DESTROY) + atomic_set(&uobj->usecnt, 0); +@@ -187,7 +187,7 @@ static int uverbs_destroy_uobject(struct ib_uobject *uobj, + /* + * This calls uverbs_destroy_uobject() using the RDMA_REMOVE_DESTROY + * sequence. It should only be used from command callbacks. On success the +- * caller must pair this with rdma_lookup_put_uobject(LOOKUP_WRITE). This ++ * caller must pair this with uobj_put_destroy(). This + * version requires the caller to have already obtained an + * LOOKUP_DESTROY uobject kref. + */ +@@ -198,6 +198,13 @@ int uobj_destroy(struct ib_uobject *uobj, struct uverbs_attr_bundle *attrs) + + down_read(&ufile->hw_destroy_rwsem); + ++ /* ++ * Once the uobject is destroyed by RDMA_REMOVE_DESTROY then it is left ++ * write locked as the callers put it back with UVERBS_LOOKUP_DESTROY. ++ * This is because any other concurrent thread can still see the object ++ * in the xarray due to RCU. Leaving it locked ensures nothing else will ++ * touch it. ++ */ + ret = uverbs_try_lock_object(uobj, UVERBS_LOOKUP_WRITE); + if (ret) + goto out_unlock; +@@ -216,7 +223,7 @@ out_unlock: + /* + * uobj_get_destroy destroys the HW object and returns a handle to the uobj + * with a NULL object pointer. The caller must pair this with +- * uverbs_put_destroy. ++ * uobj_put_destroy(). + */ + struct ib_uobject *__uobj_get_destroy(const struct uverbs_api_object *obj, + u32 id, struct uverbs_attr_bundle *attrs) +@@ -250,8 +257,7 @@ int __uobj_perform_destroy(const struct uverbs_api_object *obj, u32 id, + uobj = __uobj_get_destroy(obj, id, attrs); + if (IS_ERR(uobj)) + return PTR_ERR(uobj); +- +- rdma_lookup_put_uobject(uobj, UVERBS_LOOKUP_WRITE); ++ uobj_put_destroy(uobj); + return 0; + } + +diff --git a/include/rdma/uverbs_std_types.h b/include/rdma/uverbs_std_types.h +index 1b28ce1aba07..325fdaa3bb66 100644 +--- a/include/rdma/uverbs_std_types.h ++++ b/include/rdma/uverbs_std_types.h +@@ -88,7 +88,7 @@ struct ib_uobject *__uobj_get_destroy(const struct uverbs_api_object *obj, + + static inline void uobj_put_destroy(struct ib_uobject *uobj) + { +- rdma_lookup_put_uobject(uobj, UVERBS_LOOKUP_WRITE); ++ rdma_lookup_put_uobject(uobj, UVERBS_LOOKUP_DESTROY); + } + + static inline void uobj_put_read(struct ib_uobject *uobj) +-- +2.25.1 + diff --git a/queue-5.6/rdma-mlx5-fix-null-pointer-dereference-in-destroy_pr.patch b/queue-5.6/rdma-mlx5-fix-null-pointer-dereference-in-destroy_pr.patch new file mode 100644 index 00000000000..95d298b15d6 --- /dev/null +++ b/queue-5.6/rdma-mlx5-fix-null-pointer-dereference-in-destroy_pr.patch @@ -0,0 +1,73 @@ +From 65b4903faa418b35711d794aece7d3c46d609a50 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 May 2020 10:25:04 +0300 +Subject: RDMA/mlx5: Fix NULL pointer dereference in destroy_prefetch_work + +From: Maor Gottlieb + +[ Upstream commit 189277f3814c36133f4ff0352f4b5194a38486b6 ] + +q_deferred_work isn't initialized when creating an explicit ODP memory +region. This can lead to a NULL pointer dereference when user performs +asynchronous prefetch MR. Fix it by initializing q_deferred_work for +explicit ODP. + + BUG: kernel NULL pointer dereference, address: 0000000000000000 + #PF: supervisor read access in kernel mode + #PF: error_code(0x0000) - not-present page + PGD 0 P4D 0 + Oops: 0000 [#1] SMP PTI + CPU: 4 PID: 6074 Comm: kworker/u16:6 Not tainted 5.7.0-rc1-for-upstream-perf-2020-04-17_07-03-39-64 #1 + Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.12.1-0-ga5cab58e9a3f-prebuilt.qemu.org 04/01/2014 + Workqueue: events_unbound mlx5_ib_prefetch_mr_work [mlx5_ib] + RIP: 0010:__wake_up_common+0x49/0x120 + Code: 04 89 54 24 0c 89 4c 24 08 74 0a 41 f6 01 04 0f 85 8e 00 00 00 48 8b 47 08 48 83 e8 18 4c 8d 67 08 48 8d 50 18 49 39 d4 74 66 <48> 8b 70 18 31 db 4c 8d 7e e8 eb 17 49 8b 47 18 48 8d 50 e8 49 8d + RSP: 0000:ffffc9000097bd88 EFLAGS: 00010082 + RAX: ffffffffffffffe8 RBX: ffff888454cd9f90 RCX: 0000000000000000 + RDX: 0000000000000000 RSI: 0000000000000003 RDI: ffff888454cd9f90 + RBP: ffffc9000097bdd0 R08: 0000000000000000 R09: ffffc9000097bdd0 + R10: 0000000000000000 R11: 0000000000000001 R12: ffff888454cd9f98 + R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000003 + FS: 0000000000000000(0000) GS:ffff88846fd00000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + CR2: 0000000000000000 CR3: 000000044c19e002 CR4: 0000000000760ee0 + DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 + DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 + PKRU: 55555554 + Call Trace: + __wake_up_common_lock+0x7a/0xc0 + destroy_prefetch_work+0x5a/0x60 [mlx5_ib] + mlx5_ib_prefetch_mr_work+0x64/0x80 [mlx5_ib] + process_one_work+0x15b/0x360 + worker_thread+0x49/0x3d0 + kthread+0xf5/0x130 + ? rescuer_thread+0x310/0x310 + ? kthread_bind+0x10/0x10 + ret_from_fork+0x1f/0x30 + +Fixes: de5ed007a03d ("IB/mlx5: Fix implicit ODP race") +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20200521072504.567406-1-leon@kernel.org +Signed-off-by: Maor Gottlieb +Signed-off-by: Leon Romanovsky +Signed-off-by: Jason Gunthorpe +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/mlx5/mr.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c +index 6fa0a83c19de..9a1747a97fb6 100644 +--- a/drivers/infiniband/hw/mlx5/mr.c ++++ b/drivers/infiniband/hw/mlx5/mr.c +@@ -1319,6 +1319,7 @@ struct ib_mr *mlx5_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, + + if (is_odp_mr(mr)) { + to_ib_umem_odp(mr->umem)->private = mr; ++ init_waitqueue_head(&mr->q_deferred_work); + atomic_set(&mr->num_deferred_work, 0); + err = xa_err(xa_store(&dev->odp_mkeys, + mlx5_base_mkey(mr->mmkey.key), &mr->mmkey, +-- +2.25.1 + diff --git a/queue-5.6/rdma-pvrdma-fix-missing-pci-disable-in-pvrdma_pci_pr.patch b/queue-5.6/rdma-pvrdma-fix-missing-pci-disable-in-pvrdma_pci_pr.patch new file mode 100644 index 00000000000..c4ed628435c --- /dev/null +++ b/queue-5.6/rdma-pvrdma-fix-missing-pci-disable-in-pvrdma_pci_pr.patch @@ -0,0 +1,41 @@ +From d1c06c55173f7b1dd7604e88faa78ef5b6880c35 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 22 May 2020 22:04:57 -0500 +Subject: RDMA/pvrdma: Fix missing pci disable in pvrdma_pci_probe() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Qiushi Wu + +[ Upstream commit db857e6ae548f0f4f4a0f63fffeeedf3cca21f9d ] + +In function pvrdma_pci_probe(), pdev was not disabled in one error +path. Thus replace the jump target “err_free_device” by +"err_disable_pdev". + +Fixes: 29c8d9eba550 ("IB: Add vmw_pvrdma driver") +Link: https://lore.kernel.org/r/20200523030457.16160-1-wu000273@umn.edu +Signed-off-by: Qiushi Wu +Signed-off-by: Jason Gunthorpe +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c +index e580ae9cc55a..780fd2dfc07e 100644 +--- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c ++++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c +@@ -829,7 +829,7 @@ static int pvrdma_pci_probe(struct pci_dev *pdev, + !(pci_resource_flags(pdev, 1) & IORESOURCE_MEM)) { + dev_err(&pdev->dev, "PCI BAR region not MMIO\n"); + ret = -ENOMEM; +- goto err_free_device; ++ goto err_disable_pdev; + } + + ret = pci_request_regions(pdev, DRV_NAME); +-- +2.25.1 + diff --git a/queue-5.6/revert-block-end-bio-with-blk_sts_again-in-case-of-n.patch b/queue-5.6/revert-block-end-bio-with-blk_sts_again-in-case-of-n.patch new file mode 100644 index 00000000000..b825f0206de --- /dev/null +++ b/queue-5.6/revert-block-end-bio-with-blk_sts_again-in-case-of-n.patch @@ -0,0 +1,50 @@ +From f2a5e37a0d717a3071674b0a9fb5fedf52ec332a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 28 May 2020 13:19:29 -0600 +Subject: Revert "block: end bio with BLK_STS_AGAIN in case of non-mq devs and + REQ_NOWAIT" + +From: Jens Axboe + +[ Upstream commit b0beb28097fa04177b3769f4bb7a0d0d9c4ae76e ] + +This reverts commit c58c1f83436b501d45d4050fd1296d71a9760bcb. + +io_uring does do the right thing for this case, and we're still returning +-EAGAIN to userspace for the cases we don't support. Revert this change +to avoid doing endless spins of resubmits. + +Cc: stable@vger.kernel.org # v5.6 +Reported-by: Bijan Mottahedeh +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + block/blk-core.c | 11 ++++------- + 1 file changed, 4 insertions(+), 7 deletions(-) + +diff --git a/block/blk-core.c b/block/blk-core.c +index 60dc9552ef8d..92232907605c 100644 +--- a/block/blk-core.c ++++ b/block/blk-core.c +@@ -885,14 +885,11 @@ generic_make_request_checks(struct bio *bio) + } + + /* +- * Non-mq queues do not honor REQ_NOWAIT, so complete a bio +- * with BLK_STS_AGAIN status in order to catch -EAGAIN and +- * to give a chance to the caller to repeat request gracefully. ++ * For a REQ_NOWAIT based request, return -EOPNOTSUPP ++ * if queue is not a request based queue. + */ +- if ((bio->bi_opf & REQ_NOWAIT) && !queue_is_mq(q)) { +- status = BLK_STS_AGAIN; +- goto end_io; +- } ++ if ((bio->bi_opf & REQ_NOWAIT) && !queue_is_mq(q)) ++ goto not_supported; + + if (should_fail_bio(bio)) + goto end_io; +-- +2.25.1 + diff --git a/queue-5.6/series b/queue-5.6/series index 7a12b53182d..4d8279a5128 100644 --- a/queue-5.6/series +++ b/queue-5.6/series @@ -81,3 +81,59 @@ cifs-fix-null-pointer-check-in-cifs_read.patch csky-fixup-raw_copy_from_user.patch samples-bpf-fix-build-error.patch drivers-net-hamradio-fix-suspicious-rcu-usage-warnin.patch +input-usbtouchscreen-add-support-for-bonxeon-tp.patch +input-i8042-add-thinkpad-s230u-to-i8042-nomux-list.patch +input-evdev-call-input_flush_device-on-release-not-f.patch +input-xpad-add-custom-init-packet-for-xbox-one-s-con.patch +input-dlink-dir685-touchkeys-fix-a-typo-in-driver-na.patch +gpio-mvebu-fix-probing-for-chips-without-pwm.patch +input-i8042-add-thinkpad-s230u-to-i8042-reset-list.patch +input-synaptics-rmi4-really-fix-attn_data-use-after-.patch +input-synaptics-rmi4-fix-error-return-code-in-rmi_dr.patch +arm-8970-1-decompressor-increase-tag-size.patch +arm-uaccess-consolidate-uaccess-asm-to-asm-uaccess-a.patch +arm-uaccess-integrate-uaccess_save-and-uaccess_resto.patch +arm-uaccess-fix-dacr-mismatch-with-nested-exceptions.patch +gpio-exar-fix-bad-handling-for-ida_simple_get-error-.patch +arm64-dts-mt8173-fix-vcodec-enc-clock.patch +soc-mediatek-cmdq-return-send-msg-error-code.patch +gpu-drm-ingenic-fix-bogus-crtc_atomic_check-callback.patch +gpu-drm-ingenic-fix-opaque-pointer-casted-to-wrong-t.patch +ib-qib-call-kobject_put-when-kobject_init_and_add-fa.patch +arm-dts-imx6q-bx50v3-set-display-interface-clock-par.patch +arm-dts-bcm2835-rpi-zero-w-fix-led-polarity.patch +arm-dts-bcm-hr2-fix-ppi-interrupt-types.patch +arm-dts-mmp3-use-the-mmp3-compatible-string-for-cloc.patch +arm-dts-mmp3-dell-ariel-fix-the-spi-devices.patch +arm-dts-mmp3-drop-usb-nop-xceiv-from-hsic-phy.patch +rdma-mlx5-fix-null-pointer-dereference-in-destroy_pr.patch +mmc-block-fix-use-after-free-issue-for-rpmb.patch +gpio-pxa-fix-return-value-of-pxa_gpio_probe.patch +gpio-bcm-kona-fix-return-value-of-bcm_kona_gpio_prob.patch +rdma-pvrdma-fix-missing-pci-disable-in-pvrdma_pci_pr.patch +alsa-hwdep-fix-a-left-shifting-1-by-31-ub-bug.patch +alsa-hda-realtek-add-a-model-for-thinkpad-t570-witho.patch +alsa-usb-audio-mixer-volume-quirk-for-ess-technology.patch +exec-always-set-cap_ambient-in-cap_bprm_set_creds.patch +clk-qcom-gcc-fix-parent-for-gpll0_out_even.patch +alsa-usb-audio-quirks-for-gigabyte-trx40-aorus-maste.patch +alsa-hda-realtek-add-new-codec-supported-for-alc287.patch +libceph-ignore-pool-overlay-and-cache-logic-on-redir.patch +ceph-flush-release-queue-when-handling-caps-for-unkn.patch +rdma-core-fix-double-destruction-of-uobject.patch +drm-amd-display-drop-cursor-position-check-in-atomic.patch +drm-amd-display-split-program-front-end-part-that-oc.patch +drm-amd-display-indicate-dsc-updates-explicitly.patch +drm-amd-display-added-locking-for-atomic-update-stre.patch +drm-amd-display-use-cursor-locking-to-prevent-flip-d.patch +drm-amd-display-defer-cursor-lock-until-after-vupdat.patch +drm-amd-display-fix-potential-integer-wraparound-res.patch +ib-ipoib-fix-double-free-of-skb-in-case-of-multicast.patch +mm-thp-stop-leaking-unreleased-file-pages.patch +mm-remove-vm_bug_on-pageslab-from-page_mapcount.patch +fs-binfmt_elf.c-allocate-initialized-memory-in-fill_.patch +include-asm-generic-topology.h-guard-cpumask_of_node.patch +revert-block-end-bio-with-blk_sts_again-in-case-of-n.patch +gpio-fix-locking-open-drain-irq-lines.patch +iommu-fix-reference-count-leak-in-iommu_group_alloc.patch +parisc-fix-kernel-panic-in-mem_init.patch diff --git a/queue-5.6/soc-mediatek-cmdq-return-send-msg-error-code.patch b/queue-5.6/soc-mediatek-cmdq-return-send-msg-error-code.patch new file mode 100644 index 00000000000..23921a7f130 --- /dev/null +++ b/queue-5.6/soc-mediatek-cmdq-return-send-msg-error-code.patch @@ -0,0 +1,40 @@ +From b829ec0764d07e50cb2ec3b31e5edc7d1354eac7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 8 Mar 2020 18:52:47 +0800 +Subject: soc: mediatek: cmdq: return send msg error code + +From: Dennis YC Hsieh + +[ Upstream commit 34c4e4072603ff5c174df73b973896abb76cbb51 ] + +Return error code to client if send message fail, +so that client has chance to error handling. + +Fixes: 576f1b4bc802 ("soc: mediatek: Add Mediatek CMDQ helper") +Signed-off-by: Dennis YC Hsieh +Reviewed-by: CK Hu +Link: https://lore.kernel.org/r/1583664775-19382-6-git-send-email-dennis-yc.hsieh@mediatek.com +Signed-off-by: Matthias Brugger +Signed-off-by: Sasha Levin +--- + drivers/soc/mediatek/mtk-cmdq-helper.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c b/drivers/soc/mediatek/mtk-cmdq-helper.c +index db37144ae98c..87ee9f767b7a 100644 +--- a/drivers/soc/mediatek/mtk-cmdq-helper.c ++++ b/drivers/soc/mediatek/mtk-cmdq-helper.c +@@ -351,7 +351,9 @@ int cmdq_pkt_flush_async(struct cmdq_pkt *pkt, cmdq_async_flush_cb cb, + spin_unlock_irqrestore(&client->lock, flags); + } + +- mbox_send_message(client->chan, pkt); ++ err = mbox_send_message(client->chan, pkt); ++ if (err < 0) ++ return err; + /* We can send next packet immediately, so just call txdone. */ + mbox_client_txdone(client->chan, 0); + +-- +2.25.1 +