From: Axel Lin axel.lin@ingics.com
[ Upstream commit 3d681804efcb6e5d8089a433402e19179347d7ae ]
Show proper error code instead of 0.
Signed-off-by: Axel Lin axel.lin@ingics.com Link: https://lore.kernel.org/r/20210512075824.620580-1-axel.lin@ingics.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/regulator/cros-ec-regulator.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/regulator/cros-ec-regulator.c b/drivers/regulator/cros-ec-regulator.c index eb3fc1db4edc..c4754f3cf233 100644 --- a/drivers/regulator/cros-ec-regulator.c +++ b/drivers/regulator/cros-ec-regulator.c @@ -225,8 +225,9 @@ static int cros_ec_regulator_probe(struct platform_device *pdev)
drvdata->dev = devm_regulator_register(dev, &drvdata->desc, &cfg); if (IS_ERR(drvdata->dev)) { + ret = PTR_ERR(drvdata->dev); dev_err(&pdev->dev, "Failed to register regulator: %d\n", ret); - return PTR_ERR(drvdata->dev); + return ret; }
platform_set_drvdata(pdev, drvdata);
From: Dmitry Osipenko digetx@gmail.com
[ Upstream commit 62499a94ce5b9a41047dbadaad885347b1176079 ]
One of previous changes to regulator core causes PMIC regulators to re-probe until supply regulator is registered. Silence noisy error message about the deferred probe.
Signed-off-by: Dmitry Osipenko digetx@gmail.com Link: https://lore.kernel.org/r/20210523224243.13219-3-digetx@gmail.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/regulator/max77620-regulator.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/drivers/regulator/max77620-regulator.c b/drivers/regulator/max77620-regulator.c index 8d9731e4052b..6d0a8c696ecd 100644 --- a/drivers/regulator/max77620-regulator.c +++ b/drivers/regulator/max77620-regulator.c @@ -839,12 +839,10 @@ static int max77620_regulator_probe(struct platform_device *pdev) return ret;
rdev = devm_regulator_register(dev, rdesc, &config); - if (IS_ERR(rdev)) { - ret = PTR_ERR(rdev); - dev_err(dev, "Regulator registration %s failed: %d\n", - rdesc->name, ret); - return ret; - } + if (IS_ERR(rdev)) + return dev_err_probe(dev, PTR_ERR(rdev), + "Regulator registration %s failed\n", + rdesc->name); }
return 0;
On Tue, Jun 15, 2021 at 11:47:53AM -0400, Sasha Levin wrote:
From: Dmitry Osipenko digetx@gmail.com
[ Upstream commit 62499a94ce5b9a41047dbadaad885347b1176079 ]
One of previous changes to regulator core causes PMIC regulators to re-probe until supply regulator is registered. Silence noisy error message about the deferred probe.
This really doesn't look like stable material...
On Tue, Jun 15, 2021 at 04:54:36PM +0100, Mark Brown wrote:
On Tue, Jun 15, 2021 at 11:47:53AM -0400, Sasha Levin wrote:
From: Dmitry Osipenko digetx@gmail.com
[ Upstream commit 62499a94ce5b9a41047dbadaad885347b1176079 ]
One of previous changes to regulator core causes PMIC regulators to re-probe until supply regulator is registered. Silence noisy error message about the deferred probe.
This really doesn't look like stable material...
Not strictly, but we usually take fixes to issues that can confuse users or spam logs.
On Sun, Jun 20, 2021 at 08:55:59AM -0400, Sasha Levin wrote:
On Tue, Jun 15, 2021 at 04:54:36PM +0100, Mark Brown wrote:
On Tue, Jun 15, 2021 at 11:47:53AM -0400, Sasha Levin wrote:
From: Dmitry Osipenko digetx@gmail.com
One of previous changes to regulator core causes PMIC regulators to re-probe until supply regulator is registered. Silence noisy error message about the deferred probe.
This really doesn't look like stable material...
Not strictly, but we usually take fixes to issues that can confuse users or spam logs.
I really don't think this is appropriate (and don't know that it's even relevant without the core change mentioned in the commit log).
On Mon, Jun 21, 2021 at 11:40:42AM +0100, Mark Brown wrote:
On Sun, Jun 20, 2021 at 08:55:59AM -0400, Sasha Levin wrote:
On Tue, Jun 15, 2021 at 04:54:36PM +0100, Mark Brown wrote:
On Tue, Jun 15, 2021 at 11:47:53AM -0400, Sasha Levin wrote:
From: Dmitry Osipenko digetx@gmail.com
One of previous changes to regulator core causes PMIC regulators to re-probe until supply regulator is registered. Silence noisy error message about the deferred probe.
This really doesn't look like stable material...
Not strictly, but we usually take fixes to issues that can confuse users or spam logs.
I really don't think this is appropriate (and don't know that it's even relevant without the core change mentioned in the commit log).
Oh, I misunderstood your previous mail. Now dropped, thanks!
From: Axel Lin axel.lin@ingics.com
[ Upstream commit 0514582a1a5b4ac1a3fd64792826d392d7ae9ddc ]
The valid selectors for bd70528 bucks are 0 ~ 0xf, so the .n_voltages should be 16 (0x10). Use 0x10 to make it consistent with BD70528_LDO_VOLTS. Also remove redundant defines for BD70528_BUCK_VOLTS.
Signed-off-by: Axel Lin axel.lin@ingics.com Acked-by: Matti Vaittinen matti.vaittinen@fi.rohmeurope.com Link: https://lore.kernel.org/r/20210523071045.2168904-1-axel.lin@ingics.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/mfd/rohm-bd70528.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/include/linux/mfd/rohm-bd70528.h b/include/linux/mfd/rohm-bd70528.h index a57af878fd0c..4a5966475a35 100644 --- a/include/linux/mfd/rohm-bd70528.h +++ b/include/linux/mfd/rohm-bd70528.h @@ -26,9 +26,7 @@ struct bd70528_data { struct mutex rtc_timer_lock; };
-#define BD70528_BUCK_VOLTS 17 -#define BD70528_BUCK_VOLTS 17 -#define BD70528_BUCK_VOLTS 17 +#define BD70528_BUCK_VOLTS 0x10 #define BD70528_LDO_VOLTS 0x20
#define BD70528_REG_BUCK1_EN 0x0F
From: Til Jasper Ullrich tju@tju.me
[ Upstream commit c0e0436cb4f6627146acdae8c77828f18db01151 ]
The X1 Carbon Gen 9 uses two fans instead of one like the previous generation. This adds support for the second fan. It has been tested on my X1 Carbon Gen 9 (20XXS00100) and works fine.
Signed-off-by: Til Jasper Ullrich tju@tju.me Link: https://lore.kernel.org/r/20210525150950.14805-1-tju@tju.me Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/platform/x86/thinkpad_acpi.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 61f1c91c62de..3390168ac079 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -8808,6 +8808,7 @@ static const struct tpacpi_quirk fan_quirk_table[] __initconst = { TPACPI_Q_LNV3('N', '2', 'O', TPACPI_FAN_2CTL), /* P1 / X1 Extreme (2nd gen) */ TPACPI_Q_LNV3('N', '2', 'V', TPACPI_FAN_2CTL), /* P1 / X1 Extreme (3nd gen) */ TPACPI_Q_LNV3('N', '3', '0', TPACPI_FAN_2CTL), /* P15 (1st gen) / P15v (1st gen) */ + TPACPI_Q_LNV3('N', '3', '2', TPACPI_FAN_2CTL), /* X1 Carbon (9th gen) */ };
static int __init fan_init(struct ibm_init_struct *iibm)
From: Jack Yu jack.yu@realtek.com
[ Upstream commit 6308c44ed6eeadf65c0a7ba68d609773ed860fbb ]
The power of "LDO2", "MICBIAS1" and "Mic Det Power" were powered off after the DAPM widgets were added, and these powers were set by the JD settings "RT5659_JD_HDA_HEADER" in the probe function. In the codec probe function, these powers were ignored to prevent them controlled by DAPM.
Signed-off-by: Oder Chiou oder_chiou@realtek.com Signed-off-by: Jack Yu jack.yu@realtek.com Message-Id: 15fced51977b458798ca4eebf03dafb9@realtek.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/codecs/rt5659.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-)
diff --git a/sound/soc/codecs/rt5659.c b/sound/soc/codecs/rt5659.c index 91a4ef7f620c..a9b079d56fd6 100644 --- a/sound/soc/codecs/rt5659.c +++ b/sound/soc/codecs/rt5659.c @@ -2433,13 +2433,18 @@ static int set_dmic_power(struct snd_soc_dapm_widget *w, return 0; }
-static const struct snd_soc_dapm_widget rt5659_dapm_widgets[] = { +static const struct snd_soc_dapm_widget rt5659_particular_dapm_widgets[] = { SND_SOC_DAPM_SUPPLY("LDO2", RT5659_PWR_ANLG_3, RT5659_PWR_LDO2_BIT, 0, NULL, 0), - SND_SOC_DAPM_SUPPLY("PLL", RT5659_PWR_ANLG_3, RT5659_PWR_PLL_BIT, 0, - NULL, 0), + SND_SOC_DAPM_SUPPLY("MICBIAS1", RT5659_PWR_ANLG_2, RT5659_PWR_MB1_BIT, + 0, NULL, 0), SND_SOC_DAPM_SUPPLY("Mic Det Power", RT5659_PWR_VOL, RT5659_PWR_MIC_DET_BIT, 0, NULL, 0), +}; + +static const struct snd_soc_dapm_widget rt5659_dapm_widgets[] = { + SND_SOC_DAPM_SUPPLY("PLL", RT5659_PWR_ANLG_3, RT5659_PWR_PLL_BIT, 0, + NULL, 0), SND_SOC_DAPM_SUPPLY("Mono Vref", RT5659_PWR_ANLG_1, RT5659_PWR_VREF3_BIT, 0, NULL, 0),
@@ -2464,8 +2469,6 @@ static const struct snd_soc_dapm_widget rt5659_dapm_widgets[] = { RT5659_ADC_MONO_R_ASRC_SFT, 0, NULL, 0),
/* Input Side */ - SND_SOC_DAPM_SUPPLY("MICBIAS1", RT5659_PWR_ANLG_2, RT5659_PWR_MB1_BIT, - 0, NULL, 0), SND_SOC_DAPM_SUPPLY("MICBIAS2", RT5659_PWR_ANLG_2, RT5659_PWR_MB2_BIT, 0, NULL, 0), SND_SOC_DAPM_SUPPLY("MICBIAS3", RT5659_PWR_ANLG_2, RT5659_PWR_MB3_BIT, @@ -3660,10 +3663,23 @@ static int rt5659_set_bias_level(struct snd_soc_component *component,
static int rt5659_probe(struct snd_soc_component *component) { + struct snd_soc_dapm_context *dapm = + snd_soc_component_get_dapm(component); struct rt5659_priv *rt5659 = snd_soc_component_get_drvdata(component);
rt5659->component = component;
+ switch (rt5659->pdata.jd_src) { + case RT5659_JD_HDA_HEADER: + break; + + default: + snd_soc_dapm_new_controls(dapm, + rt5659_particular_dapm_widgets, + ARRAY_SIZE(rt5659_particular_dapm_widgets)); + break; + } + return 0; }
From: Tiezhu Yang yangtiezhu@loongson.cn
[ Upstream commit aaac9a1bd370338ce372669eb9a6059d16b929aa ]
Use clk_disable_unprepare() in the error path of mtk_phy_init() to fix some resource leaks.
Reported-by: kernel test robot lkp@intel.com Reported-by: Dan Carpenter dan.carpenter@oracle.com Signed-off-by: Tiezhu Yang yangtiezhu@loongson.cn Reviewed-by: Chunfeng Yun chunfeng.yun@mediatek.com Link: https://lore.kernel.org/r/1621420659-15858-1-git-send-email-yangtiezhu@loong... Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/phy/mediatek/phy-mtk-tphy.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c index cdbcc49f7115..731c483a04de 100644 --- a/drivers/phy/mediatek/phy-mtk-tphy.c +++ b/drivers/phy/mediatek/phy-mtk-tphy.c @@ -949,6 +949,8 @@ static int mtk_phy_init(struct phy *phy) break; default: dev_err(tphy->dev, "incompatible PHY type\n"); + clk_disable_unprepare(instance->ref_clk); + clk_disable_unprepare(instance->da_ref_clk); return -EINVAL; }
From: Nicolas Cavallari nicolas.cavallari@green-communications.fr
[ Upstream commit a8437f05384cb472518ec21bf4fffbe8f0a47378 ]
Otherwise, when compiled as module, a WARN_ON is triggered:
WARNING: CPU: 0 PID: 5 at sound/core/init.c:208 snd_card_new+0x310/0x39c [snd] [...] CPU: 0 PID: 5 Comm: kworker/0:0 Not tainted 5.10.39 #1 Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree) Workqueue: events deferred_probe_work_func [<c0111988>] (unwind_backtrace) from [<c010c8ac>] (show_stack+0x10/0x14) [<c010c8ac>] (show_stack) from [<c092784c>] (dump_stack+0xdc/0x104) [<c092784c>] (dump_stack) from [<c0129710>] (__warn+0xd8/0x114) [<c0129710>] (__warn) from [<c0922a48>] (warn_slowpath_fmt+0x5c/0xc4) [<c0922a48>] (warn_slowpath_fmt) from [<bf0496f8>] (snd_card_new+0x310/0x39c [snd]) [<bf0496f8>] (snd_card_new [snd]) from [<bf1d7df8>] (snd_soc_bind_card+0x334/0x9c4 [snd_soc_core]) [<bf1d7df8>] (snd_soc_bind_card [snd_soc_core]) from [<bf1e9cd8>] (devm_snd_soc_register_card+0x30/0x6c [snd_soc_core]) [<bf1e9cd8>] (devm_snd_soc_register_card [snd_soc_core]) from [<bf22d964>] (fsl_asoc_card_probe+0x550/0xcc8 [snd_soc_fsl_asoc_card]) [<bf22d964>] (fsl_asoc_card_probe [snd_soc_fsl_asoc_card]) from [<c060c930>] (platform_drv_probe+0x48/0x98) [...]
Signed-off-by: Nicolas Cavallari nicolas.cavallari@green-communications.fr Acked-by: Shengjiu Wang shengjiu.wang@gmail.com Link: https://lore.kernel.org/r/20210527163409.22049-1-nicolas.cavallari@green-com... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/fsl/fsl-asoc-card.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c index f62f81ceab0d..9dcbe5d5a428 100644 --- a/sound/soc/fsl/fsl-asoc-card.c +++ b/sound/soc/fsl/fsl-asoc-card.c @@ -732,6 +732,7 @@ static int fsl_asoc_card_probe(struct platform_device *pdev) /* Initialize sound card */ priv->pdev = pdev; priv->card.dev = &pdev->dev; + priv->card.owner = THIS_MODULE; ret = snd_soc_of_parse_card_name(&priv->card, "model"); if (ret) { snprintf(priv->name, sizeof(priv->name), "%s-audio",
From: Axel Lin axel.lin@ingics.com
[ Upstream commit 89082179ec5028bcd58c87171e08ada035689542 ]
The .of_map_mode should has below function prototype: unsigned int (*of_map_mode)(unsigned int mode);
Signed-off-by: Axel Lin axel.lin@ingics.com Link: https://lore.kernel.org/r/20210530022109.425054-1-axel.lin@ingics.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/regulator/mt6315-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/regulator/mt6315-regulator.c b/drivers/regulator/mt6315-regulator.c index 9edc34981ee0..6b8be52c3772 100644 --- a/drivers/regulator/mt6315-regulator.c +++ b/drivers/regulator/mt6315-regulator.c @@ -59,7 +59,7 @@ static const struct linear_range mt_volt_range1[] = { REGULATOR_LINEAR_RANGE(0, 0, 0xbf, 6250), };
-static unsigned int mt6315_map_mode(u32 mode) +static unsigned int mt6315_map_mode(unsigned int mode) { switch (mode) { case MT6315_BUCK_MODE_AUTO:
From: ChiYuan Huang cy_huang@richtek.com
[ Upstream commit 46639a5e684edd0b80ae9dff220f193feb356277 ]
- Fix to make regcache value first reading back from HW.
Signed-off-by: ChiYuan Huang cy_huang@richtek.com Link: https://lore.kernel.org/r/1622542155-6373-1-git-send-email-u0084500@gmail.co... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/regulator/rtmv20-regulator.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/regulator/rtmv20-regulator.c b/drivers/regulator/rtmv20-regulator.c index 852fb2596ffd..b37c29c9fbbb 100644 --- a/drivers/regulator/rtmv20-regulator.c +++ b/drivers/regulator/rtmv20-regulator.c @@ -27,6 +27,7 @@ #define RTMV20_REG_LDIRQ 0x30 #define RTMV20_REG_LDSTAT 0x40 #define RTMV20_REG_LDMASK 0x50 +#define RTMV20_MAX_REGS (RTMV20_REG_LDMASK + 1)
#define RTMV20_VID_MASK GENMASK(7, 4) #define RICHTEK_VID 0x80 @@ -275,6 +276,7 @@ static const struct regmap_config rtmv20_regmap_config = { .val_bits = 8, .cache_type = REGCACHE_RBTREE, .max_register = RTMV20_REG_LDMASK, + .num_reg_defaults_raw = RTMV20_MAX_REGS,
.writeable_reg = rtmv20_is_accessible_reg, .readable_reg = rtmv20_is_accessible_reg,
From: Dai Ngo dai.ngo@oracle.com
[ Upstream commit f8849e206ef52b584cd9227255f4724f0cc900bb ]
Currently if __nfs4_proc_set_acl fails with NFS4ERR_BADOWNER it re-enables the idmapper by clearing NFS_CAP_UIDGID_NOMAP before retrying again. The NFS_CAP_UIDGID_NOMAP remains cleared even if the retry fails. This causes problem for subsequent setattr requests for v4 server that does not have idmapping configured.
This patch modifies nfs4_proc_set_acl to detect NFS4ERR_BADOWNER and NFS4ERR_BADNAME and skips the retry, since the kernel isn't involved in encoding the ACEs, and return -EINVAL.
Steps to reproduce the problem:
# mount -o vers=4.1,sec=sys server:/export/test /tmp/mnt # touch /tmp/mnt/file1 # chown 99 /tmp/mnt/file1 # nfs4_setfacl -a A::unknown.user@xyz.com:wrtncy /tmp/mnt/file1 Failed setxattr operation: Invalid argument # chown 99 /tmp/mnt/file1 chown: changing ownership of ‘/tmp/mnt/file1’: Invalid argument # umount /tmp/mnt # mount -o vers=4.1,sec=sys server:/export/test /tmp/mnt # chown 99 /tmp/mnt/file1 #
v2: detect NFS4ERR_BADOWNER and NFS4ERR_BADNAME and skip retry in nfs4_proc_set_acl. Signed-off-by: Dai Ngo dai.ngo@oracle.com Signed-off-by: Trond Myklebust trond.myklebust@hammerspace.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/nfs/nfs4proc.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 0b809cc6ad1d..056d98d1d1a7 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -5940,6 +5940,14 @@ static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen do { err = __nfs4_proc_set_acl(inode, buf, buflen); trace_nfs4_set_acl(inode, err); + if (err == -NFS4ERR_BADOWNER || err == -NFS4ERR_BADNAME) { + /* + * no need to retry since the kernel + * isn't involved in encoding the ACEs. + */ + err = -EINVAL; + break; + } err = nfs4_handle_exception(NFS_SERVER(inode), err, &exception); } while (exception.retry);
From: Mark Pearson markpearson@lenovo.com
[ Upstream commit 19a0aa9b04c5ab9a063b6ceaf7211ee7d9a9d24d ]
More laptops identified where the AMD ACP bridge needs to be blocked or the microphone will not work when connected to HDMI.
Use DMI to block the microphone PCM device for these platforms.
Suggested-by: Gabriel Craciunescu nix.or.die@gmail.com Signed-off-by: Mark Pearson markpearson@lenovo.com Link: https://lore.kernel.org/r/20210531145502.6079-1-markpearson@lenovo.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/amd/renoir/rn-pci-acp3x.c | 35 +++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+)
diff --git a/sound/soc/amd/renoir/rn-pci-acp3x.c b/sound/soc/amd/renoir/rn-pci-acp3x.c index 050a61fe9693..47a4dfd81a46 100644 --- a/sound/soc/amd/renoir/rn-pci-acp3x.c +++ b/sound/soc/amd/renoir/rn-pci-acp3x.c @@ -199,6 +199,41 @@ static const struct dmi_system_id rn_acp_quirk_table[] = { DMI_EXACT_MATCH(DMI_BOARD_NAME, "20NLCTO1WW"), } }, + { + /* Lenovo ThinkPad P14s Gen 1 (20Y1) */ + .matches = { + DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_BOARD_NAME, "20Y1"), + } + }, + { + /* Lenovo ThinkPad T14s Gen1 */ + .matches = { + DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_BOARD_NAME, "20UH"), + } + }, + { + /* Lenovo ThinkPad T14s Gen1 Campus */ + .matches = { + DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_BOARD_NAME, "20UJ"), + } + }, + { + /* Lenovo ThinkPad T14 Gen 1*/ + .matches = { + DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_BOARD_NAME, "20UD"), + } + }, + { + /* Lenovo ThinkPad X13 Gen 1*/ + .matches = { + DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_BOARD_NAME, "20UF"), + } + }, {} };
On Tue, Jun 15, 2021 at 11:48:02AM -0400, Sasha Levin wrote:
From: Mark Pearson markpearson@lenovo.com
[ Upstream commit 19a0aa9b04c5ab9a063b6ceaf7211ee7d9a9d24d ]
More laptops identified where the AMD ACP bridge needs to be blocked or the microphone will not work when connected to HDMI.
Use DMI to block the microphone PCM device for these platforms.
You've backported the fix that reverts this a couple of patches later in the series but might be as well to just not backport either, the end result is the same.
On Tue, Jun 15, 2021 at 04:56:07PM +0100, Mark Brown wrote:
On Tue, Jun 15, 2021 at 11:48:02AM -0400, Sasha Levin wrote:
From: Mark Pearson markpearson@lenovo.com
[ Upstream commit 19a0aa9b04c5ab9a063b6ceaf7211ee7d9a9d24d ]
More laptops identified where the AMD ACP bridge needs to be blocked or the microphone will not work when connected to HDMI.
Use DMI to block the microphone PCM device for these platforms.
You've backported the fix that reverts this a couple of patches later in the series but might be as well to just not backport either, the end result is the same.
Good point, I'll drop it.
From: zpershuai zpershuai@gmail.com
[ Upstream commit f131767eefc47de2f8afb7950cdea78397997d66 ]
In zynq_qspi_probe function, when enable the device clock is done, the return of all the functions should goto the clk_dis_all label.
If num_cs is not right then this should return a negative error code but currently it returns success.
Signed-off-by: zpershuai zpershuai@gmail.com Link: https://lore.kernel.org/r/1622110857-21812-1-git-send-email-zpershuai@gmail.... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/spi/spi-zynq-qspi.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/spi/spi-zynq-qspi.c b/drivers/spi/spi-zynq-qspi.c index 5d8a5ee62fa2..79863c889e18 100644 --- a/drivers/spi/spi-zynq-qspi.c +++ b/drivers/spi/spi-zynq-qspi.c @@ -679,14 +679,14 @@ static int zynq_qspi_probe(struct platform_device *pdev) xqspi->irq = platform_get_irq(pdev, 0); if (xqspi->irq <= 0) { ret = -ENXIO; - goto remove_master; + goto clk_dis_all; } ret = devm_request_irq(&pdev->dev, xqspi->irq, zynq_qspi_irq, 0, pdev->name, xqspi); if (ret != 0) { ret = -ENXIO; dev_err(&pdev->dev, "request_irq failed\n"); - goto remove_master; + goto clk_dis_all; }
ret = of_property_read_u32(np, "num-cs", @@ -694,8 +694,9 @@ static int zynq_qspi_probe(struct platform_device *pdev) if (ret < 0) { ctlr->num_chipselect = 1; } else if (num_cs > ZYNQ_QSPI_MAX_NUM_CS) { + ret = -EINVAL; dev_err(&pdev->dev, "only 2 chip selects are available\n"); - goto remove_master; + goto clk_dis_all; } else { ctlr->num_chipselect = num_cs; }
From: Vincent Guittot vincent.guittot@linaro.org
[ Upstream commit fcf6631f3736985ec89bdd76392d3c7bfb60119f ]
Rounding in PELT calculation happening when entities are attached/detached of a cfs_rq can result into situations where util/runnable_avg is not null but util/runnable_sum is. This is normally not possible so we need to ensure that util/runnable_sum stays synced with util/runnable_avg.
detach_entity_load_avg() is the last place where we don't sync util/runnable_sum with util/runnbale_avg when moving some sched_entities
Signed-off-by: Vincent Guittot vincent.guittot@linaro.org Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Link: https://lkml.kernel.org/r/20210601085832.12626-1-vincent.guittot@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/sched/fair.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index a073a839cd06..a9c4f0370bdc 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -3761,11 +3761,17 @@ static void attach_entity_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *s */ static void detach_entity_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *se) { + /* + * cfs_rq->avg.period_contrib can be used for both cfs_rq and se. + * See ___update_load_avg() for details. + */ + u32 divider = get_pelt_divider(&cfs_rq->avg); + dequeue_load_avg(cfs_rq, se); sub_positive(&cfs_rq->avg.util_avg, se->avg.util_avg); - sub_positive(&cfs_rq->avg.util_sum, se->avg.util_sum); + cfs_rq->avg.util_sum = cfs_rq->avg.util_avg * divider; sub_positive(&cfs_rq->avg.runnable_avg, se->avg.runnable_avg); - sub_positive(&cfs_rq->avg.runnable_sum, se->avg.runnable_sum); + cfs_rq->avg.runnable_sum = cfs_rq->avg.runnable_avg * divider;
add_tg_cfs_propagate(cfs_rq, -se->avg.load_sum);
From: Mark Pearson markpearson@lenovo.com
[ Upstream commit 320232caf1d8febea17312dab4b2dfe02e033520 ]
Unfortunately the previous patch to fix issues using the AMD ACP bridge has the side effect of breaking the dmic in other cases and needs to be reverted.
Removing the changes while we revisit the fix and find something better. Apologies for the churn.
Suggested-by: Gabriel Craciunescu unix.or.die@gmail.com Signed-off-by: Mark Pearson markpearson@lenovo.com Link: https://lore.kernel.org/r/20210602171251.3243-1-markpearson@lenovo.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/amd/renoir/rn-pci-acp3x.c | 35 ----------------------------- 1 file changed, 35 deletions(-)
diff --git a/sound/soc/amd/renoir/rn-pci-acp3x.c b/sound/soc/amd/renoir/rn-pci-acp3x.c index 47a4dfd81a46..050a61fe9693 100644 --- a/sound/soc/amd/renoir/rn-pci-acp3x.c +++ b/sound/soc/amd/renoir/rn-pci-acp3x.c @@ -199,41 +199,6 @@ static const struct dmi_system_id rn_acp_quirk_table[] = { DMI_EXACT_MATCH(DMI_BOARD_NAME, "20NLCTO1WW"), } }, - { - /* Lenovo ThinkPad P14s Gen 1 (20Y1) */ - .matches = { - DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "LENOVO"), - DMI_MATCH(DMI_BOARD_NAME, "20Y1"), - } - }, - { - /* Lenovo ThinkPad T14s Gen1 */ - .matches = { - DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "LENOVO"), - DMI_MATCH(DMI_BOARD_NAME, "20UH"), - } - }, - { - /* Lenovo ThinkPad T14s Gen1 Campus */ - .matches = { - DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "LENOVO"), - DMI_MATCH(DMI_BOARD_NAME, "20UJ"), - } - }, - { - /* Lenovo ThinkPad T14 Gen 1*/ - .matches = { - DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "LENOVO"), - DMI_MATCH(DMI_BOARD_NAME, "20UD"), - } - }, - { - /* Lenovo ThinkPad X13 Gen 1*/ - .matches = { - DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "LENOVO"), - DMI_MATCH(DMI_BOARD_NAME, "20UF"), - } - }, {} };
From: Richard Weinberger richard@nod.at
[ Upstream commit 8bef925e37bdc9b6554b85eda16ced9a8e3c135f ]
TAS2562_TDM_CFG0_SAMPRATE_MASK starts at bit 1, not 0. So all values need to be left shifted by 1.
Signed-off-by: Richard Weinberger richard@nod.at Link: https://lore.kernel.org/r/20210530203446.19022-1-richard@nod.at Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/codecs/tas2562.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/sound/soc/codecs/tas2562.h b/sound/soc/codecs/tas2562.h index 81866aeb3fbf..55b2a1f52ca3 100644 --- a/sound/soc/codecs/tas2562.h +++ b/sound/soc/codecs/tas2562.h @@ -57,13 +57,13 @@ #define TAS2562_TDM_CFG0_RAMPRATE_MASK BIT(5) #define TAS2562_TDM_CFG0_RAMPRATE_44_1 BIT(5) #define TAS2562_TDM_CFG0_SAMPRATE_MASK GENMASK(3, 1) -#define TAS2562_TDM_CFG0_SAMPRATE_7305_8KHZ 0x0 -#define TAS2562_TDM_CFG0_SAMPRATE_14_7_16KHZ 0x1 -#define TAS2562_TDM_CFG0_SAMPRATE_22_05_24KHZ 0x2 -#define TAS2562_TDM_CFG0_SAMPRATE_29_4_32KHZ 0x3 -#define TAS2562_TDM_CFG0_SAMPRATE_44_1_48KHZ 0x4 -#define TAS2562_TDM_CFG0_SAMPRATE_88_2_96KHZ 0x5 -#define TAS2562_TDM_CFG0_SAMPRATE_176_4_192KHZ 0x6 +#define TAS2562_TDM_CFG0_SAMPRATE_7305_8KHZ (0x0 << 1) +#define TAS2562_TDM_CFG0_SAMPRATE_14_7_16KHZ (0x1 << 1) +#define TAS2562_TDM_CFG0_SAMPRATE_22_05_24KHZ (0x2 << 1) +#define TAS2562_TDM_CFG0_SAMPRATE_29_4_32KHZ (0x3 << 1) +#define TAS2562_TDM_CFG0_SAMPRATE_44_1_48KHZ (0x4 << 1) +#define TAS2562_TDM_CFG0_SAMPRATE_88_2_96KHZ (0x5 << 1) +#define TAS2562_TDM_CFG0_SAMPRATE_176_4_192KHZ (0x6 << 1)
#define TAS2562_TDM_CFG2_RIGHT_JUSTIFY BIT(6)
From: Axel Lin axel.lin@ingics.com
[ Upstream commit 50bec7fb4cb1bcf9d387046b6dec7186590791ec ]
Take ldo3_voltages as example, the ARRAY_SIZE(ldo3_voltages) is 16. i.e. the valid selector is 0 ~ 0xF. But in current code the vsel_mask is "(1 << 15) - 1", i.e. 0x7FFF. Fix it.
Signed-off-by: Axel Lin axel.lin@ingics.com Link: https://lore.kernel.org/r/20210529013236.373847-1-axel.lin@ingics.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/staging/hikey9xx/hi6421v600-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/staging/hikey9xx/hi6421v600-regulator.c b/drivers/staging/hikey9xx/hi6421v600-regulator.c index f6a14e9c3cbf..e10fe3058176 100644 --- a/drivers/staging/hikey9xx/hi6421v600-regulator.c +++ b/drivers/staging/hikey9xx/hi6421v600-regulator.c @@ -83,7 +83,7 @@ static const unsigned int ldo34_voltages[] = { .owner = THIS_MODULE, \ .volt_table = vtable, \ .n_voltages = ARRAY_SIZE(vtable), \ - .vsel_mask = (1 << (ARRAY_SIZE(vtable) - 1)) - 1, \ + .vsel_mask = ARRAY_SIZE(vtable) - 1, \ .vsel_reg = vreg, \ .enable_reg = ereg, \ .enable_mask = emask, \
From: Patrice Chotard patrice.chotard@foss.st.com
[ Upstream commit d38fa9a155b2829b7e2cfcf8a4171b6dd3672808 ]
In U-boot side, an issue has been encountered when QSPI source clock is running at low frequency (24 MHz for example), waiting for TCF bit to be set didn't ensure that all data has been send out the FIFO, we should also wait that BUSY bit is cleared.
To prevent similar issue in kernel driver, we implement similar behavior by always waiting BUSY bit to be cleared.
Signed-off-by: Patrice Chotard patrice.chotard@foss.st.com Link: https://lore.kernel.org/r/20210603073421.8441-1-patrice.chotard@foss.st.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/spi/spi-stm32-qspi.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/spi/spi-stm32-qspi.c b/drivers/spi/spi-stm32-qspi.c index 2786470a5201..4f24f6392212 100644 --- a/drivers/spi/spi-stm32-qspi.c +++ b/drivers/spi/spi-stm32-qspi.c @@ -293,7 +293,7 @@ static int stm32_qspi_wait_cmd(struct stm32_qspi *qspi, int err = 0;
if (!op->data.nbytes) - return stm32_qspi_wait_nobusy(qspi); + goto wait_nobusy;
if (readl_relaxed(qspi->io_base + QSPI_SR) & SR_TCF) goto out; @@ -314,6 +314,9 @@ static int stm32_qspi_wait_cmd(struct stm32_qspi *qspi, out: /* clear flags */ writel_relaxed(FCR_CTCF | FCR_CTEF, qspi->io_base + QSPI_FCR); +wait_nobusy: + if (!err) + err = stm32_qspi_wait_nobusy(qspi);
return err; }
From: Trond Myklebust trond.myklebust@hammerspace.com
[ Upstream commit c3aba897c6e67fa464ec02b1f17911577d619713 ]
If the inode is being evicted but has to return a layout first, then that too can cause a deadlock in the corner case where the server reboots.
Signed-off-by: Trond Myklebust trond.myklebust@hammerspace.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/nfs/nfs4proc.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 056d98d1d1a7..420d34461bb8 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -9628,15 +9628,20 @@ int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp, bool sync) &task_setup_data.rpc_client, &msg);
dprintk("--> %s\n", __func__); + lrp->inode = nfs_igrab_and_active(lrp->args.inode); if (!sync) { - lrp->inode = nfs_igrab_and_active(lrp->args.inode); if (!lrp->inode) { nfs4_layoutreturn_release(lrp); return -EAGAIN; } task_setup_data.flags |= RPC_TASK_ASYNC; } - nfs4_init_sequence(&lrp->args.seq_args, &lrp->res.seq_res, 1, 0); + if (!lrp->inode) + nfs4_init_sequence(&lrp->args.seq_args, &lrp->res.seq_res, 1, + 1); + else + nfs4_init_sequence(&lrp->args.seq_args, &lrp->res.seq_res, 1, + 0); task = rpc_run_task(&task_setup_data); if (IS_ERR(task)) return PTR_ERR(task);
From: Axel Lin axel.lin@ingics.com
[ Upstream commit cb2381cbecb81a8893b2d1e1af29bc2e5531df27 ]
devm_gpiod_get_array_optional may return NULL if no GPIO was assigned.
Signed-off-by: Axel Lin axel.lin@ingics.com Link: https://lore.kernel.org/r/20210603094944.1114156-1-axel.lin@ingics.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/regulator/rt4801-regulator.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/regulator/rt4801-regulator.c b/drivers/regulator/rt4801-regulator.c index 2055a9cb13ba..7a87788d3f09 100644 --- a/drivers/regulator/rt4801-regulator.c +++ b/drivers/regulator/rt4801-regulator.c @@ -66,7 +66,7 @@ static int rt4801_enable(struct regulator_dev *rdev) struct gpio_descs *gpios = priv->enable_gpios; int id = rdev_get_id(rdev), ret;
- if (gpios->ndescs <= id) { + if (!gpios || gpios->ndescs <= id) { dev_warn(&rdev->dev, "no dedicated gpio can control\n"); goto bypass_gpio; } @@ -88,7 +88,7 @@ static int rt4801_disable(struct regulator_dev *rdev) struct gpio_descs *gpios = priv->enable_gpios; int id = rdev_get_id(rdev);
- if (gpios->ndescs <= id) { + if (!gpios || gpios->ndescs <= id) { dev_warn(&rdev->dev, "no dedicated gpio can control\n"); goto bypass_gpio; }
From: Oder Chiou oder_chiou@realtek.com
[ Upstream commit 49783c6f4a4f49836b5a109ae0daf2f90b0d7713 ]
Based on ("5a15cd7fce20b1fd4aece6a0240e2b58cd6a225d"), the setting also should be set in soundwire mode.
Signed-off-by: Oder Chiou oder_chiou@realtek.com Link: https://lore.kernel.org/r/20210604063150.29925-1-oder_chiou@realtek.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/codecs/rt5682-sdw.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/sound/soc/codecs/rt5682-sdw.c b/sound/soc/codecs/rt5682-sdw.c index b49f1e16125d..d1dd7f720ba4 100644 --- a/sound/soc/codecs/rt5682-sdw.c +++ b/sound/soc/codecs/rt5682-sdw.c @@ -462,7 +462,8 @@ static int rt5682_io_init(struct device *dev, struct sdw_slave *slave)
regmap_update_bits(rt5682->regmap, RT5682_CBJ_CTRL_2, RT5682_EXT_JD_SRC, RT5682_EXT_JD_SRC_MANUAL); - regmap_write(rt5682->regmap, RT5682_CBJ_CTRL_1, 0xd042); + regmap_write(rt5682->regmap, RT5682_CBJ_CTRL_1, 0xd142); + regmap_update_bits(rt5682->regmap, RT5682_CBJ_CTRL_5, 0x0700, 0x0600); regmap_update_bits(rt5682->regmap, RT5682_CBJ_CTRL_3, RT5682_CBJ_IN_BUF_EN, RT5682_CBJ_IN_BUF_EN); regmap_update_bits(rt5682->regmap, RT5682_SAR_IL_CMD_1,
From: Sergio Paracuellos sergio.paracuellos@gmail.com
[ Upstream commit eb367d875f94a228c17c8538e3f2efcf2eb07ead ]
In 'rt2880_pmx_group_enable' driver is printing an error and returning -EBUSY if a pin has been already enabled. This begets anoying messages in the caller when this happens like the following:
rt2880-pinmux pinctrl: pcie is already enabled mt7621-pci 1e140000.pcie: Error applying setting, reverse things back
To avoid this just print the already enabled message in the pinctrl driver and return 0 instead to not confuse the user with a real bad problem.
Signed-off-by: Sergio Paracuellos sergio.paracuellos@gmail.com Link: https://lore.kernel.org/r/20210604055337.20407-1-sergio.paracuellos@gmail.co... Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pinctrl/ralink/pinctrl-rt2880.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/pinctrl/ralink/pinctrl-rt2880.c b/drivers/pinctrl/ralink/pinctrl-rt2880.c index 1f4bca854add..a9b511c7e850 100644 --- a/drivers/pinctrl/ralink/pinctrl-rt2880.c +++ b/drivers/pinctrl/ralink/pinctrl-rt2880.c @@ -127,7 +127,7 @@ static int rt2880_pmx_group_enable(struct pinctrl_dev *pctrldev, if (p->groups[group].enabled) { dev_err(p->dev, "%s is already enabled\n", p->groups[group].name); - return -EBUSY; + return 0; }
p->groups[group].enabled = 1;
From: Saravana Kannan saravanak@google.com
[ Upstream commit 9bf3797796f570b34438235a6a537df85832bdad ]
On sunxi boards that use HDMI output, HDMI device probe keeps being avoided indefinitely with these repeated messages in dmesg:
platform 1ee0000.hdmi: probe deferral - supplier 1ef0000.hdmi-phy not ready
There's a fwnode_link being created with fw_devlink=on between hdmi and hdmi-phy nodes, because both nodes have 'compatible' property set.
Fw_devlink code assumes that nodes that have compatible property set will also have a device associated with them by some driver eventually. This is not the case with the current sun8i-hdmi driver.
This commit makes sun8i-hdmi-phy into a proper platform device and fixes the display pipeline probe on sunxi boards that use HDMI.
More context: https://lkml.org/lkml/2021/5/16/203
Signed-off-by: Saravana Kannan saravanak@google.com Signed-off-by: Ondrej Jirman megous@megous.com Tested-by: Andre Przywara andre.przywara@arm.com Signed-off-by: Maxime Ripard maxime@cerno.tech Link: https://patchwork.freedesktop.org/patch/msgid/20210607085836.2827429-1-megou... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c | 31 ++++++++++++++++--- drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h | 5 ++-- drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c | 41 ++++++++++++++++++++++---- 3 files changed, 66 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c index bbdfd5e26ec8..f75fb157f2ff 100644 --- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c +++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c @@ -209,7 +209,7 @@ static int sun8i_dw_hdmi_bind(struct device *dev, struct device *master, goto err_disable_clk_tmds; }
- ret = sun8i_hdmi_phy_probe(hdmi, phy_node); + ret = sun8i_hdmi_phy_get(hdmi, phy_node); of_node_put(phy_node); if (ret) { dev_err(dev, "Couldn't get the HDMI PHY\n"); @@ -242,7 +242,6 @@ static int sun8i_dw_hdmi_bind(struct device *dev, struct device *master,
cleanup_encoder: drm_encoder_cleanup(encoder); - sun8i_hdmi_phy_remove(hdmi); err_disable_clk_tmds: clk_disable_unprepare(hdmi->clk_tmds); err_assert_ctrl_reset: @@ -263,7 +262,6 @@ static void sun8i_dw_hdmi_unbind(struct device *dev, struct device *master, struct sun8i_dw_hdmi *hdmi = dev_get_drvdata(dev);
dw_hdmi_unbind(hdmi->hdmi); - sun8i_hdmi_phy_remove(hdmi); clk_disable_unprepare(hdmi->clk_tmds); reset_control_assert(hdmi->rst_ctrl); gpiod_set_value(hdmi->ddc_en, 0); @@ -320,7 +318,32 @@ static struct platform_driver sun8i_dw_hdmi_pltfm_driver = { .of_match_table = sun8i_dw_hdmi_dt_ids, }, }; -module_platform_driver(sun8i_dw_hdmi_pltfm_driver); + +static int __init sun8i_dw_hdmi_init(void) +{ + int ret; + + ret = platform_driver_register(&sun8i_dw_hdmi_pltfm_driver); + if (ret) + return ret; + + ret = platform_driver_register(&sun8i_hdmi_phy_driver); + if (ret) { + platform_driver_unregister(&sun8i_dw_hdmi_pltfm_driver); + return ret; + } + + return ret; +} + +static void __exit sun8i_dw_hdmi_exit(void) +{ + platform_driver_unregister(&sun8i_dw_hdmi_pltfm_driver); + platform_driver_unregister(&sun8i_hdmi_phy_driver); +} + +module_init(sun8i_dw_hdmi_init); +module_exit(sun8i_dw_hdmi_exit);
MODULE_AUTHOR("Jernej Skrabec jernej.skrabec@siol.net"); MODULE_DESCRIPTION("Allwinner DW HDMI bridge"); diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h index d4b55af0592f..74f6ed0e2570 100644 --- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h +++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h @@ -195,14 +195,15 @@ struct sun8i_dw_hdmi { struct gpio_desc *ddc_en; };
+extern struct platform_driver sun8i_hdmi_phy_driver; + static inline struct sun8i_dw_hdmi * encoder_to_sun8i_dw_hdmi(struct drm_encoder *encoder) { return container_of(encoder, struct sun8i_dw_hdmi, encoder); }
-int sun8i_hdmi_phy_probe(struct sun8i_dw_hdmi *hdmi, struct device_node *node); -void sun8i_hdmi_phy_remove(struct sun8i_dw_hdmi *hdmi); +int sun8i_hdmi_phy_get(struct sun8i_dw_hdmi *hdmi, struct device_node *node);
void sun8i_hdmi_phy_init(struct sun8i_hdmi_phy *phy); void sun8i_hdmi_phy_set_ops(struct sun8i_hdmi_phy *phy, diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c index 9994edf67509..c9239708d398 100644 --- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c +++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c @@ -5,6 +5,7 @@
#include <linux/delay.h> #include <linux/of_address.h> +#include <linux/of_platform.h>
#include "sun8i_dw_hdmi.h"
@@ -597,10 +598,30 @@ static const struct of_device_id sun8i_hdmi_phy_of_table[] = { { /* sentinel */ } };
-int sun8i_hdmi_phy_probe(struct sun8i_dw_hdmi *hdmi, struct device_node *node) +int sun8i_hdmi_phy_get(struct sun8i_dw_hdmi *hdmi, struct device_node *node) +{ + struct platform_device *pdev = of_find_device_by_node(node); + struct sun8i_hdmi_phy *phy; + + if (!pdev) + return -EPROBE_DEFER; + + phy = platform_get_drvdata(pdev); + if (!phy) + return -EPROBE_DEFER; + + hdmi->phy = phy; + + put_device(&pdev->dev); + + return 0; +} + +static int sun8i_hdmi_phy_probe(struct platform_device *pdev) { const struct of_device_id *match; - struct device *dev = hdmi->dev; + struct device *dev = &pdev->dev; + struct device_node *node = dev->of_node; struct sun8i_hdmi_phy *phy; struct resource res; void __iomem *regs; @@ -704,7 +725,7 @@ int sun8i_hdmi_phy_probe(struct sun8i_dw_hdmi *hdmi, struct device_node *node) clk_prepare_enable(phy->clk_phy); }
- hdmi->phy = phy; + platform_set_drvdata(pdev, phy);
return 0;
@@ -728,9 +749,9 @@ int sun8i_hdmi_phy_probe(struct sun8i_dw_hdmi *hdmi, struct device_node *node) return ret; }
-void sun8i_hdmi_phy_remove(struct sun8i_dw_hdmi *hdmi) +static int sun8i_hdmi_phy_remove(struct platform_device *pdev) { - struct sun8i_hdmi_phy *phy = hdmi->phy; + struct sun8i_hdmi_phy *phy = platform_get_drvdata(pdev);
clk_disable_unprepare(phy->clk_mod); clk_disable_unprepare(phy->clk_bus); @@ -744,4 +765,14 @@ void sun8i_hdmi_phy_remove(struct sun8i_dw_hdmi *hdmi) clk_put(phy->clk_pll1); clk_put(phy->clk_mod); clk_put(phy->clk_bus); + return 0; } + +struct platform_driver sun8i_hdmi_phy_driver = { + .probe = sun8i_hdmi_phy_probe, + .remove = sun8i_hdmi_phy_remove, + .driver = { + .name = "sun8i-hdmi-phy", + .of_match_table = sun8i_hdmi_phy_of_table, + }, +};
From: Srinivasa Rao Mandadapu srivasam@codeaurora.org
[ Upstream commit c8a4556d98510ca05bad8d02265a4918b03a8c0b ]
This patch fixes PoP noise of around 15ms observed during audio capture begin. Enables BCLK and LRCLK in snd_soc_dai_ops prepare call for introducing some delay before capture start.
(am from https://patchwork.kernel.org/patch/12276369/) (also found at https://lore.kernel.org/r/20210524142114.18676-1-srivasam@codeaurora.org)
Co-developed-by: Judy Hsiao judyhsiao@chromium.org Signed-off-by: Judy Hsiao judyhsiao@chromium.org Signed-off-by: Srinivasa Rao Mandadapu srivasam@codeaurora.org Reviewed-by: Srinivas Kandagatla srinivas.kandagatla@linaro.org Link: https://lore.kernel.org/r/20210604154545.1198337-1-judyhsiao@chromium.org Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/qcom/lpass-cpu.c | 79 ++++++++++++++++++++++++++++++++++++++ sound/soc/qcom/lpass.h | 4 ++ 2 files changed, 83 insertions(+)
diff --git a/sound/soc/qcom/lpass-cpu.c b/sound/soc/qcom/lpass-cpu.c index 936384a94f25..74d3d8c58608 100644 --- a/sound/soc/qcom/lpass-cpu.c +++ b/sound/soc/qcom/lpass-cpu.c @@ -93,8 +93,30 @@ static void lpass_cpu_daiops_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai); + struct lpaif_i2sctl *i2sctl = drvdata->i2sctl; + unsigned int id = dai->driver->id;
clk_disable_unprepare(drvdata->mi2s_osr_clk[dai->driver->id]); + /* + * Ensure LRCLK is disabled even in device node validation. + * Will not impact if disabled in lpass_cpu_daiops_trigger() + * suspend. + */ + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + regmap_fields_write(i2sctl->spken, id, LPAIF_I2SCTL_SPKEN_DISABLE); + else + regmap_fields_write(i2sctl->micen, id, LPAIF_I2SCTL_MICEN_DISABLE); + + /* + * BCLK may not be enabled if lpass_cpu_daiops_prepare is called before + * lpass_cpu_daiops_shutdown. It's paired with the clk_enable in + * lpass_cpu_daiops_prepare. + */ + if (drvdata->mi2s_was_prepared[dai->driver->id]) { + drvdata->mi2s_was_prepared[dai->driver->id] = false; + clk_disable(drvdata->mi2s_bit_clk[dai->driver->id]); + } + clk_unprepare(drvdata->mi2s_bit_clk[dai->driver->id]); }
@@ -275,6 +297,18 @@ static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream, case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + /* + * Ensure lpass BCLK/LRCLK is enabled during + * device resume as lpass_cpu_daiops_prepare() is not called + * after the device resumes. We don't check mi2s_was_prepared before + * enable/disable BCLK in trigger events because: + * 1. These trigger events are paired, so the BCLK + * enable_count is balanced. + * 2. the BCLK can be shared (ex: headset and headset mic), + * we need to increase the enable_count so that we don't + * turn off the shared BCLK while other devices are using + * it. + */ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { ret = regmap_fields_write(i2sctl->spken, id, LPAIF_I2SCTL_SPKEN_ENABLE); @@ -296,6 +330,10 @@ static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream, case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + /* + * To ensure lpass BCLK/LRCLK is disabled during + * device suspend. + */ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { ret = regmap_fields_write(i2sctl->spken, id, LPAIF_I2SCTL_SPKEN_DISABLE); @@ -315,12 +353,53 @@ static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream, return ret; }
+static int lpass_cpu_daiops_prepare(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai); + struct lpaif_i2sctl *i2sctl = drvdata->i2sctl; + unsigned int id = dai->driver->id; + int ret; + + /* + * Ensure lpass BCLK/LRCLK is enabled bit before playback/capture + * data flow starts. This allows other codec to have some delay before + * the data flow. + * (ex: to drop start up pop noise before capture starts). + */ + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + ret = regmap_fields_write(i2sctl->spken, id, LPAIF_I2SCTL_SPKEN_ENABLE); + else + ret = regmap_fields_write(i2sctl->micen, id, LPAIF_I2SCTL_MICEN_ENABLE); + + if (ret) { + dev_err(dai->dev, "error writing to i2sctl reg: %d\n", ret); + return ret; + } + + /* + * Check mi2s_was_prepared before enabling BCLK as lpass_cpu_daiops_prepare can + * be called multiple times. It's paired with the clk_disable in + * lpass_cpu_daiops_shutdown. + */ + if (!drvdata->mi2s_was_prepared[dai->driver->id]) { + ret = clk_enable(drvdata->mi2s_bit_clk[id]); + if (ret) { + dev_err(dai->dev, "error in enabling mi2s bit clk: %d\n", ret); + return ret; + } + drvdata->mi2s_was_prepared[dai->driver->id] = true; + } + return 0; +} + const struct snd_soc_dai_ops asoc_qcom_lpass_cpu_dai_ops = { .set_sysclk = lpass_cpu_daiops_set_sysclk, .startup = lpass_cpu_daiops_startup, .shutdown = lpass_cpu_daiops_shutdown, .hw_params = lpass_cpu_daiops_hw_params, .trigger = lpass_cpu_daiops_trigger, + .prepare = lpass_cpu_daiops_prepare, }; EXPORT_SYMBOL_GPL(asoc_qcom_lpass_cpu_dai_ops);
diff --git a/sound/soc/qcom/lpass.h b/sound/soc/qcom/lpass.h index 83b2e08ade06..7f72214404ba 100644 --- a/sound/soc/qcom/lpass.h +++ b/sound/soc/qcom/lpass.h @@ -67,6 +67,10 @@ struct lpass_data { /* MI2S SD lines to use for playback/capture */ unsigned int mi2s_playback_sd_mode[LPASS_MAX_MI2S_PORTS]; unsigned int mi2s_capture_sd_mode[LPASS_MAX_MI2S_PORTS]; + + /* The state of MI2S prepare dai_ops was called */ + bool mi2s_was_prepared[LPASS_MAX_MI2S_PORTS]; + int hdmi_port_enable;
/* low-power audio interface (LPAIF) registers */
From: Ming Lei ming.lei@redhat.com
[ Upstream commit 66a834d092930cf41d809c0e989b13cd6f9ca006 ]
After device is initialized via device_initialize(), or its name is set via dev_set_name(), the device has to be freed via put_device(). Otherwise device name will be leaked because it is allocated dynamically in dev_set_name().
Fix the leak by replacing kfree() with put_device(). Since scsi_host_dev_release() properly handles IDA and kthread removal, remove special-casing these from the error handling as well.
Link: https://lore.kernel.org/r/20210602133029.2864069-2-ming.lei@redhat.com Cc: Bart Van Assche bvanassche@acm.org Cc: John Garry john.garry@huawei.com Cc: Hannes Reinecke hare@suse.de Tested-by: John Garry john.garry@huawei.com Reviewed-by: Bart Van Assche bvanassche@acm.org Reviewed-by: John Garry john.garry@huawei.com Reviewed-by: Hannes Reinecke hare@suse.de Signed-off-by: Ming Lei ming.lei@redhat.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/hosts.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-)
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index 2f162603876f..d835a7b23614 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -392,8 +392,10 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) mutex_init(&shost->scan_mutex);
index = ida_simple_get(&host_index_ida, 0, 0, GFP_KERNEL); - if (index < 0) - goto fail_kfree; + if (index < 0) { + kfree(shost); + return NULL; + } shost->host_no = index;
shost->dma_channel = 0xff; @@ -486,7 +488,7 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) shost_printk(KERN_WARNING, shost, "error handler thread failed to spawn, error = %ld\n", PTR_ERR(shost->ehandler)); - goto fail_index_remove; + goto fail; }
shost->tmf_work_q = alloc_workqueue("scsi_tmf_%d", @@ -495,17 +497,18 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) if (!shost->tmf_work_q) { shost_printk(KERN_WARNING, shost, "failed to create tmf workq\n"); - goto fail_kthread; + goto fail; } scsi_proc_hostdir_add(shost->hostt); return shost; + fail: + /* + * Host state is still SHOST_CREATED and that is enough to release + * ->shost_gendev. scsi_host_dev_release() will free + * dev_name(&shost->shost_dev). + */ + put_device(&shost->shost_gendev);
- fail_kthread: - kthread_stop(shost->ehandler); - fail_index_remove: - ida_simple_remove(&host_index_ida, shost->host_no); - fail_kfree: - kfree(shost); return NULL; } EXPORT_SYMBOL(scsi_host_alloc);
From: Ming Lei ming.lei@redhat.com
[ Upstream commit 3719f4ff047e20062b8314c23ec3cab84d74c908 ]
When scsi_add_host_with_dma() returns failure, the caller will call scsi_host_put(shost) to release everything allocated for this host instance. Consequently we can't also free allocated stuff in scsi_add_host_with_dma(), otherwise we will end up with a double free.
Strictly speaking, host resource allocations should have been done in scsi_host_alloc(). However, the allocations may need information which is not yet provided by the driver when that function is called. So leave the allocations where they are but rely on host device's release handler to free resources.
Link: https://lore.kernel.org/r/20210602133029.2864069-3-ming.lei@redhat.com Cc: Bart Van Assche bvanassche@acm.org Cc: John Garry john.garry@huawei.com Cc: Hannes Reinecke hare@suse.de Tested-by: John Garry john.garry@huawei.com Reviewed-by: Bart Van Assche bvanassche@acm.org Reviewed-by: John Garry john.garry@huawei.com Reviewed-by: Hannes Reinecke hare@suse.de Signed-off-by: Ming Lei ming.lei@redhat.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/hosts.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index d835a7b23614..48ec9c35daa4 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -278,23 +278,22 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev,
if (!shost->work_q) { error = -EINVAL; - goto out_free_shost_data; + goto out_del_dev; } }
error = scsi_sysfs_add_host(shost); if (error) - goto out_destroy_host; + goto out_del_dev;
scsi_proc_host_add(shost); scsi_autopm_put_host(shost); return error;
- out_destroy_host: - if (shost->work_q) - destroy_workqueue(shost->work_q); - out_free_shost_data: - kfree(shost->shost_data); + /* + * Any host allocation in this function will be freed in + * scsi_host_dev_release(). + */ out_del_dev: device_del(&shost->shost_dev); out_del_gendev: @@ -304,7 +303,6 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev, pm_runtime_disable(&shost->shost_gendev); pm_runtime_set_suspended(&shost->shost_gendev); pm_runtime_put_noidle(&shost->shost_gendev); - scsi_mq_destroy_tags(shost); fail: return error; }
From: Ming Lei ming.lei@redhat.com
[ Upstream commit 11714026c02d613c30a149c3f4c4a15047744529 ]
scsi_host_dev_release() only frees dev_name when host state is SHOST_CREATED. After host state has changed to SHOST_RUNNING, scsi_host_dev_release() no longer cleans up.
Fix this by doing a put_device(&shost->shost_dev) in the failure path when host state is SHOST_RUNNING. Move get_device(&shost->shost_gendev) before device_add(&shost->shost_dev) so that scsi_host_cls_release() can do a put on this reference.
Link: https://lore.kernel.org/r/20210602133029.2864069-4-ming.lei@redhat.com Cc: Bart Van Assche bvanassche@acm.org Cc: Hannes Reinecke hare@suse.de Reported-by: John Garry john.garry@huawei.com Tested-by: John Garry john.garry@huawei.com Reviewed-by: John Garry john.garry@huawei.com Reviewed-by: Hannes Reinecke hare@suse.de Signed-off-by: Ming Lei ming.lei@redhat.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/hosts.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index 48ec9c35daa4..a64d0c6f1c4a 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -254,12 +254,11 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev,
device_enable_async_suspend(&shost->shost_dev);
+ get_device(&shost->shost_gendev); error = device_add(&shost->shost_dev); if (error) goto out_del_gendev;
- get_device(&shost->shost_gendev); - if (shost->transportt->host_size) { shost->shost_data = kzalloc(shost->transportt->host_size, GFP_KERNEL); @@ -297,6 +296,11 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev, out_del_dev: device_del(&shost->shost_dev); out_del_gendev: + /* + * Host state is SHOST_RUNNING so we have to explicitly release + * ->shost_dev. + */ + put_device(&shost->shost_dev); device_del(&shost->shost_gendev); out_disable_runtime_pm: device_disable_async_suspend(&shost->shost_gendev);
From: Ming Lei ming.lei@redhat.com
[ Upstream commit 1e0d4e6225996f05271de1ebcb1a7c9381af0b27 ]
get_device(shost->shost_gendev.parent) is called after host state has switched to SHOST_RUNNING. scsi_host_dev_release() shouldn't release the parent device if host state is still SHOST_CREATED.
Link: https://lore.kernel.org/r/20210602133029.2864069-5-ming.lei@redhat.com Cc: Bart Van Assche bvanassche@acm.org Cc: John Garry john.garry@huawei.com Cc: Hannes Reinecke hare@suse.de Tested-by: John Garry john.garry@huawei.com Reviewed-by: John Garry john.garry@huawei.com Signed-off-by: Ming Lei ming.lei@redhat.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/hosts.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index a64d0c6f1c4a..b93dd8ef4ac8 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -347,7 +347,7 @@ static void scsi_host_dev_release(struct device *dev)
ida_simple_remove(&host_index_ida, shost->host_no);
- if (parent) + if (shost->shost_state != SHOST_CREATED) put_device(parent); kfree(shost); }
From: Chen Li chenli@uniontech.com
[ Upstream commit ab8363d3875a83f4901eb1cc00ce8afd24de6c85 ]
I met a gpu addr bug recently and the kernel log tells me the pc is memcpy/memset and link register is radeon_uvd_resume.
As we know, in some architectures, optimized memcpy/memset may not work well on device memory. Trival memcpy_toio/memset_io can fix this problem.
BTW, amdgpu has already done it in: commit ba0b2275a678 ("drm/amdgpu: use memcpy_to/fromio for UVD fw upload"), that's why it has no this issue on the same gpu and platform.
Signed-off-by: Chen Li chenli@uniontech.com Reviewed-by: Christian König christian.koenig@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/radeon/radeon_uvd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_uvd.c b/drivers/gpu/drm/radeon/radeon_uvd.c index dfa9fdbe98da..06bb24d7a9fe 100644 --- a/drivers/gpu/drm/radeon/radeon_uvd.c +++ b/drivers/gpu/drm/radeon/radeon_uvd.c @@ -286,7 +286,7 @@ int radeon_uvd_resume(struct radeon_device *rdev) if (rdev->uvd.vcpu_bo == NULL) return -EINVAL;
- memcpy(rdev->uvd.cpu_addr, rdev->uvd_fw->data, rdev->uvd_fw->size); + memcpy_toio((void __iomem *)rdev->uvd.cpu_addr, rdev->uvd_fw->data, rdev->uvd_fw->size);
size = radeon_bo_size(rdev->uvd.vcpu_bo); size -= rdev->uvd_fw->size; @@ -294,7 +294,7 @@ int radeon_uvd_resume(struct radeon_device *rdev) ptr = rdev->uvd.cpu_addr; ptr += rdev->uvd_fw->size;
- memset(ptr, 0, size); + memset_io((void __iomem *)ptr, 0, size);
return 0; }
From: Paolo Bonzini pbonzini@redhat.com
[ Upstream commit da27a83fd6cc7780fea190e1f5c19e87019da65c ]
KVM's mechanism for accessing guest memory translates a guest physical address (gpa) to a host virtual address using the right-shifted gpa (also known as gfn) and a struct kvm_memory_slot. The translation is performed in __gfn_to_hva_memslot using the following formula:
hva = slot->userspace_addr + (gfn - slot->base_gfn) * PAGE_SIZE
It is expected that gfn falls within the boundaries of the guest's physical memory. However, a guest can access invalid physical addresses in such a way that the gfn is invalid.
__gfn_to_hva_memslot is called from kvm_vcpu_gfn_to_hva_prot, which first retrieves a memslot through __gfn_to_memslot. While __gfn_to_memslot does check that the gfn falls within the boundaries of the guest's physical memory or not, a CPU can speculate the result of the check and continue execution speculatively using an illegal gfn. The speculation can result in calculating an out-of-bounds hva. If the resulting host virtual address is used to load another guest physical address, this is effectively a Spectre gadget consisting of two consecutive reads, the second of which is data dependent on the first.
Right now it's not clear if there are any cases in which this is exploitable. One interesting case was reported by the original author of this patch, and involves visiting guest page tables on x86. Right now these are not vulnerable because the hva read goes through get_user(), which contains an LFENCE speculation barrier. However, there are patches in progress for x86 uaccess.h to mask kernel addresses instead of using LFENCE; once these land, a guest could use speculation to read from the VMM's ring 3 address space. Other architectures such as ARM already use the address masking method, and would be susceptible to this same kind of data-dependent access gadgets. Therefore, this patch proactively protects from these attacks by masking out-of-bounds gfns in __gfn_to_hva_memslot, which blocks speculation of invalid hvas.
Sean Christopherson noted that this patch does not cover kvm_read_guest_offset_cached. This however is limited to a few bytes past the end of the cache, and therefore it is unlikely to be useful in the context of building a chain of data dependent accesses.
Reported-by: Artemiy Margaritov artemiy.margaritov@gmail.com Co-developed-by: Artemiy Margaritov artemiy.margaritov@gmail.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/kvm_host.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 99dccea4293c..5520d3a97c2e 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -1118,7 +1118,15 @@ __gfn_to_memslot(struct kvm_memslots *slots, gfn_t gfn) static inline unsigned long __gfn_to_hva_memslot(struct kvm_memory_slot *slot, gfn_t gfn) { - return slot->userspace_addr + (gfn - slot->base_gfn) * PAGE_SIZE; + /* + * The index was checked originally in search_memslots. To avoid + * that a malicious guest builds a Spectre gadget out of e.g. page + * table walks, do not let the processor speculate loads outside + * the guest's registered memslots. + */ + unsigned long offset = array_index_nospec(gfn - slot->base_gfn, + slot->npages); + return slot->userspace_addr + offset * PAGE_SIZE; }
static inline int memslot_id(struct kvm *kvm, gfn_t gfn)
From: Paolo Bonzini pbonzini@redhat.com
[ Upstream commit 4422829e8053068e0225e4d0ef42dc41ea7c9ef5 ]
array_index_nospec does not work for uint64_t on 32-bit builds. However, the size of a memory slot must be less than 20 bits wide on those system, since the memory slot must fit in the user address space. So just store it in an unsigned long.
Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/kvm_host.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 5520d3a97c2e..6e884bf58c0a 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -1124,8 +1124,8 @@ __gfn_to_hva_memslot(struct kvm_memory_slot *slot, gfn_t gfn) * table walks, do not let the processor speculate loads outside * the guest's registered memslots. */ - unsigned long offset = array_index_nospec(gfn - slot->base_gfn, - slot->npages); + unsigned long offset = gfn - slot->base_gfn; + offset = array_index_nospec(offset, slot->npages); return slot->userspace_addr + offset * PAGE_SIZE; }
From: Riwen Lu luriwen@kylinos.cn
[ Upstream commit 78d13552346289bad4a9bf8eabb5eec5e5a321a5 ]
The scpi hwmon shows the sub-zero temperature in an unsigned integer, which would confuse the users when the machine works in low temperature environment. This shows the sub-zero temperature in an signed value and users can get it properly from sensors.
Signed-off-by: Riwen Lu luriwen@kylinos.cn Tested-by: Xin Chen chenxin@kylinos.cn Link: https://lore.kernel.org/r/20210604030959.736379-1-luriwen@kylinos.cn Signed-off-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hwmon/scpi-hwmon.c | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/drivers/hwmon/scpi-hwmon.c b/drivers/hwmon/scpi-hwmon.c index 25aac40f2764..919877970ae3 100644 --- a/drivers/hwmon/scpi-hwmon.c +++ b/drivers/hwmon/scpi-hwmon.c @@ -99,6 +99,15 @@ scpi_show_sensor(struct device *dev, struct device_attribute *attr, char *buf)
scpi_scale_reading(&value, sensor);
+ /* + * Temperature sensor values are treated as signed values based on + * observation even though that is not explicitly specified, and + * because an unsigned u64 temperature does not really make practical + * sense especially when the temperature is below zero degrees Celsius. + */ + if (sensor->info.class == TEMPERATURE) + return sprintf(buf, "%lld\n", (s64)value); + return sprintf(buf, "%llu\n", value); }
From: Jisheng Zhang jszhang@kernel.org
[ Upstream commit 42e0e0b453bc6ead49c573ed512502069627546b ]
Some features which need code patching such as KPROBES, DYNAMIC_FTRACE KGDB can only work on !XIP_KERNEL. Add dependencies for these features that rely on code patching.
Signed-off-by: Jisheng Zhang jszhang@kernel.org Signed-off-by: Palmer Dabbelt palmerdabbelt@google.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/riscv/Kconfig | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index d9522fc35ca5..4f116be9152f 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -54,11 +54,11 @@ config RISCV select GENERIC_TIME_VSYSCALL if MMU && 64BIT select HANDLE_DOMAIN_IRQ select HAVE_ARCH_AUDITSYSCALL - select HAVE_ARCH_JUMP_LABEL - select HAVE_ARCH_JUMP_LABEL_RELATIVE + select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL + select HAVE_ARCH_JUMP_LABEL_RELATIVE if !XIP_KERNEL select HAVE_ARCH_KASAN if MMU && 64BIT select HAVE_ARCH_KASAN_VMALLOC if MMU && 64BIT - select HAVE_ARCH_KGDB + select HAVE_ARCH_KGDB if !XIP_KERNEL select HAVE_ARCH_KGDB_QXFER_PKT select HAVE_ARCH_MMAP_RND_BITS if MMU select HAVE_ARCH_SECCOMP_FILTER @@ -73,9 +73,9 @@ config RISCV select HAVE_GCC_PLUGINS select HAVE_GENERIC_VDSO if MMU && 64BIT select HAVE_IRQ_TIME_ACCOUNTING - select HAVE_KPROBES - select HAVE_KPROBES_ON_FTRACE - select HAVE_KRETPROBES + select HAVE_KPROBES if !XIP_KERNEL + select HAVE_KPROBES_ON_FTRACE if !XIP_KERNEL + select HAVE_KRETPROBES if !XIP_KERNEL select HAVE_PCI select HAVE_PERF_EVENTS select HAVE_PERF_REGS @@ -227,11 +227,11 @@ config ARCH_RV64I bool "RV64I" select 64BIT select ARCH_SUPPORTS_INT128 if CC_HAS_INT128 && GCC_VERSION >= 50000 - select HAVE_DYNAMIC_FTRACE if MMU && $(cc-option,-fpatchable-function-entry=8) + select HAVE_DYNAMIC_FTRACE if !XIP_KERNEL && MMU && $(cc-option,-fpatchable-function-entry=8) select HAVE_DYNAMIC_FTRACE_WITH_REGS if HAVE_DYNAMIC_FTRACE - select HAVE_FTRACE_MCOUNT_RECORD + select HAVE_FTRACE_MCOUNT_RECORD if !XIP_KERNEL select HAVE_FUNCTION_GRAPH_TRACER - select HAVE_FUNCTION_TRACER + select HAVE_FUNCTION_TRACER if !XIP_KERNEL select SWIOTLB if MMU
endchoice
From: Feng Tang feng.tang@intel.com
[ Upstream commit 2e3025434a6ba090c85871a1d4080ff784109e1f ]
0day robot reported a 9.2% regression for will-it-scale mmap1 test case[1], caused by commit 57efa1fe5957 ("mm/gup: prevent gup_fast from racing with COW during fork").
Further debug shows the regression is due to that commit changes the offset of hot fields 'mmap_lock' inside structure 'mm_struct', thus some cache alignment changes.
From the perf data, the contention for 'mmap_lock' is very severe and
takes around 95% cpu cycles, and it is a rw_semaphore
struct rw_semaphore { atomic_long_t count; /* 8 bytes */ atomic_long_t owner; /* 8 bytes */ struct optimistic_spin_queue osq; /* spinner MCS lock */ ...
Before commit 57efa1fe5957 adds the 'write_protect_seq', it happens to have a very optimal cache alignment layout, as Linus explained:
"and before the addition of the 'write_protect_seq' field, the mmap_sem was at offset 120 in 'struct mm_struct'.
Which meant that count and owner were in two different cachelines, and then when you have contention and spend time in rwsem_down_write_slowpath(), this is probably *exactly* the kind of layout you want.
Because first the rwsem_write_trylock() will do a cmpxchg on the first cacheline (for the optimistic fast-path), and then in the case of contention, rwsem_down_write_slowpath() will just access the second cacheline.
Which is probably just optimal for a load that spends a lot of time contended - new waiters touch that first cacheline, and then they queue themselves up on the second cacheline."
After the commit, the rw_semaphore is at offset 128, which means the 'count' and 'owner' fields are now in the same cacheline, and causes more cache bouncing.
Currently there are 3 "#ifdef CONFIG_XXX" before 'mmap_lock' which will affect its offset:
CONFIG_MMU CONFIG_MEMBARRIER CONFIG_HAVE_ARCH_COMPAT_MMAP_BASES
The layout above is on 64 bits system with 0day's default kernel config (similar to RHEL-8.3's config), in which all these 3 options are 'y'. And the layout can vary with different kernel configs.
Relayouting a structure is usually a double-edged sword, as sometimes it can helps one case, but hurt other cases. For this case, one solution is, as the newly added 'write_protect_seq' is a 4 bytes long seqcount_t (when CONFIG_DEBUG_LOCK_ALLOC=n), placing it into an existing 4 bytes hole in 'mm_struct' will not change other fields' alignment, while restoring the regression.
Link: https://lore.kernel.org/lkml/20210525031636.GB7744@xsang-OptiPlex-9020/ [1] Reported-by: kernel test robot oliver.sang@intel.com Signed-off-by: Feng Tang feng.tang@intel.com Reviewed-by: John Hubbard jhubbard@nvidia.com Reviewed-by: Jason Gunthorpe jgg@nvidia.com Cc: Peter Xu peterx@redhat.com Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/mm_types.h | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-)
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index 5aacc1c10a45..8f0fb62e8975 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -445,13 +445,6 @@ struct mm_struct { */ atomic_t has_pinned;
- /** - * @write_protect_seq: Locked when any thread is write - * protecting pages mapped by this mm to enforce a later COW, - * for instance during page table copying for fork(). - */ - seqcount_t write_protect_seq; - #ifdef CONFIG_MMU atomic_long_t pgtables_bytes; /* PTE page table pages */ #endif @@ -460,6 +453,18 @@ struct mm_struct { spinlock_t page_table_lock; /* Protects page tables and some * counters */ + /* + * With some kernel config, the current mmap_lock's offset + * inside 'mm_struct' is at 0x120, which is very optimal, as + * its two hot fields 'count' and 'owner' sit in 2 different + * cachelines, and when mmap_lock is highly contended, both + * of the 2 fields will be accessed frequently, current layout + * will help to reduce cache bouncing. + * + * So please be careful with adding new fields before + * mmap_lock, which can easily push the 2 fields into one + * cacheline. + */ struct rw_semaphore mmap_lock;
struct list_head mmlist; /* List of maybe swapped mm's. These @@ -480,7 +485,15 @@ struct mm_struct { unsigned long stack_vm; /* VM_STACK */ unsigned long def_flags;
+ /** + * @write_protect_seq: Locked when any thread is write + * protecting pages mapped by this mm to enforce a later COW, + * for instance during page table copying for fork(). + */ + seqcount_t write_protect_seq; + spinlock_t arg_lock; /* protect the below fields */ + unsigned long start_code, end_code, start_data, end_data; unsigned long start_brk, brk, start_stack; unsigned long arg_start, arg_end, env_start, env_end;
linux-stable-mirror@lists.linaro.org