From 474fa8a588c5251ed7c485c2e75dcdac7b12908f Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Mon, 26 Sep 2022 00:58:02 -0400 Subject: [PATCH] Fixes for 5.10 Signed-off-by: Sasha Levin --- ...ntime_get_sync-returned-1-device-acc.patch | 43 ++++ .../i2c-mlxbf-fix-frequency-calculation.patch | 188 ++++++++++++++++++ ...ect-base-address-passed-during-io-wr.patch | 40 ++++ ...t-stack-overflow-in-mlxbf_i2c_smbus_.patch | 39 ++++ queue-5.10/series | 5 + ...skip-lockdep-work-dependency-in-canc.patch | 98 +++++++++ 6 files changed, 413 insertions(+) create mode 100644 queue-5.10/i2c-imx-if-pm_runtime_get_sync-returned-1-device-acc.patch create mode 100644 queue-5.10/i2c-mlxbf-fix-frequency-calculation.patch create mode 100644 queue-5.10/i2c-mlxbf-incorrect-base-address-passed-during-io-wr.patch create mode 100644 queue-5.10/i2c-mlxbf-prevent-stack-overflow-in-mlxbf_i2c_smbus_.patch create mode 100644 queue-5.10/workqueue-don-t-skip-lockdep-work-dependency-in-canc.patch diff --git a/queue-5.10/i2c-imx-if-pm_runtime_get_sync-returned-1-device-acc.patch b/queue-5.10/i2c-imx-if-pm_runtime_get_sync-returned-1-device-acc.patch new file mode 100644 index 00000000000..93d682a3411 --- /dev/null +++ b/queue-5.10/i2c-imx-if-pm_runtime_get_sync-returned-1-device-acc.patch @@ -0,0 +1,43 @@ +From 3da98fbf407a227f6dcd8c6b5415167808c60bb7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 12 Sep 2022 15:20:40 +0200 +Subject: i2c: imx: If pm_runtime_get_sync() returned 1 device access is + possible +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Uwe Kleine-König + +[ Upstream commit 085aacaa73163f4b8a89dec24ecb32cfacd34017 ] + +pm_runtime_get_sync() returning 1 also means the device is powered. So +resetting the chip registers in .remove() is possible and should be +done. + +Reported-by: Dan Carpenter +Fixes: d98bdd3a5b50 ("i2c: imx: Make sure to unregister adapter on remove()") +Signed-off-by: Uwe Kleine-König +Acked-by: Oleksij Rempel +Signed-off-by: Wolfram Sang +Signed-off-by: Sasha Levin +--- + drivers/i2c/busses/i2c-imx.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c +index d3719df1c40d..be4ad516293b 100644 +--- a/drivers/i2c/busses/i2c-imx.c ++++ b/drivers/i2c/busses/i2c-imx.c +@@ -1289,7 +1289,7 @@ static int i2c_imx_remove(struct platform_device *pdev) + if (i2c_imx->dma) + i2c_imx_dma_free(i2c_imx); + +- if (ret == 0) { ++ if (ret >= 0) { + /* setup chip registers to defaults */ + imx_i2c_write_reg(0, i2c_imx, IMX_I2C_IADR); + imx_i2c_write_reg(0, i2c_imx, IMX_I2C_IFDR); +-- +2.35.1 + diff --git a/queue-5.10/i2c-mlxbf-fix-frequency-calculation.patch b/queue-5.10/i2c-mlxbf-fix-frequency-calculation.patch new file mode 100644 index 00000000000..48e46f9461f --- /dev/null +++ b/queue-5.10/i2c-mlxbf-fix-frequency-calculation.patch @@ -0,0 +1,188 @@ +From 36568f29ea6a633662fa3408b9e15d1a4a0dd1ec Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 20 Sep 2022 13:47:29 -0400 +Subject: i2c: mlxbf: Fix frequency calculation + +From: Asmaa Mnebhi + +[ Upstream commit 37f071ec327b04c83d47637c5e5c2199b39899ca ] + +The i2c-mlxbf.c driver is currently broken because there is a bug +in the calculation of the frequency. core_f, core_r and core_od +are components read from hardware registers and are used to +compute the frequency used to compute different timing parameters. +The shifting mechanism used to get core_f, core_r and core_od is +wrong. Use FIELD_GET to mask and shift the bitfields properly. + +Fixes: b5b5b32081cd206b (i2c: mlxbf: I2C SMBus driver for Mellanox BlueField SoC) +Reviewed-by: Khalil Blaiech +Signed-off-by: Asmaa Mnebhi +Signed-off-by: Wolfram Sang +Signed-off-by: Sasha Levin +--- + drivers/i2c/busses/i2c-mlxbf.c | 63 +++++++++++++--------------------- + 1 file changed, 23 insertions(+), 40 deletions(-) + +diff --git a/drivers/i2c/busses/i2c-mlxbf.c b/drivers/i2c/busses/i2c-mlxbf.c +index d78fb24d5588..bea82a787b4f 100644 +--- a/drivers/i2c/busses/i2c-mlxbf.c ++++ b/drivers/i2c/busses/i2c-mlxbf.c +@@ -6,6 +6,7 @@ + */ + + #include ++#include + #include + #include + #include +@@ -63,13 +64,14 @@ + */ + #define MLXBF_I2C_TYU_PLL_OUT_FREQ (400 * 1000 * 1000) + /* Reference clock for Bluefield - 156 MHz. */ +-#define MLXBF_I2C_PLL_IN_FREQ (156 * 1000 * 1000) ++#define MLXBF_I2C_PLL_IN_FREQ 156250000ULL + + /* Constant used to determine the PLL frequency. */ +-#define MLNXBF_I2C_COREPLL_CONST 16384 ++#define MLNXBF_I2C_COREPLL_CONST 16384ULL ++ ++#define MLXBF_I2C_FREQUENCY_1GHZ 1000000000ULL + + /* PLL registers. */ +-#define MLXBF_I2C_CORE_PLL_REG0 0x0 + #define MLXBF_I2C_CORE_PLL_REG1 0x4 + #define MLXBF_I2C_CORE_PLL_REG2 0x8 + +@@ -187,22 +189,15 @@ enum { + #define MLXBF_I2C_COREPLL_FREQ MLXBF_I2C_TYU_PLL_OUT_FREQ + + /* Core PLL TYU configuration. */ +-#define MLXBF_I2C_COREPLL_CORE_F_TYU_MASK GENMASK(12, 0) +-#define MLXBF_I2C_COREPLL_CORE_OD_TYU_MASK GENMASK(3, 0) +-#define MLXBF_I2C_COREPLL_CORE_R_TYU_MASK GENMASK(5, 0) +- +-#define MLXBF_I2C_COREPLL_CORE_F_TYU_SHIFT 3 +-#define MLXBF_I2C_COREPLL_CORE_OD_TYU_SHIFT 16 +-#define MLXBF_I2C_COREPLL_CORE_R_TYU_SHIFT 20 ++#define MLXBF_I2C_COREPLL_CORE_F_TYU_MASK GENMASK(15, 3) ++#define MLXBF_I2C_COREPLL_CORE_OD_TYU_MASK GENMASK(19, 16) ++#define MLXBF_I2C_COREPLL_CORE_R_TYU_MASK GENMASK(25, 20) + + /* Core PLL YU configuration. */ + #define MLXBF_I2C_COREPLL_CORE_F_YU_MASK GENMASK(25, 0) + #define MLXBF_I2C_COREPLL_CORE_OD_YU_MASK GENMASK(3, 0) +-#define MLXBF_I2C_COREPLL_CORE_R_YU_MASK GENMASK(5, 0) ++#define MLXBF_I2C_COREPLL_CORE_R_YU_MASK GENMASK(31, 26) + +-#define MLXBF_I2C_COREPLL_CORE_F_YU_SHIFT 0 +-#define MLXBF_I2C_COREPLL_CORE_OD_YU_SHIFT 1 +-#define MLXBF_I2C_COREPLL_CORE_R_YU_SHIFT 26 + + /* Core PLL frequency. */ + static u64 mlxbf_i2c_corepll_frequency; +@@ -485,8 +480,6 @@ static struct mutex mlxbf_i2c_bus_lock; + #define MLXBF_I2C_MASK_8 GENMASK(7, 0) + #define MLXBF_I2C_MASK_16 GENMASK(15, 0) + +-#define MLXBF_I2C_FREQUENCY_1GHZ 1000000000 +- + /* + * Function to poll a set of bits at a specific address; it checks whether + * the bits are equal to zero when eq_zero is set to 'true', and not equal +@@ -1416,24 +1409,19 @@ static int mlxbf_i2c_init_master(struct platform_device *pdev, + return 0; + } + +-static u64 mlxbf_calculate_freq_from_tyu(struct mlxbf_i2c_resource *corepll_res) ++static u64 mlxbf_i2c_calculate_freq_from_tyu(struct mlxbf_i2c_resource *corepll_res) + { +- u64 core_frequency, pad_frequency; ++ u64 core_frequency; + u8 core_od, core_r; + u32 corepll_val; + u16 core_f; + +- pad_frequency = MLXBF_I2C_PLL_IN_FREQ; +- + corepll_val = readl(corepll_res->io + MLXBF_I2C_CORE_PLL_REG1); + + /* Get Core PLL configuration bits. */ +- core_f = rol32(corepll_val, MLXBF_I2C_COREPLL_CORE_F_TYU_SHIFT) & +- MLXBF_I2C_COREPLL_CORE_F_TYU_MASK; +- core_od = rol32(corepll_val, MLXBF_I2C_COREPLL_CORE_OD_TYU_SHIFT) & +- MLXBF_I2C_COREPLL_CORE_OD_TYU_MASK; +- core_r = rol32(corepll_val, MLXBF_I2C_COREPLL_CORE_R_TYU_SHIFT) & +- MLXBF_I2C_COREPLL_CORE_R_TYU_MASK; ++ core_f = FIELD_GET(MLXBF_I2C_COREPLL_CORE_F_TYU_MASK, corepll_val); ++ core_od = FIELD_GET(MLXBF_I2C_COREPLL_CORE_OD_TYU_MASK, corepll_val); ++ core_r = FIELD_GET(MLXBF_I2C_COREPLL_CORE_R_TYU_MASK, corepll_val); + + /* + * Compute PLL output frequency as follow: +@@ -1445,31 +1433,26 @@ static u64 mlxbf_calculate_freq_from_tyu(struct mlxbf_i2c_resource *corepll_res) + * Where PLL_OUT_FREQ and PLL_IN_FREQ refer to CoreFrequency + * and PadFrequency, respectively. + */ +- core_frequency = pad_frequency * (++core_f); ++ core_frequency = MLXBF_I2C_PLL_IN_FREQ * (++core_f); + core_frequency /= (++core_r) * (++core_od); + + return core_frequency; + } + +-static u64 mlxbf_calculate_freq_from_yu(struct mlxbf_i2c_resource *corepll_res) ++static u64 mlxbf_i2c_calculate_freq_from_yu(struct mlxbf_i2c_resource *corepll_res) + { + u32 corepll_reg1_val, corepll_reg2_val; +- u64 corepll_frequency, pad_frequency; ++ u64 corepll_frequency; + u8 core_od, core_r; + u32 core_f; + +- pad_frequency = MLXBF_I2C_PLL_IN_FREQ; +- + corepll_reg1_val = readl(corepll_res->io + MLXBF_I2C_CORE_PLL_REG1); + corepll_reg2_val = readl(corepll_res->io + MLXBF_I2C_CORE_PLL_REG2); + + /* Get Core PLL configuration bits */ +- core_f = rol32(corepll_reg1_val, MLXBF_I2C_COREPLL_CORE_F_YU_SHIFT) & +- MLXBF_I2C_COREPLL_CORE_F_YU_MASK; +- core_r = rol32(corepll_reg1_val, MLXBF_I2C_COREPLL_CORE_R_YU_SHIFT) & +- MLXBF_I2C_COREPLL_CORE_R_YU_MASK; +- core_od = rol32(corepll_reg2_val, MLXBF_I2C_COREPLL_CORE_OD_YU_SHIFT) & +- MLXBF_I2C_COREPLL_CORE_OD_YU_MASK; ++ core_f = FIELD_GET(MLXBF_I2C_COREPLL_CORE_F_YU_MASK, corepll_reg1_val); ++ core_r = FIELD_GET(MLXBF_I2C_COREPLL_CORE_R_YU_MASK, corepll_reg1_val); ++ core_od = FIELD_GET(MLXBF_I2C_COREPLL_CORE_OD_YU_MASK, corepll_reg2_val); + + /* + * Compute PLL output frequency as follow: +@@ -1481,7 +1464,7 @@ static u64 mlxbf_calculate_freq_from_yu(struct mlxbf_i2c_resource *corepll_res) + * Where PLL_OUT_FREQ and PLL_IN_FREQ refer to CoreFrequency + * and PadFrequency, respectively. + */ +- corepll_frequency = (pad_frequency * core_f) / MLNXBF_I2C_COREPLL_CONST; ++ corepll_frequency = (MLXBF_I2C_PLL_IN_FREQ * core_f) / MLNXBF_I2C_COREPLL_CONST; + corepll_frequency /= (++core_r) * (++core_od); + + return corepll_frequency; +@@ -2189,14 +2172,14 @@ static struct mlxbf_i2c_chip_info mlxbf_i2c_chip[] = { + [1] = &mlxbf_i2c_corepll_res[MLXBF_I2C_CHIP_TYPE_1], + [2] = &mlxbf_i2c_gpio_res[MLXBF_I2C_CHIP_TYPE_1] + }, +- .calculate_freq = mlxbf_calculate_freq_from_tyu ++ .calculate_freq = mlxbf_i2c_calculate_freq_from_tyu + }, + [MLXBF_I2C_CHIP_TYPE_2] = { + .type = MLXBF_I2C_CHIP_TYPE_2, + .shared_res = { + [0] = &mlxbf_i2c_corepll_res[MLXBF_I2C_CHIP_TYPE_2] + }, +- .calculate_freq = mlxbf_calculate_freq_from_yu ++ .calculate_freq = mlxbf_i2c_calculate_freq_from_yu + } + }; + +-- +2.35.1 + diff --git a/queue-5.10/i2c-mlxbf-incorrect-base-address-passed-during-io-wr.patch b/queue-5.10/i2c-mlxbf-incorrect-base-address-passed-during-io-wr.patch new file mode 100644 index 00000000000..1e758d43baf --- /dev/null +++ b/queue-5.10/i2c-mlxbf-incorrect-base-address-passed-during-io-wr.patch @@ -0,0 +1,40 @@ +From 801532afa7c2c68375010b0367051bb3fef71667 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 8 Sep 2022 13:35:38 -0400 +Subject: i2c: mlxbf: incorrect base address passed during io write + +From: Asmaa Mnebhi + +[ Upstream commit 2a5be6d1340c0fefcee8a6489cff7fd88a0d5b85 ] + +Correct the base address used during io write. +This bug had no impact over the overall functionality of the read and write +transactions. MLXBF_I2C_CAUSE_OR_CLEAR=0x18 so writing to (smbus->io + 0x18) +instead of (mst_cause->ioi + 0x18) actually writes to the sc_low_timeout +register which just sets the timeout value before a read/write aborts. + +Fixes: b5b5b32081cd206b (i2c: mlxbf: I2C SMBus driver for Mellanox BlueField SoC) +Reviewed-by: Khalil Blaiech +Signed-off-by: Asmaa Mnebhi +Signed-off-by: Wolfram Sang +Signed-off-by: Sasha Levin +--- + drivers/i2c/busses/i2c-mlxbf.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/i2c/busses/i2c-mlxbf.c b/drivers/i2c/busses/i2c-mlxbf.c +index ab261d762dea..042c83b90734 100644 +--- a/drivers/i2c/busses/i2c-mlxbf.c ++++ b/drivers/i2c/busses/i2c-mlxbf.c +@@ -675,7 +675,7 @@ static int mlxbf_i2c_smbus_enable(struct mlxbf_i2c_priv *priv, u8 slave, + /* Clear status bits. */ + writel(0x0, priv->smbus->io + MLXBF_I2C_SMBUS_MASTER_STATUS); + /* Set the cause data. */ +- writel(~0x0, priv->smbus->io + MLXBF_I2C_CAUSE_OR_CLEAR); ++ writel(~0x0, priv->mst_cause->io + MLXBF_I2C_CAUSE_OR_CLEAR); + /* Zero PEC byte. */ + writel(0x0, priv->smbus->io + MLXBF_I2C_SMBUS_MASTER_PEC); + /* Zero byte count. */ +-- +2.35.1 + diff --git a/queue-5.10/i2c-mlxbf-prevent-stack-overflow-in-mlxbf_i2c_smbus_.patch b/queue-5.10/i2c-mlxbf-prevent-stack-overflow-in-mlxbf_i2c_smbus_.patch new file mode 100644 index 00000000000..f1e361bef19 --- /dev/null +++ b/queue-5.10/i2c-mlxbf-prevent-stack-overflow-in-mlxbf_i2c_smbus_.patch @@ -0,0 +1,39 @@ +From 1b27dac8fea48cb2b7f8c9666b77b219d96d844c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 8 Sep 2022 13:35:39 -0400 +Subject: i2c: mlxbf: prevent stack overflow in + mlxbf_i2c_smbus_start_transaction() + +From: Asmaa Mnebhi + +[ Upstream commit de24aceb07d426b6f1c59f33889d6a964770547b ] + +memcpy() is called in a loop while 'operation->length' upper bound +is not checked and 'data_idx' also increments. + +Fixes: b5b5b32081cd206b ("i2c: mlxbf: I2C SMBus driver for Mellanox BlueField SoC") +Reviewed-by: Khalil Blaiech +Signed-off-by: Asmaa Mnebhi +Signed-off-by: Wolfram Sang +Signed-off-by: Sasha Levin +--- + drivers/i2c/busses/i2c-mlxbf.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/i2c/busses/i2c-mlxbf.c b/drivers/i2c/busses/i2c-mlxbf.c +index 042c83b90734..d78fb24d5588 100644 +--- a/drivers/i2c/busses/i2c-mlxbf.c ++++ b/drivers/i2c/busses/i2c-mlxbf.c +@@ -744,6 +744,9 @@ mlxbf_i2c_smbus_start_transaction(struct mlxbf_i2c_priv *priv, + if (flags & MLXBF_I2C_F_WRITE) { + write_en = 1; + write_len += operation->length; ++ if (data_idx + operation->length > ++ MLXBF_I2C_MASTER_DATA_DESC_SIZE) ++ return -ENOBUFS; + memcpy(data_desc + data_idx, + operation->buffer, operation->length); + data_idx += operation->length; +-- +2.35.1 + diff --git a/queue-5.10/series b/queue-5.10/series index 0e125418846..60ee4befa84 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -130,3 +130,8 @@ drm-amdgpu-use-dirty-framebuffer-helper.patch drm-amd-display-limit-user-regamma-to-a-valid-value.patch drm-amd-display-mark-dml30-s-useminimumdcfclk-as-noi.patch drm-rockchip-fix-return-type-of-cdn_dp_connector_mod.patch +workqueue-don-t-skip-lockdep-work-dependency-in-canc.patch +i2c-imx-if-pm_runtime_get_sync-returned-1-device-acc.patch +i2c-mlxbf-incorrect-base-address-passed-during-io-wr.patch +i2c-mlxbf-prevent-stack-overflow-in-mlxbf_i2c_smbus_.patch +i2c-mlxbf-fix-frequency-calculation.patch diff --git a/queue-5.10/workqueue-don-t-skip-lockdep-work-dependency-in-canc.patch b/queue-5.10/workqueue-don-t-skip-lockdep-work-dependency-in-canc.patch new file mode 100644 index 00000000000..9cd50d8569f --- /dev/null +++ b/queue-5.10/workqueue-don-t-skip-lockdep-work-dependency-in-canc.patch @@ -0,0 +1,98 @@ +From 510da9d168073f2fa2117e623caac852c35459e7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 29 Jul 2022 13:30:23 +0900 +Subject: workqueue: don't skip lockdep work dependency in cancel_work_sync() + +From: Tetsuo Handa + +[ Upstream commit c0feea594e058223973db94c1c32a830c9807c86 ] + +Like Hillf Danton mentioned + + syzbot should have been able to catch cancel_work_sync() in work context + by checking lockdep_map in __flush_work() for both flush and cancel. + +in [1], being unable to report an obvious deadlock scenario shown below is +broken. From locking dependency perspective, sync version of cancel request +should behave as if flush request, for it waits for completion of work if +that work has already started execution. + + ---------- + #include + #include + static DEFINE_MUTEX(mutex); + static void work_fn(struct work_struct *work) + { + schedule_timeout_uninterruptible(HZ / 5); + mutex_lock(&mutex); + mutex_unlock(&mutex); + } + static DECLARE_WORK(work, work_fn); + static int __init test_init(void) + { + schedule_work(&work); + schedule_timeout_uninterruptible(HZ / 10); + mutex_lock(&mutex); + cancel_work_sync(&work); + mutex_unlock(&mutex); + return -EINVAL; + } + module_init(test_init); + MODULE_LICENSE("GPL"); + ---------- + +The check this patch restores was added by commit 0976dfc1d0cd80a4 +("workqueue: Catch more locking problems with flush_work()"). + +Then, lockdep's crossrelease feature was added by commit b09be676e0ff25bd +("locking/lockdep: Implement the 'crossrelease' feature"). As a result, +this check was once removed by commit fd1a5b04dfb899f8 ("workqueue: Remove +now redundant lock acquisitions wrt. workqueue flushes"). + +But lockdep's crossrelease feature was removed by commit e966eaeeb623f099 +("locking/lockdep: Remove the cross-release locking checks"). At this +point, this check should have been restored. + +Then, commit d6e89786bed977f3 ("workqueue: skip lockdep wq dependency in +cancel_work_sync()") introduced a boolean flag in order to distinguish +flush_work() and cancel_work_sync(), for checking "struct workqueue_struct" +dependency when called from cancel_work_sync() was causing false positives. + +Then, commit 87915adc3f0acdf0 ("workqueue: re-add lockdep dependencies for +flushing") tried to restore "struct work_struct" dependency check, but by +error checked this boolean flag. Like an example shown above indicates, +"struct work_struct" dependency needs to be checked for both flush_work() +and cancel_work_sync(). + +Link: https://lkml.kernel.org/r/20220504044800.4966-1-hdanton@sina.com [1] +Reported-by: Hillf Danton +Suggested-by: Lai Jiangshan +Fixes: 87915adc3f0acdf0 ("workqueue: re-add lockdep dependencies for flushing") +Cc: Johannes Berg +Signed-off-by: Tetsuo Handa +Signed-off-by: Tejun Heo +Signed-off-by: Sasha Levin +--- + kernel/workqueue.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/kernel/workqueue.c b/kernel/workqueue.c +index fdf5fa4bf444..0cc2a62e88f9 100644 +--- a/kernel/workqueue.c ++++ b/kernel/workqueue.c +@@ -3047,10 +3047,8 @@ static bool __flush_work(struct work_struct *work, bool from_cancel) + if (WARN_ON(!work->func)) + return false; + +- if (!from_cancel) { +- lock_map_acquire(&work->lockdep_map); +- lock_map_release(&work->lockdep_map); +- } ++ lock_map_acquire(&work->lockdep_map); ++ lock_map_release(&work->lockdep_map); + + if (start_flush_work(work, &barr, from_cancel)) { + wait_for_completion(&barr.done); +-- +2.35.1 + -- 2.47.3