From: "Maciej W. Rozycki" macro@mips.com
[ Upstream commit 2f819db565e82e5f73cd42b39925098986693378 ]
The regset API documented in <linux/regset.h> defines -ENODEV as the result of the `->active' handler to be used where the feature requested is not available on the hardware found. However code handling core file note generation in `fill_thread_core_info' interpretes any non-zero result from the `->active' handler as the regset requested being active. Consequently processing continues (and hopefully gracefully fails later on) rather than being abandoned right away for the regset requested.
Fix the problem then by making the code proceed only if a positive result is returned from the `->active' handler.
Signed-off-by: Maciej W. Rozycki macro@mips.com Signed-off-by: Paul Burton paul.burton@mips.com Fixes: 4206d3aa1978 ("elf core dump: notes user_regset") Patchwork: https://patchwork.linux-mips.org/patch/19332/ Cc: Alexander Viro viro@zeniv.linux.org.uk Cc: James Hogan jhogan@kernel.org Cc: Ralf Baechle ralf@linux-mips.org Cc: linux-fsdevel@vger.kernel.org Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- fs/binfmt_elf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index c0e3f91e28e9..469666df91da 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -1725,7 +1725,7 @@ static int fill_thread_core_info(struct elf_thread_core_info *t, const struct user_regset *regset = &view->regsets[i]; do_thread_regset_writeback(t->task, regset); if (regset->core_note_type && regset->get && - (!regset->active || regset->active(t->task, regset))) { + (!regset->active || regset->active(t->task, regset) > 0)) { int ret; size_t size = regset->n * regset->size; void *data = kmalloc(size, GFP_KERNEL);
From: Noa Osherovich noaos@mellanox.com
[ Upstream commit 0f4039104ee61e14ac4771a2181c2a20572f4ec9 ]
When translating command opcodes to a string, SET_DRIVER_VERSION command was missing.
Fixes: 42ca502e179d0 ('net/mlx5_core: Use a macro in mlx5_command_str()') Signed-off-by: Noa Osherovich noaos@mellanox.com Signed-off-by: Saeed Mahameed saeedm@mellanox.com Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- drivers/net/ethernet/mellanox/mlx5/core/cmd.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c index cf94fdf25155..c7654209668b 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c @@ -449,6 +449,7 @@ const char *mlx5_command_str(int command) MLX5_COMMAND_STR_CASE(SET_HCA_CAP); MLX5_COMMAND_STR_CASE(QUERY_ISSI); MLX5_COMMAND_STR_CASE(SET_ISSI); + MLX5_COMMAND_STR_CASE(SET_DRIVER_VERSION); MLX5_COMMAND_STR_CASE(CREATE_MKEY); MLX5_COMMAND_STR_CASE(QUERY_MKEY); MLX5_COMMAND_STR_CASE(DESTROY_MKEY);
From: Viresh Kumar viresh.kumar@linaro.org
[ Upstream commit af0e09d0c6762e486b0eb5cc4737396964c34fad ]
The cooling device properties, like "#cooling-cells" and "dynamic-power-coefficient", should either be present for all the CPUs of a cluster or none. If these are present only for a subset of CPUs of a cluster then things will start falling apart as soon as the CPUs are brought online in a different order. For example, this will happen because the operating system looks for such properties in the CPU node it is trying to bring up, so that it can register a cooling device.
Add such missing properties.
Signed-off-by: Viresh Kumar viresh.kumar@linaro.org Signed-off-by: Masahiro Yamada yamada.masahiro@socionext.com Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- arch/arm64/boot/dts/socionext/uniphier-ld20.dtsi | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/arch/arm64/boot/dts/socionext/uniphier-ld20.dtsi b/arch/arm64/boot/dts/socionext/uniphier-ld20.dtsi index a29c279b6e8e..dba6f0ff8106 100644 --- a/arch/arm64/boot/dts/socionext/uniphier-ld20.dtsi +++ b/arch/arm64/boot/dts/socionext/uniphier-ld20.dtsi @@ -55,6 +55,7 @@ clocks = <&sys_clk 32>; enable-method = "psci"; operating-points-v2 = <&cluster0_opp>; + #cooling-cells = <2>; };
cpu2: cpu@100 { @@ -73,6 +74,7 @@ clocks = <&sys_clk 33>; enable-method = "psci"; operating-points-v2 = <&cluster1_opp>; + #cooling-cells = <2>; }; };
From: Ronny Chevalier ronny.chevalier@hp.com
[ Upstream commit baa2a4fdd525c8c4b0f704d20457195b29437839 ]
audit_add_watch stores locally krule->watch without taking a reference on watch. Then, it calls audit_add_to_parent, and uses the watch stored locally.
Unfortunately, it is possible that audit_add_to_parent updates krule->watch. When it happens, it also drops a reference of watch which could free the watch.
How to reproduce (with KASAN enabled):
auditctl -w /etc/passwd -F success=0 -k test_passwd auditctl -w /etc/passwd -F success=1 -k test_passwd2
The second call to auditctl triggers the use-after-free, because audit_to_parent updates krule->watch to use a previous existing watch and drops the reference to the newly created watch.
To fix the issue, we grab a reference of watch and we release it at the end of the function.
Signed-off-by: Ronny Chevalier ronny.chevalier@hp.com Reviewed-by: Richard Guy Briggs rgb@redhat.com Signed-off-by: Paul Moore paul@paul-moore.com Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- kernel/audit_watch.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/kernel/audit_watch.c b/kernel/audit_watch.c index 9eb8b3511636..4a98f6e314a9 100644 --- a/kernel/audit_watch.c +++ b/kernel/audit_watch.c @@ -419,6 +419,13 @@ int audit_add_watch(struct audit_krule *krule, struct list_head **list) struct path parent_path; int h, ret = 0;
+ /* + * When we will be calling audit_add_to_parent, krule->watch might have + * been updated and watch might have been freed. + * So we need to keep a reference of watch. + */ + audit_get_watch(watch); + mutex_unlock(&audit_filter_mutex);
/* Avoid calling path_lookup under audit_filter_mutex. */ @@ -427,8 +434,10 @@ int audit_add_watch(struct audit_krule *krule, struct list_head **list) /* caller expects mutex locked */ mutex_lock(&audit_filter_mutex);
- if (ret) + if (ret) { + audit_put_watch(watch); return ret; + }
/* either find an old parent or attach a new one */ parent = audit_find_parent(d_backing_inode(parent_path.dentry)); @@ -446,6 +455,7 @@ int audit_add_watch(struct audit_krule *krule, struct list_head **list) *list = &audit_inode_hash[h]; error: path_put(&parent_path); + audit_put_watch(watch); return ret; }
From: Jann Horn jannh@google.com
[ Upstream commit 6c6bc9ea84d0008024606bf5ba10519e20d851bf ]
The first checks in mtdchar_read() and mtdchar_write() attempt to limit `count` such that `*ppos + count <= mtd->size`. However, they ignore the possibility of `*ppos > mtd->size`, allowing the calculation of `count` to wrap around. `mtdchar_lseek()` prevents seeking beyond mtd->size, but the pread/pwrite syscalls bypass this.
I haven't found any codepath on which this actually causes dangerous behavior, but it seems like a sensible change anyway.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Jann Horn jannh@google.com Signed-off-by: Boris Brezillon boris.brezillon@bootlin.com Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- drivers/mtd/mtdchar.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c index b25f444c5914..fa4d12217652 100644 --- a/drivers/mtd/mtdchar.c +++ b/drivers/mtd/mtdchar.c @@ -160,8 +160,12 @@ static ssize_t mtdchar_read(struct file *file, char __user *buf, size_t count,
pr_debug("MTD_read\n");
- if (*ppos + count > mtd->size) - count = mtd->size - *ppos; + if (*ppos + count > mtd->size) { + if (*ppos < mtd->size) + count = mtd->size - *ppos; + else + count = 0; + }
if (!count) return 0; @@ -246,7 +250,7 @@ static ssize_t mtdchar_write(struct file *file, const char __user *buf, size_t c
pr_debug("MTD_write\n");
- if (*ppos == mtd->size) + if (*ppos >= mtd->size) return -ENOSPC;
if (*ppos + count > mtd->size)
From: Philipp Puschmann pp@emlix.com
[ Upstream commit b71c69c26b4916d11b8d403d8e667bbd191f1b8f ]
Fixes this warning that was provoked by a pairing:
[60258.016221] WARNING: possible recursive locking detected [60258.021558] 4.15.0-RD1812-BSP #1 Tainted: G O [60258.027146] -------------------------------------------- [60258.032464] kworker/u5:0/70 is trying to acquire lock: [60258.037609] (sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP){+.+.}, at: [<87759073>] bt_accept_enqueue+0x3c/0x74 [60258.046863] [60258.046863] but task is already holding lock: [60258.052704] (sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP){+.+.}, at: [<d22d7106>] l2cap_sock_new_connection_cb+0x1c/0x88 [60258.062905] [60258.062905] other info that might help us debug this: [60258.069441] Possible unsafe locking scenario: [60258.069441] [60258.075368] CPU0 [60258.077821] ---- [60258.080272] lock(sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP); [60258.085510] lock(sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP); [60258.090748] [60258.090748] *** DEADLOCK *** [60258.090748] [60258.096676] May be due to missing lock nesting notation [60258.096676] [60258.103472] 5 locks held by kworker/u5:0/70: [60258.107747] #0: ((wq_completion)%shdev->name#2){+.+.}, at: [<9460d092>] process_one_work+0x130/0x4fc [60258.117263] #1: ((work_completion)(&hdev->rx_work)){+.+.}, at: [<9460d092>] process_one_work+0x130/0x4fc [60258.126942] #2: (&conn->chan_lock){+.+.}, at: [<7877c8c3>] l2cap_connect+0x80/0x4f8 [60258.134806] #3: (&chan->lock/2){+.+.}, at: [<2e16c724>] l2cap_connect+0x8c/0x4f8 [60258.142410] #4: (sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP){+.+.}, at: [<d22d7106>] l2cap_sock_new_connection_cb+0x1c/0x88 [60258.153043] [60258.153043] stack backtrace: [60258.157413] CPU: 1 PID: 70 Comm: kworker/u5:0 Tainted: G O 4.15.0-RD1812-BSP #1 [60258.165945] Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree) [60258.172485] Workqueue: hci0 hci_rx_work [60258.176331] Backtrace: [60258.178797] [<8010c9fc>] (dump_backtrace) from [<8010ccbc>] (show_stack+0x18/0x1c) [60258.186379] r7:80e55fe4 r6:80e55fe4 r5:20050093 r4:00000000 [60258.192058] [<8010cca4>] (show_stack) from [<809864e8>] (dump_stack+0xb0/0xdc) [60258.199301] [<80986438>] (dump_stack) from [<8016ecc8>] (__lock_acquire+0xffc/0x11d4) [60258.207144] r9:5e2bb019 r8:630f974c r7:ba8a5940 r6:ba8a5ed8 r5:815b5220 r4:80fa081c [60258.214901] [<8016dccc>] (__lock_acquire) from [<8016f620>] (lock_acquire+0x78/0x98) [60258.222655] r10:00000040 r9:00000040 r8:808729f0 r7:00000001 r6:00000000 r5:60050013 [60258.230491] r4:00000000 [60258.233045] [<8016f5a8>] (lock_acquire) from [<806ee974>] (lock_sock_nested+0x64/0x88) [60258.240970] r7:00000000 r6:b796e870 r5:00000001 r4:b796e800 [60258.246643] [<806ee910>] (lock_sock_nested) from [<808729f0>] (bt_accept_enqueue+0x3c/0x74) [60258.255004] r8:00000001 r7:ba7d3c00 r6:ba7d3ea4 r5:ba7d2000 r4:b796e800 [60258.261717] [<808729b4>] (bt_accept_enqueue) from [<808aa39c>] (l2cap_sock_new_connection_cb+0x68/0x88) [60258.271117] r5:b796e800 r4:ba7d2000 [60258.274708] [<808aa334>] (l2cap_sock_new_connection_cb) from [<808a294c>] (l2cap_connect+0x190/0x4f8) [60258.283933] r5:00000001 r4:ba6dce00 [60258.287524] [<808a27bc>] (l2cap_connect) from [<808a4a14>] (l2cap_recv_frame+0x744/0x2cf8) [60258.295800] r10:ba6dcf24 r9:00000004 r8:b78d8014 r7:00000004 r6:bb05d000 r5:00000004 [60258.303635] r4:bb05d008 [60258.306183] [<808a42d0>] (l2cap_recv_frame) from [<808a7808>] (l2cap_recv_acldata+0x210/0x214) [60258.314805] r10:b78e7800 r9:bb05d960 r8:00000001 r7:bb05d000 r6:0000000c r5:b7957a80 [60258.322641] r4:ba6dce00 [60258.325188] [<808a75f8>] (l2cap_recv_acldata) from [<8087630c>] (hci_rx_work+0x35c/0x4e8) [60258.333374] r6:80e5743c r5:bb05d7c8 r4:b7957a80 [60258.338004] [<80875fb0>] (hci_rx_work) from [<8013dc7c>] (process_one_work+0x1a4/0x4fc) [60258.346018] r10:00000001 r9:00000000 r8:baabfef8 r7:ba997500 r6:baaba800 r5:baaa5d00 [60258.353853] r4:bb05d7c8 [60258.356401] [<8013dad8>] (process_one_work) from [<8013e028>] (worker_thread+0x54/0x5cc) [60258.364503] r10:baabe038 r9:baaba834 r8:80e05900 r7:00000088 r6:baaa5d18 r5:baaba800 [60258.372338] r4:baaa5d00 [60258.374888] [<8013dfd4>] (worker_thread) from [<801448f8>] (kthread+0x134/0x160) [60258.382295] r10:ba8310b8 r9:bb07dbfc r8:8013dfd4 r7:baaa5d00 r6:00000000 r5:baaa8ac0 [60258.390130] r4:ba831080 [60258.392682] [<801447c4>] (kthread) from [<801080b4>] (ret_from_fork+0x14/0x20) [60258.399915] r10:00000000 r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:801447c4 [60258.407751] r4:baaa8ac0 r3:baabe000
Signed-off-by: Philipp Puschmann pp@emlix.com Signed-off-by: Marcel Holtmann marcel@holtmann.org Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- net/bluetooth/af_bluetooth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index 91e3ba280706..583951e82cee 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c @@ -159,7 +159,7 @@ void bt_accept_enqueue(struct sock *parent, struct sock *sk) BT_DBG("parent %p, sk %p", parent, sk);
sock_hold(sk); - lock_sock(sk); + lock_sock_nested(sk, SINGLE_DEPTH_NESTING); list_add_tail(&bt_sk(sk)->accept_q, &bt_sk(parent)->accept_q); bt_sk(sk)->parent = parent; release_sock(sk);
From: Miklos Szeredi mszeredi@redhat.com
[ Upstream commit a6795a585929d94ca3e931bc8518f8deb8bbe627 ]
The underlying real file used by overlayfs still contains the overlay path. This results in mnt_want_write_file() calls by the filesystem getting freeze protection on the wrong inode (the overlayfs one instead of the real one).
Fix by using file_inode(file)->i_sb instead of file->f_path.mnt->mnt_sb.
Reported-by: Amir Goldstein amir73il@gmail.com Signed-off-by: Miklos Szeredi mszeredi@redhat.com Reviewed-by: Christoph Hellwig hch@lst.de Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- fs/namespace.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/fs/namespace.c b/fs/namespace.c index 9dc146e7b5e0..3ee3ee5819bc 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -446,10 +446,10 @@ int mnt_want_write_file_path(struct file *file) { int ret;
- sb_start_write(file->f_path.mnt->mnt_sb); + sb_start_write(file_inode(file)->i_sb); ret = __mnt_want_write_file(file); if (ret) - sb_end_write(file->f_path.mnt->mnt_sb); + sb_end_write(file_inode(file)->i_sb); return ret; }
@@ -540,7 +540,8 @@ void __mnt_drop_write_file(struct file *file)
void mnt_drop_write_file_path(struct file *file) { - mnt_drop_write(file->f_path.mnt); + __mnt_drop_write_file(file); + sb_end_write(file_inode(file)->i_sb); }
void mnt_drop_write_file(struct file *file)
From: Boris Brezillon boris.brezillon@bootlin.com
[ Upstream commit cf3e3fd2e94f4648f17fbd5e0e26409d5d1face9 ]
Fixes the "warning: large integer implicitly truncated to unsigned type [-Woverflow]" warning when compiled for x86.
This is needed in order to allow compiling this driver when COMPILE_TEST=y.
Reported-by: Stephen Rothwell sfr@canb.auug.org.au Signed-off-by: Boris Brezillon boris.brezillon@bootlin.com Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- drivers/mtd/nand/sunxi_nand.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/mtd/nand/sunxi_nand.c b/drivers/mtd/nand/sunxi_nand.c index 958974821582..7c227d1a3152 100644 --- a/drivers/mtd/nand/sunxi_nand.c +++ b/drivers/mtd/nand/sunxi_nand.c @@ -127,7 +127,7 @@ #define NFC_CMD_TYPE_MSK GENMASK(31, 30) #define NFC_NORMAL_OP (0 << 30) #define NFC_ECC_OP (1 << 30) -#define NFC_PAGE_OP (2 << 30) +#define NFC_PAGE_OP (2U << 30)
/* define bit use in NFC_RCMD_SET */ #define NFC_READ_CMD_MSK GENMASK(7, 0)
From: Matthew Garrett mjg59@google.com
[ Upstream commit e2861fa71641c6414831d628a1f4f793b6562580 ]
When EVM attempts to appraise a file signed with a crypto algorithm the kernel doesn't have support for, it will cause the kernel to trigger a module load. If the EVM policy includes appraisal of kernel modules this will in turn call back into EVM - since EVM is holding a lock until the crypto initialisation is complete, this triggers a deadlock. Add a CRYPTO_NOLOAD flag and skip module loading if it's set, and add that flag in the EVM case in order to fail gracefully with an error message instead of deadlocking.
Signed-off-by: Matthew Garrett mjg59@google.com Acked-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Mimi Zohar zohar@linux.vnet.ibm.com Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- crypto/api.c | 2 +- include/linux/crypto.h | 5 +++++ security/integrity/evm/evm_crypto.c | 3 ++- 3 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/crypto/api.c b/crypto/api.c index 941cd4c6c7ec..e485aed11ad0 100644 --- a/crypto/api.c +++ b/crypto/api.c @@ -215,7 +215,7 @@ struct crypto_alg *crypto_larval_lookup(const char *name, u32 type, u32 mask) mask &= ~(CRYPTO_ALG_LARVAL | CRYPTO_ALG_DEAD);
alg = crypto_alg_lookup(name, type, mask); - if (!alg) { + if (!alg && !(mask & CRYPTO_NOLOAD)) { request_module("crypto-%s", name);
if (!((type ^ CRYPTO_ALG_NEED_FALLBACK) & mask & diff --git a/include/linux/crypto.h b/include/linux/crypto.h index cc36484d29e1..de96913306cb 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -111,6 +111,11 @@ */ #define CRYPTO_ALG_OPTIONAL_KEY 0x00004000
+/* + * Don't trigger module loading + */ +#define CRYPTO_NOLOAD 0x00008000 + /* * Transform masks and values (for crt_flags). */ diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c index 1d32cd20009a..ee9c3de5065a 100644 --- a/security/integrity/evm/evm_crypto.c +++ b/security/integrity/evm/evm_crypto.c @@ -94,7 +94,8 @@ static struct shash_desc *init_desc(char type) mutex_lock(&mutex); if (*tfm) goto out; - *tfm = crypto_alloc_shash(algo, 0, CRYPTO_ALG_ASYNC); + *tfm = crypto_alloc_shash(algo, 0, + CRYPTO_ALG_ASYNC | CRYPTO_NOLOAD); if (IS_ERR(*tfm)) { rc = PTR_ERR(*tfm); pr_err("Can not allocate %s (reason: %ld)\n", algo, rc);
From: Nicholas Mc Guire hofrat@osadl.org
[ Upstream commit 51eaa08f029c7343df846325d7cf047be8b96e81 ]
The call to of_find_compatible_node() is returning a pointer with incremented refcount so it must be explicitly decremented after the last use. As here it is only being used for checking of node presence but the result is not actually used in the success path it can be dropped immediately.
Signed-off-by: Nicholas Mc Guire hofrat@osadl.org Fixes: commit f725758b899f ("KVM: PPC: Book3S HV: Use OPAL XICS emulation on POWER9") Signed-off-by: Paul Mackerras paulus@ozlabs.org Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- arch/powerpc/kvm/book3s_hv.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index 377d1420bd02..58746328b9bd 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -4356,6 +4356,8 @@ static int kvmppc_book3s_init_hv(void) pr_err("KVM-HV: Cannot determine method for accessing XICS\n"); return -ENODEV; } + /* presence of intc confirmed - node can be dropped again */ + of_node_put(np); } #endif
From: Eric Biggers ebiggers@google.com
[ Upstream commit 87ea58433208d17295e200d56be5e2a4fe4ce7d6 ]
lsm_append() should return -ENOMEM if memory allocation failed.
Fixes: d69dece5f5b6 ("LSM: Add /sys/kernel/security/lsm") Signed-off-by: Eric Biggers ebiggers@google.com Signed-off-by: James Morris james.morris@microsoft.com Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- security/security.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/security/security.c b/security/security.c index 4bf0f571b4ef..95a1a0f52880 100644 --- a/security/security.c +++ b/security/security.c @@ -111,6 +111,8 @@ static int lsm_append(char *new, char **result)
if (*result == NULL) { *result = kstrdup(new, GFP_KERNEL); + if (*result == NULL) + return -ENOMEM; } else { /* Check if it is the last registered name */ if (match_last_lsm(*result, new))
From: Arvind Yadav arvind.yadav.cs@gmail.com
[ Upstream commit 2d803dc8f7a5f622ac47c3b650834ada3a2659b9 ]
Never directly free @dev after calling device_register() or device_unregister(), even if device_register() returned an error. Always use put_device() to give up the reference initialized.
Signed-off-by: Arvind Yadav arvind.yadav.cs@gmail.com Reviewed-by: Chanwoo Choi cw00.choi@samsung.com Signed-off-by: MyungJoo Ham myungjoo.ham@samsung.com Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- drivers/devfreq/devfreq.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index 8a411514a7c5..cb3f3d33557e 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -564,7 +564,8 @@ struct devfreq *devfreq_add_device(struct device *dev, err = device_register(&devfreq->dev); if (err) { mutex_unlock(&devfreq->lock); - goto err_dev; + put_device(&devfreq->dev); + goto err_out; }
devfreq->trans_table = devm_kzalloc(&devfreq->dev, @@ -610,6 +611,7 @@ err_init: mutex_unlock(&devfreq_list_lock);
device_unregister(&devfreq->dev); + devfreq = NULL; err_dev: if (devfreq) kfree(devfreq);
From: Paul Burton paul.burton@mips.com
[ Upstream commit cd87668d601f622e0ebcfea4f78d116d5f572f4d ]
The PCI_OHCI_INT_REG case in pci_ohci_read_reg() contains the following if statement:
if ((lo & 0x00000f00) == CS5536_USB_INTR)
CS5536_USB_INTR expands to the constant 11, which gives us the following condition which can never evaluate true:
if ((lo & 0xf00) == 11)
At least when using GCC 8.1.0 this falls foul of the tautoligcal-compare warning, and since the code is built with the -Werror flag the build fails.
Fix this by shifting lo right by 8 bits in order to match the corresponding PCI_OHCI_INT_REG case in pci_ohci_write_reg().
Signed-off-by: Paul Burton paul.burton@mips.com Patchwork: https://patchwork.linux-mips.org/patch/19861/ Cc: Huacai Chen chenhc@lemote.com Cc: James Hogan jhogan@kernel.org Cc: Ralf Baechle ralf@linux-mips.org Cc: linux-mips@linux-mips.org Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- arch/mips/loongson64/common/cs5536/cs5536_ohci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/mips/loongson64/common/cs5536/cs5536_ohci.c b/arch/mips/loongson64/common/cs5536/cs5536_ohci.c index f7c905e50dc4..92dc6bafc127 100644 --- a/arch/mips/loongson64/common/cs5536/cs5536_ohci.c +++ b/arch/mips/loongson64/common/cs5536/cs5536_ohci.c @@ -138,7 +138,7 @@ u32 pci_ohci_read_reg(int reg) break; case PCI_OHCI_INT_REG: _rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo); - if ((lo & 0x00000f00) == CS5536_USB_INTR) + if (((lo >> PIC_YSEL_LOW_USB_SHIFT) & 0xf) == CS5536_USB_INTR) conf_data = 1; break; default:
From: Mike Christie mchristi@redhat.com
[ Upstream commit cc57c07343bd071cdf1915a91a24ab7d40c9b590 ]
This patch fixes a bug where configfs_register_group had added a group in a tree, and userspace has done a rmdir on a dir somewhere above that group and we hit a kernel crash. The problem is configfs_rmdir will detach everything under it and unlink groups on the default_groups list. It will not unlink groups added with configfs_register_group so when configfs_unregister_group is called to drop its references to the group/items we crash when we try to access the freed dentrys.
The patch just adds a check for if a rmdir has been done above us and if so just does the unlink part of unregistration.
Sorry if you are getting this multiple times. I thouhgt I sent this to some of you and lkml, but I do not see it.
Signed-off-by: Mike Christie mchristi@redhat.com Cc: Christoph Hellwig hch@lst.de Cc: Joel Becker jlbec@evilplan.org Signed-off-by: Christoph Hellwig hch@lst.de Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- fs/configfs/dir.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c index 56fb26127fef..d2a1a79fa324 100644 --- a/fs/configfs/dir.c +++ b/fs/configfs/dir.c @@ -1777,6 +1777,16 @@ void configfs_unregister_group(struct config_group *group) struct dentry *dentry = group->cg_item.ci_dentry; struct dentry *parent = group->cg_item.ci_parent->ci_dentry;
+ mutex_lock(&subsys->su_mutex); + if (!group->cg_item.ci_parent->ci_group) { + /* + * The parent has already been unlinked and detached + * due to a rmdir. + */ + goto unlink_group; + } + mutex_unlock(&subsys->su_mutex); + inode_lock_nested(d_inode(parent), I_MUTEX_PARENT); spin_lock(&configfs_dirent_lock); configfs_detach_prep(dentry, NULL); @@ -1791,6 +1801,7 @@ void configfs_unregister_group(struct config_group *group) dput(dentry);
mutex_lock(&subsys->su_mutex); +unlink_group: unlink_group(group); mutex_unlock(&subsys->su_mutex); }
From: Tony Lindgren tony@atomide.com
[ Upstream commit dc4003d260594aa300028c3c5d040c5719abd19b ]
We must use a mutex around the generic_add functions and save the function and group selector in case we need to remove them. Otherwise the selector use will be racy for deferred probe at least.
Fixes: 5a49b644b307 ("pinctrl: Renesas RZ/A1 pin and gpio controller") Reported-by: H. Nikolaus Schaller hns@goldelico.com Cc: Christ van Willegen cvwillegen@gmail.com Cc: Haojian Zhuang haojian.zhuang@linaro.org Cc: Paul Cercueil paul@crapouillou.net Cc: Sean Wang sean.wang@mediatek.com Acked-by: Jacopo Mondi jacopo@jmondi.org Signed-off-by: Tony Lindgren tony@atomide.com Tested-By: H. Nikolaus Schaller hns@goldelico.com Reviewed-by: Andy Shevchenko andy.shevchenko@gmail.com Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- drivers/pinctrl/pinctrl-rza1.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-)
diff --git a/drivers/pinctrl/pinctrl-rza1.c b/drivers/pinctrl/pinctrl-rza1.c index 04d058706b80..a865dc56a491 100644 --- a/drivers/pinctrl/pinctrl-rza1.c +++ b/drivers/pinctrl/pinctrl-rza1.c @@ -878,6 +878,7 @@ static int rza1_dt_node_to_map(struct pinctrl_dev *pctldev, const char *grpname; const char **fngrps; int ret, npins; + int gsel, fsel;
npins = rza1_dt_node_pin_count(np); if (npins < 0) { @@ -927,18 +928,19 @@ static int rza1_dt_node_to_map(struct pinctrl_dev *pctldev, fngrps[0] = grpname;
mutex_lock(&rza1_pctl->mutex); - ret = pinctrl_generic_add_group(pctldev, grpname, grpins, npins, - NULL); - if (ret) { + gsel = pinctrl_generic_add_group(pctldev, grpname, grpins, npins, + NULL); + if (gsel < 0) { mutex_unlock(&rza1_pctl->mutex); - return ret; + return gsel; }
- ret = pinmux_generic_add_function(pctldev, grpname, fngrps, 1, - mux_confs); - if (ret) + fsel = pinmux_generic_add_function(pctldev, grpname, fngrps, 1, + mux_confs); + if (fsel < 0) { + ret = fsel; goto remove_group; - mutex_unlock(&rza1_pctl->mutex); + }
dev_info(rza1_pctl->dev, "Parsed function and group %s with %d pins\n", grpname, npins); @@ -955,15 +957,15 @@ static int rza1_dt_node_to_map(struct pinctrl_dev *pctldev, (*map)->data.mux.group = np->name; (*map)->data.mux.function = np->name; *num_maps = 1; + mutex_unlock(&rza1_pctl->mutex);
return 0;
remove_function: - mutex_lock(&rza1_pctl->mutex); - pinmux_generic_remove_last_function(pctldev); + pinmux_generic_remove_function(pctldev, fsel);
remove_group: - pinctrl_generic_remove_last_group(pctldev); + pinctrl_generic_remove_group(pctldev, gsel); mutex_unlock(&rza1_pctl->mutex);
dev_info(rza1_pctl->dev, "Unable to parse function and group %s\n",
From: Tony Lindgren tony@atomide.com
[ Upstream commit f913cfce4ee49a3382a9ff95696f49a46e56e974 ]
We must return the selector from pinmux_generic_add_function() so pin controller device drivers can remove the right group if needed for deferred probe for example. And we now must make sure that a proper name is passed so we can use it to check if the entry already exists.
Note that fixes are also needed for the pin controller drivers to use the selector value.
Fixes: a76edc89b100 ("pinctrl: core: Add generic pinctrl functions for managing groups") Reported-by: H. Nikolaus Schaller hns@goldelico.com Cc: Christ van Willegen cvwillegen@gmail.com Cc: Haojian Zhuang haojian.zhuang@linaro.org Cc: Jacopo Mondi jacopo+renesas@jmondi.org Cc: Paul Cercueil paul@crapouillou.net Cc: Sean Wang sean.wang@mediatek.com Signed-off-by: Tony Lindgren tony@atomide.com Tested-By: H. Nikolaus Schaller hns@goldelico.com Reviewed-by: Andy Shevchenko andy.shevchenko@gmail.com Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- drivers/pinctrl/pinmux.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index 55502fc4479c..ec41ed209380 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c @@ -308,7 +308,6 @@ static int pinmux_func_name_to_selector(struct pinctrl_dev *pctldev, selector++; }
- dev_err(pctldev->dev, "function '%s' not supported\n", function); return -EINVAL; }
@@ -777,6 +776,16 @@ int pinmux_generic_add_function(struct pinctrl_dev *pctldev, void *data) { struct function_desc *function; + int selector; + + if (!name) + return -EINVAL; + + selector = pinmux_func_name_to_selector(pctldev, name); + if (selector >= 0) + return selector; + + selector = pctldev->num_functions;
function = devm_kzalloc(pctldev->dev, sizeof(*function), GFP_KERNEL); if (!function) @@ -787,12 +796,11 @@ int pinmux_generic_add_function(struct pinctrl_dev *pctldev, function->num_group_names = num_groups; function->data = data;
- radix_tree_insert(&pctldev->pin_function_tree, pctldev->num_functions, - function); + radix_tree_insert(&pctldev->pin_function_tree, selector, function);
pctldev->num_functions++;
- return 0; + return selector; } EXPORT_SYMBOL_GPL(pinmux_generic_add_function);
From: Andrea Parri andrea.parri@amarulasolutions.com
[ Upstream commit 76e079fefc8f62bd9b2cd2950814d1ee806e31a5 ]
wake_woken_function() synchronizes with wait_woken() as follows:
[wait_woken] [wake_woken_function]
entry->flags &= ~wq_flag_woken; condition = true; smp_mb(); smp_wmb(); if (condition) wq_entry->flags |= wq_flag_woken; break;
This commit replaces the above smp_wmb() with an smp_mb() in order to guarantee that either wait_woken() sees the wait condition being true or the store to wq_entry->flags in woken_wake_function() follows the store in wait_woken() in the coherence order (so that the former can eventually be observed by wait_woken()).
The commit also fixes a comment associated to set_current_state() in wait_woken(): the comment pairs the barrier in set_current_state() to the above smp_wmb(), while the actual pairing involves the barrier in set_current_state() and the barrier executed by the try_to_wake_up() in wake_woken_function().
Signed-off-by: Andrea Parri andrea.parri@amarulasolutions.com Signed-off-by: Paul E. McKenney paulmck@linux.vnet.ibm.com Acked-by: Peter Zijlstra (Intel) peterz@infradead.org Cc: Linus Torvalds torvalds@linux-foundation.org Cc: Peter Zijlstra peterz@infradead.org Cc: Thomas Gleixner tglx@linutronix.de Cc: akiyks@gmail.com Cc: boqun.feng@gmail.com Cc: dhowells@redhat.com Cc: j.alglave@ucl.ac.uk Cc: linux-arch@vger.kernel.org Cc: luc.maranget@inria.fr Cc: npiggin@gmail.com Cc: parri.andrea@gmail.com Cc: stern@rowland.harvard.edu Cc: will.deacon@arm.com Link: http://lkml.kernel.org/r/20180716180605.16115-10-paulmck@linux.vnet.ibm.com Signed-off-by: Ingo Molnar mingo@kernel.org Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- kernel/sched/wait.c | 47 ++++++++++++++++++++------------------------- 1 file changed, 21 insertions(+), 26 deletions(-)
diff --git a/kernel/sched/wait.c b/kernel/sched/wait.c index 929ecb7d6b78..e29608464382 100644 --- a/kernel/sched/wait.c +++ b/kernel/sched/wait.c @@ -395,35 +395,36 @@ static inline bool is_kthread_should_stop(void) * if (condition) * break; * - * p->state = mode; condition = true; - * smp_mb(); // A smp_wmb(); // C - * if (!wq_entry->flags & WQ_FLAG_WOKEN) wq_entry->flags |= WQ_FLAG_WOKEN; - * schedule() try_to_wake_up(); - * p->state = TASK_RUNNING; ~~~~~~~~~~~~~~~~~~ - * wq_entry->flags &= ~WQ_FLAG_WOKEN; condition = true; - * smp_mb() // B smp_wmb(); // C - * wq_entry->flags |= WQ_FLAG_WOKEN; - * } - * remove_wait_queue(&wq_head, &wait); + * // in wait_woken() // in woken_wake_function() * + * p->state = mode; wq_entry->flags |= WQ_FLAG_WOKEN; + * smp_mb(); // A try_to_wake_up(): + * if (!(wq_entry->flags & WQ_FLAG_WOKEN)) <full barrier> + * schedule() if (p->state & mode) + * p->state = TASK_RUNNING; p->state = TASK_RUNNING; + * wq_entry->flags &= ~WQ_FLAG_WOKEN; ~~~~~~~~~~~~~~~~~~ + * smp_mb(); // B condition = true; + * } smp_mb(); // C + * remove_wait_queue(&wq_head, &wait); wq_entry->flags |= WQ_FLAG_WOKEN; */ long wait_woken(struct wait_queue_entry *wq_entry, unsigned mode, long timeout) { - set_current_state(mode); /* A */ /* - * The above implies an smp_mb(), which matches with the smp_wmb() from - * woken_wake_function() such that if we observe WQ_FLAG_WOKEN we must - * also observe all state before the wakeup. + * The below executes an smp_mb(), which matches with the full barrier + * executed by the try_to_wake_up() in woken_wake_function() such that + * either we see the store to wq_entry->flags in woken_wake_function() + * or woken_wake_function() sees our store to current->state. */ + set_current_state(mode); /* A */ if (!(wq_entry->flags & WQ_FLAG_WOKEN) && !is_kthread_should_stop()) timeout = schedule_timeout(timeout); __set_current_state(TASK_RUNNING);
/* - * The below implies an smp_mb(), it too pairs with the smp_wmb() from - * woken_wake_function() such that we must either observe the wait - * condition being true _OR_ WQ_FLAG_WOKEN such that we will not miss - * an event. + * The below executes an smp_mb(), which matches with the smp_mb() (C) + * in woken_wake_function() such that either we see the wait condition + * being true or the store to wq_entry->flags in woken_wake_function() + * follows ours in the coherence order. */ smp_store_mb(wq_entry->flags, wq_entry->flags & ~WQ_FLAG_WOKEN); /* B */
@@ -433,14 +434,8 @@ EXPORT_SYMBOL(wait_woken);
int woken_wake_function(struct wait_queue_entry *wq_entry, unsigned mode, int sync, void *key) { - /* - * Although this function is called under waitqueue lock, LOCK - * doesn't imply write barrier and the users expects write - * barrier semantics on wakeup functions. The following - * smp_wmb() is equivalent to smp_wmb() in try_to_wake_up() - * and is paired with smp_store_mb() in wait_woken(). - */ - smp_wmb(); /* C */ + /* Pairs with the smp_store_mb() in wait_woken(). */ + smp_mb(); /* C */ wq_entry->flags |= WQ_FLAG_WOKEN;
return default_wake_function(wq_entry, mode, sync, key);
From: Nicholas Mc Guire hofrat@osadl.org
[ Upstream commit d396cb185c0337aae5664b250cdd9a73f6eb1503 ]
Relying on an unchecked of_iomap() which can return NULL is problematic here, an explicit check seems mandatory. Also the call to of_find_compatible_node() returns a device node with refcount incremented therefor an explicit of_node_put() is needed here.
Signed-off-by: Nicholas Mc Guire hofrat@osadl.org Fixes: commit 22bae4290457 ("ARM: hi3xxx: add hotplug support") Signed-off-by: Wei Xu xuwei5@hisilicon.com Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- arch/arm/mach-hisi/hotplug.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-)
diff --git a/arch/arm/mach-hisi/hotplug.c b/arch/arm/mach-hisi/hotplug.c index a129aae72602..3f28c9141b48 100644 --- a/arch/arm/mach-hisi/hotplug.c +++ b/arch/arm/mach-hisi/hotplug.c @@ -148,13 +148,20 @@ static int hi3xxx_hotplug_init(void) struct device_node *node;
node = of_find_compatible_node(NULL, NULL, "hisilicon,sysctrl"); - if (node) { - ctrl_base = of_iomap(node, 0); - id = HI3620_CTRL; - return 0; + if (!node) { + id = ERROR_CTRL; + return -ENOENT; } - id = ERROR_CTRL; - return -ENOENT; + + ctrl_base = of_iomap(node, 0); + of_node_put(node); + if (!ctrl_base) { + id = ERROR_CTRL; + return -ENOMEM; + } + + id = HI3620_CTRL; + return 0; }
void hi3xxx_set_cpu(int cpu, bool enable)
From: Ard Biesheuvel ard.biesheuvel@linaro.org
[ Upstream commit 61f0d55569463a1af897117ff47d202b0ccb2e24 ]
The following commit:
7e1550b8f208 ("efi: Drop type and attribute checks in efi_mem_desc_lookup()")
refactored the implementation of efi_mem_desc_lookup() so that the type check is moved to the callers, one of which is the x86 version of efi_arch_mem_reserve(), where we added a modified check that only takes EFI_BOOT_SERVICES_DATA regions into account.
This is reasonable, since it is the only memory type that requires this, but doing so uncovered some unexpected behavior in the ESRT code, which permits the ESRT table to reside in other types of memory than what the UEFI spec mandates (i.e., EFI_BOOT_SERVICES_DATA), and unconditionally calls efi_mem_reserve() on the region in question. This may result in errors such as
esrt: Reserving ESRT space from 0x000000009c810318 to 0x000000009c810350. efi: Failed to lookup EFI memory descriptor for 0x000000009c810318
when the ESRT table is not in EFI_BOOT_SERVICES_DATA memory, but we try to reserve it nonetheless.
So make the call to efi_mem_reserve() conditional on the memory type.
Signed-off-by: Ard Biesheuvel ard.biesheuvel@linaro.org Cc: Linus Torvalds torvalds@linux-foundation.org Cc: Peter Jones pjones@redhat.com Cc: Peter Zijlstra peterz@infradead.org Cc: Thomas Gleixner tglx@linutronix.de Cc: linux-efi@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Ingo Molnar mingo@kernel.org Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- drivers/firmware/efi/esrt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/firmware/efi/esrt.c b/drivers/firmware/efi/esrt.c index c47e0c6ec00f..f3c28777b8c6 100644 --- a/drivers/firmware/efi/esrt.c +++ b/drivers/firmware/efi/esrt.c @@ -333,7 +333,8 @@ void __init efi_esrt_init(void)
end = esrt_data + size; pr_info("Reserving ESRT space from %pa to %pa.\n", &esrt_data, &end); - efi_mem_reserve(esrt_data, esrt_data_size); + if (md.type == EFI_BOOT_SERVICES_DATA) + efi_mem_reserve(esrt_data, esrt_data_size);
pr_debug("esrt-init: loaded.\n"); err_memunmap:
From: Nicholas Mc Guire hofrat@osadl.org
[ Upstream commit 81646a3d39ef14749301374a3a0b8311384cd412 ]
of_find_compatible_node() returns a device node with refcount incremented and thus needs an explicit of_node_put(). Further relying on an unchecked of_iomap() which can return NULL is problematic here, after all ctrl_base is critical enough for hix5hd2_set_cpu() to call BUG() if not available so a check seems mandated here.
Signed-off-by: Nicholas Mc Guire hofrat@osadl.org 0002 Fixes: commit 06cc5c1d4d73 ("ARM: hisi: enable hix5hd2 SoC") Signed-off-by: Wei Xu xuwei5@hisilicon.com Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- arch/arm/mach-hisi/hotplug.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/arch/arm/mach-hisi/hotplug.c b/arch/arm/mach-hisi/hotplug.c index 32870560b280..909bb2493781 100644 --- a/arch/arm/mach-hisi/hotplug.c +++ b/arch/arm/mach-hisi/hotplug.c @@ -180,11 +180,15 @@ static bool hix5hd2_hotplug_init(void) struct device_node *np;
np = of_find_compatible_node(NULL, NULL, "hisilicon,cpuctrl"); - if (np) { - ctrl_base = of_iomap(np, 0); - return true; - } - return false; + if (!np) + return false; + + ctrl_base = of_iomap(np, 0); + of_node_put(np); + if (!ctrl_base) + return false; + + return true; }
void hix5hd2_set_cpu(int cpu, bool enable)
From: Nicholas Mc Guire hofrat@osadl.org
[ Upstream commit 9f30b5ae0585ca5234fe979294b8f897299dec99 ]
of_iomap() can return NULL which seems critical here and thus should be explicitly flagged so that the cause of system halting can be understood. As of_find_compatible_node() is returning a device node with refcount incremented it must be explicitly decremented here.
Signed-off-by: Nicholas Mc Guire hofrat@osadl.org Fixes: commit 7fda91e73155 ("ARM: hisi: enable smp for HiP01") Signed-off-by: Wei Xu xuwei5@hisilicon.com Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- arch/arm/mach-hisi/hotplug.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/arm/mach-hisi/hotplug.c b/arch/arm/mach-hisi/hotplug.c index 3f28c9141b48..32870560b280 100644 --- a/arch/arm/mach-hisi/hotplug.c +++ b/arch/arm/mach-hisi/hotplug.c @@ -226,10 +226,10 @@ void hip01_set_cpu(int cpu, bool enable)
if (!ctrl_base) { np = of_find_compatible_node(NULL, NULL, "hisilicon,hip01-sysctrl"); - if (np) - ctrl_base = of_iomap(np, 0); - else - BUG(); + BUG_ON(!np); + ctrl_base = of_iomap(np, 0); + of_node_put(np); + BUG_ON(!ctrl_base); }
if (enable) {
From: Rick Farrington ricardo.farrington@cavium.com
[ Upstream commit ac13d6d8eaded15c67265eafc32f439ea3a0ac4a ]
When configuring SLI_PKTn_OUTPUT_CONTROL, VF driver was assuming that IPTR mode was disabled by reset, which was not true. Since DPDK driver had set IPTR mode previously, the VF driver (which uses buf-ptr-only mode) was not properly handling DROQ packets (i.e. it saw zero-length packets).
This represented an invalid hardware configuration which the driver could not handle.
Signed-off-by: Rick Farrington ricardo.farrington@cavium.com Signed-off-by: Felix Manlunas felix.manlunas@cavium.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c | 3 +++ drivers/net/ethernet/cavium/liquidio/cn23xx_vf_device.c | 3 +++ 2 files changed, 6 insertions(+)
diff --git a/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c b/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c index e8b290473ee2..2e089b5ff8f3 100644 --- a/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c +++ b/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c @@ -493,6 +493,9 @@ static void cn23xx_pf_setup_global_output_regs(struct octeon_device *oct) for (q_no = srn; q_no < ern; q_no++) { reg_val = octeon_read_csr(oct, CN23XX_SLI_OQ_PKT_CONTROL(q_no));
+ /* clear IPTR */ + reg_val &= ~CN23XX_PKT_OUTPUT_CTL_IPTR; + /* set DPTR */ reg_val |= CN23XX_PKT_OUTPUT_CTL_DPTR;
diff --git a/drivers/net/ethernet/cavium/liquidio/cn23xx_vf_device.c b/drivers/net/ethernet/cavium/liquidio/cn23xx_vf_device.c index 9338a0008378..1f8b7f651254 100644 --- a/drivers/net/ethernet/cavium/liquidio/cn23xx_vf_device.c +++ b/drivers/net/ethernet/cavium/liquidio/cn23xx_vf_device.c @@ -165,6 +165,9 @@ static void cn23xx_vf_setup_global_output_regs(struct octeon_device *oct) reg_val = octeon_read_csr(oct, CN23XX_VF_SLI_OQ_PKT_CONTROL(q_no));
+ /* clear IPTR */ + reg_val &= ~CN23XX_PKT_OUTPUT_CTL_IPTR; + /* set DPTR */ reg_val |= CN23XX_PKT_OUTPUT_CTL_DPTR;
From: Johan Hovold johan@kernel.org
[ Upstream commit 1cee38f0363a88db374e50b232ca17b9a4c12fa0 ]
When the termios CIBAUD bits are left unset (i.e. B0), we use the same output and input speed and should leave CIBAUD unchanged.
When the user requests a rate using BOTHER and c_ospeed which the driver cannot set exactly, the driver can report back the actual baud rate using tty_termios_encode_baud_rate(). If this rate is close enough to a standard rate however, we could end up setting CIBAUD to a Bfoo value despite the user having left it unset.
This in turn could lead to an unexpected input rate being set on subsequent termios updates.
Fix this by using a zero tolerance value also for the input rate when CIBAUD is clear so that the matching logic works as expected.
Fixes: 78137e3b34e1 ("[PATCH] tty: improve encode_baud_rate logic") Signed-off-by: Johan Hovold johan@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- drivers/tty/tty_baudrate.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/tty/tty_baudrate.c b/drivers/tty/tty_baudrate.c index 5c33fd25676d..8457bb941e1a 100644 --- a/drivers/tty/tty_baudrate.c +++ b/drivers/tty/tty_baudrate.c @@ -156,16 +156,20 @@ void tty_termios_encode_baud_rate(struct ktermios *termios, termios->c_ospeed = obaud;
#ifdef BOTHER + if ((termios->c_cflag >> IBSHIFT) & CBAUD) + ibinput = 1; /* An input speed was specified */ + /* If the user asked for a precise weird speed give a precise weird answer. If they asked for a Bfoo speed they may have problems digesting non-exact replies so fuzz a bit */
- if ((termios->c_cflag & CBAUD) == BOTHER) + if ((termios->c_cflag & CBAUD) == BOTHER) { oclose = 0; + if (!ibinput) + iclose = 0; + } if (((termios->c_cflag >> IBSHIFT) & CBAUD) == BOTHER) iclose = 0; - if ((termios->c_cflag >> IBSHIFT) & CBAUD) - ibinput = 1; /* An input speed was specified */ #endif termios->c_cflag &= ~CBAUD;
From: Enrico Scholz enrico.scholz@sigma-chemnitz.de
[ Upstream commit d36d0e6309dd8137cf438cbb680e72eb63c81425 ]
mbus_code_to_bus_cfg() can fail on unknown mbus codes; pass back the error to the caller.
Signed-off-by: Enrico Scholz enrico.scholz@sigma-chemnitz.de Signed-off-by: Jan Luebbe jlu@pengutronix.de [p.zabel@pengutronix.de - renamed rc to ret for consistency] Signed-off-by: Philipp Zabel p.zabel@pengutronix.de Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- drivers/gpu/ipu-v3/ipu-csi.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/ipu-v3/ipu-csi.c b/drivers/gpu/ipu-v3/ipu-csi.c index 24e12b87a0cb..2bc51d4d3f1e 100644 --- a/drivers/gpu/ipu-v3/ipu-csi.c +++ b/drivers/gpu/ipu-v3/ipu-csi.c @@ -316,13 +316,17 @@ static int mbus_code_to_bus_cfg(struct ipu_csi_bus_config *cfg, u32 mbus_code) /* * Fill a CSI bus config struct from mbus_config and mbus_framefmt. */ -static void fill_csi_bus_cfg(struct ipu_csi_bus_config *csicfg, +static int fill_csi_bus_cfg(struct ipu_csi_bus_config *csicfg, struct v4l2_mbus_config *mbus_cfg, struct v4l2_mbus_framefmt *mbus_fmt) { + int ret; + memset(csicfg, 0, sizeof(*csicfg));
- mbus_code_to_bus_cfg(csicfg, mbus_fmt->code); + ret = mbus_code_to_bus_cfg(csicfg, mbus_fmt->code); + if (ret < 0) + return ret;
switch (mbus_cfg->type) { case V4L2_MBUS_PARALLEL: @@ -353,6 +357,8 @@ static void fill_csi_bus_cfg(struct ipu_csi_bus_config *csicfg, /* will never get here, keep compiler quiet */ break; } + + return 0; }
int ipu_csi_init_interface(struct ipu_csi *csi, @@ -362,8 +368,11 @@ int ipu_csi_init_interface(struct ipu_csi *csi, struct ipu_csi_bus_config cfg; unsigned long flags; u32 width, height, data = 0; + int ret;
- fill_csi_bus_cfg(&cfg, mbus_cfg, mbus_fmt); + ret = fill_csi_bus_cfg(&cfg, mbus_cfg, mbus_fmt); + if (ret < 0) + return ret;
/* set default sensor frame width and height */ width = mbus_fmt->width; @@ -584,11 +593,14 @@ int ipu_csi_set_mipi_datatype(struct ipu_csi *csi, u32 vc, struct ipu_csi_bus_config cfg; unsigned long flags; u32 temp; + int ret;
if (vc > 3) return -EINVAL;
- mbus_code_to_bus_cfg(&cfg, mbus_fmt->code); + ret = mbus_code_to_bus_cfg(&cfg, mbus_fmt->code); + if (ret < 0) + return ret;
spin_lock_irqsave(&csi->lock, flags);
From: Johan Hovold johan@kernel.org
[ Upstream commit fada18c48d774b9e837928ecdce6a5d5fdd11ee7 ]
Make sure to clear the CIBAUD bits before OR-ing the new mask when encoding the termios input baud rate.
This could otherwise lead to an incorrect input rate being reported back and incidentally set on subsequent termios updates.
Fixes: edc6afc54968 ("[PATCH] tty: switch to ktermios and new framework") Signed-off-by: Johan Hovold johan@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- drivers/tty/tty_baudrate.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/tty/tty_baudrate.c b/drivers/tty/tty_baudrate.c index 8457bb941e1a..ebc797fc1afd 100644 --- a/drivers/tty/tty_baudrate.c +++ b/drivers/tty/tty_baudrate.c @@ -172,6 +172,9 @@ void tty_termios_encode_baud_rate(struct ktermios *termios, iclose = 0; #endif termios->c_cflag &= ~CBAUD; +#ifdef IBSHIFT + termios->c_cflag &= ~(CBAUD << IBSHIFT); +#endif
/* * Our goal is to find a close match to the standard baud rate
From: Laurentiu Tudor laurentiu.tudor@nxp.com
[ Upstream commit 5552d7ad596c3fea953f40fef74170ce0760c04d ]
SDHCI controller in ls1043a and ls1046a generate 40-bit wide addresses when doing DMA. Make sure that the corresponding dma mask is correctly configured.
Context: when enabling smmu on these chips the following problem is encountered: the smmu input address size is 48 bits so the dma mappings for sdhci end up 48-bit wide. However, on these chips sdhci only use 40-bits of that address size when doing dma. So you end up with a 48-bit address translation in smmu but the device generates transactions with clipped 40-bit addresses, thus smmu context faults are triggered. Setting up the correct dma mask fixes this situation.
Signed-off-by: Laurentiu Tudor laurentiu.tudor@nxp.com Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- drivers/mmc/host/sdhci-of-esdhc.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c index 4ffa6b173a21..8332f56e6c0d 100644 --- a/drivers/mmc/host/sdhci-of-esdhc.c +++ b/drivers/mmc/host/sdhci-of-esdhc.c @@ -22,6 +22,7 @@ #include <linux/sys_soc.h> #include <linux/clk.h> #include <linux/ktime.h> +#include <linux/dma-mapping.h> #include <linux/mmc/host.h> #include "sdhci-pltfm.h" #include "sdhci-esdhc.h" @@ -427,6 +428,11 @@ static void esdhc_of_adma_workaround(struct sdhci_host *host, u32 intmask) static int esdhc_of_enable_dma(struct sdhci_host *host) { u32 value; + struct device *dev = mmc_dev(host->mmc); + + if (of_device_is_compatible(dev->of_node, "fsl,ls1043a-esdhc") || + of_device_is_compatible(dev->of_node, "fsl,ls1046a-esdhc")) + dma_set_mask_and_coherent(dev, DMA_BIT_MASK(40));
value = sdhci_readl(host, ESDHC_DMA_SYSCTL); value |= ESDHC_DMA_SNOOP;
From: Stefan Agner stefan@agner.ch
[ Upstream commit 127407e36f4fe3a1d5e8b9998b479956ce83a7dc ]
The stack assumes that SDHC controller which support SD3.0 (SDR104) do support HS200. This is not the case for Tegra 3, which does support SD 3.0 but only supports eMMC spec 4.41.
Use SDHCI_QUIRK2_BROKEN_HS200 to indicate that the controller does not support HS200.
Note that commit 156e14b126ff ("mmc: sdhci: fix caps2 for HS200") added the tie between SD3.0 (SDR104) and HS200. I don't think that this is necessarly true. It is fully legitimate to support SD3.0 and not support HS200. The quirk naming suggests something is broken in the controller, but this is not the case: The controller simply does not support HS200.
Fixes: 7ad2ed1dfcbe ("mmc: tegra: enable UHS-I modes") Signed-off-by: Stefan Agner stefan@agner.ch Tested-by: Marcel Ziswiler marcel.ziswiler@toradex.com Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- drivers/mmc/host/sdhci-tegra.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c index 0cd6fa80db66..ce3f344d2b66 100644 --- a/drivers/mmc/host/sdhci-tegra.c +++ b/drivers/mmc/host/sdhci-tegra.c @@ -334,7 +334,8 @@ static const struct sdhci_pltfm_data sdhci_tegra30_pdata = { SDHCI_QUIRK_NO_HISPD_BIT | SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC | SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN, - .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, + .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | + SDHCI_QUIRK2_BROKEN_HS200, .ops = &tegra_sdhci_ops, };
From: Lyude Paul lyude@redhat.com
[ Upstream commit 922a8c82fafdec99688bbaea6c5889f562a42cdc ]
Noticed this as I was skimming through, if we fail to allocate memory for cli we'll end up returning without dropping the runtime PM ref we got. Additionally, we'll even return the wrong return code! (ret most likely will == 0 here, we want -ENOMEM).
Signed-off-by: Lyude Paul lyude@redhat.com Reviewed-by: Lukas Wunner lukas@wunner.de Signed-off-by: Ben Skeggs bskeggs@redhat.com Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- drivers/gpu/drm/nouveau/nouveau_drm.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 362a34cb435d..d6f13d7254de 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -848,8 +848,10 @@ nouveau_drm_open(struct drm_device *dev, struct drm_file *fpriv) get_task_comm(tmpname, current); snprintf(name, sizeof(name), "%s[%d]", tmpname, pid_nr(fpriv->pid));
- if (!(cli = kzalloc(sizeof(*cli), GFP_KERNEL))) - return ret; + if (!(cli = kzalloc(sizeof(*cli), GFP_KERNEL))) { + ret = -ENOMEM; + goto done; + }
ret = nouveau_cli_init(drm, name, cli); if (ret)
From: Stefan Agner stefan@agner.ch
[ Upstream commit 1b5190c2e74c47ebe4bcecf7a072358ad9f1feaa ]
For eMMC devices it is valid to only support 1.8V signaling. When vqmmc is set to a fixed 1.8V regulator the stack tries to set 3.3V initially and prints the following warning: mmc1: Switching to 3.3V signalling voltage failed
Clear the MMC_SIGNAL_VOLTAGE_330 flag in case 3.3V is signaling is not available. This prevents the stack from even trying to use 3.3V signaling and avoids the above warning.
Signed-off-by: Stefan Agner stefan@agner.ch Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- drivers/mmc/host/sdhci.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index d35deb79965d..f063fe569339 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -3631,14 +3631,21 @@ int sdhci_setup_host(struct sdhci_host *host) mmc_gpio_get_cd(host->mmc) < 0) mmc->caps |= MMC_CAP_NEEDS_POLL;
- /* If vqmmc regulator and no 1.8V signalling, then there's no UHS */ if (!IS_ERR(mmc->supply.vqmmc)) { ret = regulator_enable(mmc->supply.vqmmc); + + /* If vqmmc provides no 1.8V signalling, then there's no UHS */ if (!regulator_is_supported_voltage(mmc->supply.vqmmc, 1700000, 1950000)) host->caps1 &= ~(SDHCI_SUPPORT_SDR104 | SDHCI_SUPPORT_SDR50 | SDHCI_SUPPORT_DDR50); + + /* In eMMC case vqmmc might be a fixed 1.8V regulator */ + if (!regulator_is_supported_voltage(mmc->supply.vqmmc, 2700000, + 3600000)) + host->flags &= ~SDHCI_SIGNALING_330; + if (ret) { pr_warn("%s: Failed to enable vqmmc regulator: %d\n", mmc_hostname(mmc), ret);
From: Karol Herbst karolherbst@gmail.com
[ Upstream commit eaeb9010bb4bcdc20e58254fa42f3fe730a7f908 ]
Fixes various reclocking related issues on prime systems.
Signed-off-by: Karol Herbst karolherbst@gmail.com Signed-off-by: Martin Peres martin.peres@free.fr Signed-off-by: Ben Skeggs bskeggs@redhat.com Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- drivers/gpu/drm/nouveau/nouveau_debugfs.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/gpu/drm/nouveau/nouveau_debugfs.c b/drivers/gpu/drm/nouveau/nouveau_debugfs.c index 963a4dba8213..9109b69cd052 100644 --- a/drivers/gpu/drm/nouveau/nouveau_debugfs.c +++ b/drivers/gpu/drm/nouveau/nouveau_debugfs.c @@ -160,7 +160,11 @@ nouveau_debugfs_pstate_set(struct file *file, const char __user *ubuf, args.ustate = value; }
+ ret = pm_runtime_get_sync(drm->dev); + if (IS_ERR_VALUE(ret) && ret != -EACCES) + return ret; ret = nvif_mthd(ctrl, NVIF_CONTROL_PSTATE_USER, &args, sizeof(args)); + pm_runtime_put_autosuspend(drm->dev); if (ret < 0) return ret;
From: Thierry Reding treding@nvidia.com
[ Upstream commit b59fb482b52269977ee5de205308e5b236a03917 ]
Depending on the kernel configuration, early ARM architecture setup code may have attached the GPU to a DMA/IOMMU mapping that transparently uses the IOMMU to back the DMA API. Tegra requires special handling for IOMMU backed buffers (a special bit in the GPU's MMU page tables indicates the memory path to take: via the SMMU or directly to the memory controller). Transparently backing DMA memory with an IOMMU prevents Nouveau from properly handling such memory accesses and causes memory access faults.
As a side-note: buffers other than those allocated in instance memory don't need to be physically contiguous from the GPU's perspective since the GPU can map them into contiguous buffers using its own MMU. Mapping these buffers through the IOMMU is unnecessary and will even lead to performance degradation because of the additional translation. One exception to this are compressible buffers which need large pages. In order to enable these large pages, multiple small pages will have to be combined into one large (I/O virtually contiguous) mapping via the IOMMU. However, that is a topic outside the scope of this fix and isn't currently supported. An implementation will want to explicitly create these large pages in the Nouveau driver, so detaching from a DMA/IOMMU mapping would still be required.
Signed-off-by: Thierry Reding treding@nvidia.com Acked-by: Christoph Hellwig hch@lst.de Reviewed-by: Robin Murphy robin.murphy@arm.com Tested-by: Nicolas Chauvet kwizart@gmail.com Signed-off-by: Ben Skeggs bskeggs@redhat.com Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c index 189ed80e21ff..fa1ead337c23 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c @@ -23,6 +23,10 @@ #ifdef CONFIG_NOUVEAU_PLATFORM_DRIVER #include "priv.h"
+#if IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU) +#include <asm/dma-iommu.h> +#endif + static int nvkm_device_tegra_power_up(struct nvkm_device_tegra *tdev) { @@ -105,6 +109,15 @@ nvkm_device_tegra_probe_iommu(struct nvkm_device_tegra *tdev) unsigned long pgsize_bitmap; int ret;
+#if IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU) + if (dev->archdata.mapping) { + struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev); + + arm_iommu_detach_device(dev); + arm_iommu_release_mapping(mapping); + } +#endif + if (!tdev->func->iommu_bit) return;
From: Julia Lawall Julia.Lawall@lip6.fr
[ Upstream commit faa1a47388b33623e4d504c23569188907b039a0 ]
Return an error code on failure. Change leading spaces to tab on the first if.
Problem found using Coccinelle.
Signed-off-by: Julia Lawall Julia.Lawall@lip6.fr Signed-off-by: Sudip Mukherjee sudipm.mukherjee@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- drivers/parport/parport_sunbpp.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/parport/parport_sunbpp.c b/drivers/parport/parport_sunbpp.c index 01cf1c1a841a..8de329546b82 100644 --- a/drivers/parport/parport_sunbpp.c +++ b/drivers/parport/parport_sunbpp.c @@ -286,12 +286,16 @@ static int bpp_probe(struct platform_device *op)
ops = kmemdup(&parport_sunbpp_ops, sizeof(struct parport_operations), GFP_KERNEL); - if (!ops) + if (!ops) { + err = -ENOMEM; goto out_unmap; + }
dprintk(("register_port\n")); - if (!(p = parport_register_port((unsigned long)base, irq, dma, ops))) + if (!(p = parport_register_port((unsigned long)base, irq, dma, ops))) { + err = -ENOMEM; goto out_free_ops; + }
p->size = size; p->dev = &op->dev;
From: Quentin Perret quentin.perret@arm.com
[ Upstream commit 8fe5c5a937d0f4e84221631833a2718afde52285 ]
When a new task wakes-up for the first time, its initial utilization is set to half of the spare capacity of its CPU. The current implementation of post_init_entity_util_avg() uses SCHED_CAPACITY_SCALE directly as a capacity reference. As a result, on a big.LITTLE system, a new task waking up on an idle little CPU will be given ~512 of util_avg, even if the CPU's capacity is significantly less than that.
Fix this by computing the spare capacity with arch_scale_cpu_capacity().
Signed-off-by: Quentin Perret quentin.perret@arm.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Acked-by: Vincent Guittot vincent.guittot@linaro.org Cc: Linus Torvalds torvalds@linux-foundation.org Cc: Peter Zijlstra peterz@infradead.org Cc: Thomas Gleixner tglx@linutronix.de Cc: dietmar.eggemann@arm.com Cc: morten.rasmussen@arm.com Cc: patrick.bellasi@arm.com Link: http://lkml.kernel.org/r/20180612112215.25448-1-quentin.perret@arm.com Signed-off-by: Ingo Molnar mingo@kernel.org Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- kernel/sched/fair.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 0cc7098c6dfd..a5e20ceb0b5a 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -757,11 +757,12 @@ static void attach_entity_cfs_rq(struct sched_entity *se); * To solve this problem, we also cap the util_avg of successive tasks to * only 1/2 of the left utilization budget: * - * util_avg_cap = (1024 - cfs_rq->avg.util_avg) / 2^n + * util_avg_cap = (cpu_scale - cfs_rq->avg.util_avg) / 2^n * - * where n denotes the nth task. + * where n denotes the nth task and cpu_scale the CPU capacity. * - * For example, a simplest series from the beginning would be like: + * For example, for a CPU with 1024 of capacity, a simplest series from + * the beginning would be like: * * task util_avg: 512, 256, 128, 64, 32, 16, 8, ... * cfs_rq util_avg: 512, 768, 896, 960, 992, 1008, 1016, ... @@ -773,7 +774,8 @@ void post_init_entity_util_avg(struct sched_entity *se) { struct cfs_rq *cfs_rq = cfs_rq_of(se); struct sched_avg *sa = &se->avg; - long cap = (long)(SCHED_CAPACITY_SCALE - cfs_rq->avg.util_avg) / 2; + long cpu_scale = arch_scale_cpu_capacity(NULL, cpu_of(rq_of(cfs_rq))); + long cap = (long)(cpu_scale - cfs_rq->avg.util_avg) / 2;
if (cap > 0) { if (cfs_rq->avg.util_avg != 0) {
From: Suzuki K Poulose suzuki.poulose@arm.com
[ Upstream commit fe470f5f7f684ed15bc49b6183a64237547910ff ]
If we fail to find the input / output port for a LINK component while enabling a path, we should fail gracefully rather than assuming port "0".
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- drivers/hwtracing/coresight/coresight.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c index b8091bef21dc..e571e4010dff 100644 --- a/drivers/hwtracing/coresight/coresight.c +++ b/drivers/hwtracing/coresight/coresight.c @@ -115,7 +115,7 @@ static int coresight_find_link_inport(struct coresight_device *csdev, dev_err(&csdev->dev, "couldn't find inport, parent: %s, child: %s\n", dev_name(&parent->dev), dev_name(&csdev->dev));
- return 0; + return -ENODEV; }
static int coresight_find_link_outport(struct coresight_device *csdev, @@ -133,7 +133,7 @@ static int coresight_find_link_outport(struct coresight_device *csdev, dev_err(&csdev->dev, "couldn't find outport, parent: %s, child: %s\n", dev_name(&csdev->dev), dev_name(&child->dev));
- return 0; + return -ENODEV; }
static int coresight_enable_sink(struct coresight_device *csdev, u32 mode) @@ -186,6 +186,9 @@ static int coresight_enable_link(struct coresight_device *csdev, else refport = 0;
+ if (refport < 0) + return refport; + if (atomic_inc_return(&csdev->refcnt[refport]) == 1) { if (link_ops(csdev)->enable) { ret = link_ops(csdev)->enable(csdev, inport, outport);
From: Suzuki K Poulose suzuki.poulose@arm.com
[ Upstream commit 5cedd22370a0a460b663c06de1fc10b4ba3c5d0b ]
Add ETM PIDs of the Arm cortex-A CPUs to the white list of ETMs. While at it add a helper macro to make it easier to add the new entries.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- drivers/hwtracing/coresight/coresight-etm4x.c | 31 +++++++++---------- 1 file changed, 14 insertions(+), 17 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c index cf364a514c12..5a1a14bcae72 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x.c +++ b/drivers/hwtracing/coresight/coresight-etm4x.c @@ -1034,7 +1034,8 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id) }
pm_runtime_put(&adev->dev); - dev_info(dev, "%s initialized\n", (char *)id->data); + dev_info(dev, "CPU%d: ETM v%d.%d initialized\n", + drvdata->cpu, drvdata->arch >> 4, drvdata->arch & 0xf);
if (boot_enable) { coresight_enable(drvdata->csdev); @@ -1052,23 +1053,19 @@ err_arch_supported: return ret; }
+#define ETM4x_AMBA_ID(pid) \ + { \ + .id = pid, \ + .mask = 0x000fffff, \ + } + static const struct amba_id etm4_ids[] = { - { /* ETM 4.0 - Cortex-A53 */ - .id = 0x000bb95d, - .mask = 0x000fffff, - .data = "ETM 4.0", - }, - { /* ETM 4.0 - Cortex-A57 */ - .id = 0x000bb95e, - .mask = 0x000fffff, - .data = "ETM 4.0", - }, - { /* ETM 4.0 - A72, Maia, HiSilicon */ - .id = 0x000bb95a, - .mask = 0x000fffff, - .data = "ETM 4.0", - }, - { 0, 0}, + ETM4x_AMBA_ID(0x000bb95d), /* Cortex-A53 */ + ETM4x_AMBA_ID(0x000bb95e), /* Cortex-A57 */ + ETM4x_AMBA_ID(0x000bb95a), /* Cortex-A72 */ + ETM4x_AMBA_ID(0x000bb959), /* Cortex-A73 */ + ETM4x_AMBA_ID(0x000bb9da), /* Cortex-A35 */ + {}, };
static struct amba_driver etm4x_driver = {
From: Robin Murphy robin.murphy@arm.com
[ Upstream commit ccff2dfaceaca4517432f5c149594215fe9098cc ]
Probing the TPIU driver under UBSan triggers an out-of-bounds shift warning in coresight_timeout():
... [ 5.677530] UBSAN: Undefined behaviour in drivers/hwtracing/coresight/coresight.c:929:16 [ 5.685542] shift exponent 64 is too large for 64-bit type 'long unsigned int' ...
On closer inspection things are exponentially out of whack because we're passing a bitmask where a bit number should be. Amusingly, it seems that both calls will find their expected values by sheer luck and appear to succeed: 1 << FFCR_FON_MAN ends up at bit 64 which whilst undefined evaluates as zero in practice, while 1 << FFSR_FT_STOPPED finds bit 2 (TCPresent) which apparently is usually tied high.
Following the examples of other drivers, define separate FOO and FOO_BIT macros for masks vs. indices, and put things right.
CC: Robert Walker robert.walker@arm.com CC: Mike Leach mike.leach@linaro.org CC: Mathieu Poirier mathieu.poirier@linaro.org Fixes: 11595db8e17f ("coresight: Fix disabling of CoreSight TPIU") Signed-off-by: Robin Murphy robin.murphy@arm.com Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- drivers/hwtracing/coresight/coresight-tpiu.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-tpiu.c b/drivers/hwtracing/coresight/coresight-tpiu.c index 735dca089389..15dd01f8c197 100644 --- a/drivers/hwtracing/coresight/coresight-tpiu.c +++ b/drivers/hwtracing/coresight/coresight-tpiu.c @@ -47,8 +47,9 @@
/** register definition **/ /* FFSR - 0x300 */ -#define FFSR_FT_STOPPED BIT(1) +#define FFSR_FT_STOPPED_BIT 1 /* FFCR - 0x304 */ +#define FFCR_FON_MAN_BIT 6 #define FFCR_FON_MAN BIT(6) #define FFCR_STOP_FI BIT(12)
@@ -93,9 +94,9 @@ static void tpiu_disable_hw(struct tpiu_drvdata *drvdata) /* Generate manual flush */ writel_relaxed(FFCR_STOP_FI | FFCR_FON_MAN, drvdata->base + TPIU_FFCR); /* Wait for flush to complete */ - coresight_timeout(drvdata->base, TPIU_FFCR, FFCR_FON_MAN, 0); + coresight_timeout(drvdata->base, TPIU_FFCR, FFCR_FON_MAN_BIT, 0); /* Wait for formatter to stop */ - coresight_timeout(drvdata->base, TPIU_FFSR, FFSR_FT_STOPPED, 1); + coresight_timeout(drvdata->base, TPIU_FFSR, FFSR_FT_STOPPED_BIT, 1);
CS_LOCK(drvdata->base); }
From: Tuomas Tynkkynen tuomas@tuxera.com
[ Upstream commit 678c5b119307c40f9a17152512f9c949d0ec7292 ]
Currently, if bcm2835_audio_open() fails partway, the allocated workqueue is leaked. Avoid that.
While at it, propagate the return value of bcm2835_audio_open_connection() on failure instead of returning -1.
Signed-off-by: Tuomas Tynkkynen tuomas@tuxera.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- .../vc04_services/bcm2835-audio/bcm2835-vchiq.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c index 4be864dbd41c..9eb3b625a1b1 100644 --- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c +++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c @@ -442,16 +442,16 @@ int bcm2835_audio_open(struct bcm2835_alsa_stream *alsa_stream) my_workqueue_init(alsa_stream);
ret = bcm2835_audio_open_connection(alsa_stream); - if (ret) { - ret = -1; - goto exit; - } + if (ret) + goto free_wq; + instance = alsa_stream->instance; LOG_DBG(" instance (%p)\n", instance);
if (mutex_lock_interruptible(&instance->vchi_mutex)) { LOG_DBG("Interrupted whilst waiting for lock on (%d)\n", instance->num_connections); - return -EINTR; + ret = -EINTR; + goto free_wq; } vchi_service_use(instance->vchi_handle[0]);
@@ -474,7 +474,11 @@ int bcm2835_audio_open(struct bcm2835_alsa_stream *alsa_stream) unlock: vchi_service_release(instance->vchi_handle[0]); mutex_unlock(&instance->vchi_mutex); -exit: + +free_wq: + if (ret) + destroy_workqueue(alsa_stream->my_wq); + return ret; }
From: Wei Yongjun weiyongjun1@huawei.com
[ Upstream commit 9506755633d0b32ef76f67c345000178e9b0dfc4 ]
platform_get_resource() may fail and return NULL, so we should better check it's return value to avoid a NULL pointer dereference a bit later in the code.
This is detected by Coccinelle semantic patch.
@@ expression pdev, res, n, t, e, e1, e2; @@
res = platform_get_resource(pdev, t, n); + if (!res) + return -EINVAL; ... when != res == NULL e = devm_ioremap(e1, res->start, e2);
Signed-off-by: Wei Yongjun weiyongjun1@huawei.com Acked-by: Robert Jarzmik robert.jarzmik@free.fr Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- drivers/gpio/gpio-pxa.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c index 6029899789f3..2943dfc4c470 100644 --- a/drivers/gpio/gpio-pxa.c +++ b/drivers/gpio/gpio-pxa.c @@ -662,6 +662,8 @@ static int pxa_gpio_probe(struct platform_device *pdev) pchip->irq0 = irq0; pchip->irq1 = irq1; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -EINVAL; gpio_reg_base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); if (!gpio_reg_base)
From: Peter Rosin peda@axentia.se
[ Upstream commit 8c8f74f327a76604a499fad8c54c15e1c0ee8051 ]
Locking the root adapter for __i2c_transfer will deadlock if the device sits behind a mux-locked I2C mux. Switch to the finer-grained i2c_lock_bus with the I2C_LOCK_SEGMENT flag. If the device does not sit behind a mux-locked mux, the two locking variants are equivalent.
Signed-off-by: Peter Rosin peda@axentia.se Acked-by: Lee Jones lee.jones@linaro.org Signed-off-by: Wolfram Sang wsa@the-dreams.de Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- drivers/mfd/88pm860x-i2c.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/mfd/88pm860x-i2c.c b/drivers/mfd/88pm860x-i2c.c index 84e313107233..7b9052ea7413 100644 --- a/drivers/mfd/88pm860x-i2c.c +++ b/drivers/mfd/88pm860x-i2c.c @@ -146,14 +146,14 @@ int pm860x_page_reg_write(struct i2c_client *i2c, int reg, unsigned char zero; int ret;
- i2c_lock_adapter(i2c->adapter); + i2c_lock_bus(i2c->adapter, I2C_LOCK_SEGMENT); read_device(i2c, 0xFA, 0, &zero); read_device(i2c, 0xFB, 0, &zero); read_device(i2c, 0xFF, 0, &zero); ret = write_device(i2c, reg, 1, &data); read_device(i2c, 0xFE, 0, &zero); read_device(i2c, 0xFC, 0, &zero); - i2c_unlock_adapter(i2c->adapter); + i2c_unlock_bus(i2c->adapter, I2C_LOCK_SEGMENT); return ret; } EXPORT_SYMBOL(pm860x_page_reg_write); @@ -164,14 +164,14 @@ int pm860x_page_bulk_read(struct i2c_client *i2c, int reg, unsigned char zero = 0; int ret;
- i2c_lock_adapter(i2c->adapter); + i2c_lock_bus(i2c->adapter, I2C_LOCK_SEGMENT); read_device(i2c, 0xfa, 0, &zero); read_device(i2c, 0xfb, 0, &zero); read_device(i2c, 0xff, 0, &zero); ret = read_device(i2c, reg, count, buf); read_device(i2c, 0xFE, 0, &zero); read_device(i2c, 0xFC, 0, &zero); - i2c_unlock_adapter(i2c->adapter); + i2c_unlock_bus(i2c->adapter, I2C_LOCK_SEGMENT); return ret; } EXPORT_SYMBOL(pm860x_page_bulk_read);
From: Andy Shevchenko andriy.shevchenko@linux.intel.com
[ Upstream commit b23ec59926faf05b0c43680d05671c484e810ac4 ]
Since we put static variable to a header file it's copied to each module that includes the header. But not all of them are actually used it.
Mark gpio_suffixes array with __maybe_unused to hide a compiler warning:
In file included from drivers/gpio/gpiolib-legacy.c:6:0: drivers/gpio/gpiolib.h:95:27: warning: ‘gpio_suffixes’ defined but not used [-Wunused-const-variable=] static const char * const gpio_suffixes[] = { "gpios", "gpio" }; ^~~~~~~~~~~~~ In file included from drivers/gpio/gpiolib-devprop.c:17:0: drivers/gpio/gpiolib.h:95:27: warning: ‘gpio_suffixes’ defined but not used [-Wunused-const-variable=] static const char * const gpio_suffixes[] = { "gpios", "gpio" }; ^~~~~~~~~~~~~
Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- drivers/gpio/gpiolib.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h index 3d4d0634c9dd..7a3d9658d74c 100644 --- a/drivers/gpio/gpiolib.h +++ b/drivers/gpio/gpiolib.h @@ -88,7 +88,7 @@ struct acpi_gpio_info { };
/* gpio suffixes used for ACPI and device tree lookup */ -static const char * const gpio_suffixes[] = { "gpios", "gpio" }; +static __maybe_unused const char * const gpio_suffixes[] = { "gpios", "gpio" };
#ifdef CONFIG_OF_GPIO struct gpio_desc *of_find_gpio(struct device *dev,
From: "Paul E. McKenney" paulmck@linux.vnet.ibm.com
[ Upstream commit 1e64b15a4b102e1cd059d4d798b7a78f93341333 ]
Without special fail-safe quiescent-state-propagation checks, grace-period hangs can result from the following scenario:
1. CPU 1 goes offline.
2. Because CPU 1 is the only CPU in the system blocking the current grace period, the grace period ends as soon as rcu_cleanup_dying_idle_cpu()'s call to rcu_report_qs_rnp() returns.
3. At this point, the leaf rcu_node structure's ->lock is no longer held: rcu_report_qs_rnp() has released it, as it must in order to awaken the RCU grace-period kthread.
4. At this point, that same leaf rcu_node structure's ->qsmaskinitnext field still records CPU 1 as being online. This is absolutely necessary because the scheduler uses RCU (in this case on the wake-up path while awakening RCU's grace-period kthread), and ->qsmaskinitnext contains RCU's idea as to which CPUs are online. Therefore, invoking rcu_report_qs_rnp() after clearing CPU 1's bit from ->qsmaskinitnext would result in a lockdep-RCU splat due to RCU being used from an offline CPU.
5. RCU's grace-period kthread awakens, sees that the old grace period has completed and that a new one is needed. It therefore starts a new grace period, but because CPU 1's leaf rcu_node structure's ->qsmaskinitnext field still shows CPU 1 as being online, this new grace period is initialized to wait for a quiescent state from the now-offline CPU 1.
6. Without the fail-safe force-quiescent-state checks, there would be no quiescent state from the now-offline CPU 1, which would eventually result in RCU CPU stall warnings and memory exhaustion.
It would be good to get rid of the special fail-safe quiescent-state propagation checks, and thus it would be good to fix things so that the above scenario cannot happen. This commit therefore adds a new ->ofl_lock to the rcu_state structure. This lock is held by rcu_gp_init() across the applying of buffered online and offline operations to the rcu_node tree, and it is also held by rcu_cleanup_dying_idle_cpu() when buffering a new offline operation. This prevents rcu_gp_init() from acquiring the leaf rcu_node structure's lock during the interval between when rcu_cleanup_dying_idle_cpu() invokes rcu_report_qs_rnp(), which releases ->lock and the re-acquisition of that same lock. This in turn prevents the failure scenario outlined above, and will hopefully eventually allow removal of the offline-CPU checks from the force-quiescent-state code path.
Signed-off-by: Paul E. McKenney paulmck@linux.vnet.ibm.com Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- kernel/rcu/tree.c | 6 ++++++ kernel/rcu/tree.h | 4 ++++ 2 files changed, 10 insertions(+)
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c index 3e3650e94ae6..930edad27cbf 100644 --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c @@ -102,6 +102,7 @@ struct rcu_state sname##_state = { \ .abbr = sabbr, \ .exp_mutex = __MUTEX_INITIALIZER(sname##_state.exp_mutex), \ .exp_wake_mutex = __MUTEX_INITIALIZER(sname##_state.exp_wake_mutex), \ + .ofl_lock = __SPIN_LOCK_UNLOCKED(sname##_state.ofl_lock), \ }
RCU_STATE_INITIALIZER(rcu_sched, 's', call_rcu_sched); @@ -1996,11 +1997,13 @@ static bool rcu_gp_init(struct rcu_state *rsp) */ rcu_for_each_leaf_node(rsp, rnp) { rcu_gp_slow(rsp, gp_preinit_delay); + spin_lock(&rsp->ofl_lock); raw_spin_lock_irq_rcu_node(rnp); if (rnp->qsmaskinit == rnp->qsmaskinitnext && !rnp->wait_blkd_tasks) { /* Nothing to do on this leaf rcu_node structure. */ raw_spin_unlock_irq_rcu_node(rnp); + spin_unlock(&rsp->ofl_lock); continue; }
@@ -2035,6 +2038,7 @@ static bool rcu_gp_init(struct rcu_state *rsp) }
raw_spin_unlock_irq_rcu_node(rnp); + spin_unlock(&rsp->ofl_lock); }
/* @@ -3837,9 +3841,11 @@ static void rcu_cleanup_dying_idle_cpu(int cpu, struct rcu_state *rsp)
/* Remove outgoing CPU from mask in the leaf rcu_node structure. */ mask = rdp->grpmask; + spin_lock(&rsp->ofl_lock); raw_spin_lock_irqsave_rcu_node(rnp, flags); /* Enforce GP memory-order guarantee. */ rnp->qsmaskinitnext &= ~mask; raw_spin_unlock_irqrestore_rcu_node(rnp, flags); + spin_unlock(&rsp->ofl_lock); }
/* diff --git a/kernel/rcu/tree.h b/kernel/rcu/tree.h index 8e1f285f0a70..46fa50dbeb82 100644 --- a/kernel/rcu/tree.h +++ b/kernel/rcu/tree.h @@ -389,6 +389,10 @@ struct rcu_state { const char *name; /* Name of structure. */ char abbr; /* Abbreviated name. */ struct list_head flavors; /* List of RCU flavors. */ + + spinlock_t ofl_lock ____cacheline_internodealigned_in_smp; + /* Synchronize offline with */ + /* GP pre-initialization. */ };
/* Values for rcu_state structure's gp_flags field. */
From: Peter Rosin peda@axentia.se
[ Upstream commit 193c2a07cfaacb9249ab0e3d34bce32490879355 ]
Locking the root adapter for __i2c_transfer will deadlock if the device sits behind a mux-locked I2C mux. Switch to the finer-grained i2c_lock_bus with the I2C_LOCK_SEGMENT flag. If the device does not sit behind a mux-locked mux, the two locking variants are equivalent.
Signed-off-by: Peter Rosin peda@axentia.se Acked-by: Dmitry Torokhov dmitry.torokhov@gmail.com Signed-off-by: Wolfram Sang wsa@the-dreams.de Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- drivers/input/touchscreen/rohm_bu21023.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/input/touchscreen/rohm_bu21023.c b/drivers/input/touchscreen/rohm_bu21023.c index eeaf6ff03597..fc54e044fece 100644 --- a/drivers/input/touchscreen/rohm_bu21023.c +++ b/drivers/input/touchscreen/rohm_bu21023.c @@ -304,7 +304,7 @@ static int rohm_i2c_burst_read(struct i2c_client *client, u8 start, void *buf, msg[1].len = len; msg[1].buf = buf;
- i2c_lock_adapter(adap); + i2c_lock_bus(adap, I2C_LOCK_SEGMENT);
for (i = 0; i < 2; i++) { if (__i2c_transfer(adap, &msg[i], 1) < 0) { @@ -313,7 +313,7 @@ static int rohm_i2c_burst_read(struct i2c_client *client, u8 start, void *buf, } }
- i2c_unlock_adapter(adap); + i2c_unlock_bus(adap, I2C_LOCK_SEGMENT);
return ret; }
From: Wei Lu wei.lu2@amd.com
[ Upstream commit e47cb828eb3fca3e8999a0b9aa053dda18552071 ]
Return ERR_PTR(-EINVAL) if kfd_get_process fails to find the process. This fixes kernel oopses when a child process calls KFD ioctls with a file descriptor inherited from the parent process.
Signed-off-by: Wei Lu wei.lu2@amd.com Reviewed-by: Felix Kuehling Felix.Kuehling@amd.com Signed-off-by: Felix Kuehling Felix.Kuehling@amd.com Acked-by: Christian König christian.koenig@amd.com Signed-off-by: Oded Gabbay oded.gabbay@gmail.com Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- drivers/gpu/drm/amd/amdkfd/kfd_process.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c index c74cf22a1ed9..3ae88dcff08d 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c @@ -123,6 +123,8 @@ struct kfd_process *kfd_get_process(const struct task_struct *thread) return ERR_PTR(-EINVAL);
process = find_process(thread); + if (!process) + return ERR_PTR(-EINVAL);
return process; }
From: Zhouyang Jia jiazhouyang09@gmail.com
[ Upstream commit 7874b919866ba91bac253fa219d3d4c82bb944df ]
When devm_ioremap fails, the lack of error-handling code may cause unexpected results.
This patch adds error-handling code after calling devm_ioremap.
Signed-off-by: Zhouyang Jia jiazhouyang09@gmail.com Signed-off-by: Alexandre Belloni alexandre.belloni@bootlin.com Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- drivers/rtc/rtc-bq4802.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/rtc/rtc-bq4802.c b/drivers/rtc/rtc-bq4802.c index bd170cb3361c..5747a54cbd42 100644 --- a/drivers/rtc/rtc-bq4802.c +++ b/drivers/rtc/rtc-bq4802.c @@ -164,6 +164,10 @@ static int bq4802_probe(struct platform_device *pdev) } else if (p->r->flags & IORESOURCE_MEM) { p->regs = devm_ioremap(&pdev->dev, p->r->start, resource_size(p->r)); + if (!p->regs){ + err = -ENOMEM; + goto out; + } p->read = bq4802_read_mem; p->write = bq4802_write_mem; } else {
From: Timo Wischer twischer@de.adit-jv.com
[ Upstream commit ff2d6acdf6f13d9f8fdcd890844c6d7535ac1f10 ]
Without this commit the following intervals [x y), (x y) were be replaced to (y-1 y) by snd_interval_refine_last(). This was also done if y-1 is part of the previous interval. With this changes it will be replaced with [y-1 y) in case of y-1 is part of the previous interval. A similar behavior will be used for snd_interval_refine_first().
This commit adapts the changes for alsa-lib of commit 9bb985c ("pcm: snd_interval_refine_first/last: exclude value only if also excluded before")
Signed-off-by: Timo Wischer twischer@de.adit-jv.com Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- sound/core/pcm_lib.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index faa67861cbc1..729a85a6211d 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c @@ -629,27 +629,33 @@ EXPORT_SYMBOL(snd_interval_refine);
static int snd_interval_refine_first(struct snd_interval *i) { + const unsigned int last_max = i->max; + if (snd_BUG_ON(snd_interval_empty(i))) return -EINVAL; if (snd_interval_single(i)) return 0; i->max = i->min; - i->openmax = i->openmin; - if (i->openmax) + if (i->openmin) i->max++; + /* only exclude max value if also excluded before refine */ + i->openmax = (i->openmax && i->max >= last_max); return 1; }
static int snd_interval_refine_last(struct snd_interval *i) { + const unsigned int last_min = i->min; + if (snd_BUG_ON(snd_interval_empty(i))) return -EINVAL; if (snd_interval_single(i)) return 0; i->min = i->max; - i->openmin = i->openmax; - if (i->openmin) + if (i->openmax) i->min--; + /* only exclude min value if also excluded before refine */ + i->openmin = (i->openmin && i->min <= last_min); return 1; }
From: John Stultz john.stultz@linaro.org
[ Upstream commit 1416270f4a1ae83ea84156ceba19a66a8f88be1f ]
In the past we've warned when ADJ_OFFSET was in progress, usually caused by ntpd or some other time adjusting daemon running in non steady sate, which can cause the skew calculations to be incorrect.
Thus, this patch checks to see if the clock was being adjusted when we fail so that we don't cause false negatives.
Cc: Thomas Gleixner tglx@linutronix.de Cc: Ingo Molnar mingo@kernel.org Cc: Miroslav Lichvar mlichvar@redhat.com Cc: Richard Cochran richardcochran@gmail.com Cc: Prarit Bhargava prarit@redhat.com Cc: Stephen Boyd sboyd@kernel.org Cc: Shuah Khan shuah@kernel.org Cc: linux-kselftest@vger.kernel.org Suggested-by: Miroslav Lichvar mlichvar@redhat.com Signed-off-by: John Stultz john.stultz@linaro.org --- v2: Widened the checks to look for other clock adjustments that could happen, as suggested by Miroslav v3: Fixed up commit message Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- tools/testing/selftests/timers/raw_skew.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/tools/testing/selftests/timers/raw_skew.c b/tools/testing/selftests/timers/raw_skew.c index ca6cd146aafe..dcf73c5dab6e 100644 --- a/tools/testing/selftests/timers/raw_skew.c +++ b/tools/testing/selftests/timers/raw_skew.c @@ -134,6 +134,11 @@ int main(int argv, char **argc) printf(" %lld.%i(act)", ppm/1000, abs((int)(ppm%1000)));
if (llabs(eppm - ppm) > 1000) { + if (tx1.offset || tx2.offset || + tx1.freq != tx2.freq || tx1.tick != tx2.tick) { + printf(" [SKIP]\n"); + return ksft_exit_skip("The clock was adjusted externally. Shutdown NTPd or other time sync daemons\n"); + } printf(" [FAILED]\n"); return ksft_exit_fail(); }
From: Hannes Reinecke hare@suse.de
[ Upstream commit fa519f701d27198a2858bb108fc18ea9d8c106a7 ]
fc_rport_login() will be calling mutex_lock() while running inside an RCU-protected section, triggering the warning 'sleeping function called from invalid context'. To fix this we can drop the rcu functions here altogether as the disc mutex protecting the list itself is already held, preventing any list manipulation.
Fixes: a407c593398c ("scsi: libfc: Fixup disc_mutex handling") Signed-off-by: Hannes Reinecke hare@suse.com Acked-by: Johannes Thumshirn jth@kernel.org Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- drivers/scsi/libfc/fc_disc.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/scsi/libfc/fc_disc.c b/drivers/scsi/libfc/fc_disc.c index 8660f923ace0..bb9c1c016643 100644 --- a/drivers/scsi/libfc/fc_disc.c +++ b/drivers/scsi/libfc/fc_disc.c @@ -294,9 +294,11 @@ static void fc_disc_done(struct fc_disc *disc, enum fc_disc_event event) * discovery, reverify or log them in. Otherwise, log them out. * Skip ports which were never discovered. These are the dNS port * and ports which were created by PLOGI. + * + * We don't need to use the _rcu variant here as the rport list + * is protected by the disc mutex which is already held on entry. */ - rcu_read_lock(); - list_for_each_entry_rcu(rdata, &disc->rports, peers) { + list_for_each_entry(rdata, &disc->rports, peers) { if (!kref_get_unless_zero(&rdata->kref)) continue; if (rdata->disc_id) { @@ -307,7 +309,6 @@ static void fc_disc_done(struct fc_disc *disc, enum fc_disc_event event) } kref_put(&rdata->kref, fc_rport_destroy); } - rcu_read_unlock(); mutex_unlock(&disc->disc_mutex); disc->disc_callback(lport, event); mutex_lock(&disc->disc_mutex);
From: Dan Carpenter dan.carpenter@oracle.com
[ Upstream commit cd0e0ca69109d025b1a1b6609f70682db62138b0 ]
The ARRAY_SIZE() macro is type size_t. If s6e8aa0_dcs_read() returns a negative error code, then "ret < ARRAY_SIZE(id)" is false because the negative error code is type promoted to a high positive value.
Fixes: 02051ca06371 ("drm/panel: add S6E8AA0 driver") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Reviewed-by: Andrzej Hajda a.hajda@samsung.com Signed-off-by: Thierry Reding treding@nvidia.com Link: https://patchwork.freedesktop.org/patch/msgid/20180704093807.s3lqsb2v6dg2k43... Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- drivers/gpu/drm/panel/panel-samsung-s6e8aa0.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/panel/panel-samsung-s6e8aa0.c b/drivers/gpu/drm/panel/panel-samsung-s6e8aa0.c index a188a3959f1a..6ad827b93ae1 100644 --- a/drivers/gpu/drm/panel/panel-samsung-s6e8aa0.c +++ b/drivers/gpu/drm/panel/panel-samsung-s6e8aa0.c @@ -823,7 +823,7 @@ static void s6e8aa0_read_mtp_id(struct s6e8aa0 *ctx) int ret, i;
ret = s6e8aa0_dcs_read(ctx, 0xd1, id, ARRAY_SIZE(id)); - if (ret < ARRAY_SIZE(id) || id[0] == 0x00) { + if (ret < 0 || ret < ARRAY_SIZE(id) || id[0] == 0x00) { dev_err(ctx->dev, "read id failed\n"); ctx->error = -EIO; return;
From: Andy Shevchenko andriy.shevchenko@linux.intel.com
[ Upstream commit 2abc66cd499aa16876e45c6438788902f7d1ce22 ]
It appears that the driver misses the support of dmaengine_terminate_sync(). Since many of callers expects this behaviour implement the new device_synchronize() callback to allow proper synchronization when stopping a channel.
Fixes: b36f09c3c441 ("dmaengine: Add transfer termination synchronization support") Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- drivers/dma/hsu/hsu.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/drivers/dma/hsu/hsu.c b/drivers/dma/hsu/hsu.c index 29d04ca71d52..202ffa9f7611 100644 --- a/drivers/dma/hsu/hsu.c +++ b/drivers/dma/hsu/hsu.c @@ -413,6 +413,13 @@ static void hsu_dma_free_chan_resources(struct dma_chan *chan) vchan_free_chan_resources(to_virt_chan(chan)); }
+static void hsu_dma_synchronize(struct dma_chan *chan) +{ + struct hsu_dma_chan *hsuc = to_hsu_dma_chan(chan); + + vchan_synchronize(&hsuc->vchan); +} + int hsu_dma_probe(struct hsu_dma_chip *chip) { struct hsu_dma *hsu; @@ -459,6 +466,7 @@ int hsu_dma_probe(struct hsu_dma_chip *chip) hsu->dma.device_pause = hsu_dma_pause; hsu->dma.device_resume = hsu_dma_resume; hsu->dma.device_terminate_all = hsu_dma_terminate_all; + hsu->dma.device_synchronize = hsu_dma_synchronize;
hsu->dma.src_addr_widths = HSU_DMA_BUSWIDTHS; hsu->dma.dst_addr_widths = HSU_DMA_BUSWIDTHS;
From: Andy Shevchenko andriy.shevchenko@linux.intel.com
[ Upstream commit bbacb8e78a3b29ebdbb6af7d54fcf25d3f1c248f ]
It appears that the driver misses the support of dmaengine_terminate_sync(). Since many of callers expects this behaviour implement the new device_synchronize() callback to allow proper synchronization when stopping a channel.
Fixes: b36f09c3c441 ("dmaengine: Add transfer termination synchronization support") Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- drivers/dma/idma64.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/drivers/dma/idma64.c b/drivers/dma/idma64.c index 1953e57505f4..2ee93cf98f00 100644 --- a/drivers/dma/idma64.c +++ b/drivers/dma/idma64.c @@ -496,6 +496,13 @@ static int idma64_terminate_all(struct dma_chan *chan) return 0; }
+static void idma64_synchronize(struct dma_chan *chan) +{ + struct idma64_chan *idma64c = to_idma64_chan(chan); + + vchan_synchronize(&idma64c->vchan); +} + static int idma64_alloc_chan_resources(struct dma_chan *chan) { struct idma64_chan *idma64c = to_idma64_chan(chan); @@ -583,6 +590,7 @@ static int idma64_probe(struct idma64_chip *chip) idma64->dma.device_pause = idma64_pause; idma64->dma.device_resume = idma64_resume; idma64->dma.device_terminate_all = idma64_terminate_all; + idma64->dma.device_synchronize = idma64_synchronize;
idma64->dma.src_addr_widths = IDMA64_BUSWIDTHS; idma64->dma.dst_addr_widths = IDMA64_BUSWIDTHS;
From: Bart Van Assche bart.vanassche@wdc.com
[ Upstream commit 4c5743bc4fe3233cecc1c184a773c79c8ee45bbe ]
Avoid that the following compiler warning is reported when building with W=1:
drivers/infiniband/hw/nes/nes_hw.c:646:51: warning: suggest braces around empty body in an 'if' statement [-Wempty-body]
Signed-off-by: Bart Van Assche bart.vanassche@wdc.com Signed-off-by: Jason Gunthorpe jgg@mellanox.com Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- drivers/infiniband/hw/nes/nes.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/infiniband/hw/nes/nes.h b/drivers/infiniband/hw/nes/nes.h index 3f9e56e8b379..6711abdd4872 100644 --- a/drivers/infiniband/hw/nes/nes.h +++ b/drivers/infiniband/hw/nes/nes.h @@ -159,7 +159,7 @@ do { \
#define NES_EVENT_TIMEOUT 1200000 #else -#define nes_debug(level, fmt, args...) +#define nes_debug(level, fmt, args...) do {} while (0) #define assert(expr) do {} while (0)
#define NES_EVENT_TIMEOUT 100000
From: Ming Lei ming.lei@redhat.com
[ Upstream commit b04f50ab8a74129b3041a2836c33c916be3c6667 ]
Only attempt to merge bio iff the ctx->rq_list isn't empty, because:
1) for high-performance SSD, most of times dispatch may succeed, then there may be nothing left in ctx->rq_list, so don't try to merge over sw queue if it is empty, then we can save one acquiring of ctx->lock
2) we can't expect good merge performance on per-cpu sw queue, and missing one merge on sw queue won't be a big deal since tasks can be scheduled from one CPU to another.
Cc: Laurence Oberman loberman@redhat.com Cc: Omar Sandoval osandov@fb.com Cc: Bart Van Assche bart.vanassche@wdc.com Tested-by: Kashyap Desai kashyap.desai@broadcom.com Reported-by: Kashyap Desai kashyap.desai@broadcom.com Reviewed-by: Christoph Hellwig hch@lst.de Signed-off-by: Ming Lei ming.lei@redhat.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- block/blk-mq-sched.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/block/blk-mq-sched.c b/block/blk-mq-sched.c index eca011fdfa0e..ae5d8f10a27c 100644 --- a/block/blk-mq-sched.c +++ b/block/blk-mq-sched.c @@ -236,7 +236,8 @@ bool __blk_mq_sched_bio_merge(struct request_queue *q, struct bio *bio) return e->type->ops.mq.bio_merge(hctx, bio); }
- if (hctx->flags & BLK_MQ_F_SHOULD_MERGE) { + if ((hctx->flags & BLK_MQ_F_SHOULD_MERGE) && + !list_empty_careful(&ctx->rq_list)) { /* default per sw-queue merge */ spin_lock(&ctx->lock); ret = blk_mq_attempt_merge(q, ctx, bio);
From: Andy Shevchenko andriy.shevchenko@linux.intel.com
[ Upstream commit 36b312792b97933dc07abe074f50941199bd357c ]
In case we try to lock GPIO pin as IRQ when something going wrong we print a misleading message.
Correct this by checking an error code from ->get_direction() in gpiochip_lock_as_irq() and printing a corresponding message.
Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Cc: Mika Westerberg mika.westerberg@linux.intel.com Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- drivers/gpio/gpiolib.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 7e0bfd7347f6..e5bf3e774439 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -2811,6 +2811,12 @@ int gpiochip_lock_as_irq(struct gpio_chip *chip, unsigned int offset) if (!chip->can_sleep && chip->get_direction) { int dir = chip->get_direction(chip, offset);
+ if (dir < 0) { + chip_err(chip, "%s: cannot get GPIO direction\n", + __func__); + return dir; + } + if (dir) clear_bit(FLAG_IS_OUT, &desc->flags); else
From: Ming Lei ming.lei@redhat.com
[ Upstream commit 1311326cf4755c7ffefd20f576144ecf46d9906b ]
SCSI probing may synchronously create and destroy a lot of request_queues for non-existent devices. Any synchronize_rcu() in queue creation or destroy path may introduce long latency during booting, see detailed description in comment of blk_register_queue().
This patch removes one synchronize_rcu() inside blk_cleanup_queue() for this case, commit c2856ae2f315d75(blk-mq: quiesce queue before freeing queue) needs synchronize_rcu() for implementing blk_mq_quiesce_queue(), but when queue isn't initialized, it isn't necessary to do that since only pass-through requests are involved, no original issue in scsi_execute() at all.
Without this patch and previous one, it may take more 20+ seconds for virtio-scsi to complete disk probe. With the two patches, the time becomes less than 100ms.
Fixes: c2856ae2f315d75 ("blk-mq: quiesce queue before freeing queue") Reported-by: Andrew Jones drjones@redhat.com Cc: Omar Sandoval osandov@fb.com Cc: Bart Van Assche bart.vanassche@wdc.com Cc: linux-scsi@vger.kernel.org Cc: "Martin K. Petersen" martin.petersen@oracle.com Cc: Christoph Hellwig hch@lst.de Tested-by: Andrew Jones drjones@redhat.com Signed-off-by: Ming Lei ming.lei@redhat.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- block/blk-core.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/block/blk-core.c b/block/blk-core.c index 1d27e2a152e0..6aa2bc4e9652 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -669,9 +669,13 @@ void blk_cleanup_queue(struct request_queue *q) * make sure all in-progress dispatch are completed because * blk_freeze_queue() can only complete all requests, and * dispatch may still be in-progress since we dispatch requests - * from more than one contexts + * from more than one contexts. + * + * No need to quiesce queue if it isn't initialized yet since + * blk_freeze_queue() should be enough for cases of passthrough + * request. */ - if (q->mq_ops) + if (q->mq_ops && blk_queue_init_done(q)) blk_mq_quiesce_queue(q);
/* for synchronous bio-based driver finish in-flight integrity i/o */
From: Douglas Anderson dianders@chromium.org
[ Upstream commit 05e0c828955c1cab58dd71a04539442e5375d917 ]
If you do this on an sdm845 board: cat /sys/kernel/debug/pinctrl/3400000.pinctrl/pinconf-groups
...it looks like nonsense. For every pin you see listed: input bias bus hold, input bias disabled, input bias pull down, input bias pull up
That's because msm_config_group_get() isn't complying with the rules that pinconf_generic_dump_one() expects. Specifically for boolean parameters (anything with a "struct pin_config_item" where has_arg is false) the function expects that the function should return its value not through the "config" parameter but should return "0" if the value is set and "-EINVAL" if the value isn't set.
Let's fix this.
From a quick sample of other pinctrl drivers, it appears to be
tradition to also return 1 through the config parameter for these boolean parameters when they exist. I'm not one to knock tradition, so I'll follow tradition and return 1 in these cases. While I'm at it, I'll also continue searching for four leaf clovers, kocking on wood three times, and trying not to break mirrors.
Fixes: f365be092572 ("pinctrl: Add Qualcomm TLMM driver") Signed-off-by: Douglas Anderson dianders@chromium.org Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- drivers/pinctrl/qcom/pinctrl-msm.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c index ff491da64dab..31632c087504 100644 --- a/drivers/pinctrl/qcom/pinctrl-msm.c +++ b/drivers/pinctrl/qcom/pinctrl-msm.c @@ -238,22 +238,30 @@ static int msm_config_group_get(struct pinctrl_dev *pctldev, /* Convert register value to pinconf value */ switch (param) { case PIN_CONFIG_BIAS_DISABLE: - arg = arg == MSM_NO_PULL; + if (arg != MSM_NO_PULL) + return -EINVAL; + arg = 1; break; case PIN_CONFIG_BIAS_PULL_DOWN: - arg = arg == MSM_PULL_DOWN; + if (arg != MSM_PULL_DOWN) + return -EINVAL; + arg = 1; break; case PIN_CONFIG_BIAS_BUS_HOLD: if (pctrl->soc->pull_no_keeper) return -ENOTSUPP;
- arg = arg == MSM_KEEPER; + if (arg != MSM_KEEPER) + return -EINVAL; + arg = 1; break; case PIN_CONFIG_BIAS_PULL_UP: if (pctrl->soc->pull_no_keeper) arg = arg == MSM_PULL_UP_NO_KEEPER; else arg = arg == MSM_PULL_UP; + if (!arg) + return -EINVAL; break; case PIN_CONFIG_DRIVE_STRENGTH: arg = msm_regval_to_drive(arg);
From: Douglas Anderson dianders@chromium.org
[ Upstream commit 1cf86bc21257a330e3af51f2a4e885f1a705f6a5 ]
If you do this on an sdm845 board: grep "" /sys/kernel/debug/pinctrl/*spmi:pmic*/pinconf-groups
...it looks like nonsense. For every pin you see listed: input bias disabled, input bias high impedance, input bias pull down, input bias pull up, ...
That's because pmic_gpio_config_get() isn't complying with the rules that pinconf_generic_dump_one() expects. Specifically for boolean parameters (anything with a "struct pin_config_item" where has_arg is false) the function expects that the function should return its value not through the "config" parameter but should return "0" if the value is set and "-EINVAL" if the value isn't set.
Let's fix this.
From a quick sample of other pinctrl drivers, it appears to be
tradition to also return 1 through the config parameter for these boolean parameters when they exist. I'm not one to knock tradition, so I'll follow tradition and return 1 in these cases. While I'm at it, I'll also continue searching for four leaf clovers, kocking on wood three times, and trying not to break mirrors.
NOTE: This also fixes an apparent typo for reading PIN_CONFIG_BIAS_DISABLE where the old driver was accidentally using "=" instead of "==" and thus was setting some internal state when you tried to query PIN_CONFIG_BIAS_DISABLE. Oops.
Fixes: eadff3024472 ("pinctrl: Qualcomm SPMI PMIC GPIO pin controller driver") Signed-off-by: Douglas Anderson dianders@chromium.org Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- drivers/pinctrl/qcom/pinctrl-spmi-gpio.c | 32 ++++++++++++++++++------ 1 file changed, 24 insertions(+), 8 deletions(-)
diff --git a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c index c2c0bab04257..22aaf4375fac 100644 --- a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c +++ b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c @@ -390,31 +390,47 @@ static int pmic_gpio_config_get(struct pinctrl_dev *pctldev,
switch (param) { case PIN_CONFIG_DRIVE_PUSH_PULL: - arg = pad->buffer_type == PMIC_GPIO_OUT_BUF_CMOS; + if (pad->buffer_type != PMIC_GPIO_OUT_BUF_CMOS) + return -EINVAL; + arg = 1; break; case PIN_CONFIG_DRIVE_OPEN_DRAIN: - arg = pad->buffer_type == PMIC_GPIO_OUT_BUF_OPEN_DRAIN_NMOS; + if (pad->buffer_type != PMIC_GPIO_OUT_BUF_OPEN_DRAIN_NMOS) + return -EINVAL; + arg = 1; break; case PIN_CONFIG_DRIVE_OPEN_SOURCE: - arg = pad->buffer_type == PMIC_GPIO_OUT_BUF_OPEN_DRAIN_PMOS; + if (pad->buffer_type != PMIC_GPIO_OUT_BUF_OPEN_DRAIN_PMOS) + return -EINVAL; + arg = 1; break; case PIN_CONFIG_BIAS_PULL_DOWN: - arg = pad->pullup == PMIC_GPIO_PULL_DOWN; + if (pad->pullup != PMIC_GPIO_PULL_DOWN) + return -EINVAL; + arg = 1; break; case PIN_CONFIG_BIAS_DISABLE: - arg = pad->pullup = PMIC_GPIO_PULL_DISABLE; + if (pad->pullup != PMIC_GPIO_PULL_DISABLE) + return -EINVAL; + arg = 1; break; case PIN_CONFIG_BIAS_PULL_UP: - arg = pad->pullup == PMIC_GPIO_PULL_UP_30; + if (pad->pullup != PMIC_GPIO_PULL_UP_30) + return -EINVAL; + arg = 1; break; case PIN_CONFIG_BIAS_HIGH_IMPEDANCE: - arg = !pad->is_enabled; + if (pad->is_enabled) + return -EINVAL; + arg = 1; break; case PIN_CONFIG_POWER_SOURCE: arg = pad->power_source; break; case PIN_CONFIG_INPUT_ENABLE: - arg = pad->input_enabled; + if (!pad->input_enabled) + return -EINVAL; + arg = 1; break; case PIN_CONFIG_OUTPUT: arg = pad->out_value;
From: Mikko Perttunen mperttunen@nvidia.com
[ Upstream commit f7b3182232c82bb9769e2d5471d702bae2972d2b ]
When registering clocks, we just skip any that fail to register (leaving a NULL hole in the clock table). However, our of_xlate function still tries to dereference each entry while looking for the clock with the requested id, causing a crash if any clocks failed to register. Add a check to of_xlate to skip any NULL clocks.
Signed-off-by: Mikko Perttunen mperttunen@nvidia.com Acked-by: Jon Hunter jonathanh@nvidia.com Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Sasha Levin alexander.levin@microsoft.com --- drivers/clk/tegra/clk-bpmp.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/drivers/clk/tegra/clk-bpmp.c b/drivers/clk/tegra/clk-bpmp.c index 638ace64033b..6c933b0e29a3 100644 --- a/drivers/clk/tegra/clk-bpmp.c +++ b/drivers/clk/tegra/clk-bpmp.c @@ -581,9 +581,15 @@ static struct clk_hw *tegra_bpmp_clk_of_xlate(struct of_phandle_args *clkspec, unsigned int id = clkspec->args[0], i; struct tegra_bpmp *bpmp = data;
- for (i = 0; i < bpmp->num_clocks; i++) - if (bpmp->clocks[i]->id == id) - return &bpmp->clocks[i]->hw; + for (i = 0; i < bpmp->num_clocks; i++) { + struct tegra_bpmp_clk *clk = bpmp->clocks[i]; + + if (!clk) + continue; + + if (clk->id == id) + return &clk->hw; + }
return NULL; }
linux-stable-mirror@lists.linaro.org