--- /dev/null
+From 5d28ba5f8a0cfa3a874fa96c33731b8fcd141b3a Mon Sep 17 00:00:00 2001
+From: Frank van der Linden <fllinden@amazon.com>
+Date: Thu, 27 Aug 2020 23:40:12 +0000
+Subject: arm64: vdso32: make vdso32 install conditional
+
+From: Frank van der Linden <fllinden@amazon.com>
+
+commit 5d28ba5f8a0cfa3a874fa96c33731b8fcd141b3a upstream.
+
+vdso32 should only be installed if CONFIG_COMPAT_VDSO is enabled,
+since it's not even supposed to be compiled otherwise, and arm64
+builds without a 32bit crosscompiler will fail.
+
+Fixes: 8d75785a8142 ("ARM64: vdso32: Install vdso32 from vdso_install")
+Signed-off-by: Frank van der Linden <fllinden@amazon.com>
+Cc: stable@vger.kernel.org [5.4+]
+Link: https://lore.kernel.org/r/20200827234012.19757-1-fllinden@amazon.com
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm64/Makefile | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/arch/arm64/Makefile
++++ b/arch/arm64/Makefile
+@@ -158,7 +158,8 @@ zinstall install:
+ PHONY += vdso_install
+ vdso_install:
+ $(Q)$(MAKE) $(build)=arch/arm64/kernel/vdso $@
+- $(Q)$(MAKE) $(build)=arch/arm64/kernel/vdso32 $@
++ $(if $(CONFIG_COMPAT_VDSO), \
++ $(Q)$(MAKE) $(build)=arch/arm64/kernel/vdso32 $@)
+
+ # We use MRPROPER_FILES and CLEAN_FILES now
+ archclean:
--- /dev/null
+From c195d66a8a75c60515819b101975f38b7ec6577f Mon Sep 17 00:00:00 2001
+From: Herbert Xu <herbert@gondor.apana.org.au>
+Date: Thu, 27 Aug 2020 17:14:36 +1000
+Subject: crypto: af_alg - Work around empty control messages without MSG_MORE
+
+From: Herbert Xu <herbert@gondor.apana.org.au>
+
+commit c195d66a8a75c60515819b101975f38b7ec6577f upstream.
+
+The iwd daemon uses libell which sets up the skcipher operation with
+two separate control messages. As the first control message is sent
+without MSG_MORE, it is interpreted as an empty request.
+
+While libell should be fixed to use MSG_MORE where appropriate, this
+patch works around the bug in the kernel so that existing binaries
+continue to work.
+
+We will print a warning however.
+
+A separate issue is that the new kernel code no longer allows the
+control message to be sent twice within the same request. This
+restriction is obviously incompatible with what iwd was doing (first
+setting an IV and then sending the real control message). This
+patch changes the kernel so that this is explicitly allowed.
+
+Reported-by: Caleb Jorden <caljorden@hotmail.com>
+Fixes: f3c802a1f300 ("crypto: algif_aead - Only wake up when...")
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ crypto/af_alg.c | 13 ++++++++++---
+ 1 file changed, 10 insertions(+), 3 deletions(-)
+
+--- a/crypto/af_alg.c
++++ b/crypto/af_alg.c
+@@ -16,6 +16,7 @@
+ #include <linux/module.h>
+ #include <linux/net.h>
+ #include <linux/rwsem.h>
++#include <linux/sched.h>
+ #include <linux/sched/signal.h>
+ #include <linux/security.h>
+
+@@ -847,9 +848,15 @@ int af_alg_sendmsg(struct socket *sock,
+ }
+
+ lock_sock(sk);
+- if (ctx->init && (init || !ctx->more)) {
+- err = -EINVAL;
+- goto unlock;
++ if (ctx->init && !ctx->more) {
++ if (ctx->used) {
++ err = -EINVAL;
++ goto unlock;
++ }
++
++ pr_info_once(
++ "%s sent an empty control message without MSG_MORE.\n",
++ current->comm);
+ }
+ ctx->init = true;
+
--- /dev/null
+From c15e1bdda4365a5f17cdadf22bf1c1df13884a9e Mon Sep 17 00:00:00 2001
+From: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Date: Fri, 21 Aug 2020 13:53:42 +0300
+Subject: device property: Fix the secondary firmware node handling in set_primary_fwnode()
+
+From: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+
+commit c15e1bdda4365a5f17cdadf22bf1c1df13884a9e upstream.
+
+When the primary firmware node pointer is removed from a
+device (set to NULL) the secondary firmware node pointer,
+when it exists, is made the primary node for the device.
+However, the secondary firmware node pointer of the original
+primary firmware node is never cleared (set to NULL).
+
+To avoid situation where the secondary firmware node pointer
+is pointing to a non-existing object, clearing it properly
+when the primary node is removed from a device in
+set_primary_fwnode().
+
+Fixes: 97badf873ab6 ("device property: Make it possible to use secondary firmware nodes")
+Cc: All applicable <stable@vger.kernel.org>
+Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/base/core.c | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+--- a/drivers/base/core.c
++++ b/drivers/base/core.c
+@@ -3988,9 +3988,9 @@ static inline bool fwnode_is_primary(str
+ */
+ void set_primary_fwnode(struct device *dev, struct fwnode_handle *fwnode)
+ {
+- if (fwnode) {
+- struct fwnode_handle *fn = dev->fwnode;
++ struct fwnode_handle *fn = dev->fwnode;
+
++ if (fwnode) {
+ if (fwnode_is_primary(fn))
+ fn = fn->secondary;
+
+@@ -4000,8 +4000,12 @@ void set_primary_fwnode(struct device *d
+ }
+ dev->fwnode = fwnode;
+ } else {
+- dev->fwnode = fwnode_is_primary(dev->fwnode) ?
+- dev->fwnode->secondary : NULL;
++ if (fwnode_is_primary(fn)) {
++ dev->fwnode = fn->secondary;
++ fn->secondary = NULL;
++ } else {
++ dev->fwnode = NULL;
++ }
+ }
+ }
+ EXPORT_SYMBOL_GPL(set_primary_fwnode);
--- /dev/null
+From 69d9f4278d0f9d24607645f10e5ac5c59c77a4ac Mon Sep 17 00:00:00 2001
+From: Alexander Monakov <amonakov@ispras.ru>
+Date: Tue, 4 Aug 2020 23:13:13 +0300
+Subject: drm/amd/display: use correct scale for actual_brightness
+
+From: Alexander Monakov <amonakov@ispras.ru>
+
+commit 69d9f4278d0f9d24607645f10e5ac5c59c77a4ac upstream.
+
+Documentation for sysfs backlight level interface requires that
+values in both 'brightness' and 'actual_brightness' files are
+interpreted to be in range from 0 to the value given in the
+'max_brightness' file.
+
+With amdgpu, max_brightness gives 255, and values written by the user
+into 'brightness' are internally rescaled to a wider range. However,
+reading from 'actual_brightness' gives the raw register value without
+inverse rescaling. This causes issues for various userspace tools such
+as PowerTop and systemd that expect the value to be in the correct
+range.
+
+Introduce a helper to retrieve internal backlight range. Use it to
+reimplement 'convert_brightness' as 'convert_brightness_from_user' and
+introduce 'convert_brightness_to_user'.
+
+Bug: https://bugzilla.kernel.org/show_bug.cgi?id=203905
+Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1242
+Cc: Alex Deucher <alexander.deucher@amd.com>
+Cc: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Alexander Monakov <amonakov@ispras.ru>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 81 ++++++++++------------
+ 1 file changed, 40 insertions(+), 41 deletions(-)
+
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -2882,51 +2882,50 @@ static int set_backlight_via_aux(struct
+ return rc ? 0 : 1;
+ }
+
+-static u32 convert_brightness(const struct amdgpu_dm_backlight_caps *caps,
+- const uint32_t user_brightness)
++static int get_brightness_range(const struct amdgpu_dm_backlight_caps *caps,
++ unsigned *min, unsigned *max)
+ {
+- u32 min, max, conversion_pace;
+- u32 brightness = user_brightness;
+-
+ if (!caps)
+- goto out;
++ return 0;
+
+- if (!caps->aux_support) {
+- max = caps->max_input_signal;
+- min = caps->min_input_signal;
+- /*
+- * The brightness input is in the range 0-255
+- * It needs to be rescaled to be between the
+- * requested min and max input signal
+- * It also needs to be scaled up by 0x101 to
+- * match the DC interface which has a range of
+- * 0 to 0xffff
+- */
+- conversion_pace = 0x101;
+- brightness =
+- user_brightness
+- * conversion_pace
+- * (max - min)
+- / AMDGPU_MAX_BL_LEVEL
+- + min * conversion_pace;
++ if (caps->aux_support) {
++ // Firmware limits are in nits, DC API wants millinits.
++ *max = 1000 * caps->aux_max_input_signal;
++ *min = 1000 * caps->aux_min_input_signal;
+ } else {
+- /* TODO
+- * We are doing a linear interpolation here, which is OK but
+- * does not provide the optimal result. We probably want
+- * something close to the Perceptual Quantizer (PQ) curve.
+- */
+- max = caps->aux_max_input_signal;
+- min = caps->aux_min_input_signal;
+-
+- brightness = (AMDGPU_MAX_BL_LEVEL - user_brightness) * min
+- + user_brightness * max;
+- // Multiple the value by 1000 since we use millinits
+- brightness *= 1000;
+- brightness = DIV_ROUND_CLOSEST(brightness, AMDGPU_MAX_BL_LEVEL);
++ // Firmware limits are 8-bit, PWM control is 16-bit.
++ *max = 0x101 * caps->max_input_signal;
++ *min = 0x101 * caps->min_input_signal;
+ }
++ return 1;
++}
++
++static u32 convert_brightness_from_user(const struct amdgpu_dm_backlight_caps *caps,
++ uint32_t brightness)
++{
++ unsigned min, max;
++
++ if (!get_brightness_range(caps, &min, &max))
++ return brightness;
++
++ // Rescale 0..255 to min..max
++ return min + DIV_ROUND_CLOSEST((max - min) * brightness,
++ AMDGPU_MAX_BL_LEVEL);
++}
++
++static u32 convert_brightness_to_user(const struct amdgpu_dm_backlight_caps *caps,
++ uint32_t brightness)
++{
++ unsigned min, max;
++
++ if (!get_brightness_range(caps, &min, &max))
++ return brightness;
+
+-out:
+- return brightness;
++ if (brightness < min)
++ return 0;
++ // Rescale min..max to 0..255
++ return DIV_ROUND_CLOSEST(AMDGPU_MAX_BL_LEVEL * (brightness - min),
++ max - min);
+ }
+
+ static int amdgpu_dm_backlight_update_status(struct backlight_device *bd)
+@@ -2942,7 +2941,7 @@ static int amdgpu_dm_backlight_update_st
+
+ link = (struct dc_link *)dm->backlight_link;
+
+- brightness = convert_brightness(&caps, bd->props.brightness);
++ brightness = convert_brightness_from_user(&caps, bd->props.brightness);
+ // Change brightness based on AUX property
+ if (caps.aux_support)
+ return set_backlight_via_aux(link, brightness);
+@@ -2959,7 +2958,7 @@ static int amdgpu_dm_backlight_get_brigh
+
+ if (ret == DC_ERROR_UNEXPECTED)
+ return bd->props.brightness;
+- return ret;
++ return convert_brightness_to_user(&dm->backlight_caps, ret);
+ }
+
+ static const struct backlight_ops amdgpu_dm_backlight_ops = {
--- /dev/null
+From 28e628645333b7e581c4a7b04d958e4804ea10fe Mon Sep 17 00:00:00 2001
+From: Evan Quan <evan.quan@amd.com>
+Date: Tue, 25 Aug 2020 10:35:11 +0800
+Subject: drm/amd/pm: correct the thermal alert temperature limit settings
+
+From: Evan Quan <evan.quan@amd.com>
+
+commit 28e628645333b7e581c4a7b04d958e4804ea10fe upstream.
+
+Do the maths in celsius degree. This can fix the issues caused
+by the changes below:
+
+drm/amd/pm: correct Vega20 swctf limit setting
+drm/amd/pm: correct Vega12 swctf limit setting
+drm/amd/pm: correct Vega10 swctf limit setting
+
+Signed-off-by: Evan Quan <evan.quan@amd.com>
+Reviewed-by: Kenneth Feng <kenneth.feng@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.c | 15 +++++++--------
+ drivers/gpu/drm/amd/powerplay/hwmgr/vega12_thermal.c | 15 +++++++--------
+ drivers/gpu/drm/amd/powerplay/hwmgr/vega20_thermal.c | 15 +++++++--------
+ 3 files changed, 21 insertions(+), 24 deletions(-)
+
+--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.c
++++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.c
+@@ -367,14 +367,13 @@ static int vega10_thermal_set_temperatur
+ (struct phm_ppt_v2_information *)(hwmgr->pptable);
+ struct phm_tdp_table *tdp_table = pp_table_info->tdp_table;
+ struct amdgpu_device *adev = hwmgr->adev;
+- int low = VEGA10_THERMAL_MINIMUM_ALERT_TEMP *
+- PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
+- int high = VEGA10_THERMAL_MAXIMUM_ALERT_TEMP *
+- PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
++ int low = VEGA10_THERMAL_MINIMUM_ALERT_TEMP;
++ int high = VEGA10_THERMAL_MAXIMUM_ALERT_TEMP;
+ uint32_t val;
+
+- if (low < range->min)
+- low = range->min;
++ /* compare them in unit celsius degree */
++ if (low < range->min / PP_TEMPERATURE_UNITS_PER_CENTIGRADES)
++ low = range->min / PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
+ if (high > tdp_table->usSoftwareShutdownTemp)
+ high = tdp_table->usSoftwareShutdownTemp;
+
+@@ -385,8 +384,8 @@ static int vega10_thermal_set_temperatur
+
+ val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, MAX_IH_CREDIT, 5);
+ val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_IH_HW_ENA, 1);
+- val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTH, (high / PP_TEMPERATURE_UNITS_PER_CENTIGRADES));
+- val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTL, (low / PP_TEMPERATURE_UNITS_PER_CENTIGRADES));
++ val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTH, high);
++ val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTL, low);
+ val &= (~THM_THERMAL_INT_CTRL__THERM_TRIGGER_MASK_MASK) &
+ (~THM_THERMAL_INT_CTRL__THERM_INTH_MASK_MASK) &
+ (~THM_THERMAL_INT_CTRL__THERM_INTL_MASK_MASK);
+--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_thermal.c
++++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_thermal.c
+@@ -173,14 +173,13 @@ static int vega12_thermal_set_temperatur
+ struct phm_ppt_v3_information *pptable_information =
+ (struct phm_ppt_v3_information *)hwmgr->pptable;
+ struct amdgpu_device *adev = hwmgr->adev;
+- int low = VEGA12_THERMAL_MINIMUM_ALERT_TEMP *
+- PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
+- int high = VEGA12_THERMAL_MAXIMUM_ALERT_TEMP *
+- PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
++ int low = VEGA12_THERMAL_MINIMUM_ALERT_TEMP;
++ int high = VEGA12_THERMAL_MAXIMUM_ALERT_TEMP;
+ uint32_t val;
+
+- if (low < range->min)
+- low = range->min;
++ /* compare them in unit celsius degree */
++ if (low < range->min / PP_TEMPERATURE_UNITS_PER_CENTIGRADES)
++ low = range->min / PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
+ if (high > pptable_information->us_software_shutdown_temp)
+ high = pptable_information->us_software_shutdown_temp;
+
+@@ -191,8 +190,8 @@ static int vega12_thermal_set_temperatur
+
+ val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, MAX_IH_CREDIT, 5);
+ val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_IH_HW_ENA, 1);
+- val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTH, (high / PP_TEMPERATURE_UNITS_PER_CENTIGRADES));
+- val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTL, (low / PP_TEMPERATURE_UNITS_PER_CENTIGRADES));
++ val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTH, high);
++ val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTL, low);
+ val = val & (~THM_THERMAL_INT_CTRL__THERM_TRIGGER_MASK_MASK);
+
+ WREG32_SOC15(THM, 0, mmTHM_THERMAL_INT_CTRL, val);
+--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_thermal.c
++++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_thermal.c
+@@ -243,14 +243,13 @@ static int vega20_thermal_set_temperatur
+ struct phm_ppt_v3_information *pptable_information =
+ (struct phm_ppt_v3_information *)hwmgr->pptable;
+ struct amdgpu_device *adev = hwmgr->adev;
+- int low = VEGA20_THERMAL_MINIMUM_ALERT_TEMP *
+- PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
+- int high = VEGA20_THERMAL_MAXIMUM_ALERT_TEMP *
+- PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
++ int low = VEGA20_THERMAL_MINIMUM_ALERT_TEMP;
++ int high = VEGA20_THERMAL_MAXIMUM_ALERT_TEMP;
+ uint32_t val;
+
+- if (low < range->min)
+- low = range->min;
++ /* compare them in unit celsius degree */
++ if (low < range->min / PP_TEMPERATURE_UNITS_PER_CENTIGRADES)
++ low = range->min / PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
+ if (high > pptable_information->us_software_shutdown_temp)
+ high = pptable_information->us_software_shutdown_temp;
+
+@@ -261,8 +260,8 @@ static int vega20_thermal_set_temperatur
+
+ val = CGS_REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, MAX_IH_CREDIT, 5);
+ val = CGS_REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_IH_HW_ENA, 1);
+- val = CGS_REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTH, (high / PP_TEMPERATURE_UNITS_PER_CENTIGRADES));
+- val = CGS_REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTL, (low / PP_TEMPERATURE_UNITS_PER_CENTIGRADES));
++ val = CGS_REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTH, high);
++ val = CGS_REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTL, low);
+ val = val & (~THM_THERMAL_INT_CTRL__THERM_TRIGGER_MASK_MASK);
+
+ WREG32_SOC15(THM, 0, mmTHM_THERMAL_INT_CTRL, val);
--- /dev/null
+From b05d71b51078fc428c6b72582126d9d75d3c1f4c Mon Sep 17 00:00:00 2001
+From: Evan Quan <evan.quan@amd.com>
+Date: Fri, 21 Aug 2020 12:05:03 +0800
+Subject: drm/amd/pm: correct Vega10 swctf limit setting
+
+From: Evan Quan <evan.quan@amd.com>
+
+commit b05d71b51078fc428c6b72582126d9d75d3c1f4c upstream.
+
+Correct the Vega10 thermal swctf limit.
+
+Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1267
+
+Signed-off-by: Evan Quan <evan.quan@amd.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.c
++++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.c
+@@ -363,6 +363,9 @@ int vega10_thermal_get_temperature(struc
+ static int vega10_thermal_set_temperature_range(struct pp_hwmgr *hwmgr,
+ struct PP_TemperatureRange *range)
+ {
++ struct phm_ppt_v2_information *pp_table_info =
++ (struct phm_ppt_v2_information *)(hwmgr->pptable);
++ struct phm_tdp_table *tdp_table = pp_table_info->tdp_table;
+ struct amdgpu_device *adev = hwmgr->adev;
+ int low = VEGA10_THERMAL_MINIMUM_ALERT_TEMP *
+ PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
+@@ -372,8 +375,8 @@ static int vega10_thermal_set_temperatur
+
+ if (low < range->min)
+ low = range->min;
+- if (high > range->max)
+- high = range->max;
++ if (high > tdp_table->usSoftwareShutdownTemp)
++ high = tdp_table->usSoftwareShutdownTemp;
+
+ if (low > high)
+ return -EINVAL;
--- /dev/null
+From e0ffd340249699ad27a6c91abdfa3e89f7823941 Mon Sep 17 00:00:00 2001
+From: Evan Quan <evan.quan@amd.com>
+Date: Fri, 21 Aug 2020 12:18:58 +0800
+Subject: drm/amd/pm: correct Vega12 swctf limit setting
+
+From: Evan Quan <evan.quan@amd.com>
+
+commit e0ffd340249699ad27a6c91abdfa3e89f7823941 upstream.
+
+Correct the Vega12 thermal swctf limit.
+
+Signed-off-by: Evan Quan <evan.quan@amd.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/amd/powerplay/hwmgr/vega12_thermal.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_thermal.c
++++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_thermal.c
+@@ -170,6 +170,8 @@ int vega12_thermal_get_temperature(struc
+ static int vega12_thermal_set_temperature_range(struct pp_hwmgr *hwmgr,
+ struct PP_TemperatureRange *range)
+ {
++ struct phm_ppt_v3_information *pptable_information =
++ (struct phm_ppt_v3_information *)hwmgr->pptable;
+ struct amdgpu_device *adev = hwmgr->adev;
+ int low = VEGA12_THERMAL_MINIMUM_ALERT_TEMP *
+ PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
+@@ -179,8 +181,8 @@ static int vega12_thermal_set_temperatur
+
+ if (low < range->min)
+ low = range->min;
+- if (high > range->max)
+- high = range->max;
++ if (high > pptable_information->us_software_shutdown_temp)
++ high = pptable_information->us_software_shutdown_temp;
+
+ if (low > high)
+ return -EINVAL;
--- /dev/null
+From 9b51c4b2ba31396f3894ccc7df8bdf067243e9f5 Mon Sep 17 00:00:00 2001
+From: Evan Quan <evan.quan@amd.com>
+Date: Fri, 21 Aug 2020 12:21:30 +0800
+Subject: drm/amd/pm: correct Vega20 swctf limit setting
+
+From: Evan Quan <evan.quan@amd.com>
+
+commit 9b51c4b2ba31396f3894ccc7df8bdf067243e9f5 upstream.
+
+Correct the Vega20 thermal swctf limit.
+
+Signed-off-by: Evan Quan <evan.quan@amd.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/amd/powerplay/hwmgr/vega20_thermal.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_thermal.c
++++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_thermal.c
+@@ -240,6 +240,8 @@ int vega20_thermal_get_temperature(struc
+ static int vega20_thermal_set_temperature_range(struct pp_hwmgr *hwmgr,
+ struct PP_TemperatureRange *range)
+ {
++ struct phm_ppt_v3_information *pptable_information =
++ (struct phm_ppt_v3_information *)hwmgr->pptable;
+ struct amdgpu_device *adev = hwmgr->adev;
+ int low = VEGA20_THERMAL_MINIMUM_ALERT_TEMP *
+ PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
+@@ -249,8 +251,8 @@ static int vega20_thermal_set_temperatur
+
+ if (low < range->min)
+ low = range->min;
+- if (high > range->max)
+- high = range->max;
++ if (high > pptable_information->us_software_shutdown_temp)
++ high = pptable_information->us_software_shutdown_temp;
+
+ if (low > high)
+ return -EINVAL;
--- /dev/null
+From e2bf3723db563457c0abe4eaeedac25bbbbd1d76 Mon Sep 17 00:00:00 2001
+From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Date: Fri, 14 Aug 2020 11:49:13 -0400
+Subject: drm/amd/powerplay: Fix hardmins not being sent to SMU for RV
+
+From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+
+commit e2bf3723db563457c0abe4eaeedac25bbbbd1d76 upstream.
+
+[Why]
+DC uses these to raise the voltage as needed for higher dispclk/dppclk
+and to ensure that we have enough bandwidth to drive the displays.
+
+There's a bug preventing these from actuially sending messages since
+it's checking the actual clock (which is 0) instead of the incoming
+clock (which shouldn't be 0) when deciding to send the hardmin.
+
+[How]
+Check the clocks != 0 instead of the actual clocks.
+
+Fixes: 9ed9203c3ee7 ("drm/amd/powerplay: rv dal-pplib interface refactor powerplay part")
+Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+Reviewed-by: Evan Quan <evan.quan@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c | 9 +++------
+ 1 file changed, 3 insertions(+), 6 deletions(-)
+
+--- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c
++++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c
+@@ -204,8 +204,7 @@ static int smu10_set_min_deep_sleep_dcef
+ {
+ struct smu10_hwmgr *smu10_data = (struct smu10_hwmgr *)(hwmgr->backend);
+
+- if (smu10_data->need_min_deep_sleep_dcefclk &&
+- smu10_data->deep_sleep_dcefclk != clock) {
++ if (clock && smu10_data->deep_sleep_dcefclk != clock) {
+ smu10_data->deep_sleep_dcefclk = clock;
+ smum_send_msg_to_smc_with_parameter(hwmgr,
+ PPSMC_MSG_SetMinDeepSleepDcefclk,
+@@ -219,8 +218,7 @@ static int smu10_set_hard_min_dcefclk_by
+ {
+ struct smu10_hwmgr *smu10_data = (struct smu10_hwmgr *)(hwmgr->backend);
+
+- if (smu10_data->dcf_actual_hard_min_freq &&
+- smu10_data->dcf_actual_hard_min_freq != clock) {
++ if (clock && smu10_data->dcf_actual_hard_min_freq != clock) {
+ smu10_data->dcf_actual_hard_min_freq = clock;
+ smum_send_msg_to_smc_with_parameter(hwmgr,
+ PPSMC_MSG_SetHardMinDcefclkByFreq,
+@@ -234,8 +232,7 @@ static int smu10_set_hard_min_fclk_by_fr
+ {
+ struct smu10_hwmgr *smu10_data = (struct smu10_hwmgr *)(hwmgr->backend);
+
+- if (smu10_data->f_actual_hard_min_freq &&
+- smu10_data->f_actual_hard_min_freq != clock) {
++ if (clock && smu10_data->f_actual_hard_min_freq != clock) {
+ smu10_data->f_actual_hard_min_freq = clock;
+ smum_send_msg_to_smc_with_parameter(hwmgr,
+ PPSMC_MSG_SetHardMinFclkByFreq,
--- /dev/null
+From b5b97cab55eb71daba3283c8b1d2cce456d511a1 Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexander.deucher@amd.com>
+Date: Tue, 25 Aug 2020 11:43:45 -0400
+Subject: drm/amdgpu: Fix buffer overflow in INFO ioctl
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+commit b5b97cab55eb71daba3283c8b1d2cce456d511a1 upstream.
+
+The values for "se_num" and "sh_num" come from the user in the ioctl.
+They can be in the 0-255 range but if they're more than
+AMDGPU_GFX_MAX_SE (4) or AMDGPU_GFX_MAX_SH_PER_SE (2) then it results in
+an out of bounds read.
+
+Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
+Acked-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+@@ -663,8 +663,12 @@ static int amdgpu_info_ioctl(struct drm_
+ * in the bitfields */
+ if (se_num == AMDGPU_INFO_MMR_SE_INDEX_MASK)
+ se_num = 0xffffffff;
++ else if (se_num >= AMDGPU_GFX_MAX_SE)
++ return -EINVAL;
+ if (sh_num == AMDGPU_INFO_MMR_SH_INDEX_MASK)
+ sh_num = 0xffffffff;
++ else if (sh_num >= AMDGPU_GFX_MAX_SH_PER_SE)
++ return -EINVAL;
+
+ if (info->read_mmr_reg.count > 128)
+ return -EINVAL;
--- /dev/null
+From de7a1b0b8753e1b0000084f0e339ffab295d27ef Mon Sep 17 00:00:00 2001
+From: Jiansong Chen <Jiansong.Chen@amd.com>
+Date: Mon, 24 Aug 2020 18:44:09 +0800
+Subject: drm/amdgpu/gfx10: refine mgcg setting
+
+From: Jiansong Chen <Jiansong.Chen@amd.com>
+
+commit de7a1b0b8753e1b0000084f0e339ffab295d27ef upstream.
+
+1. enable ENABLE_CGTS_LEGACY to fix specviewperf11 random hang.
+2. remove obsolete RLC_CGTT_SCLK_OVERRIDE workaround.
+
+Signed-off-by: Jiansong Chen <Jiansong.Chen@amd.com>
+Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+--- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
+@@ -6854,10 +6854,8 @@ static void gfx_v10_0_update_medium_grai
+ def = data = RREG32_SOC15(GC, 0, mmRLC_CGTT_MGCG_OVERRIDE);
+ data &= ~(RLC_CGTT_MGCG_OVERRIDE__GRBM_CGTT_SCLK_OVERRIDE_MASK |
+ RLC_CGTT_MGCG_OVERRIDE__GFXIP_MGCG_OVERRIDE_MASK |
+- RLC_CGTT_MGCG_OVERRIDE__GFXIP_MGLS_OVERRIDE_MASK);
+-
+- /* only for Vega10 & Raven1 */
+- data |= RLC_CGTT_MGCG_OVERRIDE__RLC_CGTT_SCLK_OVERRIDE_MASK;
++ RLC_CGTT_MGCG_OVERRIDE__GFXIP_MGLS_OVERRIDE_MASK |
++ RLC_CGTT_MGCG_OVERRIDE__ENABLE_CGTS_LEGACY_MASK);
+
+ if (def != data)
+ WREG32_SOC15(GC, 0, mmRLC_CGTT_MGCG_OVERRIDE, data);
--- /dev/null
+From 88fee1c9007a38c19f2c558dc0ab1ddb4c323dc5 Mon Sep 17 00:00:00 2001
+From: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
+Date: Fri, 14 Aug 2020 13:01:40 -0400
+Subject: drm/dp_mst: Don't return error code when crtc is null
+
+From: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
+
+commit 88fee1c9007a38c19f2c558dc0ab1ddb4c323dc5 upstream.
+
+[Why]
+In certain cases the crtc can be NULL and returning -EINVAL causes
+atomic check to fail when it shouln't. This leads to valid
+configurations failing because atomic check fails.
+
+[How]
+Don't early return if crtc is null
+
+Signed-off-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
+Reviewed-by: Lyude Paul <lyude@redhat.com>
+[added stable cc]
+Signed-off-by: Lyude Paul <lyude@redhat.com>
+Fixes: 8ec046716ca8 ("drm/dp_mst: Add helper to trigger modeset on affected DSC MST CRTCs")
+Cc: <stable@vger.kernel.org> # v5.6+
+Link: https://patchwork.freedesktop.org/patch/msgid/20200814170140.24917-1-Bhawanpreet.Lakha@amd.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/drm_dp_mst_topology.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/drm_dp_mst_topology.c
++++ b/drivers/gpu/drm/drm_dp_mst_topology.c
+@@ -4993,8 +4993,8 @@ int drm_dp_mst_add_affected_dsc_crtcs(st
+
+ crtc = conn_state->crtc;
+
+- if (WARN_ON(!crtc))
+- return -EINVAL;
++ if (!crtc)
++ continue;
+
+ if (!drm_dp_mst_dsc_aux_for_port(pos->port))
+ continue;
--- /dev/null
+From 2c5bf028ef34745e7b3fe768f9c9355ecc7df101 Mon Sep 17 00:00:00 2001
+From: Christian Gmeiner <christian.gmeiner@gmail.com>
+Date: Sun, 23 Aug 2020 21:09:22 +0200
+Subject: drm/etnaviv: fix external abort seen on GC600 rev 0x19
+
+From: Christian Gmeiner <christian.gmeiner@gmail.com>
+
+commit 2c5bf028ef34745e7b3fe768f9c9355ecc7df101 upstream.
+
+It looks like that this GPU core triggers an abort when
+reading VIVS_HI_CHIP_PRODUCT_ID and/or VIVS_HI_CHIP_ECO_ID.
+
+I looked at different versions of Vivante's kernel driver and did
+not found anything about this issue or what feature flag can be
+used. So go the simplest route and do not read these two registers
+on the affected GPU core.
+
+Signed-off-by: Christian Gmeiner <christian.gmeiner@gmail.com>
+Reported-by: Josua Mayer <josua.mayer@jm0.eu>
+Fixes: 815e45bbd4d3 ("drm/etnaviv: determine product, customer and eco id")
+Cc: stable@vger.kernel.org
+Tested-by: Josua Mayer <josua.mayer@jm0.eu>
+Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
++++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
+@@ -337,9 +337,16 @@ static void etnaviv_hw_identify(struct e
+
+ gpu->identity.model = gpu_read(gpu, VIVS_HI_CHIP_MODEL);
+ gpu->identity.revision = gpu_read(gpu, VIVS_HI_CHIP_REV);
+- gpu->identity.product_id = gpu_read(gpu, VIVS_HI_CHIP_PRODUCT_ID);
+ gpu->identity.customer_id = gpu_read(gpu, VIVS_HI_CHIP_CUSTOMER_ID);
+- gpu->identity.eco_id = gpu_read(gpu, VIVS_HI_CHIP_ECO_ID);
++
++ /*
++ * Reading these two registers on GC600 rev 0x19 result in a
++ * unhandled fault: external abort on non-linefetch
++ */
++ if (!etnaviv_is_model_rev(gpu, GC600, 0x19)) {
++ gpu->identity.product_id = gpu_read(gpu, VIVS_HI_CHIP_PRODUCT_ID);
++ gpu->identity.eco_id = gpu_read(gpu, VIVS_HI_CHIP_ECO_ID);
++ }
+
+ /*
+ * !!!! HACK ALERT !!!!
--- /dev/null
+From e5f10d6385cda083037915c12b130887c8831d2b Mon Sep 17 00:00:00 2001
+From: Mika Kuoppala <mika.kuoppala@linux.intel.com>
+Date: Mon, 17 Aug 2020 22:59:26 +0300
+Subject: drm/i915: Fix cmd parser desc matching with masks
+
+From: Mika Kuoppala <mika.kuoppala@linux.intel.com>
+
+commit e5f10d6385cda083037915c12b130887c8831d2b upstream.
+
+Our variety of defined gpu commands have the actual
+command id field and possibly length and flags applied.
+
+We did start to apply the mask during initialization of
+the cmd descriptors but forgot to also apply it on comparisons.
+
+Fix comparisons in order to properly deny access with
+associated commands.
+
+v2: fix lri with correct mask (Chris)
+
+References: 926abff21a8f ("drm/i915/cmdparser: Ignore Length operands during command matching")
+Reported-by: Nicolai Stange <nstange@suse.de>
+Cc: stable@vger.kernel.org # v5.4+
+Cc: Miroslav Benes <mbenes@suse.cz>
+Cc: Takashi Iwai <tiwai@suse.de>
+Cc: Tyler Hicks <tyhicks@canonical.com>
+Cc: Jon Bloomfield <jon.bloomfield@intel.com>
+Cc: Chris Wilson <chris.p.wilson@intel.com>
+Signed-off-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
+Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
+Link: https://patchwork.freedesktop.org/patch/msgid/20200817195926.12671-1-mika.kuoppala@linux.intel.com
+(cherry picked from commit 3b4efa148da36f158cce3f662e831af2834b8e0f)
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/i915/i915_cmd_parser.c | 14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+--- a/drivers/gpu/drm/i915/i915_cmd_parser.c
++++ b/drivers/gpu/drm/i915/i915_cmd_parser.c
+@@ -1204,6 +1204,12 @@ static u32 *copy_batch(struct drm_i915_g
+ return dst;
+ }
+
++static inline bool cmd_desc_is(const struct drm_i915_cmd_descriptor * const desc,
++ const u32 cmd)
++{
++ return desc->cmd.value == (cmd & desc->cmd.mask);
++}
++
+ static bool check_cmd(const struct intel_engine_cs *engine,
+ const struct drm_i915_cmd_descriptor *desc,
+ const u32 *cmd, u32 length)
+@@ -1242,19 +1248,19 @@ static bool check_cmd(const struct intel
+ * allowed mask/value pair given in the whitelist entry.
+ */
+ if (reg->mask) {
+- if (desc->cmd.value == MI_LOAD_REGISTER_MEM) {
++ if (cmd_desc_is(desc, MI_LOAD_REGISTER_MEM)) {
+ DRM_DEBUG("CMD: Rejected LRM to masked register 0x%08X\n",
+ reg_addr);
+ return false;
+ }
+
+- if (desc->cmd.value == MI_LOAD_REGISTER_REG) {
++ if (cmd_desc_is(desc, MI_LOAD_REGISTER_REG)) {
+ DRM_DEBUG("CMD: Rejected LRR to masked register 0x%08X\n",
+ reg_addr);
+ return false;
+ }
+
+- if (desc->cmd.value == MI_LOAD_REGISTER_IMM(1) &&
++ if (cmd_desc_is(desc, MI_LOAD_REGISTER_IMM(1)) &&
+ (offset + 2 > length ||
+ (cmd[offset + 1] & reg->mask) != reg->value)) {
+ DRM_DEBUG("CMD: Rejected LRI to masked register 0x%08X\n",
+@@ -1478,7 +1484,7 @@ int intel_engine_cmd_parser(struct intel
+ break;
+ }
+
+- if (desc->cmd.value == MI_BATCH_BUFFER_START) {
++ if (cmd_desc_is(desc, MI_BATCH_BUFFER_START)) {
+ ret = check_bbstart(cmd, offset, length, batch_length,
+ batch_addr, shadow_addr,
+ jump_whitelist);
--- /dev/null
+From 77ef38574beb3e0b414db48e9c0f04633df68ba6 Mon Sep 17 00:00:00 2001
+From: Daniel Vetter <daniel.vetter@intel.com>
+Date: Fri, 14 Aug 2020 11:38:42 +0200
+Subject: drm/modeset-lock: Take the modeset BKL for legacy drivers
+
+From: Daniel Vetter <daniel.vetter@intel.com>
+
+commit 77ef38574beb3e0b414db48e9c0f04633df68ba6 upstream.
+
+This fell off in the conversion in
+
+commit 9bcaa3fe58ab7559e71df798bcff6e0795158695
+Author: Michal Orzel <michalorzel.eng@gmail.com>
+Date: Tue Apr 28 19:10:04 2020 +0200
+
+ drm: Replace drm_modeset_lock/unlock_all with DRM_MODESET_LOCK_ALL_* helpers
+
+but it's caught by the drm_warn_on_modeset_not_all_locked() that the
+legacy modeset code uses. Since this is the bkl and it's unclear
+what's all protected, play it safe and grab it again for legacy
+drivers.
+
+Unfortunately this means we need to sprinkle a few more #includes
+around.
+
+Also we need to add the drm_device as a parameter to the _END macro.
+
+Finally remove the mute_lock() from setcrtc, since that's now done by
+the macro.
+
+Cc: Alex Deucher <alexdeucher@gmail.com>
+References: https://gitlab.freedesktop.org/drm/amd/-/issues/1224
+Fixes: 9bcaa3fe58ab ("drm: Replace drm_modeset_lock/unlock_all with DRM_MODESET_LOCK_ALL_* helpers")
+Cc: Michal Orzel <michalorzel.eng@gmail.com>
+Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
+Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
+Cc: Maxime Ripard <mripard@kernel.org>
+Cc: Thomas Zimmermann <tzimmermann@suse.de>
+Cc: David Airlie <airlied@linux.ie>
+Cc: Daniel Vetter <daniel@ffwll.ch>
+Cc: dri-devel@lists.freedesktop.org
+Cc: <stable@vger.kernel.org> # v5.8+
+Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20200814093842.3048472-1-daniel.vetter@ffwll.ch
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/drm_atomic_helper.c | 7 ++++---
+ drivers/gpu/drm/drm_color_mgmt.c | 2 +-
+ drivers/gpu/drm/drm_crtc.c | 4 +---
+ drivers/gpu/drm/drm_mode_object.c | 4 ++--
+ drivers/gpu/drm/drm_plane.c | 2 +-
+ include/drm/drm_modeset_lock.h | 9 +++++++--
+ 6 files changed, 16 insertions(+), 12 deletions(-)
+
+--- a/drivers/gpu/drm/drm_atomic_helper.c
++++ b/drivers/gpu/drm/drm_atomic_helper.c
+@@ -34,6 +34,7 @@
+ #include <drm/drm_bridge.h>
+ #include <drm/drm_damage_helper.h>
+ #include <drm/drm_device.h>
++#include <drm/drm_drv.h>
+ #include <drm/drm_plane_helper.h>
+ #include <drm/drm_print.h>
+ #include <drm/drm_self_refresh_helper.h>
+@@ -3105,7 +3106,7 @@ void drm_atomic_helper_shutdown(struct d
+ if (ret)
+ DRM_ERROR("Disabling all crtc's during unload failed with %i\n", ret);
+
+- DRM_MODESET_LOCK_ALL_END(ctx, ret);
++ DRM_MODESET_LOCK_ALL_END(dev, ctx, ret);
+ }
+ EXPORT_SYMBOL(drm_atomic_helper_shutdown);
+
+@@ -3245,7 +3246,7 @@ struct drm_atomic_state *drm_atomic_help
+ }
+
+ unlock:
+- DRM_MODESET_LOCK_ALL_END(ctx, err);
++ DRM_MODESET_LOCK_ALL_END(dev, ctx, err);
+ if (err)
+ return ERR_PTR(err);
+
+@@ -3326,7 +3327,7 @@ int drm_atomic_helper_resume(struct drm_
+
+ err = drm_atomic_helper_commit_duplicated_state(state, &ctx);
+
+- DRM_MODESET_LOCK_ALL_END(ctx, err);
++ DRM_MODESET_LOCK_ALL_END(dev, ctx, err);
+ drm_atomic_state_put(state);
+
+ return err;
+--- a/drivers/gpu/drm/drm_color_mgmt.c
++++ b/drivers/gpu/drm/drm_color_mgmt.c
+@@ -294,7 +294,7 @@ int drm_mode_gamma_set_ioctl(struct drm_
+ crtc->gamma_size, &ctx);
+
+ out:
+- DRM_MODESET_LOCK_ALL_END(ctx, ret);
++ DRM_MODESET_LOCK_ALL_END(dev, ctx, ret);
+ return ret;
+
+ }
+--- a/drivers/gpu/drm/drm_crtc.c
++++ b/drivers/gpu/drm/drm_crtc.c
+@@ -561,7 +561,6 @@ int drm_mode_setcrtc(struct drm_device *
+ if (crtc_req->mode_valid && !drm_lease_held(file_priv, plane->base.id))
+ return -EACCES;
+
+- mutex_lock(&crtc->dev->mode_config.mutex);
+ DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx,
+ DRM_MODESET_ACQUIRE_INTERRUPTIBLE, ret);
+
+@@ -728,8 +727,7 @@ out:
+ fb = NULL;
+ mode = NULL;
+
+- DRM_MODESET_LOCK_ALL_END(ctx, ret);
+- mutex_unlock(&crtc->dev->mode_config.mutex);
++ DRM_MODESET_LOCK_ALL_END(dev, ctx, ret);
+
+ return ret;
+ }
+--- a/drivers/gpu/drm/drm_mode_object.c
++++ b/drivers/gpu/drm/drm_mode_object.c
+@@ -428,7 +428,7 @@ int drm_mode_obj_get_properties_ioctl(st
+ out_unref:
+ drm_mode_object_put(obj);
+ out:
+- DRM_MODESET_LOCK_ALL_END(ctx, ret);
++ DRM_MODESET_LOCK_ALL_END(dev, ctx, ret);
+ return ret;
+ }
+
+@@ -470,7 +470,7 @@ static int set_property_legacy(struct dr
+ break;
+ }
+ drm_property_change_valid_put(prop, ref);
+- DRM_MODESET_LOCK_ALL_END(ctx, ret);
++ DRM_MODESET_LOCK_ALL_END(dev, ctx, ret);
+
+ return ret;
+ }
+--- a/drivers/gpu/drm/drm_plane.c
++++ b/drivers/gpu/drm/drm_plane.c
+@@ -791,7 +791,7 @@ static int setplane_internal(struct drm_
+ crtc_x, crtc_y, crtc_w, crtc_h,
+ src_x, src_y, src_w, src_h, &ctx);
+
+- DRM_MODESET_LOCK_ALL_END(ctx, ret);
++ DRM_MODESET_LOCK_ALL_END(plane->dev, ctx, ret);
+
+ return ret;
+ }
+--- a/include/drm/drm_modeset_lock.h
++++ b/include/drm/drm_modeset_lock.h
+@@ -164,6 +164,8 @@ int drm_modeset_lock_all_ctx(struct drm_
+ * is 0, so no error checking is necessary
+ */
+ #define DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, flags, ret) \
++ if (!drm_drv_uses_atomic_modeset(dev)) \
++ mutex_lock(&dev->mode_config.mutex); \
+ drm_modeset_acquire_init(&ctx, flags); \
+ modeset_lock_retry: \
+ ret = drm_modeset_lock_all_ctx(dev, &ctx); \
+@@ -172,6 +174,7 @@ modeset_lock_retry: \
+
+ /**
+ * DRM_MODESET_LOCK_ALL_END - Helper to release and cleanup modeset locks
++ * @dev: drm device
+ * @ctx: local modeset acquire context, will be dereferenced
+ * @ret: local ret/err/etc variable to track error status
+ *
+@@ -188,7 +191,7 @@ modeset_lock_retry: \
+ * to that failure. In both of these cases the code between BEGIN/END will not
+ * be run, so the failure will reflect the inability to grab the locks.
+ */
+-#define DRM_MODESET_LOCK_ALL_END(ctx, ret) \
++#define DRM_MODESET_LOCK_ALL_END(dev, ctx, ret) \
+ modeset_lock_fail: \
+ if (ret == -EDEADLK) { \
+ ret = drm_modeset_backoff(&ctx); \
+@@ -196,6 +199,8 @@ modeset_lock_fail: \
+ goto modeset_lock_retry; \
+ } \
+ drm_modeset_drop_locks(&ctx); \
+- drm_modeset_acquire_fini(&ctx);
++ drm_modeset_acquire_fini(&ctx); \
++ if (!drm_drv_uses_atomic_modeset(dev)) \
++ mutex_unlock(&dev->mode_config.mutex);
+
+ #endif /* DRM_MODESET_LOCK_H_ */
--- /dev/null
+From 784a0830377d0761834e385975bc46861fea9fa0 Mon Sep 17 00:00:00 2001
+From: Thomas Gleixner <tglx@linutronix.de>
+Date: Sun, 30 Aug 2020 19:07:53 +0200
+Subject: genirq/matrix: Deal with the sillyness of for_each_cpu() on UP
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+commit 784a0830377d0761834e385975bc46861fea9fa0 upstream.
+
+Most of the CPU mask operations behave the same way, but for_each_cpu() and
+it's variants ignore the cpumask argument and claim that CPU0 is always in
+the mask. This is historical, inconsistent and annoying behaviour.
+
+The matrix allocator uses for_each_cpu() and can be called on UP with an
+empty cpumask. The calling code does not expect that this succeeds but
+until commit e027fffff799 ("x86/irq: Unbreak interrupt affinity setting")
+this went unnoticed. That commit added a WARN_ON() to catch cases which
+move an interrupt from one vector to another on the same CPU. The warning
+triggers on UP.
+
+Add a check for the cpumask being empty to prevent this.
+
+Fixes: 2f75d9e1c905 ("genirq: Implement bitmap matrix allocator")
+Reported-by: kernel test robot <rong.a.chen@intel.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/irq/matrix.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/kernel/irq/matrix.c
++++ b/kernel/irq/matrix.c
+@@ -380,6 +380,13 @@ int irq_matrix_alloc(struct irq_matrix *
+ unsigned int cpu, bit;
+ struct cpumap *cm;
+
++ /*
++ * Not required in theory, but matrix_find_best_cpu() uses
++ * for_each_cpu() which ignores the cpumask on UP .
++ */
++ if (cpumask_empty(msk))
++ return -EINVAL;
++
+ cpu = matrix_find_best_cpu(m, msk);
+ if (cpu == UINT_MAX)
+ return -ENOSPC;
--- /dev/null
+From e579076ac0a3bebb440fab101aef3c42c9f4c709 Mon Sep 17 00:00:00 2001
+From: qiuguorui1 <qiuguorui1@huawei.com>
+Date: Thu, 20 Aug 2020 11:16:29 +0800
+Subject: irqchip/stm32-exti: Avoid losing interrupts due to clearing pending bits by mistake
+
+From: qiuguorui1 <qiuguorui1@huawei.com>
+
+commit e579076ac0a3bebb440fab101aef3c42c9f4c709 upstream.
+
+In the current code, when the eoi callback of the exti clears the pending
+bit of the current interrupt, it will first read the values of fpr and
+rpr, then logically OR the corresponding bit of the interrupt number,
+and finally write back to fpr and rpr.
+
+We found through experiments that if two exti interrupts,
+we call them int1/int2, arrive almost at the same time. in our scenario,
+the time difference is 30 microseconds, assuming int1 is triggered first.
+
+there will be an extreme scenario: both int's pending bit are set to 1,
+the irq handle of int1 is executed first, and eoi handle is then executed,
+at this moment, all pending bits are cleared, but the int 2 has not
+finally been reported to the cpu yet, which eventually lost int2.
+
+According to stm32's TRM description about rpr and fpr: Writing a 1 to this
+bit will trigger a rising edge event on event x, Writing 0 has no
+effect.
+
+Therefore, when clearing the pending bit, we only need to clear the
+pending bit of the irq.
+
+Fixes: 927abfc4461e7 ("irqchip/stm32: Add stm32mp1 support with hierarchy domain")
+Signed-off-by: qiuguorui1 <qiuguorui1@huawei.com>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Cc: stable@vger.kernel.org # v4.18+
+Link: https://lore.kernel.org/r/20200820031629.15582-1-qiuguorui1@huawei.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/irqchip/irq-stm32-exti.c | 14 ++++++++++++--
+ 1 file changed, 12 insertions(+), 2 deletions(-)
+
+--- a/drivers/irqchip/irq-stm32-exti.c
++++ b/drivers/irqchip/irq-stm32-exti.c
+@@ -431,6 +431,16 @@ static void stm32_irq_ack(struct irq_dat
+ irq_gc_unlock(gc);
+ }
+
++/* directly set the target bit without reading first. */
++static inline void stm32_exti_write_bit(struct irq_data *d, u32 reg)
++{
++ struct stm32_exti_chip_data *chip_data = irq_data_get_irq_chip_data(d);
++ void __iomem *base = chip_data->host_data->base;
++ u32 val = BIT(d->hwirq % IRQS_PER_BANK);
++
++ writel_relaxed(val, base + reg);
++}
++
+ static inline u32 stm32_exti_set_bit(struct irq_data *d, u32 reg)
+ {
+ struct stm32_exti_chip_data *chip_data = irq_data_get_irq_chip_data(d);
+@@ -464,9 +474,9 @@ static void stm32_exti_h_eoi(struct irq_
+
+ raw_spin_lock(&chip_data->rlock);
+
+- stm32_exti_set_bit(d, stm32_bank->rpr_ofst);
++ stm32_exti_write_bit(d, stm32_bank->rpr_ofst);
+ if (stm32_bank->fpr_ofst != UNDEF_REG)
+- stm32_exti_set_bit(d, stm32_bank->fpr_ofst);
++ stm32_exti_write_bit(d, stm32_bank->fpr_ofst);
+
+ raw_spin_unlock(&chip_data->rlock);
+
--- /dev/null
+From e3eb6e8fba65094328b8dca635d00de74ba75b45 Mon Sep 17 00:00:00 2001
+From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
+Date: Mon, 24 Aug 2020 19:35:31 +0200
+Subject: PM: sleep: core: Fix the handling of pending runtime resume requests
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+commit e3eb6e8fba65094328b8dca635d00de74ba75b45 upstream.
+
+It has been reported that system-wide suspend may be aborted in the
+absence of any wakeup events due to unforseen interactions of it with
+the runtume PM framework.
+
+One failing scenario is when there are multiple devices sharing an
+ACPI power resource and runtime-resume needs to be carried out for
+one of them during system-wide suspend (for example, because it needs
+to be reconfigured before the whole system goes to sleep). In that
+case, the runtime-resume of that device involves turning the ACPI
+power resource "on" which in turn causes runtime-resume requests
+to be queued up for all of the other devices sharing it. Those
+requests go to the runtime PM workqueue which is frozen during
+system-wide suspend, so they are not actually taken care of until
+the resume of the whole system, but the pm_runtime_barrier()
+call in __device_suspend() sees them and triggers system wakeup
+events for them which then cause the system-wide suspend to be
+aborted if wakeup source objects are in active use.
+
+Of course, the logic that leads to triggering those wakeup events is
+questionable in the first place, because clearly there are cases in
+which a pending runtime resume request for a device is not connected
+to any real wakeup events in any way (like the one above). Moreover,
+it is racy, because the device may be resuming already by the time
+the pm_runtime_barrier() runs and so if the driver doesn't take care
+of signaling the wakeup event as appropriate, it will be lost.
+However, if the driver does take care of that, the extra
+pm_wakeup_event() call in the core is redundant.
+
+Accordingly, drop the conditional pm_wakeup_event() call fron
+__device_suspend() and make the latter call pm_runtime_barrier()
+alone. Also modify the comment next to that call to reflect the new
+code and extend it to mention the need to avoid unwanted interactions
+between runtime PM and system-wide device suspend callbacks.
+
+Fixes: 1e2ef05bb8cf8 ("PM: Limit race conditions between runtime PM and system sleep (v2)")
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Reported-by: Utkarsh H Patel <utkarsh.h.patel@intel.com>
+Tested-by: Utkarsh H Patel <utkarsh.h.patel@intel.com>
+Tested-by: Pengfei Xu <pengfei.xu@intel.com>
+Cc: All applicable <stable@vger.kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/base/power/main.c | 16 ++++++++++------
+ 1 file changed, 10 insertions(+), 6 deletions(-)
+
+--- a/drivers/base/power/main.c
++++ b/drivers/base/power/main.c
+@@ -1606,13 +1606,17 @@ static int __device_suspend(struct devic
+ }
+
+ /*
+- * If a device configured to wake up the system from sleep states
+- * has been suspended at run time and there's a resume request pending
+- * for it, this is equivalent to the device signaling wakeup, so the
+- * system suspend operation should be aborted.
++ * Wait for possible runtime PM transitions of the device in progress
++ * to complete and if there's a runtime resume request pending for it,
++ * resume it before proceeding with invoking the system-wide suspend
++ * callbacks for it.
++ *
++ * If the system-wide suspend callbacks below change the configuration
++ * of the device, they must disable runtime PM for it or otherwise
++ * ensure that its runtime-resume callbacks will not be confused by that
++ * change in case they are invoked going forward.
+ */
+- if (pm_runtime_barrier(dev) && device_may_wakeup(dev))
+- pm_wakeup_event(dev, 0);
++ pm_runtime_barrier(dev);
+
+ if (pm_wakeup_pending()) {
+ dev->power.direct_complete = false;
--- /dev/null
+From 4a133eb351ccc275683ad49305d0b04dde903733 Mon Sep 17 00:00:00 2001
+From: Christophe Leroy <christophe.leroy@csgroup.eu>
+Date: Thu, 27 Aug 2020 18:30:27 +0000
+Subject: powerpc/32s: Disable VMAP stack which CONFIG_ADB_PMU
+
+From: Christophe Leroy <christophe.leroy@csgroup.eu>
+
+commit 4a133eb351ccc275683ad49305d0b04dde903733 upstream.
+
+low_sleep_handler() can't restore the context from virtual
+stack because the stack can hardly be accessed with MMU OFF.
+
+For now, disable VMAP stack when CONFIG_ADB_PMU is selected.
+
+Fixes: cd08f109e262 ("powerpc/32s: Enable CONFIG_VMAP_STACK")
+Cc: stable@vger.kernel.org # v5.6+
+Reported-by: Giuseppe Sacco <giuseppe@sguazz.it>
+Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/ec96c15bfa1a7415ab604ee1c98cd45779c08be0.1598553015.git.christophe.leroy@csgroup.eu
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/platforms/Kconfig.cputype | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/powerpc/platforms/Kconfig.cputype
++++ b/arch/powerpc/platforms/Kconfig.cputype
+@@ -36,7 +36,7 @@ config PPC_BOOK3S_6xx
+ select PPC_HAVE_PMU_SUPPORT
+ select PPC_HAVE_KUEP
+ select PPC_HAVE_KUAP
+- select HAVE_ARCH_VMAP_STACK
++ select HAVE_ARCH_VMAP_STACK if !ADB_PMU
+
+ config PPC_BOOK3S_601
+ bool "PowerPC 601"
--- /dev/null
+From b460b512417ae9c8b51a3bdcc09020cd6c60ff69 Mon Sep 17 00:00:00 2001
+From: Alexey Kardashevskiy <aik@ozlabs.ru>
+Date: Tue, 2 Jun 2020 12:56:12 +1000
+Subject: powerpc/perf: Fix crashes with generic_compat_pmu & BHRB
+
+From: Alexey Kardashevskiy <aik@ozlabs.ru>
+
+commit b460b512417ae9c8b51a3bdcc09020cd6c60ff69 upstream.
+
+The bhrb_filter_map ("The Branch History Rolling Buffer") callback is
+only defined in raw CPUs' power_pmu structs. The "architected" CPUs
+use generic_compat_pmu, which does not have this callback, and crashes
+occur if a user tries to enable branch stack for an event.
+
+This add a NULL pointer check for bhrb_filter_map() which behaves as
+if the callback returned an error.
+
+This does not add the same check for config_bhrb() as the only caller
+checks for cpuhw->bhrb_users which remains zero if bhrb_filter_map==0.
+
+Fixes: be80e758d0c2 ("powerpc/perf: Add generic compat mode pmu driver")
+Cc: stable@vger.kernel.org # v5.2+
+Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
+Reviewed-by: Madhavan Srinivasan <maddy@linux.ibm.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20200602025612.62707-1-aik@ozlabs.ru
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/perf/core-book3s.c | 19 ++++++++++++++-----
+ 1 file changed, 14 insertions(+), 5 deletions(-)
+
+--- a/arch/powerpc/perf/core-book3s.c
++++ b/arch/powerpc/perf/core-book3s.c
+@@ -1517,9 +1517,16 @@ nocheck:
+ ret = 0;
+ out:
+ if (has_branch_stack(event)) {
+- power_pmu_bhrb_enable(event);
+- cpuhw->bhrb_filter = ppmu->bhrb_filter_map(
+- event->attr.branch_sample_type);
++ u64 bhrb_filter = -1;
++
++ if (ppmu->bhrb_filter_map)
++ bhrb_filter = ppmu->bhrb_filter_map(
++ event->attr.branch_sample_type);
++
++ if (bhrb_filter != -1) {
++ cpuhw->bhrb_filter = bhrb_filter;
++ power_pmu_bhrb_enable(event);
++ }
+ }
+
+ perf_pmu_enable(event->pmu);
+@@ -1841,7 +1848,6 @@ static int power_pmu_event_init(struct p
+ int n;
+ int err;
+ struct cpu_hw_events *cpuhw;
+- u64 bhrb_filter;
+
+ if (!ppmu)
+ return -ENOENT;
+@@ -1947,7 +1953,10 @@ static int power_pmu_event_init(struct p
+ err = power_check_constraints(cpuhw, events, cflags, n + 1);
+
+ if (has_branch_stack(event)) {
+- bhrb_filter = ppmu->bhrb_filter_map(
++ u64 bhrb_filter = -1;
++
++ if (ppmu->bhrb_filter_map)
++ bhrb_filter = ppmu->bhrb_filter_map(
+ event->attr.branch_sample_type);
+
+ if (bhrb_filter == -1) {
xhci-always-restore-ep_soft_clear_toggle-even-if-ep-reset-failed.patch
io-wq-fix-hang-after-cancelling-pending-hashed-work.patch
kvm-arm64-set-hcr_el2.ptw-to-prevent-at-taking-synchronous-exception.patch
+arm64-vdso32-make-vdso32-install-conditional.patch
+pm-sleep-core-fix-the-handling-of-pending-runtime-resume-requests.patch
+powerpc-32s-disable-vmap-stack-which-config_adb_pmu.patch
+powerpc-perf-fix-crashes-with-generic_compat_pmu-bhrb.patch
+device-property-fix-the-secondary-firmware-node-handling-in-set_primary_fwnode.patch
+crypto-af_alg-work-around-empty-control-messages-without-msg_more.patch
+usbip-implement-a-match-function-to-fix-usbip.patch
+genirq-matrix-deal-with-the-sillyness-of-for_each_cpu-on-up.patch
+irqchip-stm32-exti-avoid-losing-interrupts-due-to-clearing-pending-bits-by-mistake.patch
+x86-irq-unbreak-interrupt-affinity-setting.patch
+x86-hotplug-silence-apic-only-after-all-interrupts-are-migrated.patch
+drm-i915-fix-cmd-parser-desc-matching-with-masks.patch
+drm-etnaviv-fix-external-abort-seen-on-gc600-rev-0x19.patch
+drm-dp_mst-don-t-return-error-code-when-crtc-is-null.patch
+drm-modeset-lock-take-the-modeset-bkl-for-legacy-drivers.patch
+drm-amdgpu-fix-buffer-overflow-in-info-ioctl.patch
+drm-amd-display-use-correct-scale-for-actual_brightness.patch
+drm-amdgpu-gfx10-refine-mgcg-setting.patch
+drm-amd-powerplay-fix-hardmins-not-being-sent-to-smu-for-rv.patch
+drm-amd-pm-correct-vega10-swctf-limit-setting.patch
+drm-amd-pm-correct-vega12-swctf-limit-setting.patch
+drm-amd-pm-correct-vega20-swctf-limit-setting.patch
+drm-amd-pm-correct-the-thermal-alert-temperature-limit-settings.patch
--- /dev/null
+From 7a2f2974f26542b4e7b9b4321edb3cbbf3eeb91a Mon Sep 17 00:00:00 2001
+From: "M. Vefa Bicakci" <m.v.b@runbox.com>
+Date: Mon, 10 Aug 2020 19:00:17 +0300
+Subject: usbip: Implement a match function to fix usbip
+
+From: M. Vefa Bicakci <m.v.b@runbox.com>
+
+commit 7a2f2974f26542b4e7b9b4321edb3cbbf3eeb91a upstream.
+
+Commit 88b7381a939d ("USB: Select better matching USB drivers when
+available") introduced the use of a "match" function to select a
+non-generic/better driver for a particular USB device. This
+unfortunately breaks the operation of usbip in general, as reported in
+the kernel bugzilla with bug 208267 (linked below).
+
+Upon inspecting the aforementioned commit, one can observe that the
+original code in the usb_device_match function used to return 1
+unconditionally, but the aforementioned commit makes the usb_device_match
+function use identifier tables and "match" virtual functions, if either of
+them are available.
+
+Hence, this commit implements a match function for usbip that
+unconditionally returns true to ensure that usbip is functional again.
+
+This change has been verified to restore usbip functionality, with a
+v5.7.y kernel on an up-to-date version of Qubes OS 4.0, which uses
+usbip to redirect USB devices between VMs.
+
+Thanks to Jonathan Dieter for the effort in bisecting this issue down
+to the aforementioned commit.
+
+Fixes: 88b7381a939d ("USB: Select better matching USB drivers when available")
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=208267
+Link: https://bugzilla.redhat.com/show_bug.cgi?id=1856443
+Link: https://github.com/QubesOS/qubes-issues/issues/5905
+Signed-off-by: M. Vefa Bicakci <m.v.b@runbox.com>
+Cc: <stable@vger.kernel.org> # 5.7
+Cc: Valentina Manea <valentina.manea.m@gmail.com>
+Cc: Alan Stern <stern@rowland.harvard.edu>
+Reviewed-by: Bastien Nocera <hadess@hadess.net>
+Reviewed-by: Shuah Khan <skhan@linuxfoundation.org>
+Link: https://lore.kernel.org/r/20200810160017.46002-1-m.v.b@runbox.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/usbip/stub_dev.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/usb/usbip/stub_dev.c
++++ b/drivers/usb/usbip/stub_dev.c
+@@ -461,6 +461,11 @@ static void stub_disconnect(struct usb_d
+ return;
+ }
+
++static bool usbip_match(struct usb_device *udev)
++{
++ return true;
++}
++
+ #ifdef CONFIG_PM
+
+ /* These functions need usb_port_suspend and usb_port_resume,
+@@ -486,6 +491,7 @@ struct usb_device_driver stub_driver = {
+ .name = "usbip-host",
+ .probe = stub_probe,
+ .disconnect = stub_disconnect,
++ .match = usbip_match,
+ #ifdef CONFIG_PM
+ .suspend = stub_suspend,
+ .resume = stub_resume,
--- /dev/null
+From 52d6b926aabc47643cd910c85edb262b7f44c168 Mon Sep 17 00:00:00 2001
+From: Ashok Raj <ashok.raj@intel.com>
+Date: Wed, 26 Aug 2020 21:12:10 -0700
+Subject: x86/hotplug: Silence APIC only after all interrupts are migrated
+
+From: Ashok Raj <ashok.raj@intel.com>
+
+commit 52d6b926aabc47643cd910c85edb262b7f44c168 upstream.
+
+There is a race when taking a CPU offline. Current code looks like this:
+
+native_cpu_disable()
+{
+ ...
+ apic_soft_disable();
+ /*
+ * Any existing set bits for pending interrupt to
+ * this CPU are preserved and will be sent via IPI
+ * to another CPU by fixup_irqs().
+ */
+ cpu_disable_common();
+ {
+ ....
+ /*
+ * Race window happens here. Once local APIC has been
+ * disabled any new interrupts from the device to
+ * the old CPU are lost
+ */
+ fixup_irqs(); // Too late to capture anything in IRR.
+ ...
+ }
+}
+
+The fix is to disable the APIC *after* cpu_disable_common().
+
+Testing was done with a USB NIC that provided a source of frequent
+interrupts. A script migrated interrupts to a specific CPU and
+then took that CPU offline.
+
+Fixes: 60dcaad5736f ("x86/hotplug: Silence APIC and NMI when CPU is dead")
+Reported-by: Evan Green <evgreen@chromium.org>
+Signed-off-by: Ashok Raj <ashok.raj@intel.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Tested-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Tested-by: Evan Green <evgreen@chromium.org>
+Reviewed-by: Evan Green <evgreen@chromium.org>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/lkml/875zdarr4h.fsf@nanos.tec.linutronix.de/
+Link: https://lore.kernel.org/r/1598501530-45821-1-git-send-email-ashok.raj@intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/kernel/smpboot.c | 26 ++++++++++++++++++++------
+ 1 file changed, 20 insertions(+), 6 deletions(-)
+
+--- a/arch/x86/kernel/smpboot.c
++++ b/arch/x86/kernel/smpboot.c
+@@ -1604,14 +1604,28 @@ int native_cpu_disable(void)
+ if (ret)
+ return ret;
+
+- /*
+- * Disable the local APIC. Otherwise IPI broadcasts will reach
+- * it. It still responds normally to INIT, NMI, SMI, and SIPI
+- * messages.
+- */
+- apic_soft_disable();
+ cpu_disable_common();
+
++ /*
++ * Disable the local APIC. Otherwise IPI broadcasts will reach
++ * it. It still responds normally to INIT, NMI, SMI, and SIPI
++ * messages.
++ *
++ * Disabling the APIC must happen after cpu_disable_common()
++ * which invokes fixup_irqs().
++ *
++ * Disabling the APIC preserves already set bits in IRR, but
++ * an interrupt arriving after disabling the local APIC does not
++ * set the corresponding IRR bit.
++ *
++ * fixup_irqs() scans IRR for set bits so it can raise a not
++ * yet handled interrupt on the new destination CPU via an IPI
++ * but obviously it can't do so for IRR bits which are not set.
++ * IOW, interrupts arriving after disabling the local APIC will
++ * be lost.
++ */
++ apic_soft_disable();
++
+ return 0;
+ }
+
--- /dev/null
+From e027fffff799cdd70400c5485b1a54f482255985 Mon Sep 17 00:00:00 2001
+From: Thomas Gleixner <tglx@linutronix.de>
+Date: Wed, 26 Aug 2020 22:21:44 +0200
+Subject: x86/irq: Unbreak interrupt affinity setting
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+commit e027fffff799cdd70400c5485b1a54f482255985 upstream.
+
+Several people reported that 5.8 broke the interrupt affinity setting
+mechanism.
+
+The consolidation of the entry code reused the regular exception entry code
+for device interrupts and changed the way how the vector number is conveyed
+from ptregs->orig_ax to a function argument.
+
+The low level entry uses the hardware error code slot to push the vector
+number onto the stack which is retrieved from there into a function
+argument and the slot on stack is set to -1.
+
+The reason for setting it to -1 is that the error code slot is at the
+position where pt_regs::orig_ax is. A positive value in pt_regs::orig_ax
+indicates that the entry came via a syscall. If it's not set to a negative
+value then a signal delivery on return to userspace would try to restart a
+syscall. But there are other places which rely on pt_regs::orig_ax being a
+valid indicator for syscall entry.
+
+But setting pt_regs::orig_ax to -1 has a nasty side effect vs. the
+interrupt affinity setting mechanism, which was overlooked when this change
+was made.
+
+Moving interrupts on x86 happens in several steps. A new vector on a
+different CPU is allocated and the relevant interrupt source is
+reprogrammed to that. But that's racy and there might be an interrupt
+already in flight to the old vector. So the old vector is preserved until
+the first interrupt arrives on the new vector and the new target CPU. Once
+that happens the old vector is cleaned up, but this cleanup still depends
+on the vector number being stored in pt_regs::orig_ax, which is now -1.
+
+That -1 makes the check for cleanup: pt_regs::orig_ax == new_vector
+always false. As a consequence the interrupt is moved once, but then it
+cannot be moved anymore because the cleanup of the old vector never
+happens.
+
+There would be several ways to convey the vector information to that place
+in the guts of the interrupt handling, but on deeper inspection it turned
+out that this check is pointless and a leftover from the old affinity model
+of X86 which supported multi-CPU affinities. Under this model it was
+possible that an interrupt had an old and a new vector on the same CPU, so
+the vector match was required.
+
+Under the new model the effective affinity of an interrupt is always a
+single CPU from the requested affinity mask. If the affinity mask changes
+then either the interrupt stays on the CPU and on the same vector when that
+CPU is still in the new affinity mask or it is moved to a different CPU, but
+it is never moved to a different vector on the same CPU.
+
+Ergo the cleanup check for the matching vector number is not required and
+can be removed which makes the dependency on pt_regs:orig_ax go away.
+
+The remaining check for new_cpu == smp_processsor_id() is completely
+sufficient. If it matches then the interrupt was successfully migrated and
+the cleanup can proceed.
+
+For paranoia sake add a warning into the vector assignment code to
+validate that the assumption of never moving to a different vector on
+the same CPU holds.
+
+Fixes: 633260fa143 ("x86/irq: Convey vector as argument and not in ptregs")
+Reported-by: Alex bykov <alex.bykov@scylladb.com>
+Reported-by: Avi Kivity <avi@scylladb.com>
+Reported-by: Alexander Graf <graf@amazon.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Tested-by: Alexander Graf <graf@amazon.com>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/87wo1ltaxz.fsf@nanos.tec.linutronix.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/kernel/apic/vector.c | 16 +++++++++-------
+ 1 file changed, 9 insertions(+), 7 deletions(-)
+
+--- a/arch/x86/kernel/apic/vector.c
++++ b/arch/x86/kernel/apic/vector.c
+@@ -161,6 +161,7 @@ static void apic_update_vector(struct ir
+ apicd->move_in_progress = true;
+ apicd->prev_vector = apicd->vector;
+ apicd->prev_cpu = apicd->cpu;
++ WARN_ON_ONCE(apicd->cpu == newcpu);
+ } else {
+ irq_matrix_free(vector_matrix, apicd->cpu, apicd->vector,
+ managed);
+@@ -910,7 +911,7 @@ void send_cleanup_vector(struct irq_cfg
+ __send_cleanup_vector(apicd);
+ }
+
+-static void __irq_complete_move(struct irq_cfg *cfg, unsigned vector)
++void irq_complete_move(struct irq_cfg *cfg)
+ {
+ struct apic_chip_data *apicd;
+
+@@ -918,15 +919,16 @@ static void __irq_complete_move(struct i
+ if (likely(!apicd->move_in_progress))
+ return;
+
+- if (vector == apicd->vector && apicd->cpu == smp_processor_id())
++ /*
++ * If the interrupt arrived on the new target CPU, cleanup the
++ * vector on the old target CPU. A vector check is not required
++ * because an interrupt can never move from one vector to another
++ * on the same CPU.
++ */
++ if (apicd->cpu == smp_processor_id())
+ __send_cleanup_vector(apicd);
+ }
+
+-void irq_complete_move(struct irq_cfg *cfg)
+-{
+- __irq_complete_move(cfg, ~get_irq_regs()->orig_ax);
+-}
+-
+ /*
+ * Called from fixup_irqs() with @desc->lock held and interrupts disabled.
+ */