6.19.4-rc1 review
Greg Kroah-Hartman
maintainerPATCH 110/781 crypto: inside-secure/eip93 - unregister only available algorithm
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aleksander Jan Bajkowski <[email protected]>
[ Upstream commit 0ceeadc7b53a041d89d5843f6bf0ccb7c98b0b4f ]
EIP93 has an options register. This register indicates which crypto algorithms are implemented in silicon. Supported algorithms are registered on this basis. Unregister algorithms on the same basis. Currently, all algorithms are unregistered, even those not supported by HW. This results in panic on platforms that don't have all options implemented in silicon.
--- .../crypto/inside-secure/eip93/eip93-main.c | 92 +++++++++++-------- 1 file changed, 53 insertions(+), 39 deletions(-)
drivers/crypto/inside-secure/eip93/eip93-main.c +53 -39
@@ -77,11 +77,44 @@ inline void eip93_irq_clear(struct eip93_device *eip93, u32 mask)__raw_writel (mask, eip93->base +EIP93_REG_INT_CLR ); } -static void eip93_unregister_algs (unsigned int i) +static int eip93_algo_is_supported (u32 alg_flags,u32 supported_algo_flags) +{ +if ((IS_DES (alg_flags) ||IS_3DES (alg_flags)) && + !(supported_algo_flags &EIP93_PE_OPTION_TDES )) +return 0 ; + +if (IS_AES (alg_flags) && + !(supported_algo_flags &EIP93_PE_OPTION_AES )) +return 0 ; + +if (IS_HASH_MD5 (alg_flags) && + !(supported_algo_flags &EIP93_PE_OPTION_MD5 )) +return 0 ; + +if (IS_HASH_SHA1 (alg_flags) && + !(supported_algo_flags &EIP93_PE_OPTION_SHA_1 )) +return 0 ; + +if (IS_HASH_SHA224 (alg_flags) && + !(supported_algo_flags &EIP93_PE_OPTION_SHA_224 )) +return 0 ; + +if (IS_HASH_SHA256 (alg_flags) && + !(supported_algo_flags &EIP93_PE_OPTION_SHA_256 )) +return 0 ; + +return 1 ; +} + +static void eip93_unregister_algs (u32 supported_algo_flags,unsigned int i) {unsigned int j;for (j =0 ; j < i; j++) { +if (!eip93_algo_is_supported (eip93_algs[j]->flags, + supported_algo_flags)) +continue ; +switch (eip93_algs[j]->type) {case EIP93_ALG_TYPE_SKCIPHER :crypto_unregister_skcipher (&eip93_algs[j]->alg.skcipher);
@@ -106,49 +139,27 @@ static int eip93_register_algs(struct eip93_device *eip93, u32 supported_algo_fl eip93_algs[i]->eip93 = eip93; -if ((IS_DES (alg_flags) ||IS_3DES (alg_flags)) && - !(supported_algo_flags &EIP93_PE_OPTION_TDES )) +if (!eip93_algo_is_supported (alg_flags, supported_algo_flags))continue ; -if (IS_AES (alg_flags)) { -if (!(supported_algo_flags &EIP93_PE_OPTION_AES )) -continue ; +if (IS_AES (alg_flags) && !IS_HMAC (alg_flags)) { +if (supported_algo_flags &EIP93_PE_OPTION_AES_KEY128 ) + eip93_algs[i]->alg.skcipher.max_keysize = +AES_KEYSIZE_128 ; -if (!IS_HMAC (alg_flags)) { -if (supported_algo_flags &EIP93_PE_OPTION_AES_KEY128 ) - eip93_algs[i]->alg.skcipher.max_keysize = -AES_KEYSIZE_128 ; +if (supported_algo_flags &EIP93_PE_OPTION_AES_KEY192 ) + eip93_algs[i]->alg.skcipher.max_keysize = +AES_KEYSIZE_192 ; -if (supported_algo_flags &EIP93_PE_OPTION_AES_KEY192 ) - eip93_algs[i]->alg.skcipher.max_keysize = -AES_KEYSIZE_192 ; +if (supported_algo_flags &EIP93_PE_OPTION_AES_KEY256 ) + eip93_algs[i]->alg.skcipher.max_keysize = +AES_KEYSIZE_256 ; -if (supported_algo_flags &EIP93_PE_OPTION_AES_KEY256 ) - eip93_algs[i]->alg.skcipher.max_keysize = -AES_KEYSIZE_256 ; - -if (IS_RFC3686 (alg_flags)) - eip93_algs[i]->alg.skcipher.max_keysize += -CTR_RFC3686_NONCE_SIZE ; - } +if (IS_RFC3686 (alg_flags)) + eip93_algs[i]->alg.skcipher.max_keysize += +CTR_RFC3686_NONCE_SIZE ; } -if (IS_HASH_MD5 (alg_flags) && - !(supported_algo_flags &EIP93_PE_OPTION_MD5 )) -continue ; - -if (IS_HASH_SHA1 (alg_flags) && - !(supported_algo_flags &EIP93_PE_OPTION_SHA_1 )) -continue ; - -if (IS_HASH_SHA224 (alg_flags) && - !(supported_algo_flags &EIP93_PE_OPTION_SHA_224 )) -continue ; - -if (IS_HASH_SHA256 (alg_flags) && - !(supported_algo_flags &EIP93_PE_OPTION_SHA_256 )) -continue ; -switch (eip93_algs[i]->type) {case EIP93_ALG_TYPE_SKCIPHER : ret =crypto_register_skcipher (&eip93_algs[i]->alg.skcipher);
@@ -167,7 +178,7 @@ static int eip93_register_algs(struct eip93_device *eip93, u32 supported_algo_flreturn 0 ; fail: -eip93_unregister_algs (i); +eip93_unregister_algs (supported_algo_flags, i);return ret; }
@@ -469,8 +480,11 @@ static int eip93_crypto_probe(struct platform_device *pdev)static void eip93_crypto_remove (struct platform_device *pdev) {struct eip93_device *eip93 =platform_get_drvdata (pdev); +u32 algo_flags; + + algo_flags =readl (eip93->base +EIP93_REG_PE_OPTION_1 ); -eip93_unregister_algs (ARRAY_SIZE (eip93_algs)); +eip93_unregister_algs (algo_flags,ARRAY_SIZE (eip93_algs));eip93_cleanup (eip93); }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 111/781 x86/fgraph: Fix return_to_handler regs.rsp value
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiri Olsa <[email protected]>
[ Upstream commit 8bc11700e0d23d4fdb7d8d5a73b2e95de427cabc ]
The previous change (Fixes commit) messed up the rsp register value, which is wrong because it's already adjusted with FRAME_SIZE, we need the original rsp value.
This change does not affect fprobe current kernel unwind, the !perf_hw_regs path perf_callchain_kernel:
if (perf_hw_regs(regs)) {
if (perf_callchain_store(entry, regs->ip))
return;
unwind_start(&state, current, regs, NULL);
} else {
unwind_start(&state, current, NULL, (void *)regs->sp);
}which uses pt_regs.sp as first_frame boundary (FRAME_SIZE shift makes no difference, unwind stil stops at the right frame).
This change fixes the other path when we want to unwind directly from pt_regs sp/fp/ip state, which is coming in following change.
--- arch/x86/kernel/ftrace_64.S | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
arch/x86/kernel/ftrace_64.S +4 -1
@@ -364,6 +364,9 @@ SYM_CODE_START(return_to_handler) UNWIND_HINT_UNDEFINED ANNOTATE_NOENDBR + /* Store original rsp for pt_regs.sp value. */ + movq %rsp, %rdi + /* Restore return_to_handler value that got eaten by previous ret instruction. */ subq $8, %rsp UNWIND_HINT_FUNC
@@ -374,7 +377,7 @@ SYM_CODE_START(return_to_handler) movq %rax, RAX(%rsp) movq %rdx, RDX(%rsp) movq %rbp, RBP(%rsp) - movq %rsp, RSP(%rsp) + movq %rdi, RSP(%rsp) movq %rsp, %rdi call ftrace_return_to_handler
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 112/781 x86/fgraph,bpf: Switch kprobe_multi program stack unwind to hw_regs path
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiri Olsa <[email protected]>
[ Upstream commit aea251799998aa1b78eacdfb308f18ea114ea5b3 ]
Mahe reported missing function from stack trace on top of kprobe multi program. The missing function is the very first one in the stacktrace, the one that the bpf program is attached to.
# bpftrace -e 'kprobe:__x64_sys_newuname* { print(kstack)}'
Attaching 1 probe... do_syscall_64+134
entry_SYSCALL_64_after_hwframe+118 ('*' is used for kprobe_multi attachment)
The reason is that the previous change (the Fixes commit) fixed stack unwind for tracepoint, but removed attached function address from the stack trace on top of kprobe multi programs, which I also overlooked in the related test (check following patch).
The tracepoint and kprobe_multi have different stack setup, but use same unwind path. I think it's better to keep the previous change, which fixed tracepoint unwind and instead change the kprobe multi unwind as explained below.
The bpf program stack unwind calls perf_callchain_kernel for kernel portion and it follows two unwind paths based on X86_EFLAGS_FIXED bit in pt_regs.flags.
When the bit set we unwind from stack represented by pt_regs argument, otherwise we unwind currently executed stack up to 'first_frame' boundary.
The 'first_frame' value is taken from regs.rsp value, but ftrace_caller and ftrace_regs_caller (ftrace trampoline) functions set the regs.rsp to the previous stack frame, so we skip the attached function entry.
If we switch kprobe_multi unwind to use the X86_EFLAGS_FIXED bit, we set the start of the unwind to the attached function address. As another benefit we also cut extra unwind cycles needed to reach the 'first_frame' boundary.
The speedup can be measured with trigger bench for kprobe_multi program and stacktrace support.
- trigger bench with stacktrace on current code:
kprobe-multi : 0.810 ± 0.001M/s
kretprobe-multi: 0.808 ± 0.001M/s- and with the fix:
kprobe-multi : 1.264 ± 0.001M/s
kretprobe-multi: 1.401 ± 0.002M/sWith the fix, the entry probe stacktrace:
# bpftrace -e 'kprobe:__x64_sys_newuname* { print(kstack)}'
Attaching 1 probe... __x64_sys_newuname+9
do_syscall_64+134
entry_SYSCALL_64_after_hwframe+118The return probe skips the attached function, because it's no longer on the stack at the point of the unwind and this way is the same how standard kretprobe works.
# bpftrace -e 'kretprobe:__x64_sys_newuname* { print(kstack)}'
Attaching 1 probe... do_syscall_64+134
entry_SYSCALL_64_after_hwframe+118--- arch/x86/include/asm/ftrace.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/include/asm/ftrace.h +1 -1
@@ -57,7 +57,7 @@ arch_ftrace_get_regs(struct ftrace_regs *fregs) }#define arch_ftrace_partial_regs (regs) do { \ - regs->flags &= ~X86_EFLAGS_FIXED; \ + regs->flags |= X86_EFLAGS_FIXED; \ regs->cs = __KERNEL_CS; \ } while (0)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 113/781 selftests/bpf: Fix kprobe multi stacktrace_ips test
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiri Olsa <[email protected]>
[ Upstream commit 0207f94971e72a13380e28022c86da147e8e090f ]
We now include the attached function in the stack trace, fixing the test accordingly.
--- .../selftests/bpf/prog_tests/stacktrace_ips.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-)
tools/testing/selftests/bpf/prog_tests/stacktrace_ips.c +14 -5
@@ -74,11 +74,20 @@ static void test_stacktrace_ips_kprobe_multi(bool retprobe)load_kallsyms (); -check_stacktrace_ips (bpf_map__fd (skel->maps.stackmap), skel->bss->stack_key,4 , -ksym_get_addr ("bpf_testmod_stacktrace_test_3" ), -ksym_get_addr ("bpf_testmod_stacktrace_test_2" ), -ksym_get_addr ("bpf_testmod_stacktrace_test_1" ), -ksym_get_addr ("bpf_testmod_test_read" )); +if (retprobe) { +check_stacktrace_ips (bpf_map__fd (skel->maps.stackmap), skel->bss->stack_key,4 , +ksym_get_addr ("bpf_testmod_stacktrace_test_3" ), +ksym_get_addr ("bpf_testmod_stacktrace_test_2" ), +ksym_get_addr ("bpf_testmod_stacktrace_test_1" ), +ksym_get_addr ("bpf_testmod_test_read" )); + }else { +check_stacktrace_ips (bpf_map__fd (skel->maps.stackmap), skel->bss->stack_key,5 , +ksym_get_addr ("bpf_testmod_stacktrace_test" ), +ksym_get_addr ("bpf_testmod_stacktrace_test_3" ), +ksym_get_addr ("bpf_testmod_stacktrace_test_2" ), +ksym_get_addr ("bpf_testmod_stacktrace_test_1" ), +ksym_get_addr ("bpf_testmod_test_read" )); + } cleanup:stacktrace_ips__destroy (skel);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 114/781 crypto: hisilicon/trng - support tfms sharing the device
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Weili Qian <[email protected]>
[ Upstream commit 3d3135057ff567d5c09fff4c9ef6391a684e8042 ]
Since the number of devices is limited, and the number of tfms may exceed the number of devices, to ensure that tfms can be successfully allocated, support tfms sharing the same device.
--- drivers/crypto/hisilicon/trng/trng.c | 121 +++++++++++++++++++-------- 1 file changed, 86 insertions(+), 35 deletions(-)
drivers/crypto/hisilicon/trng/trng.c +86 -35
@@ -40,6 +40,7 @@#define SEED_SHIFT_24 24#define SEED_SHIFT_16 16#define SEED_SHIFT_8 8 +#define SW_MAX_RANDOM_BYTES 65520struct hisi_trng_list {struct mutex lock;
@@ -53,8 +54,10 @@ struct hisi_trng {struct list_head list;struct hwrng rng;u32 ver; -bool is_used; -struct mutex mutex; +u32 ctx_num; +/* The bytes of the random number generated since the last seeding. */ +u32 random_bytes; +struct mutex lock; };struct hisi_trng_ctx {
@@ -63,10 +66,14 @@ struct hisi_trng_ctx {static atomic_t trng_active_devs;static struct hisi_trng_list trng_devices; +static int hisi_trng_read (struct hwrng *rng,void *buf,size_t max,bool wait); -static void hisi_trng_set_seed (struct hisi_trng *trng,const u8 *seed) +static int hisi_trng_set_seed (struct hisi_trng *trng,const u8 *seed) {u32 val, seed_reg, i; +int ret; + +writel (0x0 , trng->base +SW_DRBG_BLOCKS );for (i =0 ; i <SW_DRBG_SEED_SIZE ; i +=SW_DRBG_SEED_SIZE /SW_DRBG_SEED_REGS_NUM ) {
@@ -78,6 +85,20 @@ static void hisi_trng_set_seed(struct hisi_trng *trng, const u8 *seed) seed_reg = (i >>SW_DRBG_NUM_SHIFT ) %SW_DRBG_SEED_REGS_NUM ;writel (val, trng->base +SW_DRBG_SEED (seed_reg)); } + +writel (SW_DRBG_BLOCKS_NUM | (0x1 <<SW_DRBG_ENABLE_SHIFT ), + trng->base +SW_DRBG_BLOCKS ); +writel (0x1 , trng->base +SW_DRBG_INIT ); + ret =readl_relaxed_poll_timeout (trng->base +SW_DRBG_STATUS , + val, val &BIT (0 ),SLEEP_US ,TIMEOUT_US ); +if (ret) { +pr_err ("failed to init trng(%d)\n" , ret); +return -EIO ; + } + + trng->random_bytes =0 ; + +return 0 ; } static int hisi_trng_seed(struct crypto_rng *tfm, const u8 *seed,
@@ -85,8 +106,7 @@ static int hisi_trng_seed(struct crypto_rng *tfm, const u8 *seed, {struct hisi_trng_ctx *ctx =crypto_rng_ctx (tfm);struct hisi_trng *trng = ctx->trng; -u32 val =0 ; -int ret =0 ; +int ret;if (slen <SW_DRBG_SEED_SIZE ) { pr_err("slen(%u) is not matched with trng(%d)\n", slen,
@@ -94,43 +114,45 @@ static int hisi_trng_seed(struct crypto_rng *tfm, const u8 *seed,return -EINVAL ; } -writel (0x0 , trng->base +SW_DRBG_BLOCKS ); -hisi_trng_set_seed (trng, seed); +mutex_lock (&trng->lock); + ret =hisi_trng_set_seed (trng, seed); +mutex_unlock (&trng->lock); -writel (SW_DRBG_BLOCKS_NUM | (0x1 <<SW_DRBG_ENABLE_SHIFT ), - trng->base +SW_DRBG_BLOCKS ); -writel (0x1 , trng->base +SW_DRBG_INIT ); +return ret; +} - ret =readl_relaxed_poll_timeout (trng->base +SW_DRBG_STATUS , - val, val &BIT (0 ),SLEEP_US ,TIMEOUT_US ); -if (ret) -pr_err ("fail to init trng(%d)\n" , ret); +static int hisi_trng_reseed (struct hisi_trng *trng) +{ +u8 seed[SW_DRBG_SEED_SIZE ]; +int size; -return ret; +if (!trng->random_bytes) +return 0 ; + + size =hisi_trng_read (&trng->rng, seed,SW_DRBG_SEED_SIZE , false); +if (size !=SW_DRBG_SEED_SIZE ) +return -EIO ; + +return hisi_trng_set_seed (trng, seed); } -static int hisi_trng_generate (struct crypto_rng *tfm,const u8 *src, -unsigned int slen,u8 *dstn,unsigned int dlen) +static int hisi_trng_get_bytes (struct hisi_trng *trng,u8 *dstn,unsigned int dlen) { -struct hisi_trng_ctx *ctx =crypto_rng_ctx (tfm); -struct hisi_trng *trng = ctx->trng;u32 data[SW_DRBG_DATA_NUM ];u32 currsize =0 ;u32 val =0 ;int ret;u32 i; -if (dlen >SW_DRBG_BLOCKS_NUM *SW_DRBG_BYTES || dlen ==0 ) { -pr_err ("dlen(%u) exceeds limit(%d)!\n" , dlen, -SW_DRBG_BLOCKS_NUM *SW_DRBG_BYTES ); -return -EINVAL ; - } + ret =hisi_trng_reseed (trng); +if (ret) +return ret; do { ret = readl_relaxed_poll_timeout(trng->base + SW_DRBG_STATUS, - val, val & BIT(1), SLEEP_US, TIMEOUT_US); + val, val & BIT(1), SLEEP_US, TIMEOUT_US); if (ret) { - pr_err("fail to generate random number(%d)!\n", ret); + pr_err("failed to generate random number(%d)!\n", ret); break; }
@@ -145,30 +167,57 @@ static int hisi_trng_generate(struct crypto_rng *tfm, const u8 *src, currsize = dlen; } + trng->random_bytes +=SW_DRBG_BYTES ;writel (0x1 , trng->base +SW_DRBG_GEN ); }while (currsize < dlen);return ret; } +static int hisi_trng_generate (struct crypto_rng *tfm,const u8 *src, +unsigned int slen,u8 *dstn,unsigned int dlen) +{ +struct hisi_trng_ctx *ctx =crypto_rng_ctx (tfm); +struct hisi_trng *trng = ctx->trng; +unsigned int currsize =0 ; +unsigned int block_size; +int ret; + +if (!dstn || !dlen) { +pr_err ("output is error, dlen %u!\n" , dlen); +return -EINVAL ; + } + +do { + block_size = min_t(unsigned int, dlen - currsize, SW_MAX_RANDOM_BYTES); +mutex_lock (&trng->lock); + ret =hisi_trng_get_bytes (trng, dstn + currsize, block_size); +mutex_unlock (&trng->lock); +if (ret) +return ret; + currsize += block_size; + }while (currsize < dlen); + +return 0 ; +} +static int hisi_trng_init (struct crypto_tfm *tfm) {struct hisi_trng_ctx *ctx =crypto_tfm_ctx (tfm);struct hisi_trng *trng; -int ret = -EBUSY ; +u32 ctx_num = ~0 ;mutex_lock (&trng_devices.lock);list_for_each_entry (trng, &trng_devices.list, list) { -if (!trng->is_used) { - trng->is_used = true; +if (trng->ctx_num < ctx_num) { + ctx_num = trng->ctx_num; ctx->trng = trng; - ret =0 ; -break ; } } + ctx->trng->ctx_num++;mutex_unlock (&trng_devices.lock); -return ret; +return 0 ; }static void hisi_trng_exit (struct crypto_tfm *tfm)
@@ -176,7 +225,7 @@ static void hisi_trng_exit(struct crypto_tfm *tfm)struct hisi_trng_ctx *ctx =crypto_tfm_ctx (tfm);mutex_lock (&trng_devices.lock); - ctx->trng->is_used = false; + ctx->trng->ctx_num--;mutex_unlock (&trng_devices.lock); }
@@ -238,7 +287,7 @@ static int hisi_trng_del_from_list(struct hisi_trng *trng)int ret = -EBUSY ;mutex_lock (&trng_devices.lock); -if (!trng->is_used) { +if (!trng->ctx_num) {list_del (&trng->list); ret =0 ; }
@@ -262,7 +311,9 @@ static int hisi_trng_probe(struct platform_device *pdev)if (IS_ERR (trng->base))return PTR_ERR (trng->base); - trng->is_used = false; + trng->ctx_num =0 ; + trng->random_bytes =SW_MAX_RANDOM_BYTES ; +mutex_init (&trng->lock); trng->ver =readl (trng->base +HISI_TRNG_VERSION );if (!trng_devices.is_init) {INIT_LIST_HEAD (&trng_devices.list);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 115/781 crypto: caam - fix netdev memory leak in dpaa2_caam_probe
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jianpeng Chang <[email protected]>
[ Upstream commit 7d43252b3060b0ba4a192dce5dba85a3f39ffe39 ]
When commit 0e1a4d427f58 ("crypto: caam: Unembed net_dev structure in dpaa2") converted embedded net_device to dynamically allocated pointers, it added cleanup in dpaa2_dpseci_disable() but missed adding cleanup in dpaa2_dpseci_free() for error paths.
This causes memory leaks when dpaa2_dpseci_dpio_setup() fails during probe due to DPIO devices not being ready yet. The kernel's deferred probe mechanism handles the retry successfully, but the netdevs allocated during the failed probe attempt are never freed, resulting in kmemleak reports showing multiple leaked netdev-related allocations all traced back to dpaa2_caam_probe().
Fix this by preserving the CPU mask of allocated netdevs during setup and using it for cleanup in dpaa2_dpseci_free(). This approach ensures that only the CPUs that actually had netdevs allocated will be cleaned up, avoiding potential issues with CPU hotplug scenarios.
--- drivers/crypto/caam/caamalg_qi2.c | 27 +++++++++++++++------------ drivers/crypto/caam/caamalg_qi2.h | 2 ++ 2 files changed, 17 insertions(+), 12 deletions(-)
drivers/crypto/caam/caamalg_qi2.c +15 -12
@@ -4814,7 +4814,8 @@ static void dpaa2_dpseci_free(struct dpaa2_caam_priv *priv) {struct device *dev = priv->dev;struct fsl_mc_device *ls_dev =to_fsl_mc_device (dev); -int err; +struct dpaa2_caam_priv_per_cpu *ppriv; +int i, err;if (DPSECI_VER (priv->major_ver, priv->minor_ver) >DPSECI_VER (5 ,3 )) { err =dpseci_reset (priv->mc_io,0 , ls_dev->mc_handle);
@@ -4822,6 +4823,12 @@ static void dpaa2_dpseci_free(struct dpaa2_caam_priv *priv)dev_err (dev,"dpseci_reset() failed\n" ); } +for_each_cpu (i, priv->clean_mask) { + ppriv =per_cpu_ptr (priv->ppriv, i); +free_netdev (ppriv->net_dev); + } +free_cpumask_var (priv->clean_mask); +dpaa2_dpseci_congestion_free (priv);dpseci_close (priv->mc_io,0 , ls_dev->mc_handle); }
@@ -5007,16 +5014,15 @@ static int __cold dpaa2_dpseci_setup(struct fsl_mc_device *ls_dev)struct device *dev = &ls_dev->dev;struct dpaa2_caam_priv *priv;struct dpaa2_caam_priv_per_cpu *ppriv; -cpumask_var_t clean_mask;int err, cpu;u8 i; err = -ENOMEM ; -if (!zalloc_cpumask_var (&clean_mask,GFP_KERNEL )) - goto err_cpumask; - priv =dev_get_drvdata (dev); +if (!zalloc_cpumask_var (&priv->clean_mask,GFP_KERNEL )) + goto err_cpumask; + priv->dev = dev; priv->dpsec_id = ls_dev->obj_desc.id;
@@ -5118,7 +5124,7 @@ static int __cold dpaa2_dpseci_setup(struct fsl_mc_device *ls_dev) err = -ENOMEM ; goto err_alloc_netdev; } -cpumask_set_cpu (cpu, clean_mask); +cpumask_set_cpu (cpu, priv->clean_mask); ppriv->net_dev->dev = *dev; netif_napi_add_tx_weight(ppriv->net_dev, &ppriv->napi,
@@ -5126,18 +5132,16 @@ static int __cold dpaa2_dpseci_setup(struct fsl_mc_device *ls_dev) DPAA2_CAAM_NAPI_WEIGHT); } - err =0 ; - goto free_cpumask; +return 0 ; err_alloc_netdev: -free_dpaa2_pcpu_netdev (priv, clean_mask); +free_dpaa2_pcpu_netdev (priv, priv->clean_mask); err_get_rx_queue:dpaa2_dpseci_congestion_free (priv); err_get_vers:dpseci_close (priv->mc_io,0 , ls_dev->mc_handle); err_open: -free_cpumask: -free_cpumask_var (clean_mask); +free_cpumask_var (priv->clean_mask); err_cpumask:return err; }
@@ -5182,7 +5186,6 @@ static int __cold dpaa2_dpseci_disable(struct dpaa2_caam_priv *priv) ppriv =per_cpu_ptr (priv->ppriv, i);napi_disable (&ppriv->napi);netif_napi_del (&ppriv->napi); -free_netdev (ppriv->net_dev); }return 0 ;
drivers/crypto/caam/caamalg_qi2.h +2 -0
@@ -42,6 +42,7 @@* @mc_io: pointer to MC portal's I/O object * @domain: IOMMU domain * @ppriv: per CPU pointers to privata data +* @clean_mask: CPU mask of CPUs that have allocated netdevs */ struct dpaa2_caam_priv {int dpsec_id;
@@ -65,6 +66,7 @@ struct dpaa2_caam_priv {struct dpaa2_caam_priv_per_cpu __percpu *ppriv;struct dentry *dfs_root; +cpumask_var_t clean_mask; };/**
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 116/781 bpf: Fix bpf_xdp_store_bytes proto for read-only arg
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paul Chaignon <[email protected]>
[ Upstream commit 6557f1565d779851c4db9c488c49c05a47a6e72f ]
While making some maps in Cilium read-only from the BPF side, we noticed that the bpf_xdp_store_bytes proto is incorrect. In particular, the verifier was throwing the following error:
; ret = ctx_store_bytes(ctx, l3_off + offsetof(struct iphdr, saddr),
&nat->address, 4, 0); 635: (79) r1 = *(u64 *)(r10 -144) ; R1=ctx() R10=fp0 fp-144=ctx() 636: (b4) w2 = 26 ; R2=26 637: (b4) w4 = 4 ; R4=4 638: (b4) w5 = 0 ; R5=0
639: (85) call bpf_xdp_store_bytes#190 write into map forbidden, value_size=6 off=0 size=4
nat comes from a BPF_F_RDONLY_PROG map, so R3 is a PTR_TO_MAP_VALUE. The verifier checks the helper's memory access to R3 in check_mem_size_reg, as it reaches ARG_CONST_SIZE argument. The third argument has expected type ARG_PTR_TO_UNINIT_MEM, which includes the MEM_WRITE flag. The verifier thus checks for a BPF_WRITE access on R3. Given R3 points to a read-only map, the check fails.
Conversely, ARG_PTR_TO_UNINIT_MEM can also lead to the helper reading from uninitialized memory.
This patch simply fixes the expected argument type to match that of bpf_skb_store_bytes.
--- net/core/filter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/core/filter.c +1 -1
@@ -4137,7 +4137,7 @@ static const struct bpf_func_proto bpf_xdp_store_bytes_proto = { .ret_type = RET_INTEGER, .arg1_type = ARG_PTR_TO_CTX, .arg2_type = ARG_ANYTHING, - .arg3_type = ARG_PTR_TO_UNINIT_MEM, + .arg3_type = ARG_PTR_TO_MEM | MEM_RDONLY, .arg4_type = ARG_CONST_SIZE, };
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 117/781 genirq: Set IRQF_COND_ONESHOT in devm_request_irq().
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sebastian Andrzej Siewior <[email protected]>
[ Upstream commit 943b052ded21feb84f293d40b06af3181cd0d0d7 ]
The flag IRQF_COND_ONESHOT was already force-added to request_irq() because the ACPI SCI interrupt handler is using the IRQF_ONESHOT flag which breaks all shared handlers.
devm_request_irq() needs the same change since some users, such as int0002_vgpio, are using this function instead.
Add IRQF_COND_ONESHOT to the flags passed to devm_request_irq().
--- include/linux/interrupt.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/interrupt.h +1 -1
@@ -228,7 +228,7 @@ static inline int __must_check devm_request_irq(struct device *dev, unsigned int irq, irq_handler_t handler, unsigned long irqflags, const char *devname, void *dev_id) { - return devm_request_threaded_irq(dev, irq, handler, NULL, irqflags, + return devm_request_threaded_irq(dev, irq, handler, NULL, irqflags | IRQF_COND_ONESHOT, devname, dev_id); }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 118/781 platform/x86: int0002: Remove IRQF_ONESHOT from request_irq()
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sebastian Andrzej Siewior <[email protected]>
[ Upstream commit f6bc712877f24dc89bdfd7bdbf1a32f3b9960b34 ]
Passing IRQF_ONESHOT ensures that the interrupt source is masked until the secondary (threaded) handler is done. If only a primary handler is used then the flag makes no sense because the interrupt cannot fire (again) while its handler is running.
The flag also prevents force-threading of the primary handler and the irq-core will warn about this.
The flag was added to match the flag on the shared handler which uses a threaded handler and therefore IRQF_ONESHOT. This is no longer needed because devm_request_irq() now passes IRQF_COND_ONESHOT for this case.
Revert adding IRQF_ONESHOT to irqflags.
--- drivers/platform/x86/intel/int0002_vgpio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/platform/x86/intel/int0002_vgpio.c +2 -2
@@ -206,8 +206,8 @@ static int int0002_probe(struct platform_device *pdev)* FIXME: augment this if we managed to pull handling of shared * IRQs into gpiolib. */ - ret =devm_request_irq (dev, irq, int0002_irq, -IRQF_ONESHOT |IRQF_SHARED ,"INT0002" , chip); + ret =devm_request_irq (dev, irq, int0002_irq,IRQF_SHARED ,"INT0002" , + chip);if (ret) {dev_err (dev,"Error requesting IRQ %d: %d\n" , irq, ret);return ret;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 119/781 iommu/amd: Use cores primary handler and set IRQF_ONESHOT
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sebastian Andrzej Siewior <[email protected]>
[ Upstream commit 5bfcdccb4d18d3909b7f87942be67fd6bdc00c1d ]
request_threaded_irq() is invoked with a primary and a secondary handler and no flags are passed. The primary handler is the same as irq_default_primary_handler() so there is no need to have an identical copy.
The lack of the IRQF_ONESHOT can be dangerous because the interrupt source is not masked while the threaded handler is active. This means, especially on LEVEL typed interrupt lines, the interrupt can fire again before the threaded handler had a chance to run.
Use the default primary interrupt handler by specifying NULL and set IRQF_ONESHOT so the interrupt source is masked until the secondary handler is done.
--- drivers/iommu/amd/amd_iommu.h | 1 - drivers/iommu/amd/init.c | 12 ++++-------- drivers/iommu/amd/iommu.c | 5 ----- 3 files changed, 4 insertions(+), 14 deletions(-)
drivers/iommu/amd/amd_iommu.h +0 -1
@@ -15,7 +15,6 @@ irqreturn_t amd_iommu_int_thread(int irq, void *data);irqreturn_t amd_iommu_int_thread_evtlog (int irq,void *data);irqreturn_t amd_iommu_int_thread_pprlog (int irq,void *data);irqreturn_t amd_iommu_int_thread_galog (int irq,void *data); -irqreturn_t amd_iommu_int_handler (int irq,void *data);void amd_iommu_restart_log (struct amd_iommu *iommu,const char *evt_type,u8 cntrl_intr,u8 cntrl_log,u32 status_run_mask,u32 status_overflow_mask);
drivers/iommu/amd/init.c +4 -8
@@ -2356,12 +2356,8 @@ static int iommu_setup_msi(struct amd_iommu *iommu)if (r)return r; - r =request_threaded_irq (iommu->dev->irq, - amd_iommu_int_handler, - amd_iommu_int_thread, -0 ,"AMD-Vi" , - iommu); - + r =request_threaded_irq (iommu->dev->irq,NULL , amd_iommu_int_thread, +IRQF_ONESHOT ,"AMD-Vi" , iommu);if (r) {pci_disable_msi (iommu->dev);return r;
@@ -2535,8 +2531,8 @@ static int __iommu_setup_intcapxt(struct amd_iommu *iommu, const char *devname,return irq; } - ret =request_threaded_irq (irq, amd_iommu_int_handler, - thread_fn,0 , devname, iommu); + ret =request_threaded_irq (irq,NULL , thread_fn,IRQF_ONESHOT , devname, + iommu);if (ret) {irq_domain_free_irqs (irq,1 );irq_domain_remove (domain);
drivers/iommu/amd/iommu.c +0 -5
@@ -1151,11 +1151,6 @@ irqreturn_t amd_iommu_int_thread(int irq, void *data)return IRQ_HANDLED ; } -irqreturn_t amd_iommu_int_handler (int irq,void *data) -{ -return IRQ_WAKE_THREAD ; -} -/**************************************************************************** * * IOMMU command queuing functions
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 120/781 Bluetooth: btintel_pcie: Use IRQF_ONESHOT and default primary handler
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sebastian Andrzej Siewior <[email protected]>
[ Upstream commit 28abed6569c87eab9071ab56c64433c2f0d9ce51 ]
There is no added value in btintel_pcie_msix_isr() compared to irq_default_primary_handler().
Using a threaded interrupt without a dedicated primary handler mandates the IRQF_ONESHOT flag to mask the interrupt source while the threaded handler is active. Otherwise the interrupt can fire again before the threaded handler had a chance to run.
Use the default primary interrupt handler by specifying NULL and set IRQF_ONESHOT so the interrupt source is masked until the secondary handler is done.
--- drivers/bluetooth/btintel_pcie.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-)
drivers/bluetooth/btintel_pcie.c +2 -7
@@ -1431,11 +1431,6 @@ static void btintel_pcie_msix_rx_handle(struct btintel_pcie_data *data) } } -static irqreturn_t btintel_pcie_msix_isr (int irq,void *data) -{ -return IRQ_WAKE_THREAD ; -} -static inline bool btintel_pcie_is_rxq_empty (struct btintel_pcie_data *data) {return data->ia.cr_hia[BTINTEL_PCIE_RXQ_NUM ] == data->ia.cr_tia[BTINTEL_PCIE_RXQ_NUM ];
@@ -1537,9 +1532,9 @@ static int btintel_pcie_setup_irq(struct btintel_pcie_data *data) err =devm_request_threaded_irq (&data->pdev->dev, msix_entry->vector, - btintel_pcie_msix_isr, +NULL , btintel_pcie_irq_msix_handler, -IRQF_SHARED , +IRQF_ONESHOT |IRQF_SHARED ,KBUILD_MODNAME , msix_entry);if (err) {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 121/781 scsi: efct: Use IRQF_ONESHOT and default primary handler
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sebastian Andrzej Siewior <[email protected]>
[ Upstream commit bd81f07e9a27c341cd7e72be95eb0b7cf3910926 ]
There is no added value in efct_intr_msix() compared to irq_default_primary_handler().
Using a threaded interrupt without a dedicated primary handler mandates the IRQF_ONESHOT flag to mask the interrupt source while the threaded handler is active. Otherwise the interrupt can fire again before the threaded handler had a chance to run.
Use the default primary interrupt handler by specifying NULL and set IRQF_ONESHOT so the interrupt source is masked until the secondary handler is done.
--- drivers/scsi/elx/efct/efct_driver.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-)
drivers/scsi/elx/efct/efct_driver.c +1 -7
@@ -415,12 +415,6 @@ efct_intr_thread(int irq, void *handle)return IRQ_HANDLED ; } -static irqreturn_t -efct_intr_msix (int irq,void *handle) -{ -return IRQ_WAKE_THREAD ; -} -static int efct_setup_msix (struct efct *efct,u32 num_intrs) {
@@ -450,7 +444,7 @@ efct_setup_msix(struct efct *efct, u32 num_intrs) intr_ctx->index = i; rc =request_threaded_irq (pci_irq_vector (efct->pci, i), - efct_intr_msix, efct_intr_thread,0 , +NULL , efct_intr_thread,IRQF_ONESHOT ,EFCT_DRIVER_NAME , intr_ctx);if (rc) { dev_err(&efct->pci->dev,
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 122/781 EDAC/altera: Remove IRQF_ONESHOT
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sebastian Andrzej Siewior <[email protected]>
[ Upstream commit 5c858d6c66304b4c7579582ec5235f02d43578ea ]
Passing IRQF_ONESHOT ensures that the interrupt source is masked until the secondary (threaded) handler is done. If only a primary handler is used then the flag makes no sense because the interrupt can not fire (again) while its handler is running.
The flag also prevents force-threading of the primary handler and the irq-core will warn about this.
Remove IRQF_ONESHOT from irqflags.
--- drivers/edac/altera_edac.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-)
drivers/edac/altera_edac.c +4 -7
@@ -1563,8 +1563,7 @@ static int altr_portb_setup(struct altr_edac_device_dev *device) goto err_release_group_1; } rc =devm_request_irq (&altdev->ddev, altdev->sb_irq, - prv->ecc_irq_handler, -IRQF_ONESHOT |IRQF_TRIGGER_HIGH , + prv->ecc_irq_handler,IRQF_TRIGGER_HIGH , ecc_name, altdev);if (rc) {edac_printk (KERN_ERR ,EDAC_DEVICE ,"PortB SBERR IRQ error\n" );
@@ -1587,8 +1586,7 @@ static int altr_portb_setup(struct altr_edac_device_dev *device) goto err_release_group_1; } rc =devm_request_irq (&altdev->ddev, altdev->db_irq, - prv->ecc_irq_handler, -IRQF_ONESHOT |IRQF_TRIGGER_HIGH , + prv->ecc_irq_handler,IRQF_TRIGGER_HIGH , ecc_name, altdev);if (rc) {edac_printk (KERN_ERR ,EDAC_DEVICE ,"PortB DBERR IRQ error\n" );
@@ -1970,8 +1968,7 @@ static int altr_edac_a10_device_add(struct altr_arria10_edac *edac, goto err_release_group1; } rc =devm_request_irq (edac->dev, altdev->sb_irq, prv->ecc_irq_handler, -IRQF_ONESHOT |IRQF_TRIGGER_HIGH , - ecc_name, altdev); +IRQF_TRIGGER_HIGH , ecc_name, altdev);if (rc) {edac_printk (KERN_ERR ,EDAC_DEVICE ,"No SBERR IRQ resource\n" ); goto err_release_group1;
@@ -1993,7 +1990,7 @@ static int altr_edac_a10_device_add(struct altr_arria10_edac *edac, goto err_release_group1; } rc =devm_request_irq (edac->dev, altdev->db_irq, prv->ecc_irq_handler, -IRQF_ONESHOT |IRQF_TRIGGER_HIGH , +IRQF_TRIGGER_HIGH , ecc_name, altdev);if (rc) {edac_printk (KERN_ERR ,EDAC_DEVICE ,"No DBERR IRQ resource\n" );
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 123/781 usb: typec: fusb302: Remove IRQF_ONESHOT
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sebastian Andrzej Siewior <[email protected]>
[ Upstream commit a7fb84ea70aae9a92a842932206e70ed1b3c7007 ]
Passing IRQF_ONESHOT ensures that the interrupt source is masked until the secondary (threaded) handler is done. If only a primary handler is used then the flag makes no sense because the interrupt can not fire (again) while its handler is running.
The flag also prevents force-threading of the primary handler and the irq-core will warn about this.
Remove IRQF_ONESHOT from irqflags.
--- drivers/usb/typec/tcpm/fusb302.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/usb/typec/tcpm/fusb302.c +1 -2
@@ -1756,8 +1756,7 @@ static int fusb302_probe(struct i2c_client *client) } ret =request_irq (chip->gpio_int_n_irq, fusb302_irq_intn, -IRQF_ONESHOT |IRQF_TRIGGER_LOW , -"fsc_interrupt_int_n" , chip); +IRQF_TRIGGER_LOW ,"fsc_interrupt_int_n" , chip);if (ret <0 ) {dev_err (dev,"cannot request IRQ for GPIO Int_N, ret=%d" , ret); goto tcpm_unregister_port;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 124/781 rtc: amlogic-a4: Remove IRQF_ONESHOT
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sebastian Andrzej Siewior <[email protected]>
[ Upstream commit 18d28446231390e4ea3634fb16200865df2c6506 ]
Passing IRQF_ONESHOT ensures that the interrupt source is masked until the secondary (threaded) handler is done. If only a primary handler is used then the flag makes no sense because the interrupt can not fire (again) while its handler is running.
The flag also prevents force-threading of the primary handler and the irq-core will warn about this.
Remove IRQF_ONESHOT from irqflags.
--- drivers/rtc/rtc-amlogic-a4.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/rtc/rtc-amlogic-a4.c +1 -1
@@ -369,7 +369,7 @@ static int aml_rtc_probe(struct platform_device *pdev)return PTR_ERR (rtc->rtc_dev); ret =devm_request_irq (dev, rtc->irq, aml_rtc_handler, -IRQF_ONESHOT ,"aml-rtc alarm" , rtc); +0 ,"aml-rtc alarm" , rtc);if (ret) {dev_err_probe (dev, ret,"IRQ%d request failed, ret = %d\n" , rtc->irq, ret);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 125/781 mfd: wm8350-core: Use IRQF_ONESHOT
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sebastian Andrzej Siewior <[email protected]>
[ Upstream commit 553b4999cbe231b5011cb8db05a3092dec168aca ]
Using a threaded interrupt without a dedicated primary handler mandates the IRQF_ONESHOT flag to mask the interrupt source while the threaded handler is active. Otherwise the interrupt can fire again before the threaded handler had a chance to run.
Mark explained that this should not happen with this hardware since it is a slow irqchip which is behind an I2C/ SPI bus but the IRQ-core will refuse to accept such a handler.
Set IRQF_ONESHOT so the interrupt source is masked until the secondary handler is done.
--- include/linux/mfd/wm8350/core.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/mfd/wm8350/core.h +1 -1
@@ -667,7 +667,7 @@ static inline int wm8350_register_irq(struct wm8350 *wm8350, int irq,return -ENODEV ;return request_threaded_irq (irq + wm8350->irq_base,NULL , - handler, flags, name, data); + handler, flags |IRQF_ONESHOT , name, data); }static inline void wm8350_free_irq (struct wm8350 *wm8350,int irq,void *data)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 126/781 media: pci: mg4b: Use IRQF_NO_THREAD
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sebastian Andrzej Siewior <[email protected]>
[ Upstream commit ef92b98f5f6758a049898b53aa30476010db04fa ]
The interrupt handler iio_trigger_generic_data_rdy_poll() will invoke other interrupt handlers and this supposed to happen from hard interrupt context.
Use IRQF_NO_THREAD to forbid forced-threading.
--- drivers/media/pci/mgb4/mgb4_trigger.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/media/pci/mgb4/mgb4_trigger.c +1 -1
@@ -115,7 +115,7 @@ static int probe_trigger(struct iio_dev *indio_dev, int irq)if (!st->trig)return -ENOMEM ; - ret =request_irq (irq, &iio_trigger_generic_data_rdy_poll,0 , + ret =request_irq (irq, &iio_trigger_generic_data_rdy_poll,IRQF_NO_THREAD ,"mgb4-trigger" , st->trig);if (ret) goto error_free_trig;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 127/781 sched/deadline: Clear the defer params
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joel Fernandes <[email protected]>
[ Upstream commit 3cb3b27693bf30defb16aa096158a3b24583b8d2 ]
The defer params were not cleared in __dl_clear_params. Clear them.
Without this is some of my test cases are flaking and the DL timer is not starting correctly AFAICS.
--- kernel/sched/deadline.c | 3 +++ 1 file changed, 3 insertions(+)
kernel/sched/deadline.c +3 -0
@@ -3656,6 +3656,9 @@ static void __dl_clear_params(struct sched_dl_entity *dl_se) dl_se->dl_non_contending =0 ; dl_se->dl_overrun =0 ; dl_se->dl_server =0 ; + dl_se->dl_defer =0 ; + dl_se->dl_defer_running =0 ; + dl_se->dl_defer_armed =0 ;#ifdef CONFIG_RT_MUTEXES dl_se->pi_se = dl_se;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 128/781 sched/rt: Skip currently executing CPU in rto_next_cpu()
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chen Jinghuang <[email protected]>
[ Upstream commit 94894c9c477e53bcea052e075c53f89df3d2a33e ]
CPU0 becomes overloaded when hosting a CPU-bound RT task, a non-CPU-bound RT task, and a CFS task stuck in kernel space. When other CPUs switch from RT to non-RT tasks, RT load balancing (LB) is triggered; with HAVE_RT_PUSH_IPI enabled, they send IPIs to CPU0 to drive the execution of rto_push_irq_work_func. During push_rt_task on CPU0,
if next_task->prio < rq->donor->prio, resched_curr() sets NEED_RESCHED and after the push operation completes, CPU0 calls rto_next_cpu(). Since only CPU0 is overloaded in this scenario, rto_next_cpu() should ideally return -1 (no further IPI needed).
However, multiple CPUs invoking tell_cpu_to_push() during LB increments rd->rto_loop_next. Even when rd->rto_cpu is set to -1, the mismatch between rd->rto_loop and rd->rto_loop_next forces rto_next_cpu() to restart its search from -1. With CPU0 remaining overloaded (satisfying rt_nr_migratory && rt_nr_total > 1), it gets reselected, causing CPU0 to queue irq_work to itself and send self-IPIs repeatedly. As long as CPU0 stays overloaded and other CPUs run pull_rt_tasks(), it falls into an infinite self-IPI loop, which triggers a CPU hardlockup due to continuous self-interrupts.
The trigging scenario is as follows:
cpu0 cpu1 cpu2
pull_rt_task
tell_cpu_to_push
<------------irq_work_queue_onrto_push_irq_work_func
push_rt_task
resched_curr(rq) pull_rt_task
rto_next_cpu tell_cpu_to_push
<-------------------------- atomic_inc(rto_loop_next)rd->rto_loop != next
rto_next_cpu
irq_work_queue_onrto_push_irq_work_func
Fix redundant self-IPI by filtering the initiating CPU in rto_next_cpu(). This solution has been verified to effectively eliminate spurious self-IPIs and prevent CPU hardlockup scenarios.
--- kernel/sched/rt.c | 5 +++++ 1 file changed, 5 insertions(+)
kernel/sched/rt.c +5 -0
@@ -2100,6 +2100,7 @@ static void push_rt_tasks(struct rq *rq)*/ static int rto_next_cpu (struct root_domain *rd) { +int this_cpu =smp_processor_id ();int next;int cpu;
@@ -2123,6 +2124,10 @@ static int rto_next_cpu(struct root_domain *rd) rd->rto_cpu = cpu; +/* Do not send IPI to self */ +if (cpu == this_cpu) +continue ; +if (cpu < nr_cpu_ids)return cpu;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 129/781 sched: Re-evaluate scheduling when migrating queued tasks out of throttled cgroups
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zicheng Qu <[email protected]>
[ Upstream commit e34881c84c255bc300f24d9fe685324be20da3d1 ]
Consider the following sequence on a CPU configured with nohz_full:
1) A task P runs in cgroup A, and cgroup A becomes throttled due to CFS bandwidth control. The gse (cgroup A) where the task P attached is
dequeued and the CPU switches to idle.
2) Before cgroup A is unthrottled, task P is migrated from cgroup A to another cgroup B (not throttled).
During sched_move_task(), the task P is observed as queued but not
running, and therefore no resched_curr() is triggered.
3) Since the CPU is nohz_full, it remains in do_idle() waiting for an explicit scheduling event, i.e., resched_curr().
4) For kernel <= 5.10: Later, cgroup A is unthrottled. However, the task P has already been migrated out of cgroup A, so unthrottle_cfs_rq()
may observe load_weight == 0 and return early without resched_curr() called. For kernel >= 6.6: The unthrottling path normally triggers resched_curr() almost cases even when no runnable tasks remain in the unthrottled cgroup, preventing the idle stall described above. However, if cgroup A is removed before it gets unthrottled, the unthrottling path for cgroup A is never executed. In a result, no resched_curr() can be called.
5) At this point, the task P is runnable in cgroup B (not throttled), but the CPU remains in do_idle() with no pending reschedule point. The system stays in this state until an unrelated event (e.g. a new task wakeup or any cases) that can trigger a resched_curr() breaks the nohz_full idle state, and then the task P finally gets scheduled.
The root cause is that sched_move_task() may classify the task as only queued, not running, and therefore fails to trigger a resched_curr(), while the later unthrottling path no longer has visibility of the migrated task.
Preserve the existing behavior for running tasks by issuing resched_curr(), and explicitly invoke check_preempt_curr() for tasks that were queued at the time of migration. This ensures that runnable tasks are reconsidered for scheduling even when nohz_full suppresses periodic ticks.
--- kernel/sched/core.c | 4 ++++ 1 file changed, 4 insertions(+)
kernel/sched/core.c +4 -0
@@ -9115,6 +9115,7 @@ void sched_move_task(struct task_struct *tsk, bool for_autogroup) {unsigned int queue_flags =DEQUEUE_SAVE |DEQUEUE_MOVE ;bool resched = false; +bool queued = false;struct rq *rq;CLASS (task_rq_lock, rq_guard)(tsk);
@@ -9126,10 +9127,13 @@ void sched_move_task(struct task_struct *tsk, bool for_autogroup)scx_cgroup_move_task (tsk);if (scope->running) resched = true; + queued = scope->queued; }if (resched)resched_curr (rq); +else if (queued) +wakeup_preempt (rq, tsk,0 );__balance_callbacks (rq, &rq_guard.rf); }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 130/781 fs/tests: exec: drop duplicate bprm_stack_limits test vectors
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Titouan Ameline de Cadeville <[email protected]>
[ Upstream commit 46a03ea50b5f380bdb99178b8f90b39c6ba1f528 ]
Remove duplicate entries from the bprm_stack_limits KUnit test vector table. The duplicates do not add coverage and only increase test size.
--- fs/tests/exec_kunit.c | 6 ------ 1 file changed, 6 deletions(-)
fs/tests/exec_kunit.c +0 -6
@@ -87,9 +87,6 @@ static const struct bprm_stack_limits_result bprm_stack_limits_results[] = { .argc = 0, .envc = ARG_MAX / sizeof(void *) - 1 }, .expected_argmin = ULONG_MAX - sizeof(void *) },/* Raising rlim_stack / 4 to _STK_LIM / 4 * 3 will see more space. */ - { { .p = ULONG_MAX, .rlim_stack.rlim_cur = 4 * (_STK_LIM / 4 * 3), - .argc = 0, .envc = 0 }, - .expected_argmin = ULONG_MAX - (_STK_LIM / 4 * 3) + sizeof(void *) }, { { .p = ULONG_MAX, .rlim_stack.rlim_cur = 4 * (_STK_LIM / 4 * 3), .argc = 0, .envc = 0 }, .expected_argmin = ULONG_MAX - (_STK_LIM / 4 * 3) + sizeof(void *) },
@@ -103,9 +100,6 @@ static const struct bprm_stack_limits_result bprm_stack_limits_results[] = { { { .p = ULONG_MAX, .rlim_stack.rlim_cur = 4 * _STK_LIM, .argc = 0, .envc = 0 }, .expected_argmin = ULONG_MAX - (_STK_LIM / 4 * 3) + sizeof(void *) }, - { { .p = ULONG_MAX, .rlim_stack.rlim_cur = 4 * _STK_LIM, - .argc = 0, .envc = 0 }, - .expected_argmin = ULONG_MAX - (_STK_LIM / 4 * 3) + sizeof(void *) }, }; static void exec_test_bprm_stack_limits(struct kunit *test)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 131/781 irqchip/sifive-plic: Handle number of hardware interrupts correctly
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Gleixner <[email protected]>
[ Upstream commit 42e025b719c128bdf8ff88584589a1e4a2448c81 ]
The driver is handling the number of hardware interrupts inconsistently.
The reason is that the firmware enumerates the maximum number of device interrupts, but the actual number of hardware interrupts is one more because hardware interrupt 0 is reserved.
There are two loop variants where this matters:
1) Iterating over the device interrupts
for (irq = 1; irq < total_irqs; irq++)
2) Iterating over the number of interrupt register groups
for (grp = 0; grp < irq_groups; grp++)
The current code stores the number of device interrupts and that requires to write the loops as:
1) for (irq = 1; irq <= device_irqs; irq++)
2) for (grp = 0; grp < DIV_ROUND_UP(device_irqs + 1); grp++)
But the code gets it wrong all over the place. Just fixing up the conditions and off by ones is not a sustainable solution as the next changes will reintroduce the same bugs over and over.
Sanitize it by storing the total number of hardware interrupts during probe and precalculating the number of groups. To future proof it mark priv::total_irqs __private, provide a correct iterator macro and adjust the code to this.
Marking it private allows sparse (C=1 build) to catch direct access to this member:
drivers/irqchip/irq-sifive-plic.c:270:9: warning: dereference of noderef expression
That should prevent at least the most obvious future damage in that area.
--- drivers/irqchip/irq-sifive-plic.c | 82 +++++++++++++++++-------------- 1 file changed, 45 insertions(+), 37 deletions(-)
drivers/irqchip/irq-sifive-plic.c +45 -37
@@ -68,15 +68,17 @@#define PLIC_QUIRK_CP100_CLAIM_REGISTER_ERRATUM 1struct plic_priv { -struct fwnode_handle *fwnode; -struct cpumask lmask; -struct irq_domain *irqdomain; -void __iomem *regs; -unsigned long plic_quirks; -unsigned int nr_irqs; -unsigned long *prio_save; -u32 gsi_base; -int acpi_plic_id; +struct fwnode_handle *fwnode; +struct cpumask lmask; +struct irq_domain *irqdomain; +void __iomem *regs; +unsigned long plic_quirks; +/* device interrupts + 1 to compensate for the reserved hwirq 0 */ +unsigned int __private total_irqs; +unsigned int irq_groups; +unsigned long *prio_save; +u32 gsi_base; +int acpi_plic_id; };struct plic_handler {
@@ -91,6 +93,12 @@ struct plic_handler {u32 *enable_save;struct plic_priv *priv; }; + +/* +* Macro to deal with the insanity of hardware interrupt 0 being reserved */ +#define for_each_device_irq (iter, priv) \ + for (unsigned int iter = 1; iter < ACCESS_PRIVATE(priv, total_irqs); iter++) +static int plic_parent_irq__ro_after_init ;static bool plic_global_setup_done__ro_after_init ; static DEFINE_PER_CPU(struct plic_handler, plic_handlers);
@@ -257,14 +265,11 @@ static int plic_irq_set_type(struct irq_data *d, unsigned int type)static int plic_irq_suspend (void *data) { -struct plic_priv *priv; - - priv =per_cpu_ptr (&plic_handlers,smp_processor_id ())->priv; +struct plic_priv *priv =this_cpu_ptr (&plic_handlers)->priv; -/* irq ID 0 is reserved */ -for (unsigned int i =1 ; i < priv->nr_irqs; i++) { -__assign_bit (i, priv->prio_save, -readl (priv->regs +PRIORITY_BASE + i *PRIORITY_PER_ID )); +for_each_device_irq (irq, priv) { +__assign_bit (irq, priv->prio_save, +readl (priv->regs +PRIORITY_BASE + irq *PRIORITY_PER_ID )); }return 0 ;
@@ -272,18 +277,15 @@ static int plic_irq_suspend(void *data)static void plic_irq_resume (void *data) { -unsigned int i, index, cpu; +struct plic_priv *priv =this_cpu_ptr (&plic_handlers)->priv; +unsigned int index, cpu;unsigned long flags;u32 __iomem *reg; -struct plic_priv *priv; - - priv =per_cpu_ptr (&plic_handlers,smp_processor_id ())->priv; -/* irq ID 0 is reserved */ -for (i =1 ; i < priv->nr_irqs; i++) { - index =BIT_WORD (i); -writel ((priv->prio_save[index] &BIT_MASK (i)) ?1 :0 , - priv->regs +PRIORITY_BASE + i *PRIORITY_PER_ID ); +for_each_device_irq (irq, priv) { + index =BIT_WORD (irq); +writel ((priv->prio_save[index] &BIT_MASK (irq)) ?1 :0 , + priv->regs +PRIORITY_BASE + irq *PRIORITY_PER_ID ); }for_each_present_cpu (cpu) {
@@ -293,7 +295,7 @@ static void plic_irq_resume(void *data)continue ;raw_spin_lock_irqsave (&handler->enable_lock, flags); -for (i =0 ; i <DIV_ROUND_UP (priv->nr_irqs,32 ); i++) { +for (unsigned int i =0 ; i < priv->irq_groups; i++) { reg = handler->enable_base + i *sizeof (u32);writel (handler->enable_save[i], reg); }
@@ -431,7 +433,7 @@ static u32 cp100_isolate_pending_irq(int nr_irq_groups, struct plic_handler *hanstatic irq_hw_number_t cp100_get_hwirq (struct plic_handler *handler,void __iomem *claim) { -int nr_irq_groups =DIV_ROUND_UP (handler->priv->nr_irqs,32 ); +int nr_irq_groups = handler->priv->irq_groups;u32 __iomem *enable = handler->enable_base;irq_hw_number_t hwirq =0 ;u32 iso_mask;
@@ -614,7 +616,6 @@ static int plic_probe(struct fwnode_handle *fwnode)struct plic_handler *handler;u32 nr_irqs, parent_hwirq;struct plic_priv *priv; -irq_hw_number_t hwirq;void __iomem *regs;int id, context_id;u32 gsi_base;
@@ -647,7 +648,16 @@ static int plic_probe(struct fwnode_handle *fwnode) priv->fwnode = fwnode; priv->plic_quirks = plic_quirks; - priv->nr_irqs = nr_irqs; +/* +* The firmware provides the number of device interrupts. As +* hardware interrupt 0 is reserved, the number of total interrupts +* is nr_irqs + 1. +*/ + nr_irqs++; +ACCESS_PRIVATE (priv, total_irqs) = nr_irqs; +/* Precalculate the number of register groups */ + priv->irq_groups =DIV_ROUND_UP (nr_irqs,32 ); + priv->regs = regs; priv->gsi_base = gsi_base; priv->acpi_plic_id = id;
@@ -686,7 +696,7 @@ static int plic_probe(struct fwnode_handle *fwnode)u32 __iomem *enable_base = priv->regs +CONTEXT_ENABLE_BASE + i *CONTEXT_ENABLE_SIZE ; -for (int j =0 ; j <= nr_irqs /32 ; j++) +for (int j =0 ; j < priv->irq_groups; j++)writel (0 , enable_base + j); }continue ;
@@ -718,23 +728,21 @@ static int plic_probe(struct fwnode_handle *fwnode)context_id *CONTEXT_ENABLE_SIZE ; handler->priv = priv; - handler->enable_save =kcalloc (DIV_ROUND_UP (nr_irqs,32 ), -sizeof (*handler->enable_save),GFP_KERNEL ); + handler->enable_save =kcalloc (priv->irq_groups,sizeof (*handler->enable_save), +GFP_KERNEL );if (!handler->enable_save) { error = -ENOMEM ; goto fail_cleanup_contexts; } done: -for (hwirq =1 ; hwirq <= nr_irqs; hwirq++) { +for_each_device_irq (hwirq, priv) {plic_toggle (handler, hwirq,0 ); -writel (1 , priv->regs +PRIORITY_BASE + - hwirq *PRIORITY_PER_ID ); +writel (1 , priv->regs +PRIORITY_BASE + hwirq *PRIORITY_PER_ID ); } nr_handlers++; } - priv->irqdomain =irq_domain_create_linear (fwnode, nr_irqs +1 , - &plic_irqdomain_ops, priv); + priv->irqdomain =irq_domain_create_linear (fwnode, nr_irqs, &plic_irqdomain_ops, priv);if (WARN_ON (!priv->irqdomain)) { error = -ENOMEM ; goto fail_cleanup_contexts;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 132/781 bpf: Limit bpf program signature size
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: KP Singh <[email protected]>
[ Upstream commit ea1535e28bb3773fc0b3cbd1f3842b808016990c ]
Practical BPF signatures are significantly smaller than KMALLOC_MAX_CACHE_SIZE
Allowing larger sizes opens the door for abuse by passing excessive size values and forcing the kernel into expensive allocation paths (via kmalloc_large or vmalloc).
--- kernel/bpf/syscall.c | 7 +++++++ 1 file changed, 7 insertions(+)
kernel/bpf/syscall.c +7 -0
@@ -2815,6 +2815,13 @@ static int bpf_prog_verify_signature(struct bpf_prog *prog, union bpf_attr *attrvoid *sig;int err =0 ; +/* +* Don't attempt to use kmalloc_large or vmalloc for signatures. +* Practical signature for BPF program should be below this limit. +*/ +if (attr->signature_size >KMALLOC_MAX_CACHE_SIZE ) +return -EINVAL ; +if (system_keyring_id_check (attr->keyring_id) ==0 ) key =bpf_lookup_system_key (attr->keyring_id);else
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 133/781 bpf: Require frozen map for calculating map hash
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: KP Singh <[email protected]>
[ Upstream commit a2c86aa621c22f2a7e26c654f936d65cfff0aa91 ]
Currently, bpf_map_get_info_by_fd calculates and caches the hash of the map regardless of the map's frozen state.
This leads to a TOCTOU bug where userspace can call BPF_OBJ_GET_INFO_BY_FD to cache the hash and then modify the map contents before freezing.
Therefore, a trusted loader can be tricked into verifying the stale hash while loading the modified contents.
Fix this by returning -EPERM if the map is not frozen when the hash is requested. This ensures the hash is only generated for the final, immutable state of the map.
--- kernel/bpf/syscall.c | 3 +++ 1 file changed, 3 insertions(+)
kernel/bpf/syscall.c +3 -0
@@ -5314,6 +5314,9 @@ static int bpf_map_get_info_by_fd(struct file *file,if (info.hash_size !=SHA256_DIGEST_SIZE )return -EINVAL ; +if (!READ_ONCE (map->frozen)) +return -EPERM ; + err = map->ops->map_get_hash (map,SHA256_DIGEST_SIZE , map->sha);if (err !=0 )return err;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 134/781 crypto: starfive - Fix memory leak in starfive_aes_aead_do_one_req()
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zilin Guan <[email protected]>
[ Upstream commit ccb679fdae2e62ed92fd9acb25ed809c0226fcc6 ]
The starfive_aes_aead_do_one_req() function allocates rctx->adata with kzalloc() but fails to free it if sg_copy_to_buffer() or starfive_aes_hw_init() fails, which lead to memory leaks.
Since rctx->adata is unconditionally freed after the write_adata operations, ensure consistent cleanup by freeing the allocation in these earlier error paths as well.
Compile tested only. Issue found using a prototype static analysis tool and code review.
--- drivers/crypto/starfive/jh7110-aes.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
drivers/crypto/starfive/jh7110-aes.c +7 -2
@@ -669,8 +669,10 @@ static int starfive_aes_aead_do_one_req(struct crypto_engine *engine, void *areqreturn -ENOMEM ;if (sg_copy_to_buffer (req->src,sg_nents_for_len (req->src, cryp->assoclen), - rctx->adata, cryp->assoclen) != cryp->assoclen) + rctx->adata, cryp->assoclen) != cryp->assoclen) { +kfree (rctx->adata);return -EINVAL ; + } }if (cryp->total_in)
@@ -681,8 +683,11 @@ static int starfive_aes_aead_do_one_req(struct crypto_engine *engine, void *areq ctx->rctx = rctx; ret =starfive_aes_hw_init (ctx); -if (ret) +if (ret) { +if (cryp->assoclen) +kfree (rctx->adata);return ret; + }if (!cryp->assoclen) goto write_text;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 135/781 hwrng: core - use RCU and work_struct to fix race condition
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lianjie Wang <[email protected]>
[ Upstream commit cc2f39d6ac48e6e3cb2d6240bc0d6df839dd0828 ]
Currently, hwrng_fill is not cleared until the hwrng_fillfn() thread exits. Since hwrng_unregister() reads hwrng_fill outside the rng_mutex lock, a concurrent hwrng_unregister() may call kthread_stop() again on the same task.
Additionally, if hwrng_unregister() is called immediately after hwrng_register(), the stopped thread may have never been executed. Thus, hwrng_fill remains dirty even after hwrng_unregister() returns. In this case, subsequent calls to hwrng_register() will fail to start new threads, and hwrng_unregister() will call kthread_stop() on the same freed task. In both cases, a use-after-free occurs:
refcount_t: addition on 0; use-after-free.
WARNING: ... at lib/refcount.c:25 refcount_warn_saturate+0xec/0x1c0
Call Trace: kthread_stop+0x181/0x360 hwrng_unregister+0x288/0x380 virtrng_remove+0xe3/0x200
This patch fixes the race by protecting the global hwrng_fill pointer inside the rng_mutex lock, so that hwrng_fillfn() thread is stopped only once, and calls to kthread_run() and kthread_stop() are serialized with the lock held.
To avoid deadlock in hwrng_fillfn() while being stopped with the lock held, we convert current_rng to RCU, so that get_current_rng() can read current_rng without holding the lock. To remove the lock from put_rng(), we also delay the actual cleanup into a work_struct.
Since get_current_rng() no longer returns ERR_PTR values, the IS_ERR() checks are removed from its callers.
With hwrng_fill protected by the rng_mutex lock, hwrng_fillfn() can no longer clear hwrng_fill itself. Therefore, if hwrng_fillfn() returns directly after current_rng is dropped, kthread_stop() would be called on a freed task_struct later. To fix this, hwrng_fillfn() calls schedule() now to keep the task alive until being stopped. The kthread_stop() call is also moved from hwrng_unregister() to drop_current_rng(), ensuring kthread_stop() is called on all possible paths where current_rng becomes NULL, so that the thread would not wait forever.
--- drivers/char/hw_random/core.c | 168 +++++++++++++++++++++------------- include/linux/hw_random.h | 2 + 2 files changed, 107 insertions(+), 63 deletions(-)
drivers/char/hw_random/core.c +105 -63
@@ -20,23 +20,25 @@#include <linux/miscdevice.h> #include <linux/module.h> #include <linux/random.h> +#include <linux/rcupdate.h> #include <linux/sched.h> #include <linux/sched/signal.h> #include <linux/slab.h> #include <linux/string.h> #include <linux/uaccess.h> +#include <linux/workqueue.h> #define RNG_MODULE_NAME "hw_random"#define RNG_BUFFER_SIZE (SMP_CACHE_BYTES < 32 ? 32 : SMP_CACHE_BYTES) -static struct hwrng *current_rng; +static struct hwrng __rcu *current_rng;/* the current rng has been explicitly chosen by user via sysfs */ static int cur_rng_set_by_user;static struct task_struct *hwrng_fill;/* list of registered rngs */ static LIST_HEAD (rng_list); -/* Protects rng_list and current_rng */ +/* Protects rng_list, hwrng_fill and updating on current_rng */ static DEFINE_MUTEX (rng_mutex);/* Protects rng read functions, data_avail, rng_buffer and rng_fillbuf */ static DEFINE_MUTEX (reading_mutex);
@@ -64,18 +66,39 @@ static size_t rng_buffer_size(void)return RNG_BUFFER_SIZE ; } -static inline void cleanup_rng (struct kref *kref) +static void cleanup_rng_work (struct work_struct *work) { - struct hwrng *rng = container_of(kref, struct hwrng, ref); + struct hwrng *rng = container_of(work, struct hwrng, cleanup_work); + +/* +* Hold rng_mutex here so we serialize in case they set_current_rng +* on rng again immediately. +*/ +mutex_lock (&rng_mutex); + +/* Skip if rng has been reinitialized. */ +if (kref_read (&rng->ref)) { +mutex_unlock (&rng_mutex); +return ; + }if (rng->cleanup) rng->cleanup (rng);complete (&rng->cleanup_done); +mutex_unlock (&rng_mutex); +} + +static inline void cleanup_rng (struct kref *kref) +{ + struct hwrng *rng = container_of(kref, struct hwrng, ref); + +schedule_work (&rng->cleanup_work); }static int set_current_rng (struct hwrng *rng) { +struct hwrng *old_rng;int err;BUG_ON (!mutex_is_locked (&rng_mutex));
@@ -84,8 +107,14 @@ static int set_current_rng(struct hwrng *rng)if (err)return err; -drop_current_rng (); - current_rng = rng; + old_rng =rcu_dereference_protected (current_rng, +lockdep_is_held (&rng_mutex)); +rcu_assign_pointer (current_rng, rng); + +if (old_rng) { +synchronize_rcu (); +kref_put (&old_rng->ref, cleanup_rng); + }/* if necessary, start hwrng thread */ if (!hwrng_fill) {
@@ -101,47 +130,56 @@ static int set_current_rng(struct hwrng *rng)static void drop_current_rng (void ) { -BUG_ON (!mutex_is_locked (&rng_mutex)); -if (!current_rng) +struct hwrng *rng; + + rng =rcu_dereference_protected (current_rng, +lockdep_is_held (&rng_mutex)); +if (!rng)return ; +RCU_INIT_POINTER (current_rng,NULL ); +synchronize_rcu (); + +if (hwrng_fill) { +kthread_stop (hwrng_fill); + hwrng_fill =NULL ; + } +/* decrease last reference for triggering the cleanup */ -kref_put (¤t_rng->ref, cleanup_rng); - current_rng =NULL ; +kref_put (&rng->ref, cleanup_rng); } -/* Returns ERR_PTR(), NULL or refcounted hwrng */ +/* Returns NULL or refcounted hwrng */ static struct hwrng *get_current_rng_nolock (void ) { -if (current_rng) -kref_get (¤t_rng->ref); +struct hwrng *rng; + + rng =rcu_dereference_protected (current_rng, +lockdep_is_held (&rng_mutex)); +if (rng) +kref_get (&rng->ref); -return current_rng; +return rng; }static struct hwrng *get_current_rng (void ) {struct hwrng *rng; -if (mutex_lock_interruptible (&rng_mutex)) -return ERR_PTR (-ERESTARTSYS ); +rcu_read_lock (); + rng =rcu_dereference (current_rng); +if (rng) +kref_get (&rng->ref); - rng =get_current_rng_nolock (); +rcu_read_unlock (); -mutex_unlock (&rng_mutex);return rng; }static void put_rng (struct hwrng *rng) { -/* -* Hold rng_mutex here so we serialize in case they set_current_rng -* on rng again immediately. -*/ -mutex_lock (&rng_mutex);if (rng)kref_put (&rng->ref, cleanup_rng); -mutex_unlock (&rng_mutex); }static int hwrng_init (struct hwrng *rng)
@@ -213,10 +251,6 @@ static ssize_t rng_dev_read(struct file *filp, char __user *buf,while (size) { rng =get_current_rng (); -if (IS_ERR (rng)) { - err =PTR_ERR (rng); - goto out; - }if (!rng) { err = -ENODEV ; goto out;
@@ -303,7 +337,7 @@ static struct miscdevice rng_miscdev = {static int enable_best_rng (void ) { -struct hwrng *rng, *new_rng =NULL ; +struct hwrng *rng, *cur_rng, *new_rng =NULL ;int ret = -ENODEV ;BUG_ON (!mutex_is_locked (&rng_mutex));
@@ -321,7 +355,9 @@ static int enable_best_rng(void) new_rng = rng; } - ret = ((new_rng == current_rng) ?0 :set_current_rng (new_rng)); + cur_rng =rcu_dereference_protected (current_rng, +lockdep_is_held (&rng_mutex)); + ret = ((new_rng == cur_rng) ?0 :set_current_rng (new_rng));if (!ret) cur_rng_set_by_user =0 ;
@@ -371,8 +407,6 @@ static ssize_t rng_current_show(struct device *dev,struct hwrng *rng; rng =get_current_rng (); -if (IS_ERR (rng)) -return PTR_ERR (rng); ret =sysfs_emit (buf,"%s\n" , rng ? rng->name :"none" );put_rng (rng);
@@ -416,8 +450,6 @@ static ssize_t rng_quality_show(struct device *dev,struct hwrng *rng; rng =get_current_rng (); -if (IS_ERR (rng)) -return PTR_ERR (rng);if (!rng)/* no need to put_rng */ return -ENODEV ;
@@ -432,6 +464,7 @@ static ssize_t rng_quality_store(struct device *dev,struct device_attribute *attr, const char *buf, size_t len) { + struct hwrng *rng;u16 quality;int ret = -EINVAL ;
@@ -448,12 +481,13 @@ static ssize_t rng_quality_store(struct device *dev, goto out; } -if (!current_rng) { + rng =rcu_dereference_protected (current_rng,lockdep_is_held (&rng_mutex)); +if (!rng) { ret = -ENODEV ; goto out; } - current_rng->quality = quality; + rng->quality = quality; current_quality = quality;/* obsolete */ /* the best available RNG may have changed */
@@ -489,8 +523,20 @@ static int hwrng_fillfn(void *unused)struct hwrng *rng; rng =get_current_rng (); -if (IS_ERR (rng) || !rng) +if (!rng) { +/* +* Keep the task_struct alive until kthread_stop() +* is called to avoid UAF in drop_current_rng(). +*/ +while (!kthread_should_stop ()) { +set_current_state (TASK_INTERRUPTIBLE ); +if (!kthread_should_stop ()) +schedule (); + } +set_current_state (TASK_RUNNING );break ; + } +mutex_lock (&reading_mutex); rc =rng_get_data (rng, rng_fillbuf,rng_buffer_size (),1 );
@@ -518,14 +564,13 @@ static int hwrng_fillfn(void *unused)add_hwgenerator_randomness ((void *)rng_fillbuf, rc, entropy >>10 , true); } - hwrng_fill =NULL ;return 0 ; }int hwrng_register (struct hwrng *rng) {int err = -EINVAL ; -struct hwrng *tmp; +struct hwrng *cur_rng, *tmp;if (!rng->name || (!rng->data_read && !rng->read)) goto out;
@@ -540,6 +585,7 @@ int hwrng_register(struct hwrng *rng) }list_add_tail (&rng->list, &rng_list); +INIT_WORK (&rng->cleanup_work, cleanup_rng_work);init_completion (&rng->cleanup_done);complete (&rng->cleanup_done);init_completion (&rng->dying);
@@ -547,16 +593,19 @@ int hwrng_register(struct hwrng *rng)/* Adjust quality field to always have a proper value */ rng->quality =min3 (default_quality,1024 , rng->quality ?:1024 ); -if (!cur_rng_set_by_user && - (!current_rng || rng->quality > current_rng->quality)) { -/* -* Set new rng as current as the new rng source -* provides better entropy quality and was not -* chosen by userspace. -*/ - err =set_current_rng (rng); -if (err) - goto out_unlock; +if (!cur_rng_set_by_user) { + cur_rng =rcu_dereference_protected (current_rng, +lockdep_is_held (&rng_mutex)); +if (!cur_rng || rng->quality > cur_rng->quality) { +/* +* Set new rng as current as the new rng source +* provides better entropy quality and was not +* chosen by userspace. +*/ + err =set_current_rng (rng); +if (err) + goto out_unlock; + } }mutex_unlock (&rng_mutex);return 0 ;
@@ -569,14 +618,17 @@ EXPORT_SYMBOL_GPL(hwrng_register);void hwrng_unregister (struct hwrng *rng) { -struct hwrng *new_rng; +struct hwrng *cur_rng;int err;mutex_lock (&rng_mutex);list_del (&rng->list);complete_all (&rng->dying); -if (current_rng == rng) { + + cur_rng =rcu_dereference_protected (current_rng, +lockdep_is_held (&rng_mutex)); +if (cur_rng == rng) { err =enable_best_rng ();if (err) {drop_current_rng ();
@@ -584,17 +636,7 @@ void hwrng_unregister(struct hwrng *rng) } } - new_rng =get_current_rng_nolock (); -if (list_empty (&rng_list)) { -mutex_unlock (&rng_mutex); -if (hwrng_fill) -kthread_stop (hwrng_fill); - }else -mutex_unlock (&rng_mutex); - -if (new_rng) -put_rng (new_rng); - +mutex_unlock (&rng_mutex);wait_for_completion (&rng->cleanup_done); }EXPORT_SYMBOL_GPL (hwrng_unregister);
@@ -682,7 +724,7 @@ static int __init hwrng_modinit(void) static void __exit hwrng_modexit(void) {mutex_lock (&rng_mutex); -BUG_ON (current_rng); +WARN_ON (rcu_access_pointer (current_rng));kfree (rng_buffer);kfree (rng_fillbuf);mutex_unlock (&rng_mutex);
include/linux/hw_random.h +2 -0
@@ -15,6 +15,7 @@#include <linux/completion.h> #include <linux/kref.h> #include <linux/types.h> +#include <linux/workqueue_types.h> /** * struct hwrng - Hardware Random Number Generator driver
@@ -48,6 +49,7 @@ struct hwrng {/* internal. */ struct list_head list;struct kref ref; +struct work_struct cleanup_work;struct completion cleanup_done;struct completion dying; };
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 136/781 selftests/xsk: properly handle batch ending in the middle of a packet
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Larysa Zaremba <[email protected]>
[ Upstream commit 42e41b2a0afa04ca49ee2725aadf90ccb058ed28 ]
Referenced commit reduced the scope of the variable pkt, so now it has to be reinitialized via pkt_stream_get_next_rx_pkt(), which also increments some counters. When the packet is interrupted by the batch ending, pkt stream therefore proceeds to the next packet, while xsk ring still contains the previous one, this results in a pkt_nb mismatch.
Decrement the affected counters when packet is interrupted.
--- tools/testing/selftests/bpf/prog_tests/test_xsk.c | 2 ++ 1 file changed, 2 insertions(+)
tools/testing/selftests/bpf/prog_tests/test_xsk.c +2 -0
@@ -1090,6 +1090,8 @@ static int __receive_pkts(struct test_spec *test, struct xsk_socket_info *xsk)xsk_ring_prod__cancel (&umem->fq, nb_frags); } frags_processed -= nb_frags; +pkt_stream_cancel (pkt_stream); + pkts_sent--; }if (ifobj->use_fill_ring)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 137/781 selftests/xsk: fix number of Tx frags in invalid packet
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Larysa Zaremba <[email protected]>
[ Upstream commit 88af9fefed412e4bea9a1a771cbe6fe347fa3507 ]
The issue occurs in TOO_MANY_FRAGS test case when xdp_zc_max_segs is set to an odd number.
TOO_MANY_FRAGS test case contains an invalid packet consisting of (xdp_zc_max_segs) frags. Every frag, even the last one has XDP_PKT_CONTD flag set. This packet is expected to be dropped. After that, there is a valid linear packet, which is expected to be received back.
Once (xdp_zc_max_segs) is an odd number, the last packet cannot be received, if packet forwarding between Rx and Tx interfaces relies on the ethernet header, e.g. checks for ETH_P_LOOPBACK. Packet is malformed, if all traffic is looped.
Turns out, sending function processes multiple invalid frags as if they were in 2-frag packets. So once the invalid mbuf packet contains an odd number of those, the valid packet after gets paired with the previous invalid descriptor, and hence does not get an ethernet header generated, so it is either dropped or malformed.
Make invalid packets in verbatim mode always have only a single frag. For such packets, number of frags is otherwise meaningless, as descriptor flags are pre-configured in verbatim mode and packet data is not generated for invalid descriptors.
--- tools/testing/selftests/bpf/prog_tests/test_xsk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/testing/selftests/bpf/prog_tests/test_xsk.c +1 -1
@@ -433,7 +433,7 @@ static u32 pkt_nb_frags(u32 frame_size, struct pkt_stream *pkt_stream, struct pk }/* Search for the end of the packet in verbatim mode */ -if (!pkt_continues (pkt->options)) +if (!pkt_continues (pkt->options) || !pkt->valid)return nb_frags; next_frag = pkt_stream->current_pkt_nb;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 138/781 pstore/ram: fix buffer overflow in persistent_ram_save_old()
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sai Ritvik Tanksalkar <[email protected]>
[ Upstream commit 5669645c052f235726a85f443769b6fc02f66762 ]
persistent_ram_save_old() can be called multiple times for the same persistent_ram_zone (e.g., via ramoops_pstore_read -> ramoops_get_next_prz for PSTORE_TYPE_DMESG records).
Currently, the function only allocates prz->old_log when it is NULL, but it unconditionally updates prz->old_log_size to the current buffer size and then performs memcpy_fromio() using this new size. If the buffer size has grown since the first allocation (which can happen across different kernel boot cycles), this leads to:
1. A heap buffer overflow (OOB write) in the memcpy_fromio() calls
2. A subsequent OOB read when ramoops_pstore_read() accesses the buffer using the incorrect (larger) old_log_size
The KASAN splat would look similar to:
BUG: KASAN: slab-out-of-bounds in ramoops_pstore_read+0x... Read of size N at addr ... by task ...
The conditions are likely extremely hard to hit:
0. Crash with a ramoops write of less-than-record-max-size bytes.
1. Reboot: ramoops registers, pstore_get_records(0) reads old crash, allocates old_log with size X
2. Crash handler registered, timer started (if pstore_update_ms >= 0)
3. Oops happens (non-fatal, system continues)
4. pstore_dump() writes oops via ramoops_pstore_write() size Y (>X)
5. pstore_new_entry = 1, pstore_timer_kick() called
6. System continues running (not a panic oops)
7. Timer fires after pstore_update_ms milliseconds
8. pstore_timefunc() → schedule_work() → pstore_dowork() → pstore_get_records(1)
9. ramoops_get_next_prz() → persistent_ram_save_old()
10. buffer_size() returns Y, but old_log is X bytes
11. Y > X: memcpy_fromio() overflows heap
Requirements:
- a prior crash record exists that did not fill the record size (almost impossible since the crash handler writes as much as it can possibly fit into the record, capped by max record size and the kmsg buffer almost always exceeds the max record size)
- pstore_update_ms >= 0 (disabled by default)
- Non-fatal oops (system survives)
Free and reallocate the buffer when the new size differs from the previously allocated size. This ensures old_log always has sufficient space for the data being copied.
--- fs/pstore/ram_core.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
fs/pstore/ram_core.c +11 -0
@@ -298,6 +298,17 @@ void persistent_ram_save_old(struct persistent_ram_zone *prz)if (!size)return ; +/* +* If the existing buffer is differently sized, free it so a new +* one is allocated. This can happen when persistent_ram_save_old() +* is called early in boot and later for a timer-triggered +* survivable crash when the crash dumps don't match in size +* (which would be extremely unlikely given kmsg buffers usually +* exceed prz buffer sizes). +*/ +if (prz->old_log && prz->old_log_size != size) +persistent_ram_free_old (prz); +if (!prz->old_log) {persistent_ram_ecc_old (prz); prz->old_log =kvzalloc (size,GFP_KERNEL );
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 139/781 arm64: dts: ti: k3-am69-aquila-dev: Fix USB-C Sink PDO
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Francesco Dolcini <[email protected]>
[ Upstream commit 36ee9f8b1ae07fe82885a7a3553a5be347d3f978 ]
Change USB-C Sink PDO and the amount of power that the device can sink to zero to maximize compatibility with other USB peers (the Aquila Development Board is not sinking any current, it is self powered).
--- arch/arm64/boot/dts/ti/k3-am69-aquila-dev.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm64/boot/dts/ti/k3-am69-aquila-dev.dts +2 -2
@@ -399,8 +399,8 @@ connector { try-power-role = "sink"; self-powered; source-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>; - sink-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>; - op-sink-microwatt = <1000000>; + sink-pdos = <PDO_FIXED(5000, 0, PDO_FIXED_USB_COMM)>; + op-sink-microwatt = <0>; ports { #address-cells = <1>;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 140/781 arm64: dts: ti: k3-am69-aquila-clover: Fix USB-C Sink PDO
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Francesco Dolcini <[email protected]>
[ Upstream commit b548f3949937b55ee19ab418343f05700fdf7009 ]
Change USB-C Sink PDO and the amount of power that the device can sink to zero to maximize compatibility with other USB peers (the Aquila Clover Board is not sinking any current, it is self powered).
--- arch/arm64/boot/dts/ti/k3-am69-aquila-clover.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm64/boot/dts/ti/k3-am69-aquila-clover.dts +2 -2
@@ -280,8 +280,8 @@ connector { try-power-role = "sink"; self-powered; source-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>; - sink-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>; - op-sink-microwatt = <1000000>; + sink-pdos = <PDO_FIXED(5000, 0, PDO_FIXED_USB_COMM)>; + op-sink-microwatt = <0>; ports { #address-cells = <1>;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 141/781 soc: qcom: smem: handle ENOMEM error during probe
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jorge Ramirez-Ortiz <[email protected]>
[ Upstream commit 0fe01a7955f4fef97e7cc6d14bfc5931c660402b ]
Fail the driver probe if the region can't be mapped
--- drivers/soc/qcom/smem.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/soc/qcom/smem.c +3 -1
@@ -1219,7 +1219,9 @@ static int qcom_smem_probe(struct platform_device *pdev) smem->item_count =qcom_smem_get_item_count (smem);break ;case SMEM_GLOBAL_HEAP_VERSION : -qcom_smem_map_global (smem, size); + ret =qcom_smem_map_global (smem, size); +if (ret <0 ) +return ret; smem->item_count =SMEM_ITEM_COUNT ;break ;default :
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 142/781 EDAC/i5000: Fix snprintf() size calculation in calculate_dimm_size()
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
[ Upstream commit 7b5c7e83ac405ff9ecbdd92b37a477f4288f8814 ]
The snprintf() can't really overflow because we're writing a max of 42 bytes to a PAGE_SIZE buffer. But the limit calculation doesn't take the first 11 bytes that we wrote into consideration so the limit is not correct. Just fix it for correctness even though it doesn't affect runtime.
--- drivers/edac/i5000_edac.c | 1 + 1 file changed, 1 insertion(+)
drivers/edac/i5000_edac.c +1 -0
@@ -1111,6 +1111,7 @@ static void calculate_dimm_size(struct i5000_pvt *pvt) n =snprintf (p, space," " ); p += n; + space -= n;for (branch =0 ; branch <MAX_BRANCHES ; branch++) { n =snprintf (p, space," branch %d | " , branch); p += n;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 143/781 EDAC/i5400: Fix snprintf() limit calculation in calculate_dimm_size()
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
[ Upstream commit 72f12683611344853ab030fe7d19b23970ed2bd8 ]
The snprintf() can't really overflow because we're writing a max of 42 bytes to a PAGE_SIZE buffer. But my static checker complains because the limit calculation doesn't take the first 11 space characters that we wrote into the buffer into consideration. Fix this for the sake of correctness even though it doesn't affect runtime.
Also delete an earlier "space -= n;" which was not used.
--- drivers/edac/i5400_edac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/edac/i5400_edac.c +1 -1
@@ -1026,13 +1026,13 @@ static void calculate_dimm_size(struct i5400_pvt *pvt) space -= n; } - space -= n;edac_dbg (2 ,"%s\n" , mem_buffer); p = mem_buffer; space =PAGE_SIZE ; n =snprintf (p, space," " ); p += n; + space -= n;for (branch =0 ; branch <MAX_BRANCHES ; branch++) { n =snprintf (p, space," branch %d | " , branch); p += n;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 144/781 firmware: arm_ffa: Correct 32-bit response handling in NOTIFICATION_INFO_GET
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sudeep Holla <[email protected]>
[ Upstream commit be4d4543f78074fbebd530ba5109d39a2a34e668 ]
The FF-A specification allows NOTIFICATION_INFO_GET to return either a 64-bit (FFA_FN64_SUCCESS) or a 32-bit (FFA_SUCCESS) response, depending on whether the firmware chooses the SMC64 or SMC32 calling convention.
The driver previously detected the response format by checking ret.a0, but still interpreted the returned ID lists (x3..x17 or w3..w7) as if they always followed the 64-bit SMC64 layout. In the SMC32 case, the upper 32 bits of each argument register are undefined by the calling convention, meaning the driver could read stale or garbage values when parsing notification IDs.
This resulted in incorrectly decoded partition/VCPU IDs whenever the FF-A firmware used an SMC32 return path.
Fix the issue by:
- Introducing logic to map list indices to the correct u16 offsets, depending on whether the response width matches the kernel word size or is a 32-bit response on a 64-bit kernel.
- Ensuring that the packed ID list is parsed using the proper layout, avoiding reads from undefined upper halves in the SMC32 case.
With this change, NOTIFICATION_INFO_GET now correctly interprets ID list entries regardless of the response width, aligning the driver with the FF-A specification.
Message-Id: <[email protected]>
--- drivers/firmware/arm_ffa/driver.c | 33 +++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-)
drivers/firmware/arm_ffa/driver.c +29 -4
@@ -981,10 +981,27 @@ static void __do_sched_recv_cb(u16 part_id, u16 vcpu, bool is_per_vcpu) } } +/* +* Map logical ID index to the u16 index within the packed ID list. +* +* For native responses (FF-A width == kernel word size), IDs are +* tightly packed: idx -> idx. +* +* For 32-bit responses on a 64-bit kernel, each 64-bit register +* contributes 4 x u16 values but only the lower 2 are defined; the +* upper 2 are garbage. This mapping skips those upper halves: +* 0,1,2,3,4,5,... -> 0,1,4,5,8,9,... +*/ +static int list_idx_to_u16_idx (int idx,bool is_native_resp) +{ +return is_native_resp ? idx : idx +2 * (idx >>1 ); +} +static void ffa_notification_info_get (void ) { -int idx, list, max_ids, lists_cnt, ids_processed, ids_count[MAX_IDS_64 ]; -bool is_64b_resp; +int ids_processed, ids_count[MAX_IDS_64 ]; +int idx, list, max_ids, lists_cnt; +bool is_64b_resp, is_native_resp;ffa_value_t ret;u64 id_list;
@@ -1001,6 +1018,7 @@ static void ffa_notification_info_get(void) } is_64b_resp = (ret.a0 ==FFA_FN64_SUCCESS ); + is_native_resp = (ret.a0 ==FFA_FN_NATIVE (SUCCESS )); ids_processed =0 ; lists_cnt =FIELD_GET (NOTIFICATION_INFO_GET_ID_COUNT , ret.a2);
@@ -1017,12 +1035,16 @@ static void ffa_notification_info_get(void)/* Process IDs */ for (list =0 ; list < lists_cnt; list++) { +int u16_idx;u16 vcpu_id, part_id, *packed_id_list = (u16 *)&ret.a3;if (ids_processed >= max_ids -1 )break ; - part_id = packed_id_list[ids_processed++]; + u16_idx =list_idx_to_u16_idx (ids_processed, + is_native_resp); + part_id = packed_id_list[u16_idx]; + ids_processed++;if (ids_count[list] ==1 ) {/* Global Notification */ __do_sched_recv_cb (part_id,0 , false);
@@ -1034,7 +1056,10 @@ static void ffa_notification_info_get(void)if (ids_processed >= max_ids -1 )break ; - vcpu_id = packed_id_list[ids_processed++]; + u16_idx =list_idx_to_u16_idx (ids_processed, + is_native_resp); + vcpu_id = packed_id_list[u16_idx]; + ids_processed++;__do_sched_recv_cb (part_id, vcpu_id, true); }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 145/781 riscv: dts: sophgo: cv180x: fix USB dwc2 FIFO sizes
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Anton D. Stavinskii <[email protected]>
[ Upstream commit 03ea8676919af21b99bea01f18ef1a271d19f92f ]
I've tested the current dwc2 FIFO configuration and found that USB device mode breaks in ECM mode when transmitting frames larger than 128 bytes. For example, large ICMP packets or iperf3 traffic cause the USB link to hang and eventually disconnect without any messages in dmesg.
After switching to more conservative FIFO sizes, ECM becomes stable and no longer drops the connection. iperf3 now shows ~130 Mbit/s RX and ~100 Mbit/s TX on SG2002 (MilkV Duo 256M).
Fix the FIFO sizes accordingly.
--- arch/riscv/boot/dts/sophgo/cv180x.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/riscv/boot/dts/sophgo/cv180x.dtsi +2 -2
@@ -438,8 +438,8 @@ usb: usb@4340000 { clocks = <&clk CLK_AXI4_USB>, <&clk CLK_APB_USB>; clock-names = "otg", "utmi"; g-np-tx-fifo-size = <32>; - g-rx-fifo-size = <536>; - g-tx-fifo-size = <768 512 512 384 128 128>; + g-rx-fifo-size = <1536>; + g-tx-fifo-size = <128 128 64 64 64 64 32 32>; interrupts = <SOC_PERIPHERAL_IRQ(14) IRQ_TYPE_LEVEL_HIGH>; phys = <&usbphy>; phy-names = "usb2-phy";
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 146/781 arm64: dts: tqma8mpql-mba8mpxl: Fix HDMI CEC pad control settings
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Stein <[email protected]>
[ Upstream commit 8401527abb5e3a00c867b6597b8e1b29c80c9824 ]
As per datasheet of the HDMI protection IC the CEC_IC pin has been configured as open-drain.
--- arch/arm64/boot/dts/freescale/imx8mp-tqma8mpql-mba8mpxl.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/freescale/imx8mp-tqma8mpql-mba8mpxl.dts +1 -1
@@ -867,7 +867,7 @@ pinctrl_hdmi: hdmigrp { fsl,pins = <MX8MP_IOMUXC_HDMI_DDC_SCL__HDMIMIX_HDMI_SCL 0x400001c2>, <MX8MP_IOMUXC_HDMI_DDC_SDA__HDMIMIX_HDMI_SDA 0x400001c2>, <MX8MP_IOMUXC_HDMI_HPD__HDMIMIX_HDMI_HPD 0x40000010>, - <MX8MP_IOMUXC_HDMI_CEC__HDMIMIX_HDMI_CEC 0x40000010>; + <MX8MP_IOMUXC_HDMI_CEC__HDMIMIX_HDMI_CEC 0x40000030>; }; pinctrl_hoggpio2: hoggpio2grp {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 147/781 arm64: dts: tqma8mpql-mba8mp-ras314: Fix HDMI CEC pad control settings
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Stein <[email protected]>
[ Upstream commit 53a5c1d98d1155ece4c9446c0fea55e17d08774a ]
As per datasheet of the HDMI protection IC the CEC_IC pin has been configured as open-drain.
--- .../arm64/boot/dts/freescale/imx8mp-tqma8mpql-mba8mp-ras314.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/freescale/imx8mp-tqma8mpql-mba8mp-ras314.dts +1 -1
@@ -704,7 +704,7 @@ pinctrl_hdmi: hdmigrp { fsl,pins = <MX8MP_IOMUXC_HDMI_DDC_SCL__HDMIMIX_HDMI_SCL 0x400001c2>, <MX8MP_IOMUXC_HDMI_DDC_SDA__HDMIMIX_HDMI_SDA 0x400001c2>, <MX8MP_IOMUXC_HDMI_HPD__HDMIMIX_HDMI_HPD 0x40000010>, - <MX8MP_IOMUXC_HDMI_CEC__HDMIMIX_HDMI_CEC 0x40000154>; + <MX8MP_IOMUXC_HDMI_CEC__HDMIMIX_HDMI_CEC 0x40000030>; }; pinctrl_gpt1: gpt1grp {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 148/781 EDAC/amd64: Avoid a -Wformat-security warning
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arnd Bergmann <[email protected]>
[ Upstream commit c816ba1dcd931b9db8d66c71e1ae34ddcdbf968f ]
Using a variable as a format string causes a (default-disabled) warning:
drivers/edac/amd64_edac.c: In function 'per_family_init':
drivers/edac/amd64_edac.c:3914:17: error: format not a string literal and no format arguments [-Werror=format-security]
3914 | scnprintf(pvt->ctl_name, sizeof(pvt->ctl_name), tmp_name);
| ^~~~~~~~~The code here is safe, but in order to enable the warning by default in the future, change this instance to pass the name indirectly.
--- drivers/edac/amd64_edac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/edac/amd64_edac.c +1 -1
@@ -3911,7 +3911,7 @@ static int per_family_init(struct amd64_pvt *pvt) }if (tmp_name) -scnprintf (pvt->ctl_name,sizeof (pvt->ctl_name), tmp_name); +scnprintf (pvt->ctl_name,sizeof (pvt->ctl_name),"%s" , tmp_name);else scnprintf (pvt->ctl_name,sizeof (pvt->ctl_name),"F%02Xh_M%02Xh" , pvt->fam, pvt->model);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 149/781 clk: qcom: Return correct error code in qcom_cc_probe_by_index()
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haotian Zhang <[email protected]>
[ Upstream commit 1e07ebe744fb522983bd52a4a6148601675330c7 ]
When devm_platform_ioremap_resource() fails, it returns various error codes. Returning a hardcoded -ENOMEM masks the actual failure reason.
Use PTR_ERR() to propagate the actual error code returned by devm_platform_ioremap_resource() instead of -ENOMEM.
--- drivers/clk/qcom/common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/clk/qcom/common.c +1 -1
@@ -454,7 +454,7 @@ int qcom_cc_probe_by_index(struct platform_device *pdev, int index, base =devm_platform_ioremap_resource (pdev, index);if (IS_ERR (base)) -return -ENOMEM ; +return PTR_ERR (base); regmap =devm_regmap_init_mmio (&pdev->dev, base, desc->config);if (IS_ERR (regmap))
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 150/781 arm64: dts: qcom: sdm630: fix gpu_speed_bin size
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Baryshkov <[email protected]>
[ Upstream commit e814796dfcae8905682ac3ac2dd57f512a9f6726 ]
Historically sdm630.dtsi has used 1 byte length for the gpu_speed_bin cell, although it spans two bytes (offset 5, size 7 bits). It was being accepted by the kernel because before the commit 7a06ef751077 ("nvmem:
core: fix bit offsets of more than one byte") the kernel didn't have length check. After this commit nvmem core rejects QFPROM on sdm630 / sdm660, making GPU and USB unusable on those platforms.
Set the size of the gpu_speed_bin cell to 2 bytes, fixing the parsing error. While we are at it, update the length to 8 bits as pointed out by Alexey Minnekhanov.
--- arch/arm64/boot/dts/qcom/sdm630.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm64/boot/dts/qcom/sdm630.dtsi +2 -2
@@ -598,8 +598,8 @@ qusb2_hstx_trim: hstx-trim@240 { }; gpu_speed_bin: gpu-speed-bin@41a0 { - reg = <0x41a2 0x1>; - bits = <5 7>; + reg = <0x41a2 0x2>; + bits = <5 8>; }; };
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 151/781 arm64: dts: qcom: sm8150-hdk,mtp: specify ZAP firmware name
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Baryshkov <[email protected]>
[ Upstream commit d43019ef200d567454a8f68e60a5b2df01d8c706 ]
The DT file has GPU node enabled, but doesn't specify the file name of the ZAP firmware, which means using a default file name. Specify the name to the ZAP shader firmware, pointing to the file in the linux-firmware repo.
--- arch/arm64/boot/dts/qcom/sm8150-hdk.dts | 4 ++++ arch/arm64/boot/dts/qcom/sm8150-mtp.dts | 4 ++++ 2 files changed, 8 insertions(+)
arch/arm64/boot/dts/qcom/sm8150-hdk.dts +4 -0
@@ -387,6 +387,10 @@ &gpu { status = "okay"; }; +&gpu_zap_shader { + firmware-name = "qcom/sm8150/a640_zap.mbn"; +}; + &i2c4 { clock-frequency = <100000>;
arch/arm64/boot/dts/qcom/sm8150-mtp.dts +4 -0
@@ -358,6 +358,10 @@ &gpu { status = "okay"; }; +&gpu_zap_shader { + firmware-name = "qcom/sm8150/a640_zap.mbn"; +}; + &pon { mode-bootloader = <0x2>; mode-recovery = <0x1>;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 152/781 arm64: dts: qcom: sm8250-hdk: specify ZAP firmware name
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Baryshkov <[email protected]>
[ Upstream commit 95c121244a5d46435559bc74dbc7b5519394db08 ]
The DT file has GPU node enabled, but doesn't specify the file name of the ZAP firmware, which means using a default file name. Specify the name to the ZAP shader firmware, pointing to the file in the linux-firmware repo.
--- arch/arm64/boot/dts/qcom/sm8250-hdk.dts | 4 ++++ 1 file changed, 4 insertions(+)
arch/arm64/boot/dts/qcom/sm8250-hdk.dts +4 -0
@@ -373,6 +373,10 @@ &gpu { status = "okay"; }; +&gpu_zap_shader { + firmware-name = "qcom/sm8250/a650_zap.mbn"; +}; + &pon { mode-bootloader = <0x2>; mode-recovery = <0x1>;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 153/781 arm64: dts: qcom: sdm850-huawei-matebook-e-2019: Remove duplicate reserved-memroy nodes
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jingzhou Zhu <[email protected]>
[ Upstream commit a499c40ccd8e748ef363e2d13fb7a5c0ed6a788a ]
The adsp_mem and slpi_mem defined in sdm845.dtsi work well. Remove these nodes here to avoid redefinition.
Stable-dep-of: bc11f6f1d247 ("arm64: dts: qcom: sdm850-huawei-matebook-e-2019: Correct ipa_fw_mem for the driver to load successfully")
--- .../boot/dts/qcom/sdm850-huawei-matebook-e-2019.dts | 11 ----------- 1 file changed, 11 deletions(-)
arch/arm64/boot/dts/qcom/sdm850-huawei-matebook-e-2019.dts +0 -11
@@ -30,9 +30,7 @@ /delete-node/ &ipa_fw_mem; /delete-node/ &ipa_gsi_mem; /delete-node/ &gpu_mem; -/delete-node/ &adsp_mem; /delete-node/ &wlan_msa_mem; -/delete-node/ &slpi_mem; / { model = "Huawei MateBook E 2019";
@@ -145,20 +143,11 @@ wlan_msa_mem: wlan-msa@8c400000 { no-map; }; - adsp_mem: adsp@8c500000 { - reg = <0 0x8c500000 0 0x1a00000>; - no-map; - }; - ipa_fw_mem: ipa-fw@8df00000 { reg = <0 0x8df00000 0 0x100000>; no-map; }; - slpi_mem: slpi@96700000 { - reg = <0 0x96700000 0 0x1200000>; - }; - gpu_mem: gpu@97900000 { reg = <0 0x97900000 0 0x5000>; no-map;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 154/781 arm64: dts: qcom: sdm850-huawei-matebook-e-2019: Correct ipa_fw_mem for the driver to load successfully
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jingzhou Zhu <[email protected]>
[ Upstream commit bc11f6f1d2470fa59846be077555f9d4b7c2c0d3 ]
The ipa driver refuses to load with the old ipa_fw_mem in newer kernels. Shrinking its size to 0x5a000 fixes the problem.
--- arch/arm64/boot/dts/qcom/sdm850-huawei-matebook-e-2019.dts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
arch/arm64/boot/dts/qcom/sdm850-huawei-matebook-e-2019.dts +3 -3
@@ -144,12 +144,12 @@ wlan_msa_mem: wlan-msa@8c400000 { }; ipa_fw_mem: ipa-fw@8df00000 { - reg = <0 0x8df00000 0 0x100000>; + reg = <0 0x8df00000 0 0x5a000>; no-map; }; - gpu_mem: gpu@97900000 { - reg = <0 0x97900000 0 0x5000>; + gpu_mem: gpu@8df5a000 { + reg = <0 0x8df5a000 0 0x5000>; no-map; };
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 155/781 arm64: dts: qcom: sdm845-oneplus: Dont mark ts supply boot-on
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Casey Connolly <[email protected]>
[ Upstream commit c9b98b9dad9749bf2eb7336a6fca31a6af1039d7 ]
The touchscreen isn't enabled by bootloader and doesn't need to be enabled at boot, only when the driver probes, thus remove the regulator-boot-on property.
--- arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi | 1 - 1 file changed, 1 deletion(-)
arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi +0 -1
@@ -148,7 +148,6 @@ ts_1p8_supply: ts-1p8-regulator { gpio = <&tlmm 88 0>; enable-active-high; - regulator-boot-on; }; panel_vci_3v3: panel-vci-3v3-regulator {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 156/781 arm64: dts: qcom: sdm845-oneplus: Dont keep panel regulator always on
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Casey Connolly <[email protected]>
[ Upstream commit 45d1f42d3e84b5880cf9fab1eb24a7818320eeb7 ]
The panel regulator doesn't need to be always on, so remove this property.
--- arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi | 1 - 1 file changed, 1 deletion(-)
arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi +0 -1
@@ -272,7 +272,6 @@ vreg_l14a_1p88: ldo14 { regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; - regulator-always-on; }; vreg_l17a_1p3: ldo17 {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 157/781 arm64: dts: qcom: sdm845-oneplus: Mark l14a regulator as boot-on
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Casey Connolly <[email protected]>
[ Upstream commit ad33ee060be46794a03d033894c9db3a9d6c1a0f ]
This regulator is used only for the display, which is enabled by the bootloader and left on for continuous splash. Mark it as such.
--- arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi | 1 + 1 file changed, 1 insertion(+)
arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi +1 -0
@@ -272,6 +272,7 @@ vreg_l14a_1p88: ldo14 { regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-boot-on; }; vreg_l17a_1p3: ldo17 {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 158/781 arm64: dts: qcom: x1e80100: Fix USB combo PHYs SS1 and SS2 ref clocks
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Abel Vesa <[email protected]>
[ Upstream commit 3af51501e2b8c87564b5cda43b0e5c316cf54717 ]
It seems the USB combo SS1 and SS2 ref clocks have another gate, unlike the SS0. These gates are part of the TCSR clock controller.
At least on Dell XPS 13 (9345), if the ref clock provided by the TCSR clock controller for SS1 PHY is disabled on the clk_disable_unused late initcall, the PHY fails to initialize. It doesn't happen on the SS0 PHY and the SS2 is not used on this device.
This doesn't seem to be a problem on CRD though. It might be that the RPMh has a vote for it from some other consumer and does not actually disable it when ther kernel drops its vote.
Either way, these TCSR provided clocks seem to be the correct ones for the SS1 and SS2, so use them instead.
--- arch/arm64/boot/dts/qcom/hamoa.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm64/boot/dts/qcom/hamoa.dtsi +2 -2
@@ -2937,7 +2937,7 @@ usb_1_ss1_qmpphy: phy@fda000 { reg = <0 0x00fda000 0 0x4000>; clocks = <&gcc GCC_USB3_SEC_PHY_AUX_CLK>, - <&rpmhcc RPMH_CXO_CLK>, + <&tcsr TCSR_USB4_1_CLKREF_EN>, <&gcc GCC_USB3_SEC_PHY_COM_AUX_CLK>, <&gcc GCC_USB3_SEC_PHY_PIPE_CLK>; clock-names = "aux",
@@ -3008,7 +3008,7 @@ usb_1_ss2_qmpphy: phy@fdf000 { reg = <0 0x00fdf000 0 0x4000>; clocks = <&gcc GCC_USB3_TERT_PHY_AUX_CLK>, - <&rpmhcc RPMH_CXO_CLK>, + <&tcsr TCSR_USB4_2_CLKREF_EN>, <&gcc GCC_USB3_TERT_PHY_COM_AUX_CLK>, <&gcc GCC_USB3_TERT_PHY_PIPE_CLK>; clock-names = "aux",
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 159/781 arm64: dts: renesas: r9a09g047e57-smarc: Remove duplicate SW_LCD_EN
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Geert Uytterhoeven <[email protected]>
[ Upstream commit 44cfd102ce28e749a07bb0f1668cf932077b1175 ]
SW_LCD_EN is defined twice.
--- arch/arm64/boot/dts/renesas/r9a09g047e57-smarc.dts | 1 - 1 file changed, 1 deletion(-)
arch/arm64/boot/dts/renesas/r9a09g047e57-smarc.dts +0 -1
@@ -8,7 +8,6 @@ /dts-v1/; /* Switch selection settings */ -#define SW_LCD_EN 0 #define SW_GPIO8_CAN0_STB 0 #define SW_GPIO9_CAN1_STB 0 #define SW_LCD_EN 0
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 160/781 arm64: dts: qcom: msm8994-octagon: Fix Analog Devices vendor prefix of AD7147
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vladimir Zapolskiy <[email protected]>
[ Upstream commit 7db5fbe508deedec6c183d5056cf3c504c027f40 ]
Trivial change, Analog Devices vendor prefix is "adi", but there is a valid "ad" vendor prefix of another company, this may explain why the issue hasn't been discovered by the automatic tests.
A problem of not described compatible value is out of this change scope.
--- arch/arm64/boot/dts/qcom/msm8994-msft-lumia-octagon.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/qcom/msm8994-msft-lumia-octagon.dtsi +1 -1
@@ -378,7 +378,7 @@ &blsp2_i2c1 { status = "okay"; sideinteraction: touch@2c { - compatible = "ad,ad7147_captouch"; + compatible = "adi,ad7147_captouch"; reg = <0x2c>; pinctrl-names = "default", "sleep";
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 161/781 ARM: dts: allwinner: sun5i-a13-utoo-p66: delete "power-gpios" property
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chen-Yu Tsai <[email protected]>
[ Upstream commit 0b2761eb1287bd9f62367cccf6626eb3107cef6f ]
The P66's device tree includes the reference design dtsi files, which defines a node and properties for the touchpanel in the common design. The P66 dts file then overrides all the properties to match its own design, but as the touchpanel model is different, a different schema is matched. This other schema uses a different name for the GPIO.
The original submission added the correct GPIO property, but did not delete the one inherited from the reference design, causing validation errors.
Explicitly delete the incorrect GPIO property.
--- arch/arm/boot/dts/allwinner/sun5i-a13-utoo-p66.dts | 1 + 1 file changed, 1 insertion(+)
arch/arm/boot/dts/allwinner/sun5i-a13-utoo-p66.dts +1 -0
@@ -102,6 +102,7 @@ &touchscreen { /* The P66 uses a different EINT then the reference design */ interrupts = <6 9 IRQ_TYPE_EDGE_FALLING>; /* EINT9 (PG9) */ /* The icn8318 binding expects wake-gpios instead of power-gpios */ + /delete-property/ power-gpios; wake-gpios = <&pio 1 3 GPIO_ACTIVE_HIGH>; /* PB3 */ touchscreen-size-x = <800>; touchscreen-size-y = <480>;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 162/781 powerpc/uaccess: Move barrier_nospec() out of allow_read_{from/write}_user()
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christophe Leroy <[email protected]>
[ Upstream commit 5fbc09eb0b4f4b1a4b33abebacbeee0d29f195e9 ]
Commit 74e19ef0ff80 ("uaccess: Add speculation barrier to copy_from_user()") added a redundant barrier_nospec() in copy_from_user(), because powerpc is already calling barrier_nospec() in allow_read_from_user() and allow_read_write_user(). But on other architectures that call to barrier_nospec() was missing. So change powerpc instead of reverting the above commit and having to fix other architectures one by one. This is now possible because barrier_nospec() has also been added in copy_from_user_iter().
Move barrier_nospec() out of allow_read_from_user() and allow_read_write_user(). This will also allow reuse of those functions when implementing masked user access which doesn't require barrier_nospec().
Don't add it back in raw_copy_from_user() as it is already called by copy_from_user() and copy_from_user_iter().
--- arch/powerpc/include/asm/kup.h | 2 -- arch/powerpc/include/asm/uaccess.h | 4 ++++ 2 files changed, 4 insertions(+), 2 deletions(-)
arch/powerpc/include/asm/kup.h +0 -2
@@ -134,7 +134,6 @@ static __always_inline void kuap_assert_locked(void) static __always_inline void allow_read_from_user(const void __user *from, unsigned long size) { -barrier_nospec ();allow_user_access (NULL , from, size,KUAP_READ ); }
@@ -146,7 +145,6 @@ static __always_inline void allow_write_to_user(void __user *to, unsigned long s static __always_inline void allow_read_write_user(void __user *to, const void __user *from,unsigned long size) { -barrier_nospec ();allow_user_access (to, from, size,KUAP_READ_WRITE ); }
arch/powerpc/include/asm/uaccess.h +4 -0
@@ -301,6 +301,7 @@ do { \__typeof__ (sizeof(*(ptr ))) __gu_size =sizeof (*(ptr)); \ \might_fault (); \ +barrier_nospec (); \allow_read_from_user (__gu_addr, __gu_size); \__get_user_size_allowed (__gu_val, __gu_addr, __gu_size, __gu_err); \prevent_read_from_user (__gu_addr, __gu_size); \
@@ -329,6 +330,7 @@ raw_copy_in_user(void __user *to, const void __user *from, unsigned long n) {unsigned long ret; +barrier_nospec ();allow_read_write_user (to, from, n); ret =__copy_tofrom_user (to, from, n);prevent_read_write_user (to, from, n);
@@ -415,6 +417,7 @@ static __must_check __always_inline bool user_access_begin(const void __user *ptmight_fault (); +barrier_nospec ();allow_read_write_user ((void __user *)ptr, ptr, len);return true; }
@@ -431,6 +434,7 @@ user_read_access_begin(const void __user *ptr, size_t len)might_fault (); +barrier_nospec ();allow_read_from_user (ptr, len);return true; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 163/781 soc: qcom: cmd-db: Use devm_memremap() to fix memory leak in cmd_db_dev_probe
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haotian Zhang <[email protected]>
[ Upstream commit 0da7824734d8d83e6a844dd0207f071cb0c50cf4 ]
If cmd_db_magic_matches() fails after memremap() succeeds, the function returns -EINVAL without unmapping the memory region, causing a potential resource leak.
Switch to devm_memremap to automatically manage the map resource.
--- drivers/soc/qcom/cmd-db.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/soc/qcom/cmd-db.c +4 -3
@@ -349,15 +349,16 @@ static int cmd_db_dev_probe(struct platform_device *pdev)return -EINVAL ; } - cmd_db_header =memremap (rmem->base, rmem->size,MEMREMAP_WC ); -if (!cmd_db_header) { - ret = -ENOMEM ; + cmd_db_header =devm_memremap (&pdev->dev, rmem->base, rmem->size,MEMREMAP_WC ); +if (IS_ERR (cmd_db_header)) { + ret =PTR_ERR (cmd_db_header); cmd_db_header =NULL ;return ret; }if (!cmd_db_magic_matches (cmd_db_header)) {dev_err (&pdev->dev,"Invalid Command DB Magic\n" ); + cmd_db_header =NULL ;return -EINVAL ; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 164/781 soc: mediatek: svs: Fix memory leak in svs_enable_debug_write()
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zilin Guan <[email protected]>
[ Upstream commit 6259094ee806fb813ca95894c65fb80e2ec98bf1 ]
In svs_enable_debug_write(), the buf allocated by memdup_user_nul() is leaked if kstrtoint() fails.
Fix this by using __free(kfree) to automatically free buf, eliminating the need for explicit kfree() calls and preventing leaks.
--- drivers/soc/mediatek/mtk-svs.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/soc/mediatek/mtk-svs.c +2 -3
@@ -9,6 +9,7 @@#include <linux/bits.h> #include <linux/clk.h> #include <linux/completion.h> +#include <linux/cleanup.h> #include <linux/cpu.h> #include <linux/cpuidle.h> #include <linux/debugfs.h>
@@ -789,7 +790,7 @@ static ssize_t svs_enable_debug_write(struct file *filp,struct svs_bank *svsb =file_inode (filp)->i_private;struct svs_platform *svsp =dev_get_drvdata (svsb->dev);int enabled, ret; -char *buf =NULL ; + char *buf __free(kfree) = NULL;if (count >=PAGE_SIZE )return -EINVAL ;
@@ -807,8 +808,6 @@ static ssize_t svs_enable_debug_write(struct file *filp, svsb->mode_support =SVSB_MODE_ALL_DISABLE ; } -kfree (buf); -return count; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 165/781 powerpc/eeh: fix recursive pci_lock_rescan_remove locking in EEH event handling
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Narayana Murty N <[email protected]>
[ Upstream commit 815a8d2feb5615ae7f0b5befd206af0b0160614c ]
The recent commit 1010b4c012b0 ("powerpc/eeh: Make EEH driver device hotplug safe") restructured the EEH driver to improve synchronization with the PCI hotplug layer.
However, it inadvertently moved pci_lock_rescan_remove() outside its intended scope in eeh_handle_normal_event(), leading to broken PCI error reporting and improper EEH event triggering. Specifically, eeh_handle_normal_event() acquired pci_lock_rescan_remove() before calling eeh_pe_bus_get(), but eeh_pe_bus_get() itself attempts to acquire the same lock internally, causing nested locking and disrupting normal EEH event handling paths.
This patch adds a boolean parameter do_lock to _eeh_pe_bus_get(), with two public wrappers:
eeh_pe_bus_get() with locking enabled. eeh_pe_bus_get_nolock() that skips locking.
Callers that already hold pci_lock_rescan_remove() now use eeh_pe_bus_get_nolock() to avoid recursive lock acquisition.
Additionally, pci_lock_rescan_remove() calls are restored to the correct position—after eeh_pe_bus_get() and immediately before iterating affected PEs and devices. This ensures EEH-triggered PCI removes occur under proper bus rescan locking without recursive lock contention.
The eeh_pe_loc_get() function has been split into two functions:
eeh_pe_loc_get(struct eeh_pe *pe) which retrieves the loc for given PE. eeh_pe_loc_get_bus(struct pci_bus *bus) which retrieves the location code for given bus.
This resolves lockdep warnings such as:
<snip>
[ 84.964298] [ T928] ============================================
[ 84.964304] [ T928] WARNING: possible recursive locking detected
[ 84.964311] [ T928] 6.18.0-rc3 #51 Not tainted
[ 84.964315] [ T928] --------------------------------------------
[ 84.964320] [ T928] eehd/928 is trying to acquire lock:
[ 84.964324] [ T928] c000000003b29d58 (pci_rescan_remove_lock){+.+.}-{3:3}, at: pci_lock_rescan_remove+0x28/0x40
[ 84.964342] [ T928]
but task is already holding lock:
[ 84.964347] [ T928] c000000003b29d58 (pci_rescan_remove_lock){+.+.}-{3:3}, at: pci_lock_rescan_remove+0x28/0x40
[ 84.964357] [ T928]
other info that might help us debug this:
[ 84.964363] [ T928] Possible unsafe locking scenario:[ 84.964367] [ T928] CPU0
[ 84.964370] [ T928] ----
[ 84.964373] [ T928] lock(pci_rescan_remove_lock);
[ 84.964378] [ T928] lock(pci_rescan_remove_lock);
[ 84.964383] [ T928]
*** DEADLOCK ***[ 84.964388] [ T928] May be due to missing lock nesting notation
[ 84.964393] [ T928] 1 lock held by eehd/928:
[ 84.964397] [ T928] #0: c000000003b29d58 (pci_rescan_remove_lock){+.+.}-{3:3}, at: pci_lock_rescan_remove+0x28/0x40
[ 84.964408] [ T928]
stack backtrace:
[ 84.964414] [ T928] CPU: 2 UID: 0 PID: 928 Comm: eehd Not tainted 6.18.0-rc3 #51 VOLUNTARY
[ 84.964417] [ T928] Hardware name: IBM,9080-HEX POWER10 (architected) 0x800200 0xf000006 of:IBM,FW1060.00 (NH1060_022) hv:phyp pSeries
[ 84.964419] [ T928] Call Trace:
[ 84.964420] [ T928] [c0000011a7157990] [c000000001705de4] dump_stack_lvl+0xc8/0x130 (unreliable)
[ 84.964424] [ T928] [c0000011a71579d0] [c0000000002f66e0] print_deadlock_bug+0x430/0x440
[ 84.964428] [ T928] [c0000011a7157a70] [c0000000002fd0c0] __lock_acquire+0x1530/0x2d80
[ 84.964431] [ T928] [c0000011a7157ba0] [c0000000002fea54] lock_acquire+0x144/0x410
[ 84.964433] [ T928] [c0000011a7157cb0] [c0000011a7157cb0] __mutex_lock+0xf4/0x1050
[ 84.964436] [ T928] [c0000011a7157e00] [c000000000de21d8] pci_lock_rescan_remove+0x28/0x40
[ 84.964439] [ T928] [c0000011a7157e20] [c00000000004ed98] eeh_pe_bus_get+0x48/0xc0
[ 84.964442] [ T928] [c0000011a7157e50] [c000000000050434] eeh_handle_normal_event+0x64/0xa60
[ 84.964446] [ T928] [c0000011a7157f30] [c000000000051de8] eeh_event_handler+0xf8/0x190
[ 84.964450] [ T928] [c0000011a7157f90] [c0000000002747ac] kthread+0x16c/0x180
[ 84.964453] [ T928] [c0000011a7157fe0] [c00000000000ded8] start_kernel_thread+0x14/0x18</snip>
--- arch/powerpc/include/asm/eeh.h | 2 + arch/powerpc/kernel/eeh_driver.c | 11 ++--- arch/powerpc/kernel/eeh_pe.c | 74 ++++++++++++++++++++++++++++++-- 3 files changed, 78 insertions(+), 9 deletions(-)
arch/powerpc/include/asm/eeh.h +2 -0
@@ -289,6 +289,8 @@ void eeh_pe_dev_traverse(struct eeh_pe *root,void eeh_pe_restore_bars (struct eeh_pe *pe);const char *eeh_pe_loc_get (struct eeh_pe *pe);struct pci_bus *eeh_pe_bus_get (struct eeh_pe *pe); +const char *eeh_pe_loc_get_bus (struct pci_bus *bus); +struct pci_bus *eeh_pe_bus_get_nolock (struct eeh_pe *pe);void eeh_show_enabled (void );int __init eeh_init (struct eeh_ops *ops);
arch/powerpc/kernel/eeh_driver.c +6 -5
@@ -846,7 +846,7 @@ void eeh_handle_normal_event(struct eeh_pe *pe)pci_lock_rescan_remove (); - bus =eeh_pe_bus_get (pe); + bus =eeh_pe_bus_get_nolock (pe);if (!bus) {pr_err ("%s: Cannot find PCI bus for PHB#%x-PE#%x\n" , __func__, pe->phb->global_number, pe->addr);
@@ -886,14 +886,15 @@ void eeh_handle_normal_event(struct eeh_pe *pe)/* Log the event */ if (pe->type &EEH_PE_PHB ) {pr_err ("EEH: Recovering PHB#%x, location: %s\n" , - pe->phb->global_number,eeh_pe_loc_get (pe)); + pe->phb->global_number,eeh_pe_loc_get_bus (bus)); }else {struct eeh_pe *phb_pe =eeh_phb_pe_get (pe->phb);pr_err ("EEH: Recovering PHB#%x-PE#%x\n" , pe->phb->global_number, pe->addr);pr_err ("EEH: PE location: %s, PHB location: %s\n" , -eeh_pe_loc_get (pe),eeh_pe_loc_get (phb_pe)); +eeh_pe_loc_get_bus (bus), +eeh_pe_loc_get_bus (eeh_pe_bus_get_nolock (phb_pe))); }#ifdef CONFIG_STACKTRACE
@@ -1098,7 +1099,7 @@ void eeh_handle_normal_event(struct eeh_pe *pe)eeh_pe_state_clear (pe,EEH_PE_PRI_BUS , true);eeh_pe_dev_mode_mark (pe,EEH_DEV_REMOVED ); - bus =eeh_pe_bus_get (pe); + bus =eeh_pe_bus_get_nolock (pe);if (bus)pci_hp_remove_devices (bus);else
@@ -1222,7 +1223,7 @@ void eeh_handle_special_event(void) (phb_pe->state & EEH_PE_RECOVERING))continue ; - bus =eeh_pe_bus_get (phb_pe); + bus =eeh_pe_bus_get_nolock (phb_pe);if (!bus) { pr_err("%s: Cannot find PCI bus for " "PHB#%x-PE#%x\n",
arch/powerpc/kernel/eeh_pe.c +70 -4
102 lines not on this page · raw message
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 166/781 arm64: dts: renesas: rzt2h-n2h-evk-common: Use GPIO for SD0 write protect
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lad Prabhakar <[email protected]>
[ Upstream commit a1b1ee0348f889ec262482e16e9ff670617db7b0 ]
Switch SD0 write-protect detection to a GPIO on the RZ/T2H and RZ/N2H EVKs. Both boards use a full-size SD card slot on the SD0 channel with a dedicated WP pin.
The RZ/T2H and RZ/N2H SoCs use of_data_rcar_gen3, which sets MMC_CAP2_NO_WRITE_PROTECT and causes the core to ignore the WP signal unless a wp-gpios property is provided. Describe the WP pin as a GPIO to allow the MMC core to evaluate the write-protect status correctly.
--- arch/arm64/boot/dts/renesas/rzt2h-n2h-evk-common.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm64/boot/dts/renesas/rzt2h-n2h-evk-common.dtsi +2 -2
@@ -224,8 +224,7 @@ data-pins { ctrl-pins { pinmux = <RZT2H_PORT_PINMUX(12, 0, 0x29)>, /* SD0_CLK */ <RZT2H_PORT_PINMUX(12, 1, 0x29)>, /* SD0_CMD */ - <RZT2H_PORT_PINMUX(22, 5, 0x29)>, /* SD0_CD */ - <RZT2H_PORT_PINMUX(22, 6, 0x29)>; /* SD0_WP */ + <RZT2H_PORT_PINMUX(22, 5, 0x29)>; /* SD0_CD */ }; };
@@ -282,6 +281,7 @@ &sdhi0 { pinctrl-names = "default", "state_uhs"; vmmc-supply = <®_3p3v>; vqmmc-supply = <&vqmmc_sdhi0>; + wp-gpios = <&pinctrl RZT2H_GPIO(22, 6) GPIO_ACTIVE_HIGH>; bus-width = <4>; sd-uhs-sdr50; sd-uhs-sdr104;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 167/781 arm: dts: lpc32xx: add clocks property to Motor Control PWM device tree node
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vladimir Zapolskiy <[email protected]>
[ Upstream commit 71630e581a0e34c03757f5c1706f57c853b92555 ]
Motor Control PWM depends on its own supply clock, the clock gate control is present in TIMCLK_CTRL1 register.
--- arch/arm/boot/dts/nxp/lpc/lpc32xx.dtsi | 1 + 1 file changed, 1 insertion(+)
arch/arm/boot/dts/nxp/lpc/lpc32xx.dtsi +1 -0
@@ -302,6 +302,7 @@ i2c2: i2c@400a8000 { mpwm: pwm@400e8000 { compatible = "nxp,lpc3220-motor-pwm"; reg = <0x400e8000 0x78>; + clocks = <&clk LPC32XX_CLK_MCPWM>; #pwm-cells = <3>; status = "disabled"; };
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 168/781 arm64: dts: mediatek: mt8183-jacuzzi-pico6: Fix typo in pinmux node
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: AngeloGioacchino Del Regno <[email protected]>
[ Upstream commit b1fc81a986c9b8089db31e21a372cc8b6514e900 ]
Rename "piins-bt-wakeup" to "pins-bt-wakeup" to fix a dtbs_check warning happening due to this typo.
--- arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-pico6.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-pico6.dts +1 -1
@@ -91,7 +91,7 @@ bluetooth@2 { &pio { bt_pins_wakeup: bt-pins-wakeup { - piins-bt-wakeup { + pins-bt-wakeup { pinmux = <PINMUX_GPIO42__FUNC_GPIO42>; input-enable; };
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 169/781 arm64: dts: amlogic: s4: assign mmc b clock to 24MHz
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jerome Brunet <[email protected]>
[ Upstream commit 86124a8becb43eed3103f2459399daee8af2c99d ]
The amlogic MMC driver operate with the assumption that MMC clock is configured to provide 24MHz. It uses this path for low rates such as 400kHz.
This assumption did hold true until but it now, but it is apparently not the case with s4. The clock has been reported to provide 1GHz instead. This is most likely due to how the bootloader is using the MMC clock on this platform.
Regardless of why the MMC clock rate is 1GHz, if the MMC driver expects 24MHz, the clock should be properly assigned, so assign it.
--- arch/arm64/boot/dts/amlogic/meson-s4.dtsi | 3 +++ 1 file changed, 3 insertions(+)
arch/arm64/boot/dts/amlogic/meson-s4.dtsi +3 -0
@@ -838,6 +838,9 @@ sd: mmc@fe08a000 { clock-names = "core", "clkin0", "clkin1"; resets = <&reset RESET_SD_EMMC_B>; status = "disabled"; + + assigned-clocks = <&clkc_periphs CLKID_SD_EMMC_B>; + assigned-clock-rates = <24000000>; }; emmc: mmc@fe08c000 {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 170/781 arm64: dts: amlogic: s4: fix mmc clock assignment
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jerome Brunet <[email protected]>
[ Upstream commit 3a115d42922cffc91b303992eadf220111d66c31 ]
MMC A and C are mis-represented as having their "clkin0" input connected to xtal while it is actually connected to the MMC clock, probably in an attempt to provide 24MHz to the device on this input.
Fix this and assign the clock to 24MHz to actually provide the required rate.
--- arch/arm64/boot/dts/amlogic/meson-s4.dtsi | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
arch/arm64/boot/dts/amlogic/meson-s4.dtsi +8 -2
@@ -819,13 +819,16 @@ sdio: mmc@fe088000 { reg = <0x0 0xfe088000 0x0 0x800>; interrupts = <GIC_SPI 176 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clkc_periphs CLKID_SDEMMC_A>, - <&xtal>, + <&clkc_periphs CLKID_SD_EMMC_A>, <&clkc_pll CLKID_FCLK_DIV2>; clock-names = "core", "clkin0", "clkin1"; resets = <&reset RESET_SD_EMMC_A>; cap-sdio-irq; keep-power-in-suspend; status = "disabled"; + + assigned-clocks = <&clkc_periphs CLKID_SD_EMMC_A>; + assigned-clock-rates = <24000000>; }; sd: mmc@fe08a000 {
@@ -848,13 +851,16 @@ emmc: mmc@fe08c000 { reg = <0x0 0xfe08c000 0x0 0x800>; interrupts = <GIC_SPI 178 IRQ_TYPE_EDGE_RISING>; clocks = <&clkc_periphs CLKID_NAND>, - <&xtal>, + <&clkc_periphs CLKID_SD_EMMC_C>, <&clkc_pll CLKID_FCLK_DIV2>; clock-names = "core", "clkin0", "clkin1"; resets = <&reset RESET_NAND_EMMC>; no-sdio; no-sd; status = "disabled"; + + assigned-clocks = <&clkc_periphs CLKID_SD_EMMC_C>; + assigned-clock-rates = <24000000>; }; }; };
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 171/781 arm64: dts: ti: k3-j784s4-main.dtsi: Move c71_3 node to appropriate order
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Abhash Kumar Jha <[email protected]>
[ Upstream commit 24c9d5fb8bbf5e8c9e6fc2beffeb80ac2da83de4 ]
The device tree nodes should be ordered by unit addresses in ascending order.
Correct the order by moving the c71_3 DSP node at the end as it has a higher unit address.
Stable-dep-of: 61acc4428a7f ("arm64: dts: ti: k3-j784s4-j742s2-main-common.dtsi: Refactor watchdog instances for j784s4")
--- arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi | 26 +++++++++++----------- 1 file changed, 13 insertions(+), 13 deletions(-)
arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi +13 -13
@@ -6,19 +6,6 @@ */ &cbass_main { - c71_3: dsp@67800000 { - compatible = "ti,j721s2-c71-dsp"; - reg = <0x00 0x67800000 0x00 0x00080000>, - <0x00 0x67e00000 0x00 0x0000c000>; - reg-names = "l2sram", "l1dram"; - resets = <&k3_reset 40 1>; - firmware-name = "j784s4-c71_3-fw"; - ti,sci = <&sms>; - ti,sci-dev-id = <40>; - ti,sci-proc-ids = <0x33 0xff>; - status = "disabled"; - }; - pcie2_rc: pcie@2920000 { compatible = "ti,j784s4-pcie-host"; reg = <0x00 0x02920000 0x00 0x1000>,
@@ -113,6 +100,19 @@ serdes2: serdes@5020000 { status = "disabled"; }; }; + + c71_3: dsp@67800000 { + compatible = "ti,j721s2-c71-dsp"; + reg = <0x00 0x67800000 0x00 0x00080000>, + <0x00 0x67e00000 0x00 0x0000c000>; + reg-names = "l2sram", "l1dram"; + resets = <&k3_reset 40 1>; + firmware-name = "j784s4-c71_3-fw"; + ti,sci = <&sms>; + ti,sci-dev-id = <40>; + ti,sci-proc-ids = <0x33 0xff>; + status = "disabled"; + }; }; &scm_conf {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 172/781 arm64: dts: ti: k3-j784s4-j742s2-main-common.dtsi: Refactor watchdog instances for j784s4
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Abhash Kumar Jha <[email protected]>
[ Upstream commit 61acc4428a7f52e0a13e226ba76f2ce2ca66c065 ]
Each A72 core has one watchdog instance associated with it. Since j742s2 has 4 A72 cores, the common file should not define 8 watchdog instances.
Refactor the last 4 extra watchdogs from the common file to j784s4 specific file, as j784s4 has 8 A72 cores and thus hardware description requires 8 watchdog instances.
--- .../dts/ti/k3-j784s4-j742s2-main-common.dtsi | 36 ------------------- arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi | 36 +++++++++++++++++++ 2 files changed, 36 insertions(+), 36 deletions(-)
arch/arm64/boot/dts/ti/k3-j784s4-j742s2-main-common.dtsi +0 -36
@@ -2378,42 +2378,6 @@ watchdog3: watchdog@2230000 { assigned-clock-parents = <&k3_clks 351 4>; }; - watchdog4: watchdog@2240000 { - compatible = "ti,j7-rti-wdt"; - reg = <0x00 0x2240000 0x00 0x100>; - clocks = <&k3_clks 352 0>; - power-domains = <&k3_pds 352 TI_SCI_PD_EXCLUSIVE>; - assigned-clocks = <&k3_clks 352 0>; - assigned-clock-parents = <&k3_clks 352 4>; - }; - - watchdog5: watchdog@2250000 { - compatible = "ti,j7-rti-wdt"; - reg = <0x00 0x2250000 0x00 0x100>; - clocks = <&k3_clks 353 0>; - power-domains = <&k3_pds 353 TI_SCI_PD_EXCLUSIVE>; - assigned-clocks = <&k3_clks 353 0>; - assigned-clock-parents = <&k3_clks 353 4>; - }; - - watchdog6: watchdog@2260000 { - compatible = "ti,j7-rti-wdt"; - reg = <0x00 0x2260000 0x00 0x100>; - clocks = <&k3_clks 354 0>; - power-domains = <&k3_pds 354 TI_SCI_PD_EXCLUSIVE>; - assigned-clocks = <&k3_clks 354 0>; - assigned-clock-parents = <&k3_clks 354 4>; - }; - - watchdog7: watchdog@2270000 { - compatible = "ti,j7-rti-wdt"; - reg = <0x00 0x2270000 0x00 0x100>; - clocks = <&k3_clks 355 0>; - power-domains = <&k3_pds 355 TI_SCI_PD_EXCLUSIVE>; - assigned-clocks = <&k3_clks 355 0>; - assigned-clock-parents = <&k3_clks 355 4>; - }; - /* * The following RTI instances are coupled with MCU R5Fs, c7x and * GPU so keeping them reserved as these will be used by their
arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi +36 -0
@@ -6,6 +6,42 @@ */ &cbass_main { + watchdog4: watchdog@2240000 { + compatible = "ti,j7-rti-wdt"; + reg = <0x00 0x2240000 0x00 0x100>; + clocks = <&k3_clks 352 0>; + power-domains = <&k3_pds 352 TI_SCI_PD_EXCLUSIVE>; + assigned-clocks = <&k3_clks 352 0>; + assigned-clock-parents = <&k3_clks 352 4>; + }; + + watchdog5: watchdog@2250000 { + compatible = "ti,j7-rti-wdt"; + reg = <0x00 0x2250000 0x00 0x100>; + clocks = <&k3_clks 353 0>; + power-domains = <&k3_pds 353 TI_SCI_PD_EXCLUSIVE>; + assigned-clocks = <&k3_clks 353 0>; + assigned-clock-parents = <&k3_clks 353 4>; + }; + + watchdog6: watchdog@2260000 { + compatible = "ti,j7-rti-wdt"; + reg = <0x00 0x2260000 0x00 0x100>; + clocks = <&k3_clks 354 0>; + power-domains = <&k3_pds 354 TI_SCI_PD_EXCLUSIVE>; + assigned-clocks = <&k3_clks 354 0>; + assigned-clock-parents = <&k3_clks 354 4>; + }; + + watchdog7: watchdog@2270000 { + compatible = "ti,j7-rti-wdt"; + reg = <0x00 0x2270000 0x00 0x100>; + clocks = <&k3_clks 355 0>; + power-domains = <&k3_pds 355 TI_SCI_PD_EXCLUSIVE>; + assigned-clocks = <&k3_clks 355 0>; + assigned-clock-parents = <&k3_clks 355 4>; + }; + pcie2_rc: pcie@2920000 { compatible = "ti,j784s4-pcie-host"; reg = <0x00 0x02920000 0x00 0x1000>,
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 173/781 soc: qcom: ubwc: add missing include
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Baryshkov <[email protected]>
[ Upstream commit ccef4b2703ff5b0de0b1bda30a0de3026d52eb19 ]
The header has a function which calls pr_err(). Don't require users of the header to include <linux/printk.h> and include it here.
--- include/linux/soc/qcom/ubwc.h | 1 + 1 file changed, 1 insertion(+)
include/linux/soc/qcom/ubwc.h +1 -0
@@ -8,6 +8,7 @@#define __QCOM_UBWC_H__#include <linux/bits.h> +#include <linux/printk.h> #include <linux/types.h> struct qcom_ubwc_cfg_data {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 174/781 hwspinlock: omap: Handle devm_pm_runtime_enable() errors
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haotian Zhang <[email protected]>
[ Upstream commit 3bd4edd67b034f8e1f61c86e0eb098de6179e3f2 ]
Although unlikely, devm_pm_runtime_enable() can fail due to memory allocations. Without proper error handling, the subsequent pm_runtime_resume_and_get() call may operate on incorrectly initialized runtime PM state.
Add error handling to check the return value ofdevm_pm_runtime_enable() and return on failure.
--- drivers/hwspinlock/omap_hwspinlock.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/hwspinlock/omap_hwspinlock.c +3 -1
@@ -88,7 +88,9 @@ static int omap_hwspinlock_probe(struct platform_device *pdev)* make sure the module is enabled and clocked before reading * the module SYSSTATUS register */ -devm_pm_runtime_enable (&pdev->dev); + ret =devm_pm_runtime_enable (&pdev->dev); +if (ret) +return ret; ret =pm_runtime_resume_and_get (&pdev->dev);if (ret <0 )return ret;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 175/781 arm64: dts: amlogic: c3: assign the MMC signal clocks
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jerome Brunet <[email protected]>
[ Upstream commit 69330fd2368371c4eb47d60ace6bca09763d24a0 ]
The amlogic MMC driver operate with the assumption that MMC clock is configured to provide 24MHz. It uses this path for low rates such as 400kHz.
Assign the clocks to make sure they are properly configured
--- arch/arm64/boot/dts/amlogic/amlogic-c3.dtsi | 7 +++++++ 1 file changed, 7 insertions(+)
arch/arm64/boot/dts/amlogic/amlogic-c3.dtsi +7 -0
@@ -969,6 +969,10 @@ sdio: mmc@88000 { no-sd; resets = <&reset RESET_SD_EMMC_A>; status = "disabled"; + + assigned-clocks = <&clkc_periphs CLKID_SD_EMMC_A>; + assigned-clock-rates = <24000000>; + }; sd: mmc@8a000 {
@@ -984,6 +988,9 @@ sd: mmc@8a000 { no-sdio; resets = <&reset RESET_SD_EMMC_B>; status = "disabled"; + + assigned-clocks = <&clkc_periphs CLKID_SD_EMMC_B>; + assigned-clock-rates = <24000000>; }; nand: nand-controller@8d000 {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 176/781 arm64: dts: amlogic: axg: assign the MMC signal clocks
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jerome Brunet <[email protected]>
[ Upstream commit 13d3fe2318ef6e46d6fcfe13bc373827fdf2aeac ]
The amlogic MMC driver operate with the assumption that MMC clock is configured to provide 24MHz. It uses this path for low rates such as 400kHz.
Assign the clocks to make sure they are properly configured
--- arch/arm64/boot/dts/amlogic/meson-axg.dtsi | 6 ++++++ 1 file changed, 6 insertions(+)
arch/arm64/boot/dts/amlogic/meson-axg.dtsi +6 -0
@@ -1960,6 +1960,9 @@ sd_emmc_b: mmc@5000 { <&clkc CLKID_FCLK_DIV2>; clock-names = "core", "clkin0", "clkin1"; resets = <&reset RESET_SD_EMMC_B>; + + assigned-clocks = <&clkc CLKID_SD_EMMC_B_CLK0>; + assigned-clock-rates = <24000000>; }; sd_emmc_c: mmc@7000 {
@@ -1972,6 +1975,9 @@ sd_emmc_c: mmc@7000 { <&clkc CLKID_FCLK_DIV2>; clock-names = "core", "clkin0", "clkin1"; resets = <&reset RESET_SD_EMMC_C>; + + assigned-clocks = <&clkc CLKID_SD_EMMC_C_CLK0>; + assigned-clock-rates = <24000000>; }; nfc: nand-controller@7800 {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 177/781 arm64: dts: amlogic: gx: assign the MMC signal clocks
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jerome Brunet <[email protected]>
[ Upstream commit 406706559046eebc09a31e8ae5e78620bfd746fe ]
The amlogic MMC driver operate with the assumption that MMC clock is configured to provide 24MHz. It uses this path for low rates such as 400kHz.
Assign the clocks to make sure they are properly configured
--- arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | 9 +++++++++ arch/arm64/boot/dts/amlogic/meson-gxl.dtsi | 9 +++++++++ 2 files changed, 18 insertions(+)
arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi +9 -0
@@ -824,6 +824,9 @@ &sd_emmc_a { <&clkc CLKID_FCLK_DIV2>; clock-names = "core", "clkin0", "clkin1"; resets = <&reset RESET_SD_EMMC_A>; + + assigned-clocks = <&clkc CLKID_SD_EMMC_A_CLK0>; + assigned-clock-rates = <24000000>; }; &sd_emmc_b {
@@ -832,6 +835,9 @@ &sd_emmc_b { <&clkc CLKID_FCLK_DIV2>; clock-names = "core", "clkin0", "clkin1"; resets = <&reset RESET_SD_EMMC_B>; + + assigned-clocks = <&clkc CLKID_SD_EMMC_B_CLK0>; + assigned-clock-rates = <24000000>; }; &sd_emmc_c {
@@ -840,6 +846,9 @@ &sd_emmc_c { <&clkc CLKID_FCLK_DIV2>; clock-names = "core", "clkin0", "clkin1"; resets = <&reset RESET_SD_EMMC_C>; + + assigned-clocks = <&clkc CLKID_SD_EMMC_C_CLK0>; + assigned-clock-rates = <24000000>; }; &simplefb_hdmi {
arch/arm64/boot/dts/amlogic/meson-gxl.dtsi +9 -0
@@ -894,6 +894,9 @@ &sd_emmc_a { <&clkc CLKID_FCLK_DIV2>; clock-names = "core", "clkin0", "clkin1"; resets = <&reset RESET_SD_EMMC_A>; + + assigned-clocks = <&clkc CLKID_SD_EMMC_A_CLK0>; + assigned-clock-rates = <24000000>; }; &sd_emmc_b {
@@ -902,6 +905,9 @@ &sd_emmc_b { <&clkc CLKID_FCLK_DIV2>; clock-names = "core", "clkin0", "clkin1"; resets = <&reset RESET_SD_EMMC_B>; + + assigned-clocks = <&clkc CLKID_SD_EMMC_B_CLK0>; + assigned-clock-rates = <24000000>; }; &sd_emmc_c {
@@ -910,6 +916,9 @@ &sd_emmc_c { <&clkc CLKID_FCLK_DIV2>; clock-names = "core", "clkin0", "clkin1"; resets = <&reset RESET_SD_EMMC_C>; + + assigned-clocks = <&clkc CLKID_SD_EMMC_C_CLK0>; + assigned-clock-rates = <24000000>; }; &simplefb_hdmi {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 178/781 arm64: dts: amlogic: g12: assign the MMC B and C signal clocks
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jerome Brunet <[email protected]>
[ Upstream commit be2ff5fdb0e83e32d4ec4e68a69875cec0d14621 ]
The amlogic MMC driver operate with the assumption that MMC clock is configured to provide 24MHz. It uses this path for low rates such as 400kHz.
Assign the clocks to make sure they are properly configured
--- arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi | 6 ++++++ 1 file changed, 6 insertions(+)
arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi +6 -0
@@ -2443,6 +2443,9 @@ sd_emmc_b: mmc@ffe05000 { <&clkc CLKID_FCLK_DIV2>; clock-names = "core", "clkin0", "clkin1"; resets = <&reset RESET_SD_EMMC_B>; + + assigned-clocks = <&clkc CLKID_SD_EMMC_B_CLK0>; + assigned-clock-rates = <24000000>; }; sd_emmc_c: mmc@ffe07000 {
@@ -2455,6 +2458,9 @@ sd_emmc_c: mmc@ffe07000 { <&clkc CLKID_FCLK_DIV2>; clock-names = "core", "clkin0", "clkin1"; resets = <&reset RESET_SD_EMMC_C>; + + assigned-clocks = <&clkc CLKID_SD_EMMC_C_CLK0>; + assigned-clock-rates = <24000000>; }; usb: usb@ffe09000 {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 179/781 arm64: dts: amlogic: g12: assign the MMC A signal clock
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jerome Brunet <[email protected]>
[ Upstream commit 3c941feaa363f1573a501452391ddf513394c84b ]
The amlogic MMC driver operate with the assumption that MMC clock is configured to provide 24MHz. It uses this path for low rates such as 400kHz.
Assign the clock to make sure it is properly configured
--- arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi | 3 +++ 1 file changed, 3 insertions(+)
arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi +3 -0
@@ -2431,6 +2431,9 @@ sd_emmc_a: mmc@ffe03000 { <&clkc CLKID_FCLK_DIV2>; clock-names = "core", "clkin0", "clkin1"; resets = <&reset RESET_SD_EMMC_A>; + + assigned-clocks = <&clkc CLKID_SD_EMMC_A_CLK0>; + assigned-clock-rates = <24000000>; }; sd_emmc_b: mmc@ffe05000 {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 180/781 arm64: dts: qcom: qrb4210-rb2: Fix UART3 wakeup IRQ storm
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Baryshkov <[email protected]>
[ Upstream commit c5dc4812f6bf397b82290c540085e9ec98b47b30 ]
Follow commit 9c92d36b0b1e ("arm64: dts: qcom: qrb2210-rb1: Fix UART3 wakeup IRQ storm") and apply the similar fix to the RB2 platform.
Having RX / TX pins as pull up and wakup interrupt as high-level triggered generates an interrupt storm when trying to suspend the device. Avoid the storm by using the falling edge trigger (as all other platforms do).
--- arch/arm64/boot/dts/qcom/qrb4210-rb2.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/qcom/qrb4210-rb2.dts +1 -1
@@ -694,7 +694,7 @@ sdc2_card_det_n: sd-card-det-n-state { &uart3 { interrupts-extended = <&intc GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH>, - <&tlmm 11 IRQ_TYPE_LEVEL_HIGH>; + <&tlmm 11 IRQ_TYPE_EDGE_FALLING>; pinctrl-0 = <&uart3_default>; pinctrl-1 = <&uart3_sleep>; pinctrl-names = "default", "sleep";
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 181/781 arm64: dts: qcom: sdm845-db845c: drop CS from SPIO0
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Baryshkov <[email protected]>
[ Upstream commit 8bfb696ccdc5bcfad7a45b84c2c8a36757070e19 ]
On SDM845 SPI uses hardware-provided chip select, while specifying cs-gpio makes the driver request GPIO pin, which on DB845c conflicts with the normal host controllers pinctrl entry.
Drop the cs-gpios property to restore SPI functionality.
--- arch/arm64/boot/dts/qcom/sdm845-db845c.dts | 1 - 1 file changed, 1 deletion(-)
arch/arm64/boot/dts/qcom/sdm845-db845c.dts +0 -1
@@ -850,7 +850,6 @@ &spi0 { status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&qup_spi0_default>; - cs-gpios = <&tlmm 3 GPIO_ACTIVE_LOW>; can@0 { compatible = "microchip,mcp2517fd";
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 182/781 arm64: dts: qcom: sdm845-db845c: specify power for WiFi CH1
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Baryshkov <[email protected]>
[ Upstream commit c303e89f7f17c29981d09f8beaaf60937ae8b1f2 ]
Specify power supply for the second chain / antenna output of the onboard WiFi chip.
--- arch/arm64/boot/dts/qcom/sdm845-db845c.dts | 7 +++++++ 1 file changed, 7 insertions(+)
arch/arm64/boot/dts/qcom/sdm845-db845c.dts +7 -0
@@ -379,6 +379,12 @@ vreg_l21a_2p95: ldo21 { regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; }; + vreg_l23a_3p3: ldo23 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3312000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + vreg_l24a_3p075: ldo24 { regulator-min-microvolt = <3088000>; regulator-max-microvolt = <3088000>;
@@ -1155,6 +1161,7 @@ &wifi { vdd-1.8-xo-supply = <&vreg_l7a_1p8>; vdd-1.3-rfa-supply = <&vreg_l17a_1p3>; vdd-3.3-ch0-supply = <&vreg_l25a_3p3>; + vdd-3.3-ch1-supply = <&vreg_l23a_3p3>; qcom,snoc-host-cap-8bit-quirk; qcom,calibration-variant = "Thundercomm_DB845C";
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 183/781 arm64: dts: ti: k3-am67a-kontron-sa67-base: Fix CMA node
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Walle <[email protected]>
[ Upstream commit 11a6a5bb72ce271de24330fd859e83f7bc281609 ]
Fix the size of the CMA node by making it a 64bit size. This was probably a copy&paste mistake. Also drop the unneeded alignment.
--- arch/arm64/boot/dts/ti/k3-am67a-kontron-sa67-base.dts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
arch/arm64/boot/dts/ti/k3-am67a-kontron-sa67-base.dts +1 -2
@@ -85,8 +85,7 @@ reserved_memory: reserved-memory { linux,cma { compatible = "shared-dma-pool"; reusable; - size = <0x10000000>; - alignment = <0x2000>; + size = <0x00 0x10000000>; linux,cma-default; };
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 184/781 arm64: dts: ti: k3-am67a-kontron-sa67-base: Fix SD card regulator
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Walle <[email protected]>
[ Upstream commit 53289af62b66812d07a7b0f5f9d62f429c94d317 ]
The property "enable-active-high" was missing, as the default is active-low. Add it.
--- arch/arm64/boot/dts/ti/k3-am67a-kontron-sa67-base.dts | 1 + 1 file changed, 1 insertion(+)
arch/arm64/boot/dts/ti/k3-am67a-kontron-sa67-base.dts +1 -0
@@ -173,6 +173,7 @@ vcc_3p3_sd_vio_s0: regulator-6 { regulator-max-microvolt = <3300000>; vin-supply = <&vcc_3p3_s0>; regulator-boot-on; + enable-active-high; enable-gpios = <&main_gpio0 7 GPIO_ACTIVE_HIGH>; gpios = <&main_gpio0 8 GPIO_ACTIVE_HIGH>; states = <3300000 0x0>,
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 185/781 arm64: dts: qcom: x1e: bus is 40-bits (fix 64GB models)
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonathan Marek <[email protected]>
[ Upstream commit b38dd256e11a4c8bd5a893e11fc42d493939c907 ]
Unlike the phone SoCs this was copied from, x1e has a 40-bit physical bus. The upper address space is used to support more than 32GB of memory.
This fixes issues when DMA buffers are allocated outside the 36-bit range.
--- arch/arm64/boot/dts/qcom/hamoa.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm64/boot/dts/qcom/hamoa.dtsi +2 -2
@@ -791,8 +791,8 @@ soc: soc@0 { #address-cells = <2>; #size-cells = <2>; - dma-ranges = <0 0 0 0 0x10 0>; - ranges = <0 0 0 0 0x10 0>; + dma-ranges = <0 0 0 0 0x100 0>; + ranges = <0 0 0 0 0x100 0>; gcc: clock-controller@100000 { compatible = "qcom,x1e80100-gcc";
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 186/781 arm64: dts: imx95: Use GPU_CGC as core clock for GPU
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marek Vasut <[email protected]>
[ Upstream commit fc61fdfdc4dd03fa5cea784e1969ed3df049c6c8 ]
The i.MX95 imx-sm introduced new GPU_CGC clock since imx-sm commit ca5e078833fa ("SM-128: Add clock management via CCM LPCG direct control") which are downstream clock of GPU clock. These new GPU_CGC clock gate the existing GPU clock. Currently, without clk_ignore_unused on kernel command line, those new GPU_CGC clock are unused and the kernel will disable them. This has no impact on i.MX95 A0/A1, but does prevent GPU register access from working at all on i.MX95 B0. The GPU_CGC clock are present on both i.MX95 A0/A1/B0, therefore update the DT such, that the GPU core clock are the GPU_CGC clock. When the panthor driver enables the GPU core clock, it enables both the GPU_CGC as well as its parent GPU clock.
--- arch/arm64/boot/dts/freescale/imx95-clock.h | 1 + arch/arm64/boot/dts/freescale/imx95.dtsi | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-)
arch/arm64/boot/dts/freescale/imx95-clock.h +1 -0
@@ -183,5 +183,6 @@#define IMX95_CLK_SEL_A55P (IMX95_CCM_NUM_CLK_SRC + 123 + 7)#define IMX95_CLK_SEL_DRAM (IMX95_CCM_NUM_CLK_SRC + 123 + 8)#define IMX95_CLK_SEL_TEMPSENSE (IMX95_CCM_NUM_CLK_SRC + 123 + 9) +#define IMX95_CLK_GPU_CGC (IMX95_CCM_NUM_CLK_SRC + 123 + 10)#endif /* __CLOCK_IMX95_H */
arch/arm64/boot/dts/freescale/imx95.dtsi +1 -1
@@ -2164,7 +2164,7 @@ netc_emdio: mdio@0,0 { gpu: gpu@4d900000 { compatible = "nxp,imx95-mali", "arm,mali-valhall-csf"; reg = <0 0x4d900000 0 0x480000>; - clocks = <&scmi_clk IMX95_CLK_GPU>, <&scmi_clk IMX95_CLK_GPUAPB>; + clocks = <&scmi_clk IMX95_CLK_GPU_CGC>, <&scmi_clk IMX95_CLK_GPUAPB>; clock-names = "core", "coregroup"; interrupts = <GIC_SPI 289 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 290 IRQ_TYPE_LEVEL_HIGH>,
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 187/781 arm64: dts: qcom: talos: Drop opp-shared from QUP OPP table
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Viken Dadhaniya <[email protected]>
[ Upstream commit dda4bdd325326dd67ae4401f4f3d35b9cf781e3f ]
QUP devices are currently marked with opp-shared in their OPP table, causing the kernel to treat them as part of a shared OPP domain. This leads to the qcom_geni_serial driver failing to probe with error -EBUSY (-16).
Remove the opp-shared property to ensure the OPP framework treats the QUP OPP table as device-specific, allowing the serial driver to probe successfully
--- arch/arm64/boot/dts/qcom/talos.dtsi | 1 - 1 file changed, 1 deletion(-)
arch/arm64/boot/dts/qcom/talos.dtsi +0 -1
@@ -537,7 +537,6 @@ cdsp_smp2p_in: slave-kernel { qup_opp_table: opp-table-qup { compatible = "operating-points-v2"; - opp-shared; opp-75000000 { opp-hz = /bits/ 64 <75000000>;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 188/781 arm64: dts: amlogic: meson-sm1-odroid: Eliminate Odroid HC4 power glitches during boot.
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Neulight <[email protected]>
[ Upstream commit 436418ef5baa024b7b15dd730c36d651c6aaaf47 ]
Fix issue with Odroid HC4 (and all meson-sm1-odroid) DTS that causes regulator power to momentarily glitch OFF-ON during boot. Add regulator-boot-on to all regulator-fixed and regulator-gpio entries that (1) define a gpio AND (2) define regulator-always-on.
U-boot powers on devices necessary for boot then hands off the DTB to the kernel. During probe, linux drivers/regulator/fixed.c and gpio-regulator.c both first set the regulator control gpio (that U-boot already turned ON) to default OFF before then setting it to the defined (ON) state. This glitches the power to the affected devices, unless regulator-boot-on is specified with it. In fact, U-boot has the same behavior. So, during reboot, a power glitch can actually happen twice:
once when U-boot reads the DTB and probes the gpio and again when the kernel reads the DTB and probes the gpio.
Problem this fixes: On the Odroid HC4, power to the SATA ports glitches during boot and causes some HDDs to do emergency head retract, which should be avoided. On the HC4, power glitches to the SD card, USB, SATA, and HDMI interfaces during boot. These are all boot devices. A power glitch can potentially cause a problem for any sensitive devices during boot.
NOTE: This is not limited to just the HC4, likely an issue with ALL DTS with regulator-fixed or regulator-gpio entries that (1) define a gpio AND (2) define regulator-always-on. All such entries should also include regulator-boot-on in order to avoid potential power glitches. At worst, adding regulator-boot-on in such cases is harmless because of regulator-always-on, and, at best, it eliminates detrimental power glitches during boot. So, this is best-practice.
--- arch/arm64/boot/dts/amlogic/meson-sm1-odroid-hc4.dts | 2 ++ arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi | 3 +++ 2 files changed, 5 insertions(+)
arch/arm64/boot/dts/amlogic/meson-sm1-odroid-hc4.dts +2 -0
@@ -52,6 +52,7 @@ p12v_0: regulator-p12v-0 { gpio = <&gpio GPIOH_8 GPIO_OPEN_DRAIN>; enable-active-high; + regulator-boot-on; regulator-always-on; };
@@ -65,6 +66,7 @@ p12v_1: regulator-p12v-1 { gpio = <&gpio GPIOH_8 GPIO_OPEN_DRAIN>; enable-active-high; + regulator-boot-on; regulator-always-on; };
arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi +3 -0
@@ -37,6 +37,7 @@ tflash_vdd: regulator-tflash-vdd { gpio = <&gpio_ao GPIOAO_3 GPIO_OPEN_DRAIN>; enable-active-high; + regulator-boot-on; regulator-always-on; };
@@ -50,6 +51,7 @@ tf_io: gpio-regulator-tf-io { enable-gpios = <&gpio_ao GPIOE_2 GPIO_OPEN_DRAIN>; enable-active-high; + regulator-boot-on; regulator-always-on; gpios = <&gpio_ao GPIOAO_6 GPIO_OPEN_SOURCE>;
@@ -81,6 +83,7 @@ vcc_5v: regulator-vcc-5v { regulator-name = "5V"; regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; + regulator-boot-on; regulator-always-on; vin-supply = <&main_12v>; gpio = <&gpio GPIOH_8 GPIO_OPEN_DRAIN>;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 189/781 arm64: dts: qcom: agatti: Add CX_MEM/DBGC GPU regions
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Konrad Dybcio <[email protected]>
[ Upstream commit 0fdcc948929a6d673bd0f90631dd6e42090c3dbd ]
Describe the GPU register regions, with the former existing but not being used much if at all on this silicon, and the latter containing various debugging levers generally related to dumping the state of the IP upon a crash.
--- arch/arm64/boot/dts/qcom/agatti.dtsi | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
arch/arm64/boot/dts/qcom/agatti.dtsi +6 -2
@@ -1591,8 +1591,12 @@ usb_dwc3_ss: endpoint { gpu: gpu@5900000 { compatible = "qcom,adreno-07000200", "qcom,adreno"; - reg = <0x0 0x05900000 0x0 0x40000>; - reg-names = "kgsl_3d0_reg_memory"; + reg = <0x0 0x05900000 0x0 0x40000>, + <0x0 0x0599e000 0x0 0x1000>, + <0x0 0x05961000 0x0 0x800>; + reg-names = "kgsl_3d0_reg_memory", + "cx_mem", + "cx_dbgc"; interrupts = <GIC_SPI 177 IRQ_TYPE_LEVEL_HIGH>;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 190/781 arm64: dts: qcom: sm6115: Add CX_MEM/DBGC GPU regions
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Konrad Dybcio <[email protected]>
[ Upstream commit 78c13dac18cf0e6f6cbc6ea85d4f967e6cca9562 ]
Describe the GPU register regions, with the former existing but not being used much if at all on this silicon, and the latter containing various debugging levers generally related to dumping the state of the IP upon a crash.
--- arch/arm64/boot/dts/qcom/sm6115.dtsi | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
arch/arm64/boot/dts/qcom/sm6115.dtsi +6 -2
@@ -1715,8 +1715,12 @@ usb_dwc3_ss: endpoint { gpu: gpu@5900000 { compatible = "qcom,adreno-610.0", "qcom,adreno"; - reg = <0x0 0x05900000 0x0 0x40000>; - reg-names = "kgsl_3d0_reg_memory"; + reg = <0x0 0x05900000 0x0 0x40000>, + <0x0 0x0599e000 0x0 0x1000>, + <0x0 0x05961000 0x0 0x800>; + reg-names = "kgsl_3d0_reg_memory", + "cx_mem", + "cx_dbgc"; /* There's no (real) GMU, so we have to handle quite a bunch of clocks! */ clocks = <&gpucc GPU_CC_GX_GFX3D_CLK>,
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 191/781 reset: canaan: k230: drop OF dependency and enable by default
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Junhui Liu <[email protected]>
[ Upstream commit c7a5e01e229d21e0560d78bd645b4f7398667ce4 ]
The driver doesn't use any symbols depending on CONFIG_OF, so drop the dependency. Also, enable it by default when ARCH_CANAAN is selected.
--- drivers/reset/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/reset/Kconfig +1 -1
@@ -161,7 +161,7 @@ config RESET_K210 config RESET_K230 tristate "Reset controller driver for Canaan Kendryte K230 SoC" depends on ARCH_CANAAN || COMPILE_TEST - depends on OF + default ARCH_CANAAN help Support for the Canaan Kendryte K230 RISC-V SoC reset controller. Say Y if you want to control reset signals provided by this
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 192/781 drm/xe/pf: Fix .bulk_profile/sched_priority description
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michal Wajdeczko <[email protected]>
[ Upstream commit 5a062505aa0ed5f9124c22f07da6ba58950475b2 ]
The .bulk_profile/sched_priority file is always write-only, unlike the profile/sched_priority files which can be either read-write or read-only (in case of PF or VFs respectively).
--- Documentation/ABI/testing/sysfs-driver-intel-xe-sriov | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
Documentation/ABI/testing/sysfs-driver-intel-xe-sriov +1 -1
@@ -119,7 +119,7 @@ Description: The GT preemption timeout (PT) in [us] to be applied to all functions. See sriov_admin/{pf,vf<N>}/profile/preempt_timeout_us for more details. - sched_priority: (RW/RO) string + sched_priority: (WO) string The GT scheduling priority to be applied for all functions. See sriov_admin/{pf,vf<N>}/profile/sched_priority for more details.
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 193/781 drm/panthor: Recover from panthor_gpu_flush_caches() failures
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Boris Brezillon <[email protected]>
[ Upstream commit 3c0a60195b37af83bbbaf223cd3a78945bace49e ]
We have seen a few cases where the whole memory subsystem is blocked and flush operations never complete. When that happens, we want to:
- schedule a reset, so we can recover from this situation
- in the reset path, we need to reset the pending_reqs so we can send new commands after the reset
- if more panthor_gpu_flush_caches() operations are queued after the timeout, we skip them and return -EIO directly to avoid needless waits (the memory block won't miraculously work again)
Note that we drop the WARN_ON()s because these hangs can be triggered with buggy GPU jobs created by the UMD, and there's no way we can prevent it. We do keep the error messages though.
v2:
- New patch
v3:
- Collect R-b
- Explicitly mention the fact we dropped the WARN_ON()s in the commit message
v4:
- No changes
--- drivers/gpu/drm/panthor/panthor_gpu.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-)
drivers/gpu/drm/panthor/panthor_gpu.c +12 -7
@@ -289,38 +289,42 @@ int panthor_gpu_l2_power_on(struct panthor_device *ptdev)int panthor_gpu_flush_caches (struct panthor_device *ptdev,u32 l2,u32 lsc,u32 other) { -bool timedout = false;unsigned long flags; +int ret =0 ;/* Serialize cache flush operations. */ guard (mutex)(&ptdev->gpu->cache_flush_lock);spin_lock_irqsave (&ptdev->gpu->reqs_lock, flags); -if (!drm_WARN_ON (&ptdev->base, - ptdev->gpu->pending_reqs &GPU_IRQ_CLEAN_CACHES_COMPLETED )) { +if (!(ptdev->gpu->pending_reqs &GPU_IRQ_CLEAN_CACHES_COMPLETED )) { ptdev->gpu->pending_reqs |=GPU_IRQ_CLEAN_CACHES_COMPLETED ;gpu_write (ptdev,GPU_CMD ,GPU_FLUSH_CACHES (l2, lsc, other)); + }else { + ret = -EIO ; }spin_unlock_irqrestore (&ptdev->gpu->reqs_lock, flags); +if (ret) +return ret; +if (!wait_event_timeout (ptdev->gpu->reqs_acked, !(ptdev->gpu->pending_reqs &GPU_IRQ_CLEAN_CACHES_COMPLETED ),msecs_to_jiffies (100 ))) {spin_lock_irqsave (&ptdev->gpu->reqs_lock, flags);if ((ptdev->gpu->pending_reqs &GPU_IRQ_CLEAN_CACHES_COMPLETED ) !=0 && !(gpu_read (ptdev,GPU_INT_RAWSTAT ) &GPU_IRQ_CLEAN_CACHES_COMPLETED )) - timedout = true; + ret = -ETIMEDOUT ;else ptdev->gpu->pending_reqs &= ~GPU_IRQ_CLEAN_CACHES_COMPLETED ;spin_unlock_irqrestore (&ptdev->gpu->reqs_lock, flags); } -if (timedout) { +if (ret) { +panthor_device_schedule_reset (ptdev);drm_err (&ptdev->base,"Flush caches timeout" ); -return -ETIMEDOUT ; } -return 0 ; +return ret; }/**
@@ -360,6 +364,7 @@ int panthor_gpu_soft_reset(struct panthor_device *ptdev)return -ETIMEDOUT ; } + ptdev->gpu->pending_reqs =0 ;return 0 ; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 194/781 drm/panthor: Fix the full_tick check
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Boris Brezillon <[email protected]>
[ Upstream commit a3c2d0b40b108bd45d44f6c1dfa33c39d577adcd ]
We have a full tick when the remaining time to the next tick is zero, not the other way around. Declare a full_tick variable so we don't get that test wrong in other places.
v2:
- Add R-b
v3:
- Collect R-b
--- drivers/gpu/drm/panthor/panthor_sched.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/gpu/drm/panthor/panthor_sched.c +5 -2
@@ -2483,6 +2483,7 @@ static void tick_work(struct work_struct *work)u64 remaining_jiffies =0 , resched_delay;u64 now =get_jiffies_64 ();int prio, ret, cookie; +bool full_tick;if (!drm_dev_enter (&ptdev->base, &cookie))return ;
@@ -2494,15 +2495,17 @@ static void tick_work(struct work_struct *work)if (time_before64 (now, sched->resched_target)) remaining_jiffies = sched->resched_target - now; + full_tick = remaining_jiffies ==0 ; +mutex_lock (&sched->lock);if (panthor_device_reset_is_pending (sched->ptdev)) goto out_unlock; -tick_ctx_init (sched, &ctx, remaining_jiffies !=0 ); +tick_ctx_init (sched, &ctx, full_tick);if (ctx.csg_upd_failed_mask) goto out_cleanup_ctx; -if (remaining_jiffies) { +if (!full_tick) {/* Scheduling forced in the middle of a tick. Only RT groups * can preempt non-RT ones. Currently running RT groups can't be * preempted.
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 195/781 drm/panthor: Fix the group priority rotation logic
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Boris Brezillon <[email protected]>
[ Upstream commit 55429c51d5db3db24c2ad561944c6a0ca922d476 ]
When rotating group priorities, we want the group with the highest priority to go back to the end of the queue, and all other active groups to get their priority bumped, otherwise some groups will never get a chance to run with the highest priority. This implies moving the rotation itself to tick_work(), and only dealing with old group ordering in tick_ctx_insert_old_group().
v2:
- Add R-b
- Fix the commit message
v3:
- Drop the full_tick argument in tick_ctx_init()
- Collect R-b
--- drivers/gpu/drm/panthor/panthor_sched.c | 52 +++++++++++++++---------- 1 file changed, 31 insertions(+), 21 deletions(-)
drivers/gpu/drm/panthor/panthor_sched.c +31 -21
@@ -2085,31 +2085,22 @@ tick_ctx_pick_groups_from_list(const struct panthor_scheduler *sched,static void tick_ctx_insert_old_group (struct panthor_scheduler *sched,struct panthor_sched_tick_ctx *ctx, -struct panthor_group *group, -bool full_tick) +struct panthor_group *group) {struct panthor_csg_slot *csg_slot = &sched->csg_slots[group->csg_id];struct panthor_group *other_group; -if (!full_tick) { -list_add_tail (&group->run_node, &ctx->old_groups[group->priority]); -return ; - } - -/* Rotate to make sure groups with lower CSG slot -* priorities have a chance to get a higher CSG slot -* priority next time they get picked. This priority -* has an impact on resource request ordering, so it's -* important to make sure we don't let one group starve -* all other groups with the same group priority. -*/ +/* Class groups in descending priority order so we can easily rotate. */ list_for_each_entry (other_group, &ctx->old_groups[csg_slot->group->priority], run_node) {struct panthor_csg_slot *other_csg_slot = &sched->csg_slots[other_group->csg_id]; -if (other_csg_slot->priority > csg_slot->priority) { -list_add_tail (&csg_slot->group->run_node, &other_group->run_node); +/* Our group has a higher prio than the one we're testing against, +* place it just before. +*/ +if (csg_slot->priority > other_csg_slot->priority) { +list_add_tail (&group->run_node, &other_group->run_node);return ; } }
@@ -2119,8 +2110,7 @@ tick_ctx_insert_old_group(struct panthor_scheduler *sched,static void tick_ctx_init (struct panthor_scheduler *sched, -struct panthor_sched_tick_ctx *ctx, -bool full_tick) +struct panthor_sched_tick_ctx *ctx) {struct panthor_device *ptdev = sched->ptdev;struct panthor_csg_slots_upd_ctx upd_ctx;
@@ -2158,7 +2148,7 @@ tick_ctx_init(struct panthor_scheduler *sched, group->fatal_queues |=GENMASK (group->queue_count -1 ,0 ); } -tick_ctx_insert_old_group (sched, ctx, group, full_tick); +tick_ctx_insert_old_group (sched, ctx, group);csgs_upd_ctx_queue_reqs (ptdev, &upd_ctx, i, csg_iface->output->ack ^CSG_STATUS_UPDATE ,CSG_STATUS_UPDATE );
@@ -2501,7 +2491,7 @@ static void tick_work(struct work_struct *work)if (panthor_device_reset_is_pending (sched->ptdev)) goto out_unlock; -tick_ctx_init (sched, &ctx, full_tick); +tick_ctx_init (sched, &ctx);if (ctx.csg_upd_failed_mask) goto out_cleanup_ctx;
@@ -2527,9 +2517,29 @@ static void tick_work(struct work_struct *work)for (prio =PANTHOR_CSG_PRIORITY_COUNT -1 ; prio >=0 && !tick_ctx_is_full (sched, &ctx); prio--) { +struct panthor_group *old_highest_prio_group = +list_first_entry_or_null (&ctx.old_groups[prio], + struct panthor_group, run_node); + +/* Pull out the group with the highest prio for rotation. */ +if (old_highest_prio_group) +list_del (&old_highest_prio_group->run_node); + +/* Re-insert old active groups so they get a chance to run with higher prio. */ +tick_ctx_pick_groups_from_list (sched, &ctx, &ctx.old_groups[prio], true, true); + +/* Fill the remaining slots with runnable groups. */ tick_ctx_pick_groups_from_list (sched, &ctx, &sched->groups.runnable[prio], true, false); -tick_ctx_pick_groups_from_list (sched, &ctx, &ctx.old_groups[prio], true, true); + +/* Re-insert the old group with the highest prio, and give it a chance to be +* scheduled again (but with a lower prio) if there's room left. +*/ +if (old_highest_prio_group) { +list_add_tail (&old_highest_prio_group->run_node, &ctx.old_groups[prio]); +tick_ctx_pick_groups_from_list (sched, &ctx, &ctx.old_groups[prio], + true, true); + } }/* If we have free CSG slots left, pick idle groups */
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 196/781 drm/panthor: Fix immediate ticking on a disabled tick
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Boris Brezillon <[email protected]>
[ Upstream commit 4356d21994f4ff5c87305b874939b359f16f6677 ]
We have a few paths where we schedule the tick work immediately without changing the resched_target. If the tick was stopped, this would lead to a remaining_jiffies that's always > 0, and it wouldn't force a full tick in that case. Add extra checks to cover that case properly.
v2:
- Fix typo
- Simplify the code as suggested by Steve
v3:
- Collect R-b
--- drivers/gpu/drm/panthor/panthor_sched.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
drivers/gpu/drm/panthor/panthor_sched.c +7 -2
@@ -2470,6 +2470,7 @@ static void tick_work(struct work_struct *work) tick_work.work);struct panthor_device *ptdev = sched->ptdev;struct panthor_sched_tick_ctx ctx; +u64 resched_target = sched->resched_target;u64 remaining_jiffies =0 , resched_delay;u64 now =get_jiffies_64 ();int prio, ret, cookie;
@@ -2482,8 +2483,12 @@ static void tick_work(struct work_struct *work)if (drm_WARN_ON (&ptdev->base, ret)) goto out_dev_exit; -if (time_before64 (now, sched->resched_target)) - remaining_jiffies = sched->resched_target - now; +/* If the tick is stopped, calculate when the next tick would be */ +if (resched_target ==U64_MAX ) + resched_target = sched->last_tick + sched->tick_period; + +if (time_before64 (now, resched_target)) + remaining_jiffies = resched_target - now; full_tick = remaining_jiffies ==0 ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 197/781 drm/panthor: Fix the logic that decides when to stop ticking
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Boris Brezillon <[email protected]>
[ Upstream commit 61d9a43d70dc3e1709ecd14a34f6d5f01e21dfc9 ]
When we have multiple active groups with the same priority, we need to keep ticking for the priority rotation to take place. If we don't do that, we might starve slots with lower priorities.
It's annoying to deal with that in tick_ctx_update_resched_target(), so let's add a ::stop_tick field to the tick context which is initialized to true, and downgraded to false as soon as we detect something that requires to tick to happen. This way we can complement the current logic with extra conditions if needed.
v2:
- Add R-b
v3:
- Drop panthor_sched_tick_ctx::min_priority (no longer relevant)
- Collect R-b
--- drivers/gpu/drm/panthor/panthor_sched.c | 44 ++++++++++--------------- 1 file changed, 17 insertions(+), 27 deletions(-)
drivers/gpu/drm/panthor/panthor_sched.c +17 -27
@@ -2020,10 +2020,10 @@ struct panthor_sched_tick_ctx {struct list_head groups[PANTHOR_CSG_PRIORITY_COUNT ];u32 idle_group_count;u32 group_count; -enum panthor_csg_priority min_priority;struct panthor_vm *vms[MAX_CS_PER_CSG ];u32 as_count;bool immediate_tick; +bool stop_tick;u32 csg_upd_failed_mask; };
@@ -2066,17 +2066,21 @@ tick_ctx_pick_groups_from_list(const struct panthor_scheduler *sched,if (!owned_by_tick_ctx)group_get (group); -list_move_tail (&group->run_node, &ctx->groups[group->priority]); ctx->group_count++; + +/* If we have more than one active group with the same priority, +* we need to keep ticking to rotate the CSG priority. +*/ if (group_is_idle (group)) ctx->idle_group_count++; +else if (!list_empty (&ctx->groups[group->priority])) + ctx->stop_tick = false; + +list_move_tail (&group->run_node, &ctx->groups[group->priority]);if (i == ctx->as_count) ctx->vms[ctx->as_count++] = group->vm; -if (ctx->min_priority > group->priority) - ctx->min_priority = group->priority; -if (tick_ctx_is_full (sched, ctx))return ; }
@@ -2120,7 +2124,7 @@ tick_ctx_init(struct panthor_scheduler *sched,memset (ctx,0 ,sizeof (*ctx));csgs_upd_ctx_init (&upd_ctx); - ctx->min_priority =PANTHOR_CSG_PRIORITY_COUNT ; + ctx->stop_tick = true;for (i =0 ; i <ARRAY_SIZE (ctx->groups); i++) {INIT_LIST_HEAD (&ctx->groups[i]);INIT_LIST_HEAD (&ctx->old_groups[i]);
@@ -2432,32 +2436,18 @@ static u64 tick_ctx_update_resched_target(struct panthor_scheduler *sched, const struct panthor_sched_tick_ctx *ctx) { -/* We had space left, no need to reschedule until some external event happens. */ -if (!tick_ctx_is_full (sched, ctx)) - goto no_tick; - -/* If idle groups were scheduled, no need to wake up until some external -* event happens (group unblocked, new job submitted, ...). -*/ -if (ctx->idle_group_count) - goto no_tick; + u64 resched_target; -if (drm_WARN_ON (&sched->ptdev->base, ctx->min_priority >=PANTHOR_CSG_PRIORITY_COUNT )) +if (ctx->stop_tick) goto no_tick; -/* If there are groups of the same priority waiting, we need to -* keep the scheduler ticking, otherwise, we'll just wait for -* new groups with higher priority to be queued. -*/ -if (!list_empty (&sched->groups.runnable[ctx->min_priority])) { -u64 resched_target = sched->last_tick + sched->tick_period; + resched_target = sched->last_tick + sched->tick_period; -if (time_before64 (sched->resched_target, sched->last_tick) || -time_before64 (resched_target, sched->resched_target)) - sched->resched_target = resched_target; +if (time_before64 (sched->resched_target, sched->last_tick) || +time_before64 (resched_target, sched->resched_target)) + sched->resched_target = resched_target; -return sched->resched_target - sched->last_tick; - } +return sched->resched_target - sched->last_tick; no_tick: sched->resched_target =U64_MAX ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 198/781 drm/panthor: Make sure we resume the tick when new jobs are submitted
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Boris Brezillon <[email protected]>
[ Upstream commit 99820b4b7e50d9651f01d2d55b6b9ba92dcc5b99 ]
If the group is already assigned a slot but was idle before this job submission, we need to make sure the priority rotation happens in the future. Extract the existing logic living in group_schedule_locked() and call this new sched_resume_tick() helper from the "group is assigned a slot" path.
v2:
- Add R-b
v3:
- Re-use queue_mask to clear the bit
- Collect R-b
--- drivers/gpu/drm/panthor/panthor_sched.c | 43 +++++++++++++++++++------ 1 file changed, 34 insertions(+), 9 deletions(-)
drivers/gpu/drm/panthor/panthor_sched.c +34 -9
@@ -2659,14 +2659,33 @@ static void sync_upd_work(struct work_struct *work)sched_queue_delayed_work (sched, tick,0 ); } +static void sched_resume_tick (struct panthor_device *ptdev) +{ +struct panthor_scheduler *sched = ptdev->scheduler; +u64 delay_jiffies, now; + +drm_WARN_ON (&ptdev->base, sched->resched_target !=U64_MAX ); + +/* Scheduler tick was off, recalculate the resched_target based on the +* last tick event, and queue the scheduler work. +*/ + now =get_jiffies_64 (); + sched->resched_target = sched->last_tick + sched->tick_period; +if (sched->used_csg_slot_count == sched->csg_slot_count && +time_before64 (now, sched->resched_target)) + delay_jiffies = min_t(unsigned long, sched->resched_target - now, ULONG_MAX); +else + delay_jiffies =0 ; + +sched_queue_delayed_work (sched, tick, delay_jiffies); +} +static void group_schedule_locked (struct panthor_group *group,u32 queue_mask) {struct panthor_device *ptdev = group->ptdev;struct panthor_scheduler *sched = ptdev->scheduler;struct list_head *queue = &sched->groups.runnable[group->priority]; -u64 delay_jiffies =0 ;bool was_idle; -u64 now;if (!group_can_run (group))return ;
@@ -2711,13 +2730,7 @@ static void group_schedule_locked(struct panthor_group *group, u32 queue_mask)/* Scheduler tick was off, recalculate the resched_target based on the * last tick event, and queue the scheduler work. */ - now =get_jiffies_64 (); - sched->resched_target = sched->last_tick + sched->tick_period; -if (sched->used_csg_slot_count == sched->csg_slot_count && -time_before64 (now, sched->resched_target)) - delay_jiffies = min_t(unsigned long, sched->resched_target - now, ULONG_MAX); - -sched_queue_delayed_work (sched, tick, delay_jiffies); +sched_resume_tick (ptdev); } static void queue_stop(struct panthor_queue *queue,
@@ -3351,6 +3364,18 @@ queue_run_job(struct drm_sched_job *sched_job)if (group->csg_id <0 ) {group_schedule_locked (group,BIT (job->queue_idx)); }else { +u32 queue_mask =BIT (job->queue_idx); +bool resume_tick =group_is_idle (group) && + (group->idle_queues & queue_mask) && + !(group->blocked_queues & queue_mask) && + sched->resched_target ==U64_MAX ; + +/* We just added something to the queue, so it's no longer idle. */ + group->idle_queues &= ~queue_mask; + +if (resume_tick) +sched_resume_tick (ptdev); +gpu_write (ptdev,CSF_DOORBELL (queue->doorbell_id),1 );if (!sched->pm.has_ref && !(group->blocked_queues &BIT (job->queue_idx))) {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 199/781 drm/panthor: Remove redundant call to disable the MCU
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Akash Goel <[email protected]>
[ Upstream commit cedf6765ecfd60197d90437ec648feb8b3e31cb1 ]
This commit removes the redundant call to disable the MCU firmware in the suspend path.
--- drivers/gpu/drm/panthor/panthor_fw.c | 1 - 1 file changed, 1 deletion(-)
drivers/gpu/drm/panthor/panthor_fw.c +0 -1
@@ -1187,7 +1187,6 @@ void panthor_fw_pre_reset(struct panthor_device *ptdev, bool on_hang)else ptdev->reset.fast = true; } -panthor_fw_stop (ptdev);panthor_job_irq_suspend (&ptdev->fw->irq);panthor_fw_stop (ptdev);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 200/781 drm/panthor: fix queue_reset_timeout_locked
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chia-I Wu <[email protected]>
[ Upstream commit ac5b392a8c355001c4c3f230a0e4b1f904e359ca ]
queue_check_job_completion calls queue_reset_timeout_locked to reset the timeout when progress is made. We want the reset to happen when the timeout is running, not when it is suspended.
--- drivers/gpu/drm/panthor/panthor_sched.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-)
drivers/gpu/drm/panthor/panthor_sched.c +12 -12
@@ -1072,18 +1072,6 @@ group_is_idle(struct panthor_group *group)return hweight32 (inactive_queues) == group->queue_count; } -static void -queue_reset_timeout_locked (struct panthor_queue *queue) -{ -lockdep_assert_held (&queue->fence_ctx.lock); - -if (queue->timeout.remaining !=MAX_SCHEDULE_TIMEOUT ) { -mod_delayed_work (queue->scheduler.timeout_wq, - &queue->timeout.work, -msecs_to_jiffies (JOB_TIMEOUT_MS )); - } -} -static bool group_can_run (struct panthor_group *group) {
@@ -1100,6 +1088,18 @@ queue_timeout_is_suspended(struct panthor_queue *queue)return queue->timeout.remaining !=MAX_SCHEDULE_TIMEOUT ; } +static void +queue_reset_timeout_locked (struct panthor_queue *queue) +{ +lockdep_assert_held (&queue->fence_ctx.lock); + +if (!queue_timeout_is_suspended (queue)) { +mod_delayed_work (queue->scheduler.timeout_wq, + &queue->timeout.work, +msecs_to_jiffies (JOB_TIMEOUT_MS )); + } +} +static void queue_suspend_timeout_locked (struct panthor_queue *queue) {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 201/781 workqueue: Process rescuer work items one-by-one using a cursor
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lai Jiangshan <[email protected]>
[ Upstream commit e5a30c303b07a4d6083e0f7f051b53add6d93c5d ]
Previously, the rescuer scanned for all matching work items at once and processed them within a single rescuer thread, which could cause one blocking work item to stall all others.
Make the rescuer process work items one-by-one instead of slurping all matches in a single pass.
Break the rescuer loop after finding and processing the first matching work item, then restart the search to pick up the next. This gives normal worker threads a chance to process other items which gives them the opportunity to be processed instead of waiting on the rescuer's queue and prevents a blocking work item from stalling the rest once memory pressure is relieved.
Introduce a dummy cursor work item to avoid potentially O(N^2) rescans of the work list. The marker records the resume position for the next scan, eliminating redundant traversals.
Also introduce RESCUER_BATCH to control the maximum number of work items the rescuer processes in each turn, and move on to other PWQs when the limit is reached.
--- kernel/workqueue.c | 75 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 59 insertions(+), 16 deletions(-)
kernel/workqueue.c +59 -16
@@ -117,6 +117,8 @@ enum wq_internal_consts {MAYDAY_INTERVAL =HZ /10 ,/* and then every 100ms */ CREATE_COOLDOWN =HZ ,/* time to breath after fail */ +RESCUER_BATCH =16 ,/* process items per turn */ +/* * Rescue workers are used only on emergencies and shared by * all cpus. Give MIN_NICE.
@@ -286,6 +288,7 @@ struct pool_workqueue {struct list_head pending_node;/* LN: node on wq_node_nr_active->pending_pwqs */ struct list_head pwqs_node;/* WR: node on wq->pwqs */ struct list_head mayday_node;/* MD: node on wq->maydays */ +struct work_struct mayday_cursor;/* L: cursor on pool->worklist */ u64 stats[PWQ_NR_STATS ];
@@ -1120,6 +1123,12 @@ static struct worker *find_worker_executing_work(struct worker_pool *pool,return NULL ; } +static void mayday_cursor_func (struct work_struct *work) +{ +/* should not be processed, only for marking position */ +BUG (); +} +/** * move_linked_works - move linked works to a list * @work: start of series of works to be scheduled
@@ -1182,6 +1191,16 @@ static bool assign_work(struct work_struct *work, struct worker *worker,lockdep_assert_held (&pool->lock); +/* The cursor work should not be processed */ +if (unlikely (work->func == mayday_cursor_func)) { +/* only worker_thread() can possibly take this branch */ +WARN_ON_ONCE (worker->rescue_wq); +if (nextp) + *nextp =list_next_entry (work, entry); +list_del_init (&work->entry); +return false; + } +/* * A single work shouldn't be executed concurrently by multiple workers. * __queue_work() ensures that @work doesn't jump to a different pool
@@ -3440,22 +3459,30 @@ static int worker_thread(void *__worker)static bool assign_rescuer_work (struct pool_workqueue *pwq,struct worker *rescuer) {struct worker_pool *pool = pwq->pool; +struct work_struct *cursor = &pwq->mayday_cursor;struct work_struct *work, *n;/* need rescue? */ if (!pwq->nr_active || !need_to_create_worker (pool))return false; -/* -* Slurp in all works issued via this workqueue and -* process'em. -*/ -list_for_each_entry_safe (work, n, &pool->worklist, entry) { -if (get_work_pwq (work) == pwq &&assign_work (work, rescuer, &n)) +/* search from the start or cursor if available */ +if (list_empty (&cursor->entry)) + work = list_first_entry(&pool->worklist, struct work_struct, entry); +else + work =list_next_entry (cursor, entry); + +/* find the next work item to rescue */ +list_for_each_entry_safe_from (work, n, &pool->worklist, entry) { +if (get_work_pwq (work) == pwq &&assign_work (work, rescuer, &n)) { pwq->stats[PWQ_STAT_RESCUED ]++; +/* put the cursor for next search */ +list_move_tail (&cursor->entry, &n->entry); +return true; + } } -return !list_empty (&rescuer->scheduled); +return false; }/**
@@ -3512,6 +3539,7 @@ static int rescuer_thread(void *__rescuer)struct pool_workqueue *pwq =list_first_entry (&wq->maydays, struct pool_workqueue, mayday_node);struct worker_pool *pool = pwq->pool; +unsigned int count =0 ;__set_current_state (TASK_RUNNING );list_del_init (&pwq->mayday_node);
@@ -3524,19 +3552,16 @@ static int rescuer_thread(void *__rescuer)WARN_ON_ONCE (!list_empty (&rescuer->scheduled)); -if (assign_rescuer_work (pwq, rescuer)) { +while (assign_rescuer_work (pwq, rescuer)) {process_scheduled_works (rescuer);/* -* The above execution of rescued work items could -* have created more to rescue through -* pwq_activate_first_inactive() or chained -* queueing. Let's put @pwq back on mayday list so -* that such back-to-back work items, which may be -* being used to relieve memory pressure, don't -* incur MAYDAY_INTERVAL delay inbetween. +* If the per-turn work item limit is reached and other +* PWQs are in mayday, requeue mayday for this PWQ and +* let the rescuer handle the other PWQs first. */ -if (pwq->nr_active &&need_to_create_worker (pool)) { +if (++count >RESCUER_BATCH && !list_empty (&pwq->wq->maydays) && + pwq->nr_active &&need_to_create_worker (pool)) {raw_spin_lock (&wq_mayday_lock);/* * Queue iff somebody else hasn't queued it already.
@@ -3546,9 +3571,14 @@ static int rescuer_thread(void *__rescuer)list_add_tail (&pwq->mayday_node, &wq->maydays); }raw_spin_unlock (&wq_mayday_lock); +break ; } } +/* The cursor can not be left behind without the rescuer watching it. */ +if (!list_empty (&pwq->mayday_cursor.entry) &&list_empty (&pwq->mayday_node)) +list_del_init (&pwq->mayday_cursor.entry); +/* * Leave this pool. Notify regular workers; otherwise, we end up * with 0 concurrency and stalling the execution.
@@ -5167,6 +5197,19 @@ static void init_pwq(struct pool_workqueue *pwq, struct workqueue_struct *wq,INIT_LIST_HEAD (&pwq->pwqs_node);INIT_LIST_HEAD (&pwq->mayday_node);kthread_init_work (&pwq->release_work, pwq_release_workfn); + +/* +* Set the dummy cursor work with valid function and get_work_pwq(). +* +* The cursor work should only be in the pwq->pool->worklist, and +* should not be treated as a processable work item. +* +* WORK_STRUCT_PENDING and WORK_STRUCT_INACTIVE just make it less +* surprise for kernel debugging tools and reviewers. +*/ +INIT_WORK (&pwq->mayday_cursor, mayday_cursor_func); +atomic_long_set (&pwq->mayday_cursor.data, (unsigned long )pwq | +WORK_STRUCT_PENDING |WORK_STRUCT_PWQ |WORK_STRUCT_INACTIVE ); }/* sync @pwq with the current state of its associated wq and link it */
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 202/781 drm/amdgpu: dont attach the tlb fence for SI
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
[ Upstream commit 820b3d376e8a102c6aeab737ec6edebbbb710e04 ]
SI hardware doesn't support pasids, user mode queues, or KIQ/MES so there is no need for this. Doing so results in a segfault as these callbacks are non-existent for SI.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +3 -1
@@ -1069,7 +1069,9 @@ amdgpu_vm_tlb_flush(struct amdgpu_vm_update_params *params, }/* Prepare a TLB flush fence to be attached to PTs */ -if (!params->unlocked) { +if (!params->unlocked && +/* SI doesn't support pasid or KIQ/MES */ + params->adev->family >AMDGPU_FAMILY_SI ) {amdgpu_vm_tlb_fence_create (params->adev, vm, fence);/* Makes sure no PD/PT is freed before the flush */
Signature · 1 line
2.51.0
Re: [PATCH 6.19 202/781] drm/amdgpu: dont attach the tlb fence for SI
Quoted 7 lines · Greg Kroah-Hartman
6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
[ Upstream commit
820b3d376e8a102c6aeab737ec6edebbbb710e04]
Bah :/.
It was applied in 6.19 as:
commit eb296c09805ee37dd4ea520a7fb3ec157c31090f
Author: Alex Deucher <[email protected]> Date: Tue Dec 2 14:24:03 2025 -0500
drm/amdgpu: don't attach the tlb fence for SI
...
(cherry picked from commit 820b3d376e8a102c6aeab737ec6edebbbb710e04)
and reverted by:
commit 808c2052f046d730a588f7b92b04a12f64970853
Author: Prike Liang <[email protected]> Date: Fri Jan 9 16:15:11 2026 +0800
Revert "drm/amdgpu: don't attach the tlb fence for SI"
...
(cherry picked from commit 9163fe4d790fb4e16d6b0e23f55b43cddd3d4a65)
still in 6.19 (the cherry picks suggest fixes takes to some 6.19-fixes tree).
Then merged to 7.0 as:
commit 820b3d376e8a102c6aeab737ec6edebbbb710e04
Author: Alex Deucher <[email protected]> Date: Tue Dec 2 14:24:03 2025 -0500
drm/amdgpu: don't attach the tlb fence for SI
and reverted by:
commit 9163fe4d790fb4e16d6b0e23f55b43cddd3d4a65
Author: Prike Liang <[email protected]> Date: Fri Jan 9 16:15:11 2026 +0800
Revert "drm/amdgpu: don't attach the tlb fence for SI"
It should be dropped or the latter revert added too.
Quoted 28 lines
SI hardware doesn't support pasids, user mode queues, or KIQ/MES so there is no need for this. Doing so results in a segfault as these callbacks are non-existent for SI.
Fixes f3854e04b708 ("drm/amdgpu: attach tlb fence to the PTs update")Reviewed-by Timur Kristóf <[email protected]>Signed-off-by Alex Deucher <[email protected]>Signed-off-by Sasha Levin <[email protected]>--- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +3
-1@@ -1069,7 +1069,9 @@ amdgpu_vm_tlb_flush(struct amdgpu_vm_update_params *params, }/* Prepare a TLB flush fence to be attached to PTs */ -if (!params->unlocked) { +if (!params->unlocked && +/* SI doesn't support pasid or KIQ/MES */ + params->adev->family >AMDGPU_FAMILY_SI ) {amdgpu_vm_tlb_fence_create (params->adev, vm, fence);/* Makes sure no PD/PT is freed before the flush */
Signature · 2 lines
js suse labs
Re: [PATCH 6.19 202/781] drm/amdgpu: dont attach the tlb fence for SI
Quoted 47 lines · Jiri Slaby
Quoted 7 lines · Greg Kroah-Hartman
6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
[ Upstream commit
820b3d376e8a102c6aeab737ec6edebbbb710e04]Bah :/.
It was applied in 6.19 as:
commiteb296c09805ee37dd4ea520a7fb3ec157c31090fAuthor: Alex Deucher <[email protected]> Date: Tue Dec 2 14:24:03 2025 -0500drm/amdgpu: don't attach the tlb fence for SI
...(cherry picked from commit 820b3d376e8a102c6aeab737ec6edebbbb710e04)and reverted by:
commit808c2052f046d730a588f7b92b04a12f64970853Author: Prike Liang <[email protected]> Date: Fri Jan 9 16:15:11 2026 +0800Revert "drm/amdgpu: don't attach the tlb fence for SI"
...(cherry picked from commit 9163fe4d790fb4e16d6b0e23f55b43cddd3d4a65)still in 6.19 (the cherry picks suggest fixes takes to some 6.19-fixes tree).
Then merged to 7.0 as:
commit820b3d376e8a102c6aeab737ec6edebbbb710e04Author: Alex Deucher <[email protected]> Date: Tue Dec 2 14:24:03 2025 -0500drm/amdgpu: don't attach the tlb fence for SI
Quoted 8 lines
and reverted by:
commit9163fe4d790fb4e16d6b0e23f55b43cddd3d4a65Author: Prike Liang <[email protected]> Date: Fri Jan 9 16:15:11 2026 +0800Revert "drm/amdgpu: don't attach the tlb fence for SI"
It should be dropped or the latter revert added too.
what a mess. Again, I hate this "cherry-pick forward in time" monster...
I've applied this now, thanks.
greg k-h
Greg Kroah-Hartman
maintainerPATCH 203/781 drm/panthor: Fix panthor_gpu_coherency_set()
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Boris Brezillon <[email protected]>
[ Upstream commit 9beb8dca9e749e9983e70b22e9823e6fcd519f91 ]
GPU_COHERENCY_PROTOCOL takes one of GPU_COHERENCY_xx not BIT(GPU_COHERENCY_xx).
v3:
- New commit
v4:
- Add Steve's R-b
v5:
- No changes
v6:
- No changes
v7:
- No changes
v8:
- No changes
--- drivers/gpu/drm/panthor/panthor_gpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/panthor/panthor_gpu.c +1 -1
@@ -51,7 +51,7 @@ struct panthor_gpu {static void panthor_gpu_coherency_set (struct panthor_device *ptdev) {gpu_write (ptdev,GPU_COHERENCY_PROTOCOL , - ptdev->coherent ?GPU_COHERENCY_PROT_BIT (ACE_LITE ) :GPU_COHERENCY_NONE ); + ptdev->coherent ?GPU_COHERENCY_ACE_LITE :GPU_COHERENCY_NONE ); }static void panthor_gpu_l2_config_set (struct panthor_device *ptdev)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 204/781 accel/amdxdna: Fix race condition when checking rpm_on
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lizhi Hou <[email protected]>
[ Upstream commit 00ffe45ece80160aef446d74ded906352f21dd72 ]
When autosuspend is triggered, driver rpm_on flag is set to indicate that a suspend/resume is already in progress. However, when a userspace application submits a command during this narrow window, amdxdna_pm_resume_get() may incorrectly skip the resume operation because the rpm_on flag is still set. This results in commands being submitted while the device has not actually resumed, causing unexpected behavior.
The set_dpm() is called by suspend/resume, it relied on rpm_on flag to avoid calling into rpm suspend/resume recursivly. So to fix this, remove the use of the rpm_on flag entirely. Instead, introduce aie2_pm_set_dpm() which explicitly resumes the device before invoking set_dpm(). With this change, set_dpm() is called directly inside the suspend or resume execution path. Otherwise, aie2_pm_set_dpm() is called.
--- drivers/accel/amdxdna/aie2_message.c | 1 - drivers/accel/amdxdna/aie2_pci.c | 2 +- drivers/accel/amdxdna/aie2_pci.h | 1 + drivers/accel/amdxdna/aie2_pm.c | 17 +++++++++++++++- drivers/accel/amdxdna/aie2_smu.c | 27 ++++--------------------- drivers/accel/amdxdna/amdxdna_pci_drv.h | 1 - drivers/accel/amdxdna/amdxdna_pm.c | 22 ++------------------ 7 files changed, 24 insertions(+), 47 deletions(-)
drivers/accel/amdxdna/aie2_message.c +0 -1
@@ -39,7 +39,6 @@ static int aie2_send_mgmt_msg_wait(struct amdxdna_dev_hdl *ndev,if (!ndev->mgmt_chann)return -ENODEV ; -drm_WARN_ON (&xdna->ddev, xdna->rpm_on && !mutex_is_locked (&xdna->dev_lock)); ret =xdna_send_msg_wait (xdna, ndev->mgmt_chann, msg);if (ret == -ETIME ) {xdna_mailbox_stop_channel (ndev->mgmt_chann);
drivers/accel/amdxdna/aie2_pci.c +1 -1
@@ -322,7 +322,7 @@ static int aie2_xrs_set_dft_dpm_level(struct drm_device *ddev, u32 dpm_level)if (ndev->pw_mode !=POWER_MODE_DEFAULT || ndev->dpm_level == dpm_level)return 0 ; -return ndev->priv->hw_ops.set_dpm (ndev, dpm_level); +return aie2_pm_set_dpm (ndev, dpm_level); }static struct xrs_action_ops aie2_xrs_actions = {
drivers/accel/amdxdna/aie2_pci.h +1 -0
@@ -285,6 +285,7 @@ int npu4_set_dpm(struct amdxdna_dev_hdl *ndev, u32 dpm_level);/* aie2_pm.c */ int aie2_pm_init (struct amdxdna_dev_hdl *ndev);int aie2_pm_set_mode (struct amdxdna_dev_hdl *ndev,enum amdxdna_power_mode_type target); +int aie2_pm_set_dpm (struct amdxdna_dev_hdl *ndev,u32 dpm_level);/* aie2_psp.c */ struct psp_device *aie2m_psp_create (struct drm_device *ddev,struct psp_config *conf);
drivers/accel/amdxdna/aie2_pm.c +16 -1
@@ -10,6 +10,7 @@#include "aie2_pci.h" #include "amdxdna_pci_drv.h" +#include "amdxdna_pm.h" #define AIE2_CLK_GATING_ENABLE 1#define AIE2_CLK_GATING_DISABLE 0
@@ -26,6 +27,20 @@ static int aie2_pm_set_clk_gating(struct amdxdna_dev_hdl *ndev, u32 val)return 0 ; } +int aie2_pm_set_dpm (struct amdxdna_dev_hdl *ndev,u32 dpm_level) +{ +int ret; + + ret =amdxdna_pm_resume_get (ndev->xdna); +if (ret) +return ret; + + ret = ndev->priv->hw_ops.set_dpm (ndev, dpm_level); +amdxdna_pm_suspend_put (ndev->xdna); + +return ret; +} +int aie2_pm_init (struct amdxdna_dev_hdl *ndev) {int ret;
@@ -94,7 +109,7 @@ int aie2_pm_set_mode(struct amdxdna_dev_hdl *ndev, enum amdxdna_power_mode_typereturn -EOPNOTSUPP ; } - ret = ndev->priv->hw_ops.set_dpm (ndev, dpm_level); + ret =aie2_pm_set_dpm (ndev, dpm_level);if (ret)return ret;
drivers/accel/amdxdna/aie2_smu.c +4 -23
@@ -11,7 +11,6 @@#include "aie2_pci.h" #include "amdxdna_pci_drv.h" -#include "amdxdna_pm.h" #define SMU_RESULT_OK 1
@@ -67,16 +66,12 @@ int npu1_set_dpm(struct amdxdna_dev_hdl *ndev, u32 dpm_level)u32 freq;int ret; - ret =amdxdna_pm_resume_get (ndev->xdna); -if (ret) -return ret; - ret =aie2_smu_exec (ndev,AIE2_SMU_SET_MPNPUCLK_FREQ , ndev->priv->dpm_clk_tbl[dpm_level].npuclk, &freq);if (ret) {XDNA_ERR (ndev->xdna,"Set npu clock to %d failed, ret %d\n" , ndev->priv->dpm_clk_tbl[dpm_level].npuclk, ret); - goto suspend_put; +return ret; } ndev->npuclk_freq = freq;
@@ -85,10 +80,9 @@ int npu1_set_dpm(struct amdxdna_dev_hdl *ndev, u32 dpm_level)if (ret) {XDNA_ERR (ndev->xdna,"Set h clock to %d failed, ret %d\n" , ndev->priv->dpm_clk_tbl[dpm_level].hclk, ret); - goto suspend_put; +return ret; } -amdxdna_pm_suspend_put (ndev->xdna); ndev->hclk_freq = freq; ndev->dpm_level = dpm_level; ndev->max_tops =2 * ndev->total_col;
@@ -98,35 +92,26 @@ int npu1_set_dpm(struct amdxdna_dev_hdl *ndev, u32 dpm_level) ndev->npuclk_freq, ndev->hclk_freq);return 0 ; - -suspend_put: -amdxdna_pm_suspend_put (ndev->xdna); -return ret; }int npu4_set_dpm (struct amdxdna_dev_hdl *ndev,u32 dpm_level) {int ret; - ret =amdxdna_pm_resume_get (ndev->xdna); -if (ret) -return ret; - ret =aie2_smu_exec (ndev,AIE2_SMU_SET_HARD_DPMLEVEL , dpm_level,NULL );if (ret) {XDNA_ERR (ndev->xdna,"Set hard dpm level %d failed, ret %d " , dpm_level, ret); - goto suspend_put; +return ret; } ret =aie2_smu_exec (ndev,AIE2_SMU_SET_SOFT_DPMLEVEL , dpm_level,NULL );if (ret) {XDNA_ERR (ndev->xdna,"Set soft dpm level %d failed, ret %d" , dpm_level, ret); - goto suspend_put; +return ret; } -amdxdna_pm_suspend_put (ndev->xdna); ndev->npuclk_freq = ndev->priv->dpm_clk_tbl[dpm_level].npuclk; ndev->hclk_freq = ndev->priv->dpm_clk_tbl[dpm_level].hclk; ndev->dpm_level = dpm_level;
@@ -137,10 +122,6 @@ int npu4_set_dpm(struct amdxdna_dev_hdl *ndev, u32 dpm_level) ndev->npuclk_freq, ndev->hclk_freq);return 0 ; - -suspend_put: -amdxdna_pm_suspend_put (ndev->xdna); -return ret; }int aie2_smu_init (struct amdxdna_dev_hdl *ndev)
drivers/accel/amdxdna/amdxdna_pci_drv.h +0 -1
@@ -101,7 +101,6 @@ struct amdxdna_dev {struct amdxdna_fw_ver fw_ver;struct rw_semaphore notifier_lock;/* for mmu notifier*/ struct workqueue_struct *notifier_wq; -bool rpm_on; };/*
drivers/accel/amdxdna/amdxdna_pm.c +2 -20
@@ -15,14 +15,9 @@ int amdxdna_pm_suspend(struct device *dev) {struct amdxdna_dev *xdna =to_xdna_dev (dev_get_drvdata (dev));int ret = -EOPNOTSUPP ; -bool rpm; -if (xdna->dev_info->ops->suspend) { - rpm = xdna->rpm_on; - xdna->rpm_on = false; +if (xdna->dev_info->ops->suspend) ret = xdna->dev_info->ops->suspend (xdna); - xdna->rpm_on = rpm; - }XDNA_DBG (xdna,"Suspend done ret %d" , ret);return ret;
@@ -32,14 +27,9 @@ int amdxdna_pm_resume(struct device *dev) {struct amdxdna_dev *xdna =to_xdna_dev (dev_get_drvdata (dev));int ret = -EOPNOTSUPP ; -bool rpm; -if (xdna->dev_info->ops->resume) { - rpm = xdna->rpm_on; - xdna->rpm_on = false; +if (xdna->dev_info->ops->resume) ret = xdna->dev_info->ops->resume (xdna); - xdna->rpm_on = rpm; - }XDNA_DBG (xdna,"Resume done ret %d" , ret);return ret;
@@ -50,9 +40,6 @@ int amdxdna_pm_resume_get(struct amdxdna_dev *xdna)struct device *dev = xdna->ddev.dev;int ret; -if (!xdna->rpm_on) -return 0 ; - ret =pm_runtime_resume_and_get (dev);if (ret) {XDNA_ERR (xdna,"Resume failed: %d" , ret);
@@ -66,9 +53,6 @@ void amdxdna_pm_suspend_put(struct amdxdna_dev *xdna) {struct device *dev = xdna->ddev.dev; -if (!xdna->rpm_on) -return ; -pm_runtime_put_autosuspend (dev); }
@@ -81,14 +65,12 @@ void amdxdna_pm_init(struct amdxdna_dev *xdna)pm_runtime_use_autosuspend (dev);pm_runtime_allow (dev);pm_runtime_put_autosuspend (dev); - xdna->rpm_on = true; }void amdxdna_pm_fini (struct amdxdna_dev *xdna) {struct device *dev = xdna->ddev.dev; - xdna->rpm_on = false;pm_runtime_get_noresume (dev);pm_runtime_forbid (dev); }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 205/781 accel/amdxdna: Fix cu_idx being cleared by memset() during command setup
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lizhi Hou <[email protected]>
[ Upstream commit 3d32eb7a5ecff92d83a5fd34c45c171c17d3d5d0 ]
For one command type, cu_idx is assigned before calling memset() on the command structure. This results in cu_idx being overwritten, causing the firmware to receive an incomplete or invalid command and leading to unexpected command failures.
Fix this by moving the memset() call before initializing cu_idx so that all fields are populated in the correct order.
--- drivers/accel/amdxdna/aie2_message.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/accel/amdxdna/aie2_message.c +4 -4
@@ -645,6 +645,7 @@ aie2_cmdlist_fill_npu_cf(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *sizu32 cmd_len;void *cmd; +memset (npu_slot,0 ,sizeof (*npu_slot)); cmd =amdxdna_cmd_get_payload (cmd_bo, &cmd_len);if (*size <sizeof (*npu_slot) + cmd_len)return -EINVAL ;
@@ -653,7 +654,6 @@ aie2_cmdlist_fill_npu_cf(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *sizif (npu_slot->cu_idx ==INVALID_CU_IDX )return -EINVAL ; -memset (npu_slot,0 ,sizeof (*npu_slot)); npu_slot->type =EXEC_NPU_TYPE_NON_ELF ; npu_slot->arg_cnt = cmd_len /sizeof (u32);memcpy (npu_slot->args, cmd, cmd_len);
@@ -670,6 +670,7 @@ aie2_cmdlist_fill_npu_dpu(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *siu32 cmd_len;u32 arg_sz; +memset (npu_slot,0 ,sizeof (*npu_slot)); sn =amdxdna_cmd_get_payload (cmd_bo, &cmd_len); arg_sz = cmd_len -sizeof (*sn);if (cmd_len <sizeof (*sn) || arg_sz >MAX_NPU_ARGS_SIZE )
@@ -682,7 +683,6 @@ aie2_cmdlist_fill_npu_dpu(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *siif (npu_slot->cu_idx ==INVALID_CU_IDX )return -EINVAL ; -memset (npu_slot,0 ,sizeof (*npu_slot)); npu_slot->type =EXEC_NPU_TYPE_PARTIAL_ELF ; npu_slot->inst_buf_addr = sn->buffer; npu_slot->inst_size = sn->buffer_size;
@@ -702,6 +702,7 @@ aie2_cmdlist_fill_npu_preempt(struct amdxdna_gem_obj *cmd_bo, void *slot, size_tu32 cmd_len;u32 arg_sz; +memset (npu_slot,0 ,sizeof (*npu_slot)); pd =amdxdna_cmd_get_payload (cmd_bo, &cmd_len); arg_sz = cmd_len -sizeof (*pd);if (cmd_len <sizeof (*pd) || arg_sz >MAX_NPU_ARGS_SIZE )
@@ -714,7 +715,6 @@ aie2_cmdlist_fill_npu_preempt(struct amdxdna_gem_obj *cmd_bo, void *slot, size_tif (npu_slot->cu_idx ==INVALID_CU_IDX )return -EINVAL ; -memset (npu_slot,0 ,sizeof (*npu_slot)); npu_slot->type =EXEC_NPU_TYPE_PREEMPT ; npu_slot->inst_buf_addr = pd->inst_buf; npu_slot->save_buf_addr = pd->save_buf;
@@ -738,6 +738,7 @@ aie2_cmdlist_fill_npu_elf(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *siu32 cmd_len;u32 arg_sz; +memset (npu_slot,0 ,sizeof (*npu_slot)); pd =amdxdna_cmd_get_payload (cmd_bo, &cmd_len); arg_sz = cmd_len -sizeof (*pd);if (cmd_len <sizeof (*pd) || arg_sz >MAX_NPU_ARGS_SIZE )
@@ -746,7 +747,6 @@ aie2_cmdlist_fill_npu_elf(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *siif (*size <sizeof (*npu_slot) + arg_sz)return -EINVAL ; -memset (npu_slot,0 ,sizeof (*npu_slot)); npu_slot->type =EXEC_NPU_TYPE_ELF ; npu_slot->inst_buf_addr = pd->inst_buf; npu_slot->save_buf_addr = pd->save_buf;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 206/781 drm/plane: Fix IS_ERR() vs NULL bug drm_plane_create_color_pipeline_property()
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
[ Upstream commit 470cb09a2936d3c1ff8aeff46e3c14dcc4314e9b ]
The drm_property_create_enum() function returns NULL on error, it never returns error pointers. Fix the error checking to match.
--- drivers/gpu/drm/drm_plane.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/drm_plane.c +2 -2
@@ -1867,9 +1867,9 @@ int drm_plane_create_color_pipeline_property(struct drm_plane *plane, prop =drm_property_create_enum (plane->dev,DRM_MODE_PROP_ATOMIC ,"COLOR_PIPELINE" , all_pipelines, len); -if (IS_ERR (prop)) { +if (!prop) {kfree (all_pipelines); -return PTR_ERR (prop); +return -ENOMEM ; }drm_object_attach_property (&plane->base, prop,0 );
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 207/781 accel/amdxdna: Fix race where send ring appears full due to delayed head update
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lizhi Hou <[email protected]>
[ Upstream commit 343f5683cfa443000904c88ce2e23656375fc51c ]
The firmware sends a response and interrupts the driver before advancing the mailbox send ring head pointer. As a result, the driver may observe the response and attempt to send a new request before the firmware has updated the head pointer. In this window, the send ring still appears full, causing the driver to incorrectly fail the send operation.
This race can be triggered more easily in a multithreaded environment, leading to unexpected and spurious "send ring full" failures.
To address this, poll the send ring head pointer for up to 100us before returning a full-ring condition. This allows the firmware time to update the head pointer.
--- drivers/accel/amdxdna/amdxdna_mailbox.c | 27 +++++++++++++++---------- 1 file changed, 16 insertions(+), 11 deletions(-)
drivers/accel/amdxdna/amdxdna_mailbox.c +16 -11
@@ -207,26 +207,34 @@ mailbox_send_msg(struct mailbox_channel *mb_chann, struct mailbox_msg *mb_msg)u32 head, tail;u32 start_addr;u32 tmp_tail; +int ret; head =mailbox_get_headptr (mb_chann,CHAN_RES_X2I ); tail = mb_chann->x2i_tail; - ringbuf_size =mailbox_get_ringbuf_size (mb_chann,CHAN_RES_X2I ); + ringbuf_size =mailbox_get_ringbuf_size (mb_chann,CHAN_RES_X2I ) -sizeof (u32); start_addr = mb_chann->res[CHAN_RES_X2I ].rb_start_addr; tmp_tail = tail + mb_msg->pkg_size; -if (tail < head && tmp_tail >= head) - goto no_space; - -if (tail >= head && (tmp_tail > ringbuf_size -sizeof (u32) && - mb_msg->pkg_size >= head)) - goto no_space; -if (tail >= head && tmp_tail > ringbuf_size -sizeof (u32)) { +check_again: +if (tail >= head && tmp_tail > ringbuf_size) { write_addr = mb_chann->mb->res.ringbuf_base + start_addr + tail;writel (TOMBSTONE , write_addr);/* tombstone is set. Write from the start of the ringbuf */ tail =0 ; + tmp_tail = tail + mb_msg->pkg_size; + } + +if (tail < head && tmp_tail >= head) { + ret =read_poll_timeout (mailbox_get_headptr, head, + tmp_tail < head || tail >= head, +1 ,100 , false, mb_chann,CHAN_RES_X2I ); +if (ret) +return ret; + +if (tail >= head) + goto check_again; } write_addr = mb_chann->mb->res.ringbuf_base + start_addr + tail;
@@ -238,9 +246,6 @@ mailbox_send_msg(struct mailbox_channel *mb_chann, struct mailbox_msg *mb_msg) mb_msg->pkg.header.id);return 0 ; - -no_space: -return -ENOSPC ; } static int
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 208/781 firmware: cs_dsp: Remove __free() from cs_dsp_debugfs_string_read()
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Richard Fitzgerald <[email protected]>
[ Upstream commit 7a9fa7fda93b7b3ae515f40f67bbf8e1d16337e8 ]
Don't use __free(kfree) in cs_dsp_debugfs_string_read. Instead use normal kfree() to cleanup.
The use of __free() can create new cleanup bugs that are difficult to spot because the defective code is idiomatically correct regular C. This function used the suspect declaration __free(kfree) = NULL;.
The __free(kfree) didn't really do anything here. The function can be rearranged to avoid any need to return or goto within the code.
--- drivers/firmware/cirrus/cs_dsp.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-)
drivers/firmware/cirrus/cs_dsp.c +14 -9
@@ -412,18 +412,23 @@ static ssize_t cs_dsp_debugfs_string_read(struct cs_dsp *dsp, size_t count, loff_t *ppos, const char **pstr) { - const char *str __free(kfree) = NULL; + const char *str; +ssize_t ret =0 ; scoped_guard(mutex, &dsp->pwr_lock) { -if (!*pstr) -return 0 ; - - str =kasprintf (GFP_KERNEL ,"%s\n" , *pstr); -if (!str) -return -ENOMEM ; - -return simple_read_from_buffer (user_buf, count, ppos, str,strlen (str)); +if (*pstr) { + str =kasprintf (GFP_KERNEL ,"%s\n" , *pstr); +if (str) { + ret =simple_read_from_buffer (user_buf, count, + ppos, str,strlen (str)); +kfree (str); + }else { + ret = -ENOMEM ; + } + } } + +return ret; } static ssize_t cs_dsp_debugfs_wmfw_read(struct file *file,
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 209/781 firmware: cs_dsp: Dont use __free() in cs_dsp_load() and cs_dsp_load_coeff()
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Richard Fitzgerald <[email protected]>
[ Upstream commit ae9ccaed3f6701ee0fe40ad919516e0aa0844f21 ]
Replace the __free(kfree) in cs_dsp_load() and cs_dsp_load_coeff() with a kfree(buf) at the end of the function.
The use of __free() can create new cleanup bugs that are difficult to spot because the defective code is idiomatically correct regular C. In these two functions the __free() was mixed with gotos, and also used the suspect declaration __free(kfree) = NULL;.
The __free() did not do anything to simplify the code. There aren't any early returns after the pointer is set, and the __free() can be replaced by a kfree() at the end of the function.
--- drivers/firmware/cirrus/cs_dsp.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/firmware/cirrus/cs_dsp.c +6 -2
@@ -1488,7 +1488,7 @@ static int cs_dsp_load(struct cs_dsp *dsp, const struct firmware *firmware,const struct wmfw_region *region;const struct cs_dsp_region *mem;const char *region_name; - u8 *buf __free(kfree) = NULL; +u8 *buf =NULL ;size_t buf_len =0 ;size_t region_len;unsigned int reg;
@@ -1643,6 +1643,8 @@ static int cs_dsp_load(struct cs_dsp *dsp, const struct firmware *firmware, ret =0 ; out_fw: +kfree (buf); +if (ret == -EOVERFLOW )cs_dsp_err (dsp,"%s: file content overflows file data\n" , file);
@@ -2174,7 +2176,7 @@ static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmwarestruct cs_dsp_alg_region *alg_region;const char *region_name;int ret, pos, blocks, type, offset, reg, version; - u8 *buf __free(kfree) = NULL; +u8 *buf =NULL ;size_t buf_len =0 ;size_t region_len;
@@ -2353,6 +2355,8 @@ static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware ret =0 ; out_fw: +kfree (buf); +if (ret == -EOVERFLOW )cs_dsp_err (dsp,"%s: file content overflows file data\n" , file);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 210/781 spi: cadence-qspi: Remove redundant pm_runtime_mark_last_busy call
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Akif Ejaz <[email protected]>
[ Upstream commit 28d21dfcea0121afec04451733a6c553fd319c8e ]
The pm_runtime_mark_last_busy() call is redundant in probe function as pm_runtime_put_autosuspend() already calls pm_runtime_mark_last_busy() internally to update the last access time of the device before queuing autosuspend.
Remove the pm_runtime_mark_last_busy() call from the probe function.
Tested on StarFive VisionFive 2 v1.2A board.
--- drivers/spi/spi-cadence-quadspi.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
drivers/spi/spi-cadence-quadspi.c +1 -3
@@ -2012,10 +2012,8 @@ static int cqspi_probe(struct platform_device *pdev) goto probe_setup_failed; } -if (!(ddata && (ddata->quirks &CQSPI_DISABLE_RUNTIME_PM ))) { -pm_runtime_mark_last_busy (dev); +if (!(ddata && (ddata->quirks &CQSPI_DISABLE_RUNTIME_PM )))pm_runtime_put_autosuspend (dev); - }return 0 ; probe_setup_failed:
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 211/781 accel/amdxdna: Fix potential NULL pointer dereference in context cleanup
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lizhi Hou <[email protected]>
[ Upstream commit 97f27573837ef96b4ba42af463cc800cab615c0e ]
aie_destroy_context() is invoked during error handling in aie2_create_context(). However, aie_destroy_context() assumes that the context's mailbox channel pointer is non-NULL. If mailbox channel creation fails, the pointer remains NULL and calling aie_destroy_context() can lead to a NULL pointer dereference.
In aie2_create_context(), replace aie_destroy_context() with a function which request firmware to remove the context created previously.
--- drivers/accel/amdxdna/aie2_message.c | 50 +++++++++++++++------------- 1 file changed, 26 insertions(+), 24 deletions(-)
drivers/accel/amdxdna/aie2_message.c +26 -24
@@ -185,6 +185,19 @@ int aie2_query_firmware_version(struct amdxdna_dev_hdl *ndev,return 0 ; } +static int aie2_destroy_context_req (struct amdxdna_dev_hdl *ndev,u32 id) +{ +DECLARE_AIE2_MSG (destroy_ctx,MSG_OP_DESTROY_CONTEXT ); +struct amdxdna_dev *xdna = ndev->xdna; +int ret; + + req.context_id = id; + ret =aie2_send_mgmt_msg_wait (ndev, &msg); +if (ret) +XDNA_WARN (xdna,"Destroy context failed, ret %d" , ret); + +return ret; +}int aie2_create_context (struct amdxdna_dev_hdl *ndev,struct amdxdna_hwctx *hwctx) {DECLARE_AIE2_MSG (create_ctx,MSG_OP_CREATE_CONTEXT );
@@ -207,13 +220,14 @@ int aie2_create_context(struct amdxdna_dev_hdl *ndev, struct amdxdna_hwctx *hwctreturn ret; hwctx->fw_ctx_id = resp.context_id; -WARN_ONCE (hwctx->fw_ctx_id ==-1 ,"Unexpected context id" ); +if (WARN_ON_ONCE (hwctx->fw_ctx_id ==-1 )) +return -EINVAL ;if (ndev->force_preempt_enabled) { ret =aie2_runtime_cfg (ndev,AIE2_RT_CFG_FORCE_PREEMPT , &hwctx->fw_ctx_id);if (ret) {XDNA_ERR (xdna,"failed to enable force preempt %d" , ret); -return ret; + goto del_ctx_req; } }
@@ -230,51 +244,39 @@ int aie2_create_context(struct amdxdna_dev_hdl *ndev, struct amdxdna_hwctx *hwct ret =pci_irq_vector (to_pci_dev (xdna->ddev.dev), resp.msix_id);if (ret == -EINVAL ) { -XDNA_ERR (xdna,"not able to create channel" ); - goto out_destroy_context; +XDNA_ERR (xdna,"Alloc IRQ failed %d" , ret); + goto del_ctx_req; } intr_reg = i2x.mb_head_ptr_reg +4 ; hwctx->priv->mbox_chann =xdna_mailbox_create_channel (ndev->mbox, &x2i, &i2x, intr_reg, ret);if (!hwctx->priv->mbox_chann) { -XDNA_ERR (xdna,"not able to create channel" ); +XDNA_ERR (xdna,"Not able to create channel" ); ret = -EINVAL ; - goto out_destroy_context; + goto del_ctx_req; } ndev->hwctx_num++; -XDNA_DBG (xdna,"%s mailbox channel irq: %d, msix_id: %d" , - hwctx->name, ret, resp.msix_id); -XDNA_DBG (xdna,"%s created fw ctx %d pasid %d" , hwctx->name, - hwctx->fw_ctx_id, hwctx->client->pasid); +XDNA_DBG (xdna,"Mailbox channel irq: %d, msix_id: %d" , ret, resp.msix_id); +XDNA_DBG (xdna,"Created fw ctx %d pasid %d" , hwctx->fw_ctx_id, hwctx->client->pasid);return 0 ; -out_destroy_context: -aie2_destroy_context (ndev, hwctx); +del_ctx_req: +aie2_destroy_context_req (ndev, hwctx->fw_ctx_id);return ret; }int aie2_destroy_context (struct amdxdna_dev_hdl *ndev,struct amdxdna_hwctx *hwctx) { -DECLARE_AIE2_MSG (destroy_ctx,MSG_OP_DESTROY_CONTEXT );struct amdxdna_dev *xdna = ndev->xdna;int ret; -if (hwctx->fw_ctx_id ==-1 ) -return 0 ; -xdna_mailbox_stop_channel (hwctx->priv->mbox_chann); - - req.context_id = hwctx->fw_ctx_id; - ret =aie2_send_mgmt_msg_wait (ndev, &msg); -if (ret) -XDNA_WARN (xdna,"%s destroy context failed, ret %d" , hwctx->name, ret); - + ret =aie2_destroy_context_req (ndev, hwctx->fw_ctx_id);xdna_mailbox_destroy_channel (hwctx->priv->mbox_chann); -XDNA_DBG (xdna,"%s destroyed fw ctx %d" , hwctx->name, - hwctx->fw_ctx_id); +XDNA_DBG (xdna,"Destroyed fw ctx %d" , hwctx->fw_ctx_id); hwctx->priv->mbox_chann =NULL ; hwctx->fw_ctx_id =-1 ; ndev->hwctx_num--;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 212/781 drm/panel: sw43408: Remove manual invocation of unprepare at remove
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Heidelberg <[email protected]>
[ Upstream commit cbc1e99a9e0a6c8b22ddcbb40ca37457066f9493 ]
The drm_panel_remove should take care of disable/unprepare. Remove the manual call from the sw43408_remove function.
--- drivers/gpu/drm/panel/panel-lg-sw43408.c | 4 ---- 1 file changed, 4 deletions(-)
drivers/gpu/drm/panel/panel-lg-sw43408.c +0 -4
@@ -294,10 +294,6 @@ static void sw43408_remove(struct mipi_dsi_device *dsi)struct sw43408_panel *ctx =mipi_dsi_get_drvdata (dsi);int ret; - ret =sw43408_unprepare (&ctx->base); -if (ret <0 ) -dev_err (&dsi->dev,"failed to unprepare panel: %d\n" , ret); - ret =mipi_dsi_detach (dsi);if (ret <0 )dev_err (&dsi->dev,"failed to detach from DSI host: %d\n" , ret);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 213/781 ALSA: compress_offload: Relax __free() variable declarations
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
[ Upstream commit 14324b8f0760ca6f56202bb4ad356ec459ce165b ]
We used to have a variable declaration with __free() initialized with NULL. This was to keep the old coding style rule, but recently it's relaxed and rather recommends to follow the new rule to declare in place of use for __free() -- which avoids potential deadlocks or UAFs with nested cleanups.
Although the current code has no bug, per se, let's follow the new standard and move the declaration to the place of assignment.
--- sound/core/compress_offload.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-)
sound/core/compress_offload.c +16 -12
@@ -514,12 +514,12 @@ static int snd_compr_get_codec_caps(struct snd_compr_stream *stream, unsigned long arg) { int retval; - struct snd_compr_codec_caps *caps __free(kfree) = NULL;if (!stream->ops->get_codec_caps)return -ENXIO ; - caps =kzalloc (sizeof (*caps),GFP_KERNEL ); + struct snd_compr_codec_caps *caps __free(kfree) = +kzalloc (sizeof (*caps),GFP_KERNEL );if (!caps)return -ENOMEM ;
@@ -647,7 +647,6 @@ snd_compress_check_input(struct snd_compr_stream *stream, struct snd_compr_paramstatic int snd_compr_set_params (struct snd_compr_stream *stream,unsigned long arg) { - struct snd_compr_params *params __free(kfree) = NULL;int retval;if (stream->runtime->state ==SNDRV_PCM_STATE_OPEN || stream->next_track) {
@@ -655,7 +654,9 @@ snd_compr_set_params(struct snd_compr_stream *stream, unsigned long arg)* we should allow parameter change only when stream has been * opened not in other cases */ - params =memdup_user ((void __user *)arg,sizeof (*params)); + struct snd_compr_params *params __free(kfree) = +memdup_user ((void __user *)arg,sizeof (*params)); +if (IS_ERR (params))return PTR_ERR (params);
@@ -687,13 +688,13 @@ snd_compr_set_params(struct snd_compr_stream *stream, unsigned long arg)static int snd_compr_get_params (struct snd_compr_stream *stream,unsigned long arg) { - struct snd_codec *params __free(kfree) = NULL;int retval;if (!stream->ops->get_params)return -EBADFD ; - params =kzalloc (sizeof (*params),GFP_KERNEL ); + struct snd_codec *params __free(kfree) = +kzalloc (sizeof (*params),GFP_KERNEL );if (!params)return -ENOMEM ; retval = stream->ops->get_params (stream, params);
@@ -1104,12 +1105,13 @@ static int snd_compr_task_new(struct snd_compr_stream *stream, struct snd_compr_static int snd_compr_task_create (struct snd_compr_stream *stream,unsigned long arg) { - struct snd_compr_task *task __free(kfree) = NULL;int retval;if (stream->runtime->state !=SNDRV_PCM_STATE_SETUP )return -EPERM ; - task =memdup_user ((void __user *)arg,sizeof (*task)); + + struct snd_compr_task *task __free(kfree) = +memdup_user ((void __user *)arg,sizeof (*task));if (IS_ERR (task))return PTR_ERR (task); retval =snd_compr_task_new (stream, task);
@@ -1165,12 +1167,13 @@ static int snd_compr_task_start(struct snd_compr_stream *stream, struct snd_compstatic int snd_compr_task_start_ioctl (struct snd_compr_stream *stream,unsigned long arg) { - struct snd_compr_task *task __free(kfree) = NULL;int retval;if (stream->runtime->state !=SNDRV_PCM_STATE_SETUP )return -EPERM ; - task =memdup_user ((void __user *)arg,sizeof (*task)); + + struct snd_compr_task *task __free(kfree) = +memdup_user ((void __user *)arg,sizeof (*task));if (IS_ERR (task))return PTR_ERR (task); retval =snd_compr_task_start (stream, task);
@@ -1256,12 +1259,13 @@ static int snd_compr_task_status(struct snd_compr_stream *stream,static int snd_compr_task_status_ioctl (struct snd_compr_stream *stream,unsigned long arg) { - struct snd_compr_task_status *status __free(kfree) = NULL;int retval;if (stream->runtime->state !=SNDRV_PCM_STATE_SETUP )return -EPERM ; - status =memdup_user ((void __user *)arg,sizeof (*status)); + + struct snd_compr_task_status *status __free(kfree) = +memdup_user ((void __user *)arg,sizeof (*status));if (IS_ERR (status))return PTR_ERR (status); retval =snd_compr_task_status (stream, status);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 214/781 ALSA: control: Relax __free() variable declarations
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
[ Upstream commit 7b4721ca3159bce6338dbdf9188b785083571ed4 ]
We used to have a variable declaration with __free() initialized with NULL. This was to keep the old coding style rule, but recently it's relaxed and rather recommends to follow the new rule to declare in place of use for __free() -- which avoids potential deadlocks or UAFs with nested cleanups.
Although the current code has no bug, per se, let's follow the new standard and move the declaration to the place of assignment (or directly assign the allocated result) instead of NULL initializations.
--- sound/core/control.c | 12 ++++++------ sound/core/control_compat.c | 21 +++++++++++---------- sound/core/control_led.c | 12 ++++++------ 3 files changed, 23 insertions(+), 22 deletions(-)
sound/core/control.c +6 -6
@@ -867,9 +867,9 @@ EXPORT_SYMBOL(snd_ctl_find_id);static int snd_ctl_card_info (struct snd_card *card,struct snd_ctl_file * ctl,unsigned int cmd,void __user *arg) { - struct snd_ctl_card_info *info __free(kfree) = NULL; + struct snd_ctl_card_info *info __free(kfree) = +kzalloc (sizeof (*info),GFP_KERNEL ); - info =kzalloc (sizeof (*info),GFP_KERNEL );if (! info)return -ENOMEM ; scoped_guard(rwsem_read, &snd_ioctl_rwsem) {
@@ -1244,10 +1244,10 @@ static int snd_ctl_elem_read(struct snd_card *card,static int snd_ctl_elem_read_user (struct snd_card *card,struct snd_ctl_elem_value __user *_control) { - struct snd_ctl_elem_value *control __free(kfree) = NULL;int result; + struct snd_ctl_elem_value *control __free(kfree) = +memdup_user (_control,sizeof (*control)); - control =memdup_user (_control,sizeof (*control));if (IS_ERR (control))return PTR_ERR (control);
@@ -1320,11 +1320,11 @@ static int snd_ctl_elem_write(struct snd_card *card, struct snd_ctl_file *file,static int snd_ctl_elem_write_user (struct snd_ctl_file *file,struct snd_ctl_elem_value __user *_control) { - struct snd_ctl_elem_value *control __free(kfree) = NULL;struct snd_card *card;int result; + struct snd_ctl_elem_value *control __free(kfree) = +memdup_user (_control,sizeof (*control)); - control =memdup_user (_control,sizeof (*control));if (IS_ERR (control))return PTR_ERR (control);
sound/core/control_compat.c +11 -10
@@ -80,10 +80,10 @@ static int snd_ctl_elem_info_compat(struct snd_ctl_file *ctl, struct snd_ctl_elem_info32 __user *data32) {struct snd_card *card = ctl->card; - struct snd_ctl_elem_info *data __free(kfree) = NULL;int err; + struct snd_ctl_elem_info *data __free(kfree) = +kzalloc (sizeof (*data),GFP_KERNEL ); - data =kzalloc (sizeof (*data),GFP_KERNEL );if (! data)return -ENOMEM ;
@@ -169,14 +169,15 @@ static int get_ctl_type(struct snd_card *card, struct snd_ctl_elem_id *id, int *countp) {struct snd_kcontrol *kctl; - struct snd_ctl_elem_info *info __free(kfree) = NULL;int err;guard (rwsem_read)(&card->controls_rwsem); kctl =snd_ctl_find_id (card, id);if (!kctl)return -ENOENT ; - info =kzalloc (sizeof (*info),GFP_KERNEL ); + + struct snd_ctl_elem_info *info __free(kfree) = +kzalloc (sizeof (*info),GFP_KERNEL );if (info ==NULL )return -ENOMEM ; info->id = *id;
@@ -280,10 +281,10 @@ static int copy_ctl_value_to_user(void __user *userdata,static int __ctl_elem_read_user (struct snd_card *card,void __user *userdata,void __user *valuep) { - struct snd_ctl_elem_value *data __free(kfree) = NULL;int err, type, count; + struct snd_ctl_elem_value *data __free(kfree) = +kzalloc (sizeof (*data),GFP_KERNEL ); - data =kzalloc (sizeof (*data),GFP_KERNEL );if (data ==NULL )return -ENOMEM ;
@@ -314,11 +315,11 @@ static int ctl_elem_read_user(struct snd_card *card,static int __ctl_elem_write_user (struct snd_ctl_file *file,void __user *userdata,void __user *valuep) { - struct snd_ctl_elem_value *data __free(kfree) = NULL;struct snd_card *card = file->card;int err, type, count; + struct snd_ctl_elem_value *data __free(kfree) = +kzalloc (sizeof (*data),GFP_KERNEL ); - data =kzalloc (sizeof (*data),GFP_KERNEL );if (data ==NULL )return -ENOMEM ;
@@ -378,9 +379,9 @@ static int snd_ctl_elem_add_compat(struct snd_ctl_file *file, struct snd_ctl_elem_info32 __user *data32, int replace) { - struct snd_ctl_elem_info *data __free(kfree) = NULL; + struct snd_ctl_elem_info *data __free(kfree) = +kzalloc (sizeof (*data),GFP_KERNEL ); - data =kzalloc (sizeof (*data),GFP_KERNEL );if (! data)return -ENOMEM ;
sound/core/control_led.c +6 -6
@@ -245,12 +245,12 @@ DEFINE_FREE(snd_card_unref, struct snd_card *, if (_T) snd_card_unref(_T))static int snd_ctl_led_set_id (int card_number,struct snd_ctl_elem_id *id,unsigned int group,bool set) { - struct snd_card *card __free(snd_card_unref) = NULL;struct snd_kcontrol *kctl;struct snd_kcontrol_volatile *vd;unsigned int ioff, access, new_access; + struct snd_card *card __free(snd_card_unref) = +snd_card_ref (card_number); - card =snd_card_ref (card_number);if (!card)return -ENXIO ;guard (rwsem_write)(&card->controls_rwsem);
@@ -302,13 +302,13 @@ static void snd_ctl_led_clean(struct snd_card *card)static int snd_ctl_led_reset (int card_number,unsigned int group) { - struct snd_card *card __free(snd_card_unref) = NULL;struct snd_ctl_led_ctl *lctl, *_lctl;struct snd_ctl_led *led;struct snd_kcontrol_volatile *vd;bool change = false; + struct snd_card *card __free(snd_card_unref) = +snd_card_ref (card_number); - card =snd_card_ref (card_number);if (!card)return -ENXIO ;
@@ -598,11 +598,11 @@ static ssize_t list_show(struct device *dev, struct device_attribute *attr, char *buf) { struct snd_ctl_led_card *led_card = container_of(dev, struct snd_ctl_led_card, dev); - struct snd_card *card __free(snd_card_unref) = NULL;struct snd_ctl_led_ctl *lctl;size_t l =0 ; + struct snd_card *card __free(snd_card_unref) = +snd_card_ref (led_card->number); - card =snd_card_ref (led_card->number);if (!card)return -ENXIO ;guard (rwsem_read)(&card->controls_rwsem);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 215/781 ALSA: pcm: Relax __free() variable declarations
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
[ Upstream commit f3d233daf011abbad2f6ebd0e545b42d2f378a4f ]
We used to have a variable declaration with __free() initialized with NULL. This was to keep the old coding style rule, but recently it's relaxed and rather recommends to follow the new rule to declare in place of use for __free() -- which avoids potential deadlocks or UAFs with nested cleanups.
Although the current code has no bug, per se, let's follow the new standard and move the declaration to the place of assignment (or directly assign the allocated result) instead of NULL initializations.
--- sound/core/pcm.c | 4 ++-- sound/core/pcm_compat.c | 9 ++++---- sound/core/pcm_native.c | 50 +++++++++++++++++++++-------------------- 3 files changed, 33 insertions(+), 30 deletions(-)
sound/core/pcm.c +2 -2
@@ -328,13 +328,13 @@ static const char *snd_pcm_oss_format_name(int format)static void snd_pcm_proc_info_read (struct snd_pcm_substream *substream,struct snd_info_buffer *buffer) { - struct snd_pcm_info *info __free(kfree) = NULL;int err;if (! substream)return ; - info =kmalloc (sizeof (*info),GFP_KERNEL ); + struct snd_pcm_info *info __free(kfree) = +kmalloc (sizeof (*info),GFP_KERNEL );if (!info)return ;
sound/core/pcm_compat.c +5 -4
@@ -235,7 +235,6 @@ static int snd_pcm_ioctl_hw_params_compat(struct snd_pcm_substream *substream,int refine, struct snd_pcm_hw_params32 __user *data32) { - struct snd_pcm_hw_params *data __free(kfree) = NULL; struct snd_pcm_runtime *runtime;int err;
@@ -243,7 +242,8 @@ static int snd_pcm_ioctl_hw_params_compat(struct snd_pcm_substream *substream,if (!runtime)return -ENOTTY ; - data =kmalloc (sizeof (*data),GFP_KERNEL ); + struct snd_pcm_hw_params *data __free(kfree) = +kmalloc (sizeof (*data),GFP_KERNEL );if (!data)return -ENOMEM ;
@@ -332,7 +332,6 @@ static int snd_pcm_ioctl_xfern_compat(struct snd_pcm_substream *substream,compat_caddr_t buf;compat_caddr_t __user *bufptr;u32 frames; - void __user **bufs __free(kfree) = NULL;int err, ch, i;if (! substream->runtime)
@@ -349,7 +348,9 @@ static int snd_pcm_ioctl_xfern_compat(struct snd_pcm_substream *substream, get_user(frames, &data32->frames))return -EFAULT ; bufptr =compat_ptr (buf); - bufs =kmalloc_array (ch,sizeof (void __user *),GFP_KERNEL ); + + void __user **bufs __free(kfree) = +kmalloc_array (ch,sizeof (void __user *),GFP_KERNEL );if (bufs ==NULL )return -ENOMEM ;for (i =0 ; i < ch; i++) {
sound/core/pcm_native.c +26 -24
156 lines not on this page · raw message
Signature · 1 line
2.51.0
Re: [PATCH 6.19 215/781] ALSA: pcm: Relax __free() variable declarations
Quoted 14 lines · Greg Kroah-Hartman
6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
[ Upstream commit
f3d233daf011abbad2f6ebd0e545b42d2f378a4f]We used to have a variable declaration with
__free()initialized with NULL. This was to keep the old coding style rule, but recently it's relaxed and rather recommends to follow the new rule to declare in place of use for__free()-- which avoids potential deadlocks or UAFs with nested cleanups.
Quoted 8 lines
Although the current code has no bug, per se, let's follow the new standard and move the declaration to the place of assignment (or directly assign the allocated result) instead of NULL initializations.
Fixes ae9213984864 ("ALSA: pcm: Use automatic cleanup of kfree()")Signed-off-by Takashi Iwai <[email protected]>Signed-off-by Sasha Levin <[email protected]>
Please apply commit 0585c53b2154 ("ALSA: pcm: Revert bufs move in snd_pcm_xfern_frames_ioctl()") to all branches that took this change to fix the build with older supported versions of clang.
Cheers,
Nathan
Greg Kroah-Hartman
maintainerPATCH 216/781 ALSA: oss: Relax __free() variable declarations
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
[ Upstream commit 55f98ece9939a0ad5f83c6124dd1f00d678f9f46 ]
We used to have a variable declaration with __free() initialized with NULL. This was to keep the old coding style rule, but recently it's relaxed and rather recommends to follow the new rule to declare in place of use for __free() -- which avoids potential deadlocks or UAFs with nested cleanups.
Although the current code has no bug, per se, let's follow the new standard and move the declaration to the place of assignment (or directly assign the allocated result) instead of NULL initializations.
--- sound/core/oss/mixer_oss.c | 64 ++++++++++++++++++++------------------ sound/core/oss/pcm_oss.c | 19 ++++++----- 2 files changed, 45 insertions(+), 38 deletions(-)
sound/core/oss/mixer_oss.c +34 -30
@@ -517,8 +517,6 @@ static void snd_mixer_oss_get_volume1_vol(struct snd_mixer_oss_file *fmixer,unsigned int numid, int *left, int *right) { - struct snd_ctl_elem_info *uinfo __free(kfree) = NULL; - struct snd_ctl_elem_value *uctl __free(kfree) = NULL; struct snd_kcontrol *kctl;struct snd_card *card = fmixer->card;
@@ -528,8 +526,11 @@ static void snd_mixer_oss_get_volume1_vol(struct snd_mixer_oss_file *fmixer, kctl =snd_ctl_find_numid (card, numid);if (!kctl)return ; - uinfo =kzalloc (sizeof (*uinfo),GFP_KERNEL ); - uctl =kzalloc (sizeof (*uctl),GFP_KERNEL ); + + struct snd_ctl_elem_info *uinfo __free(kfree) = +kzalloc (sizeof (*uinfo),GFP_KERNEL ); + struct snd_ctl_elem_value *uctl __free(kfree) = +kzalloc (sizeof (*uctl),GFP_KERNEL );if (uinfo ==NULL || uctl ==NULL )return ;if (kctl->info (kctl, uinfo))
@@ -550,8 +551,6 @@ static void snd_mixer_oss_get_volume1_sw(struct snd_mixer_oss_file *fmixer, int *left, int *right, int route) { - struct snd_ctl_elem_info *uinfo __free(kfree) = NULL; - struct snd_ctl_elem_value *uctl __free(kfree) = NULL; struct snd_kcontrol *kctl;struct snd_card *card = fmixer->card;
@@ -561,8 +560,11 @@ static void snd_mixer_oss_get_volume1_sw(struct snd_mixer_oss_file *fmixer, kctl =snd_ctl_find_numid (card, numid);if (!kctl)return ; - uinfo =kzalloc (sizeof (*uinfo),GFP_KERNEL ); - uctl =kzalloc (sizeof (*uctl),GFP_KERNEL ); + + struct snd_ctl_elem_info *uinfo __free(kfree) = +kzalloc (sizeof (*uinfo),GFP_KERNEL ); + struct snd_ctl_elem_value *uctl __free(kfree) = +kzalloc (sizeof (*uctl),GFP_KERNEL );if (uinfo ==NULL || uctl ==NULL )return ;if (kctl->info (kctl, uinfo))
@@ -609,8 +611,6 @@ static void snd_mixer_oss_put_volume1_vol(struct snd_mixer_oss_file *fmixer,unsigned int numid, int left, int right) { - struct snd_ctl_elem_info *uinfo __free(kfree) = NULL; - struct snd_ctl_elem_value *uctl __free(kfree) = NULL; struct snd_kcontrol *kctl;struct snd_card *card = fmixer->card;int res;
@@ -621,8 +621,11 @@ static void snd_mixer_oss_put_volume1_vol(struct snd_mixer_oss_file *fmixer, kctl =snd_ctl_find_numid (card, numid);if (!kctl)return ; - uinfo =kzalloc (sizeof (*uinfo),GFP_KERNEL ); - uctl =kzalloc (sizeof (*uctl),GFP_KERNEL ); + + struct snd_ctl_elem_info *uinfo __free(kfree) = +kzalloc (sizeof (*uinfo),GFP_KERNEL ); + struct snd_ctl_elem_value *uctl __free(kfree) = +kzalloc (sizeof (*uctl),GFP_KERNEL );if (uinfo ==NULL || uctl ==NULL )return ;if (kctl->info (kctl, uinfo))
@@ -646,8 +649,6 @@ static void snd_mixer_oss_put_volume1_sw(struct snd_mixer_oss_file *fmixer, int left, int right, int route) { - struct snd_ctl_elem_info *uinfo __free(kfree) = NULL; - struct snd_ctl_elem_value *uctl __free(kfree) = NULL; struct snd_kcontrol *kctl;struct snd_card *card = fmixer->card;int res;
@@ -658,8 +659,11 @@ static void snd_mixer_oss_put_volume1_sw(struct snd_mixer_oss_file *fmixer, kctl =snd_ctl_find_numid (card, numid);if (!kctl)return ; - uinfo =kzalloc (sizeof (*uinfo),GFP_KERNEL ); - uctl =kzalloc (sizeof (*uctl),GFP_KERNEL ); + + struct snd_ctl_elem_info *uinfo __free(kfree) = +kzalloc (sizeof (*uinfo),GFP_KERNEL ); + struct snd_ctl_elem_value *uctl __free(kfree) = +kzalloc (sizeof (*uctl),GFP_KERNEL );if (uinfo ==NULL || uctl ==NULL )return ;if (kctl->info (kctl, uinfo))
@@ -783,12 +787,12 @@ static int snd_mixer_oss_get_recsrc2(struct snd_mixer_oss_file *fmixer, unsignedstruct snd_kcontrol *kctl;struct snd_mixer_oss_slot *pslot;struct slot *slot; - struct snd_ctl_elem_info *uinfo __free(kfree) = NULL; - struct snd_ctl_elem_value *uctl __free(kfree) = NULL;int err, idx; - uinfo =kzalloc (sizeof (*uinfo),GFP_KERNEL ); - uctl =kzalloc (sizeof (*uctl),GFP_KERNEL ); + struct snd_ctl_elem_info *uinfo __free(kfree) = +kzalloc (sizeof (*uinfo),GFP_KERNEL ); + struct snd_ctl_elem_value *uctl __free(kfree) = + uctl =kzalloc (sizeof (*uctl),GFP_KERNEL );if (uinfo ==NULL || uctl ==NULL )return -ENOMEM ;guard (rwsem_read)(&card->controls_rwsem);
@@ -825,13 +829,13 @@ static int snd_mixer_oss_put_recsrc2(struct snd_mixer_oss_file *fmixer, unsignedstruct snd_kcontrol *kctl;struct snd_mixer_oss_slot *pslot;struct slot *slot =NULL ; - struct snd_ctl_elem_info *uinfo __free(kfree) = NULL; - struct snd_ctl_elem_value *uctl __free(kfree) = NULL;int err;unsigned int idx; - uinfo =kzalloc (sizeof (*uinfo),GFP_KERNEL ); - uctl =kzalloc (sizeof (*uctl),GFP_KERNEL ); + struct snd_ctl_elem_info *uinfo __free(kfree) = +kzalloc (sizeof (*uinfo),GFP_KERNEL ); + struct snd_ctl_elem_value *uctl __free(kfree) = +kzalloc (sizeof (*uctl),GFP_KERNEL );if (uinfo ==NULL || uctl ==NULL )return -ENOMEM ;guard (rwsem_read)(&card->controls_rwsem);
@@ -872,18 +876,18 @@ struct snd_mixer_oss_assign_table {static int snd_mixer_oss_build_test (struct snd_mixer_oss *mixer,struct slot *slot,const char *name,int index,int item) { - struct snd_ctl_elem_info *info __free(kfree) = NULL;struct snd_kcontrol *kcontrol;struct snd_card *card = mixer->card;int err; + struct snd_ctl_elem_info *info __free(kfree) = +kmalloc (sizeof (*info),GFP_KERNEL ); +if (!info) +return -ENOMEM ; scoped_guard(rwsem_read, &card->controls_rwsem) { kcontrol =snd_mixer_oss_test_id (mixer, name, index);if (kcontrol ==NULL )return 0 ; - info =kmalloc (sizeof (*info),GFP_KERNEL ); -if (!info) -return -ENOMEM ; err = kcontrol->info (kcontrol, info);if (err <0 )return err;
@@ -1006,9 +1010,9 @@ static int snd_mixer_oss_build_input(struct snd_mixer_oss *mixer,if (!ptr->index) kctl =snd_mixer_oss_test_id (mixer,"Capture Source" ,0 );if (kctl) { - struct snd_ctl_elem_info *uinfo __free(kfree) = NULL; + struct snd_ctl_elem_info *uinfo __free(kfree) = +kzalloc (sizeof (*uinfo),GFP_KERNEL ); - uinfo =kzalloc (sizeof (*uinfo),GFP_KERNEL );if (!uinfo)return -ENOMEM ;
sound/core/oss/pcm_oss.c +11 -8
@@ -377,7 +377,6 @@ static int snd_pcm_hw_param_near(struct snd_pcm_substream *pcm, snd_pcm_hw_param_t var, unsigned int best, int *dir) { - struct snd_pcm_hw_params *save __free(kfree) = NULL; int v;unsigned int saved_min;int last =0 ;
@@ -397,19 +396,22 @@ static int snd_pcm_hw_param_near(struct snd_pcm_substream *pcm, maxdir =1 ; max--; } - save =kmalloc (sizeof (*save),GFP_KERNEL ); + + struct snd_pcm_hw_params *save __free(kfree) = +kmalloc (sizeof (*save),GFP_KERNEL );if (save ==NULL )return -ENOMEM ; *save = *params; saved_min = min; min =snd_pcm_hw_param_min (pcm, params, var, min, &mindir);if (min >=0 ) { - struct snd_pcm_hw_params *params1 __free(kfree) = NULL;if (max <0 ) goto _end;if ((unsigned int )min == saved_min && mindir == valdir) goto _end; - params1 =kmalloc (sizeof (*params1),GFP_KERNEL ); + + struct snd_pcm_hw_params *params1 __free(kfree) = +kmalloc (sizeof (*params1),GFP_KERNEL );if (params1 ==NULL )return -ENOMEM ; *params1 = *save;
@@ -781,10 +783,10 @@ static int choose_rate(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, unsigned int best_rate) { const struct snd_interval *it; - struct snd_pcm_hw_params *save __free(kfree) = NULL;unsigned int rate, prev; - save =kmalloc (sizeof (*save),GFP_KERNEL ); + struct snd_pcm_hw_params *save __free(kfree) = +kmalloc (sizeof (*save),GFP_KERNEL );if (save ==NULL )return -ENOMEM ; *save = *params;
@@ -1836,7 +1838,6 @@ static int snd_pcm_oss_get_formats(struct snd_pcm_oss_file *pcm_oss_file)struct snd_pcm_substream *substream;int err;int direct; - struct snd_pcm_hw_params *params __free(kfree) = NULL;unsigned int formats =0 ;const struct snd_mask *format_mask;int fmt;
@@ -1856,7 +1857,9 @@ static int snd_pcm_oss_get_formats(struct snd_pcm_oss_file *pcm_oss_file)AFMT_S32_LE |AFMT_S32_BE |AFMT_S24_LE |AFMT_S24_BE |AFMT_S24_PACKED ; - params =kmalloc (sizeof (*params),GFP_KERNEL ); + + struct snd_pcm_hw_params *params __free(kfree) = +kmalloc (sizeof (*params),GFP_KERNEL );if (!params)return -ENOMEM ;_snd_pcm_hw_params_any (params);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 217/781 ALSA: seq: oss: Relax __free() variable declarations
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
[ Upstream commit df27c92753474cc8540e46a476119857ced7ae21 ]
We used to have a variable declaration with __free() initialized with NULL. This was to keep the old coding style rule, but recently it's relaxed and rather recommends to follow the new rule to declare in place of use for __free() -- which avoids potential deadlocks or UAFs with nested cleanups.
Although the current code has no bug, per se, let's follow the new standard and move the declaration to the place of assignment (or directly assign the allocated result) instead of NULL initializations.
--- sound/core/seq/oss/seq_oss_init.c | 4 +-- sound/core/seq/oss/seq_oss_midi.c | 45 +++++++++++++++--------------- sound/core/seq/oss/seq_oss_synth.c | 23 +++++++-------- 3 files changed, 36 insertions(+), 36 deletions(-)
sound/core/seq/oss/seq_oss_init.c +2 -2
@@ -63,10 +63,10 @@ int __initsnd_seq_oss_create_client (void) {int rc; - struct snd_seq_port_info *port __free(kfree) = NULL;struct snd_seq_port_callback port_callback; + struct snd_seq_port_info *port __free(kfree) = +kzalloc (sizeof (*port),GFP_KERNEL ); - port =kzalloc (sizeof (*port),GFP_KERNEL );if (!port)return -ENOMEM ;
sound/core/seq/oss/seq_oss_midi.c +22 -23
120 lines not on this page · raw message
sound/core/seq/oss/seq_oss_synth.c +12 -11
@@ -368,7 +368,6 @@ reset_channels(struct seq_oss_synthinfo *info)void snd_seq_oss_synth_reset (struct seq_oss_devinfo *dp,int dev) { - struct seq_oss_synth *rec __free(seq_oss_synth) = NULL;struct seq_oss_synthinfo *info; info =get_synthinfo_nospec (dp, dev);
@@ -391,7 +390,8 @@ snd_seq_oss_synth_reset(struct seq_oss_devinfo *dp, int dev)return ; } - rec =get_sdev (dev); + struct seq_oss_synth *rec __free(seq_oss_synth) = +get_sdev (dev);if (rec ==NULL )return ;if (rec->oper.reset) {
@@ -415,7 +415,6 @@ int snd_seq_oss_synth_load_patch(struct seq_oss_devinfo *dp, int dev, int fmt, const char __user *buf, int p, int c) { - struct seq_oss_synth *rec __free(seq_oss_synth) = NULL; struct seq_oss_synthinfo *info; info =get_synthinfo_nospec (dp, dev);
@@ -424,7 +423,9 @@ snd_seq_oss_synth_load_patch(struct seq_oss_devinfo *dp, int dev, int fmt,if (info->is_midi)return 0 ; - rec =get_synthdev (dp, dev); + + struct seq_oss_synth *rec __free(seq_oss_synth) = +get_synthdev (dp, dev);if (!rec)return -ENXIO ;
@@ -440,9 +441,9 @@ snd_seq_oss_synth_load_patch(struct seq_oss_devinfo *dp, int dev, int fmt,struct seq_oss_synthinfo *snd_seq_oss_synth_info (struct seq_oss_devinfo *dp,int dev) { - struct seq_oss_synth *rec __free(seq_oss_synth) = NULL; + struct seq_oss_synth *rec __free(seq_oss_synth) = +get_synthdev (dp, dev); - rec =get_synthdev (dp, dev);if (rec)return get_synthinfo_nospec (dp, dev);return NULL ;
@@ -495,13 +496,14 @@ snd_seq_oss_synth_addr(struct seq_oss_devinfo *dp, int dev, struct snd_seq_eventint snd_seq_oss_synth_ioctl (struct seq_oss_devinfo *dp,int dev,unsigned int cmd,unsigned long addr) { - struct seq_oss_synth *rec __free(seq_oss_synth) = NULL;struct seq_oss_synthinfo *info; info =get_synthinfo_nospec (dp, dev);if (!info || info->is_midi)return -ENXIO ; - rec =get_synthdev (dp, dev); + + struct seq_oss_synth *rec __free(seq_oss_synth) = +get_synthdev (dp, dev);if (!rec)return -ENXIO ;if (rec->oper.ioctl ==NULL )
@@ -575,10 +577,9 @@ snd_seq_oss_synth_info_read(struct snd_info_buffer *buf)snd_iprintf (buf,"\nNumber of synth devices: %d\n" , max_synth_devs);for (i =0 ; i < max_synth_devs; i++) { - struct seq_oss_synth *rec __free(seq_oss_synth) = NULL; -snd_iprintf (buf,"\nsynth %d: " , i); - rec =get_sdev (i); + struct seq_oss_synth *rec __free(seq_oss_synth) = +get_sdev (i);if (rec ==NULL ) {snd_iprintf (buf,"*empty*\n" );continue ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 218/781 ALSA: seq: Relax __free() variable declarations
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
[ Upstream commit 13bc5c5394b22fd0a0585733bbbd9266159a840c ]
We used to have a variable declaration with __free() initialized with NULL. This was to keep the old coding style rule, but recently it's relaxed and rather recommends to follow the new rule to declare in place of use for __free() -- which avoids potential deadlocks or UAFs with nested cleanups.
Although the current code has no bug, per se, let's follow the new standard and move the declaration to the place of assignment (or directly assign the allocated result) instead of NULL initializations.
Note that there is a remaining __free() with NULL initialization; it's because of the non-trivial code conditionally assigning the data.
--- sound/core/seq/seq_clientmgr.c | 171 ++++++++++++++++---------------- sound/core/seq/seq_compat.c | 4 +- sound/core/seq/seq_midi.c | 10 +- sound/core/seq/seq_ports.c | 11 +- sound/core/seq/seq_queue.c | 32 +++--- sound/core/seq/seq_ump_client.c | 16 +-- sound/core/seq/seq_virmidi.c | 4 +- 7 files changed, 126 insertions(+), 122 deletions(-)
sound/core/seq/seq_clientmgr.c +86 -85
@@ -494,9 +494,9 @@ static int check_port_perm(struct snd_seq_client_port *port, unsigned int flags)*/ static struct snd_seq_client *get_event_dest_client (struct snd_seq_event *event) { - struct snd_seq_client *dest __free(snd_seq_client) = NULL; + struct snd_seq_client *dest __free(snd_seq_client) = +snd_seq_client_use_ptr (event->dest.client); - dest =snd_seq_client_use_ptr (event->dest.client);if (dest ==NULL )return NULL ;if (! dest->accept_input)
@@ -565,9 +565,9 @@ static int bounce_error_event(struct snd_seq_client *client,static int update_timestamp_of_queue (struct snd_seq_event *event,int queue,int real_time) { - struct snd_seq_queue *q __free(snd_seq_queue) = NULL; + struct snd_seq_queue *q __free(snd_seq_queue) = +queueptr (queue); - q =queueptr (queue);if (! q)return 0 ; event->queue = queue;
@@ -609,13 +609,13 @@ static int _snd_seq_deliver_single_event(struct snd_seq_client *client,struct snd_seq_event *event, int atomic, int hop) { - struct snd_seq_client *dest __free(snd_seq_client) = NULL; - struct snd_seq_client_port *dest_port __free(snd_seq_port) = NULL; - - dest =get_event_dest_client (event); + struct snd_seq_client *dest __free(snd_seq_client) = +get_event_dest_client (event);if (dest ==NULL )return -ENOENT ; - dest_port =snd_seq_port_use_ptr (dest, event->dest.port); + + struct snd_seq_client_port *dest_port __free(snd_seq_port) = +snd_seq_port_use_ptr (dest, event->dest.port);if (dest_port ==NULL )return -ENOENT ;
@@ -672,7 +672,6 @@ static int __deliver_to_subscribers(struct snd_seq_client *client,struct snd_seq_event *event, int port, int atomic, int hop) { - struct snd_seq_client_port *src_port __free(snd_seq_port) = NULL; struct snd_seq_subscribers *subs;int err, result =0 , num_ev =0 ;union __snd_seq_event event_saved;
@@ -681,7 +680,9 @@ static int __deliver_to_subscribers(struct snd_seq_client *client,if (port <0 )return 0 ; - src_port =snd_seq_port_use_ptr (client, port); + + struct snd_seq_client_port *src_port __free(snd_seq_port) = +snd_seq_port_use_ptr (client, port);if (!src_port)return 0 ;
@@ -801,13 +802,13 @@ static int snd_seq_deliver_event(struct snd_seq_client *client, struct snd_seq_e*/ int snd_seq_dispatch_event (struct snd_seq_event_cell *cell,int atomic,int hop) { - struct snd_seq_client *client __free(snd_seq_client) = NULL;int result;if (snd_BUG_ON (!cell))return -EINVAL ; - client =snd_seq_client_use_ptr (cell->event.source.client); + struct snd_seq_client *client __free(snd_seq_client) = +snd_seq_client_use_ptr (cell->event.source.client);if (client ==NULL ) {snd_seq_cell_free (cell);/* release this cell */ return -EINVAL ;
@@ -1154,10 +1155,10 @@ static int snd_seq_ioctl_system_info(struct snd_seq_client *client, void *arg)static int snd_seq_ioctl_running_mode (struct snd_seq_client *client,void *arg) {struct snd_seq_running_info *info = arg; - struct snd_seq_client *cptr __free(snd_seq_client) = NULL; -/* requested client number */ - cptr =client_load_and_use_ptr (info->client); + struct snd_seq_client *cptr __free(snd_seq_client) = +client_load_and_use_ptr (info->client); +if (cptr ==NULL )return -ENOENT ;/* don't change !!! */
@@ -1207,10 +1208,10 @@ static int snd_seq_ioctl_get_client_info(struct snd_seq_client *client, void *arg) {struct snd_seq_client_info *client_info = arg; - struct snd_seq_client *cptr __free(snd_seq_client) = NULL; -/* requested client number */ - cptr =client_load_and_use_ptr (client_info->client); + struct snd_seq_client *cptr __free(snd_seq_client) = +client_load_and_use_ptr (client_info->client); +if (cptr ==NULL )return -ENOENT ;/* don't change !!! */
@@ -1344,14 +1345,14 @@ static int snd_seq_ioctl_delete_port(struct snd_seq_client *client, void *arg)static int snd_seq_ioctl_get_port_info (struct snd_seq_client *client,void *arg) {struct snd_seq_port_info *info = arg; - struct snd_seq_client *cptr __free(snd_seq_client) = NULL; - struct snd_seq_client_port *port __free(snd_seq_port) = NULL; - cptr =client_load_and_use_ptr (info->addr.client); + struct snd_seq_client *cptr __free(snd_seq_client) = +client_load_and_use_ptr (info->addr.client);if (cptr ==NULL )return -ENXIO ; - port =snd_seq_port_use_ptr (cptr, info->addr.port); + struct snd_seq_client_port *port __free(snd_seq_port) = +snd_seq_port_use_ptr (cptr, info->addr.port);if (port ==NULL )return -ENOENT ;/* don't change */
@@ -1367,11 +1368,12 @@ static int snd_seq_ioctl_get_port_info(struct snd_seq_client *client, void *arg)static int snd_seq_ioctl_set_port_info (struct snd_seq_client *client,void *arg) {struct snd_seq_port_info *info = arg; - struct snd_seq_client_port *port __free(snd_seq_port) = NULL;if (info->addr.client != client->number)/* only set our own ports ! */ return -EPERM ; - port =snd_seq_port_use_ptr (client, info->addr.port); + + struct snd_seq_client_port *port __free(snd_seq_port) = +snd_seq_port_use_ptr (client, info->addr.port);if (port) {snd_seq_set_port_info (port, info);/* notify the change */
@@ -1444,22 +1446,22 @@ static int snd_seq_ioctl_subscribe_port(struct snd_seq_client *client, void *arg) {struct snd_seq_port_subscribe *subs = arg; - struct snd_seq_client *receiver __free(snd_seq_client) = NULL; - struct snd_seq_client *sender __free(snd_seq_client) = NULL; - struct snd_seq_client_port *sport __free(snd_seq_port) = NULL; - struct snd_seq_client_port *dport __free(snd_seq_port) = NULL;int result; - receiver =client_load_and_use_ptr (subs->dest.client); + struct snd_seq_client *receiver __free(snd_seq_client) = +client_load_and_use_ptr (subs->dest.client);if (!receiver)return -EINVAL ; - sender =client_load_and_use_ptr (subs->sender.client); + struct snd_seq_client *sender __free(snd_seq_client) = +client_load_and_use_ptr (subs->sender.client);if (!sender)return -EINVAL ; - sport =snd_seq_port_use_ptr (sender, subs->sender.port); + struct snd_seq_client_port *sport __free(snd_seq_port) = +snd_seq_port_use_ptr (sender, subs->sender.port);if (!sport)return -EINVAL ; - dport =snd_seq_port_use_ptr (receiver, subs->dest.port); + struct snd_seq_client_port *dport __free(snd_seq_port) = +snd_seq_port_use_ptr (receiver, subs->dest.port);if (!dport)return -EINVAL ;
@@ -1483,22 +1485,22 @@ static int snd_seq_ioctl_unsubscribe_port(struct snd_seq_client *client, void *arg) {struct snd_seq_port_subscribe *subs = arg; - struct snd_seq_client *receiver __free(snd_seq_client) = NULL; - struct snd_seq_client *sender __free(snd_seq_client) = NULL; - struct snd_seq_client_port *sport __free(snd_seq_port) = NULL; - struct snd_seq_client_port *dport __free(snd_seq_port) = NULL;int result; - receiver =snd_seq_client_use_ptr (subs->dest.client); + struct snd_seq_client *receiver __free(snd_seq_client) = +snd_seq_client_use_ptr (subs->dest.client);if (!receiver)return -ENXIO ; - sender =snd_seq_client_use_ptr (subs->sender.client); + struct snd_seq_client *sender __free(snd_seq_client) = +snd_seq_client_use_ptr (subs->sender.client);if (!sender)return -ENXIO ; - sport =snd_seq_port_use_ptr (sender, subs->sender.port); + struct snd_seq_client_port *sport __free(snd_seq_port) = +snd_seq_port_use_ptr (sender, subs->sender.port);if (!sport)return -ENXIO ; - dport =snd_seq_port_use_ptr (receiver, subs->dest.port); + struct snd_seq_client_port *dport __free(snd_seq_port) = +snd_seq_port_use_ptr (receiver, subs->dest.port);if (!dport)return -ENXIO ;
@@ -1518,9 +1520,9 @@ static int snd_seq_ioctl_unsubscribe_port(struct snd_seq_client *client,static int snd_seq_ioctl_create_queue (struct snd_seq_client *client,void *arg) {struct snd_seq_queue_info *info = arg; - struct snd_seq_queue *q __free(snd_seq_queue) = NULL; + struct snd_seq_queue *q __free(snd_seq_queue) = +snd_seq_queue_alloc (client->number, info->locked, info->flags); - q =snd_seq_queue_alloc (client->number, info->locked, info->flags);if (IS_ERR (q))return PTR_ERR (q);
@@ -1549,9 +1551,9 @@ static int snd_seq_ioctl_get_queue_info(struct snd_seq_client *client, void *arg) {struct snd_seq_queue_info *info = arg; - struct snd_seq_queue *q __free(snd_seq_queue) = NULL; + struct snd_seq_queue *q __free(snd_seq_queue) = +queueptr (info->queue); - q =queueptr (info->queue);if (q ==NULL )return -EINVAL ;
@@ -1569,7 +1571,6 @@ static int snd_seq_ioctl_set_queue_info(struct snd_seq_client *client, void *arg) {struct snd_seq_queue_info *info = arg; - struct snd_seq_queue *q __free(snd_seq_queue) = NULL;if (info->owner != client->number)return -EINVAL ;
@@ -1584,7 +1585,8 @@ static int snd_seq_ioctl_set_queue_info(struct snd_seq_client *client,return -EPERM ; } - q =queueptr (info->queue); + struct snd_seq_queue *q __free(snd_seq_queue) = +queueptr (info->queue);if (! q)return -EINVAL ;if (q->owner != client->number)
@@ -1599,9 +1601,9 @@ static int snd_seq_ioctl_get_named_queue(struct snd_seq_client *client, void *arg) {struct snd_seq_queue_info *info = arg; - struct snd_seq_queue *q __free(snd_seq_queue) = NULL; + struct snd_seq_queue *q __free(snd_seq_queue) = +snd_seq_queue_find_name (info->name); - q =snd_seq_queue_find_name (info->name);if (q ==NULL )return -EINVAL ; info->queue = q->queue;
@@ -1616,10 +1618,10 @@ static int snd_seq_ioctl_get_queue_status(struct snd_seq_client *client, void *arg) {struct snd_seq_queue_status *status = arg; - struct snd_seq_queue *queue __free(snd_seq_queue) = NULL;struct snd_seq_timer *tmr; + struct snd_seq_queue *queue __free(snd_seq_queue) = +queueptr (status->queue); - queue =queueptr (status->queue);if (queue ==NULL )return -EINVAL ;memset (status,0 ,sizeof (*status));
@@ -1644,10 +1646,10 @@ static int snd_seq_ioctl_get_queue_tempo(struct snd_seq_client *client, void *arg) {struct snd_seq_queue_tempo *tempo = arg; - struct snd_seq_queue *queue __free(snd_seq_queue) = NULL;struct snd_seq_timer *tmr; + struct snd_seq_queue *queue __free(snd_seq_queue) = +queueptr (tempo->queue); - queue =queueptr (tempo->queue);if (queue ==NULL )return -EINVAL ;memset (tempo,0 ,sizeof (*tempo));
@@ -1693,10 +1695,10 @@ static int snd_seq_ioctl_get_queue_timer(struct snd_seq_client *client, void *arg) {struct snd_seq_queue_timer *timer = arg; - struct snd_seq_queue *queue __free(snd_seq_queue) = NULL;struct snd_seq_timer *tmr; + struct snd_seq_queue *queue __free(snd_seq_queue) = +queueptr (timer->queue); - queue =queueptr (timer->queue);if (queue ==NULL )return -EINVAL ;
@@ -1726,10 +1728,10 @@ static int snd_seq_ioctl_set_queue_timer(struct snd_seq_client *client,return -EINVAL ;if (snd_seq_queue_check_access (timer->queue, client->number)) { - struct snd_seq_queue *q __free(snd_seq_queue) = NULL;struct snd_seq_timer *tmr; + struct snd_seq_queue *q __free(snd_seq_queue) = +queueptr (timer->queue); - q =queueptr (timer->queue);if (q ==NULL )return -ENXIO ;guard (mutex)(&q->timer_mutex);
@@ -1788,9 +1790,9 @@ static int snd_seq_ioctl_get_client_pool(struct snd_seq_client *client, void *arg) {struct snd_seq_client_pool *info = arg; - struct snd_seq_client *cptr __free(snd_seq_client) = NULL; + struct snd_seq_client *cptr __free(snd_seq_client) = +client_load_and_use_ptr (info->client); - cptr =client_load_and_use_ptr (info->client);if (cptr ==NULL )return -ENOENT ;memset (info,0 ,sizeof (*info));
@@ -1888,13 +1890,13 @@ static int snd_seq_ioctl_get_subscription(struct snd_seq_client *client, void *arg) {struct snd_seq_port_subscribe *subs = arg; - struct snd_seq_client *sender __free(snd_seq_client) = NULL; - struct snd_seq_client_port *sport __free(snd_seq_port) = NULL; - sender =client_load_and_use_ptr (subs->sender.client); + struct snd_seq_client *sender __free(snd_seq_client) = +client_load_and_use_ptr (subs->sender.client);if (!sender)return -EINVAL ; - sport =snd_seq_port_use_ptr (sender, subs->sender.port); + struct snd_seq_client_port *sport __free(snd_seq_port) = +snd_seq_port_use_ptr (sender, subs->sender.port);if (!sport)return -EINVAL ;return snd_seq_port_get_subscription (&sport->c_src, &subs->dest, subs);
@@ -1907,16 +1909,16 @@ static int snd_seq_ioctl_get_subscription(struct snd_seq_client *client,static int snd_seq_ioctl_query_subs (struct snd_seq_client *client,void *arg) {struct snd_seq_query_subs *subs = arg; - struct snd_seq_client *cptr __free(snd_seq_client) = NULL; - struct snd_seq_client_port *port __free(snd_seq_port) = NULL;struct snd_seq_port_subs_info *group;struct list_head *p;int i; - cptr =client_load_and_use_ptr (subs->root.client); + struct snd_seq_client *cptr __free(snd_seq_client) = +client_load_and_use_ptr (subs->root.client);if (!cptr)return -ENXIO ; - port =snd_seq_port_use_ptr (cptr, subs->root.port); + struct snd_seq_client_port *port __free(snd_seq_port) = +snd_seq_port_use_ptr (cptr, subs->root.port);if (!port)return -ENXIO ;
@@ -1963,7 +1965,6 @@ static int snd_seq_ioctl_query_next_client(struct snd_seq_client *client, void *arg) {struct snd_seq_client_info *info = arg; - struct snd_seq_client *cptr __free(snd_seq_client) = NULL;/* search for next client */ if (info->client <INT_MAX )
@@ -1971,7 +1972,8 @@ static int snd_seq_ioctl_query_next_client(struct snd_seq_client *client,if (info->client <0 ) info->client =0 ;for (; info->client <SNDRV_SEQ_MAX_CLIENTS ; info->client++) { - cptr =client_load_and_use_ptr (info->client); + struct snd_seq_client *cptr __free(snd_seq_client) = +client_load_and_use_ptr (info->client);if (cptr) {get_client_info (cptr, info);return 0 ;/* found */
@@ -1987,16 +1989,16 @@ static int snd_seq_ioctl_query_next_port(struct snd_seq_client *client, void *arg) {struct snd_seq_port_info *info = arg; - struct snd_seq_client *cptr __free(snd_seq_client) = NULL; - struct snd_seq_client_port *port __free(snd_seq_port) = NULL; - cptr =client_load_and_use_ptr (info->addr.client); + struct snd_seq_client *cptr __free(snd_seq_client) = +client_load_and_use_ptr (info->addr.client);if (cptr ==NULL )return -ENXIO ;/* search for next port */ info->addr.port++; - port =snd_seq_port_query_nearest (cptr, info); + struct snd_seq_client_port *port __free(snd_seq_port) = +snd_seq_port_query_nearest (cptr, info);if (port ==NULL )return -ENOENT ;
@@ -2067,7 +2069,6 @@ static int snd_seq_ioctl_client_ump_info(struct snd_seq_client *caller, {struct snd_seq_client_ump_info __user *argp = (struct snd_seq_client_ump_info __user *)arg; - struct snd_seq_client *cptr __free(snd_seq_client) = NULL;int client, type, err =0 ;size_t size;void *p;
@@ -2083,7 +2084,9 @@ static int snd_seq_ioctl_client_ump_info(struct snd_seq_client *caller, size =sizeof (struct snd_ump_endpoint_info ); else size =sizeof (struct snd_ump_block_info ); - cptr =client_load_and_use_ptr (client); + + struct snd_seq_client *cptr __free(snd_seq_client) = +client_load_and_use_ptr (client);if (!cptr)return -ENOENT ;
@@ -2342,8 +2345,6 @@ EXPORT_SYMBOL(snd_seq_delete_kernel_client);int snd_seq_kernel_client_enqueue (int client,struct snd_seq_event *ev,struct file *file,bool blocking) { - struct snd_seq_client *cptr __free(snd_seq_client) = NULL; -if (snd_BUG_ON (!ev))return -EINVAL ;
@@ -2360,7 +2361,8 @@ int snd_seq_kernel_client_enqueue(int client, struct snd_seq_event *ev,if (check_event_type_and_length (ev))return -EINVAL ; - cptr =client_load_and_use_ptr (client); + struct snd_seq_client *cptr __free(snd_seq_client) = +client_load_and_use_ptr (client);if (cptr ==NULL )return -EINVAL ;
@@ -2385,8 +2387,6 @@ EXPORT_SYMBOL(snd_seq_kernel_client_enqueue);int snd_seq_kernel_client_dispatch (int client,struct snd_seq_event * ev,int atomic,int hop) { - struct snd_seq_client *cptr __free(snd_seq_client) = NULL; -if (snd_BUG_ON (!ev))return -EINVAL ;
@@ -2397,7 +2397,8 @@ int snd_seq_kernel_client_dispatch(int client, struct snd_seq_event * ev,if (check_event_type_and_length (ev))return -EINVAL ; - cptr =snd_seq_client_use_ptr (client); + struct snd_seq_client *cptr __free(snd_seq_client) = +snd_seq_client_use_ptr (client);if (cptr ==NULL )return -EINVAL ;
@@ -2450,9 +2451,9 @@ EXPORT_SYMBOL(snd_seq_kernel_client_ctl);/* a similar like above but taking locks; used only from OSS sequencer layer */ int snd_seq_kernel_client_ioctl (int clientid,unsigned int cmd,void *arg) { - struct snd_seq_client *client __free(snd_seq_client) = NULL; + struct snd_seq_client *client __free(snd_seq_client) = +client_load_and_use_ptr (clientid); - client =client_load_and_use_ptr (clientid);if (!client)return -ENXIO ;guard (mutex)(&client->ioctl_mutex);
@@ -2597,9 +2598,9 @@ void snd_seq_info_clients_read(struct snd_info_entry *entry,/* list the client table */ for (c =0 ; c <SNDRV_SEQ_MAX_CLIENTS ; c++) { - struct snd_seq_client *client __free(snd_seq_client) = NULL; + struct snd_seq_client *client __free(snd_seq_client) = +client_load_and_use_ptr (c); - client =client_load_and_use_ptr (c);if (client ==NULL )continue ;if (client->type ==NO_CLIENT )
sound/core/seq/seq_compat.c +2 -2
@@ -31,10 +31,10 @@ struct snd_seq_port_info32 {static int snd_seq_call_port_info_ioctl (struct snd_seq_client *client,unsigned int cmd,struct snd_seq_port_info32 __user *data32) { - struct snd_seq_port_info *data __free(kfree) = NULL;int err; + struct snd_seq_port_info *data __free(kfree) = +kmalloc (sizeof (*data),GFP_KERNEL ); - data =kmalloc (sizeof (*data),GFP_KERNEL );if (!data)return -ENOMEM ;
sound/core/seq/seq_midi.c +6 -4
@@ -270,8 +270,6 @@ snd_seq_midisynth_probe(struct device *_dev)struct snd_seq_device *dev =to_seq_dev (_dev);struct seq_midisynth_client *client;struct seq_midisynth *msynth, *ms; - struct snd_seq_port_info *port __free(kfree) = NULL; - struct snd_rawmidi_info *info __free(kfree) = NULL;struct snd_rawmidi *rmidi = dev->private_data;int newclient =0 ;unsigned int p, ports;
@@ -282,7 +280,9 @@ snd_seq_midisynth_probe(struct device *_dev)if (snd_BUG_ON (!card || device <0 || device >=SNDRV_RAWMIDI_DEVICES ))return -EINVAL ; - info =kmalloc (sizeof (*info),GFP_KERNEL ); + + struct snd_rawmidi_info *info __free(kfree) = +kmalloc (sizeof (*info),GFP_KERNEL );if (! info)return -ENOMEM ; info->device = device;
@@ -320,7 +320,9 @@ snd_seq_midisynth_probe(struct device *_dev) } msynth =kcalloc (ports,sizeof (struct seq_midisynth ),GFP_KERNEL ); - port =kmalloc (sizeof (*port),GFP_KERNEL ); + + struct snd_seq_port_info *port __free(kfree) = +kmalloc (sizeof (*port),GFP_KERNEL );if (msynth ==NULL || port ==NULL ) goto __nomem;
sound/core/seq/seq_ports.c +5 -6
@@ -211,14 +211,13 @@ static void clear_subscriber_list(struct snd_seq_client *client,list_for_each_safe (p, n, &grp->list_head) {struct snd_seq_subscribers *subs; - struct snd_seq_client *c __free(snd_seq_client) = NULL; - struct snd_seq_client_port *aport __free(snd_seq_port) = NULL; subs =get_subscriber (p, is_src); -if (is_src) - aport =get_client_port (&subs->info.dest, &c); -else - aport =get_client_port (&subs->info.sender, &c); + struct snd_seq_client *c __free(snd_seq_client) = NULL; + struct snd_seq_client_port *aport __free(snd_seq_port) = + is_src ? +get_client_port (&subs->info.dest, &c) : +get_client_port (&subs->info.sender, &c);delete_and_unsubscribe_port (client, port, subs, is_src, false);if (!aport) {
sound/core/seq/seq_queue.c +17 -15
@@ -211,8 +211,9 @@ struct snd_seq_queue *snd_seq_queue_find_name(char *name)int i;for (i =0 ; i <SNDRV_SEQ_MAX_QUEUES ; i++) { - struct snd_seq_queue *q __free(snd_seq_queue) = NULL; - q =queueptr (i); + struct snd_seq_queue *q __free(snd_seq_queue) = +queueptr (i); +if (q) {if (strncmp (q->name, name,sizeof (q->name)) ==0 )return no_free_ptr (q);
@@ -285,12 +286,13 @@ void snd_seq_check_queue(struct snd_seq_queue *q, int atomic, int hop)int snd_seq_enqueue_event (struct snd_seq_event_cell *cell,int atomic,int hop) {int dest, err; - struct snd_seq_queue *q __free(snd_seq_queue) = NULL;if (snd_BUG_ON (!cell))return -EINVAL ; dest = cell->event.queue;/* destination queue */ - q =queueptr (dest); + + struct snd_seq_queue *q __free(snd_seq_queue) = +queueptr (dest);if (q ==NULL )return -EINVAL ;/* handle relative time stamps, convert them into absolute */
@@ -403,10 +405,10 @@ int snd_seq_queue_set_owner(int queueid, int client, int locked)int snd_seq_queue_timer_open (int queueid) {int result =0 ; - struct snd_seq_queue *queue __free(snd_seq_queue) = NULL;struct snd_seq_timer *tmr; + struct snd_seq_queue *queue __free(snd_seq_queue) = +queueptr (queueid); - queue =queueptr (queueid);if (queue ==NULL )return -EINVAL ; tmr = queue->timer;
@@ -423,10 +425,10 @@ int snd_seq_queue_timer_open(int queueid)*/ int snd_seq_queue_timer_close (int queueid) { - struct snd_seq_queue *queue __free(snd_seq_queue) = NULL;int result =0 ; + struct snd_seq_queue *queue __free(snd_seq_queue) = +queueptr (queueid); - queue =queueptr (queueid);if (queue ==NULL )return -EINVAL ;snd_seq_timer_close (queue);
@@ -479,9 +481,9 @@ static void queue_use(struct snd_seq_queue *queue, int client, int use)*/ int snd_seq_queue_use (int queueid,int client,int use) { - struct snd_seq_queue *queue __free(snd_seq_queue) = NULL; + struct snd_seq_queue *queue __free(snd_seq_queue) = +queueptr (queueid); - queue =queueptr (queueid);if (queue ==NULL )return -EINVAL ;guard (mutex)(&queue->timer_mutex);
@@ -496,9 +498,9 @@ int snd_seq_queue_use(int queueid, int client, int use)*/ int snd_seq_queue_is_used (int queueid,int client) { - struct snd_seq_queue *q __free(snd_seq_queue) = NULL; + struct snd_seq_queue *q __free(snd_seq_queue) = +queueptr (queueid); - q =queueptr (queueid);if (q ==NULL )return -EINVAL ;/* invalid queue */ return test_bit (client, q->clients_bitmap) ?1 :0 ;
@@ -642,11 +644,11 @@ static void snd_seq_queue_process_event(struct snd_seq_queue *q,*/ int snd_seq_control_queue (struct snd_seq_event *ev,int atomic,int hop) { - struct snd_seq_queue *q __free(snd_seq_queue) = NULL; -if (snd_BUG_ON (!ev))return -EINVAL ; - q =queueptr (ev->data.queue.queue); + + struct snd_seq_queue *q __free(snd_seq_queue) = +queueptr (ev->data.queue.queue);if (q ==NULL )return -EINVAL ;
sound/core/seq/seq_ump_client.c +8 -8
@@ -214,13 +214,13 @@ static bool skip_group(struct seq_ump_client *client, struct snd_ump_group *groustatic int seq_ump_group_init (struct seq_ump_client *client,int group_index) {struct snd_ump_group *group = &client->ump->groups[group_index]; - struct snd_seq_port_info *port __free(kfree) = NULL;struct snd_seq_port_callback pcallbacks;if (skip_group (client, group))return 0 ; - port =kzalloc (sizeof (*port),GFP_KERNEL ); + struct snd_seq_port_info *port __free(kfree) = +kzalloc (sizeof (*port),GFP_KERNEL );if (!port)return -ENOMEM ;
@@ -243,12 +243,12 @@ static int seq_ump_group_init(struct seq_ump_client *client, int group_index)/* update the sequencer ports; called from notify_fb_change callback */ static void update_port_infos (struct seq_ump_client *client) { - struct snd_seq_port_info *old __free(kfree) = NULL; - struct snd_seq_port_info *new __free(kfree) = NULL;int i, err; - old =kzalloc (sizeof (*old),GFP_KERNEL ); - new =kzalloc (sizeof (*new),GFP_KERNEL ); + struct snd_seq_port_info *old __free(kfree) = +kzalloc (sizeof (*old),GFP_KERNEL ); + struct snd_seq_port_info *new __free(kfree) = +kzalloc (sizeof (*new),GFP_KERNEL );if (!old || !new)return ;
@@ -278,12 +278,12 @@ static void update_port_infos(struct seq_ump_client *client)/* create a UMP Endpoint port */ static int create_ump_endpoint_port (struct seq_ump_client *client) { - struct snd_seq_port_info *port __free(kfree) = NULL;struct snd_seq_port_callback pcallbacks;unsigned int rawmidi_info = client->ump->core.info_flags;int err; - port =kzalloc (sizeof (*port),GFP_KERNEL ); + struct snd_seq_port_info *port __free(kfree) = +kzalloc (sizeof (*port),GFP_KERNEL );if (!port)return -ENOMEM ;
sound/core/seq/seq_virmidi.c +2 -2
@@ -361,13 +361,13 @@ static int snd_virmidi_dev_attach_seq(struct snd_virmidi_dev *rdev) {int client;struct snd_seq_port_callback pcallbacks; - struct snd_seq_port_info *pinfo __free(kfree) = NULL;int err;if (rdev->client >=0 )return 0 ; - pinfo =kzalloc (sizeof (*pinfo),GFP_KERNEL ); + struct snd_seq_port_info *pinfo __free(kfree) = +kzalloc (sizeof (*pinfo),GFP_KERNEL );if (!pinfo)return -ENOMEM ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 219/781 ALSA: timer: Relax __free() variable declarations
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
[ Upstream commit b1bf8ac5319010e0f73183bdb78c1daf5552c8cb ]
We used to have a variable declaration with __free() initialized with NULL. This was to keep the old coding style rule, but recently it's relaxed and rather recommends to follow the new rule to declare in place of use for __free() -- which avoids potential deadlocks or UAFs with nested cleanups.
Although the current code has no bug, per se, let's follow the new standard and move the declaration to the place of assignment (or directly assign the allocated result) instead of NULL initializations.
--- sound/core/timer.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
sound/core/timer.c +6 -6
@@ -1614,12 +1614,12 @@ static int snd_timer_user_next_device(struct snd_timer_id __user *_tid)static int snd_timer_user_ginfo (struct file *file,struct snd_timer_ginfo __user *_ginfo) { - struct snd_timer_ginfo *ginfo __free(kfree) = NULL;struct snd_timer_id tid;struct snd_timer *t;struct list_head *p; + struct snd_timer_ginfo *ginfo __free(kfree) = +memdup_user (_ginfo,sizeof (*ginfo)); - ginfo =memdup_user (_ginfo,sizeof (*ginfo));if (IS_ERR (ginfo))return PTR_ERR (ginfo);
@@ -1756,7 +1756,6 @@ static int snd_timer_user_info(struct file *file, struct snd_timer_info __user *_info) {struct snd_timer_user *tu; - struct snd_timer_info *info __free(kfree) = NULL;struct snd_timer *t; tu = file->private_data;
@@ -1766,7 +1765,8 @@ static int snd_timer_user_info(struct file *file,if (!t)return -EBADFD ; - info =kzalloc (sizeof (*info),GFP_KERNEL ); + struct snd_timer_info *info __free(kfree) = +kzalloc (sizeof (*info),GFP_KERNEL );if (! info)return -ENOMEM ; info->card = t->card ? t->card->number :-1 ;
@@ -2192,10 +2192,10 @@ static int snd_utimer_ioctl_create(struct file *file, struct snd_timer_uinfo __user *_utimer_info) {struct snd_utimer *utimer; - struct snd_timer_uinfo *utimer_info __free(kfree) = NULL;int err, timer_fd; + struct snd_timer_uinfo *utimer_info __free(kfree) = +memdup_user (_utimer_info,sizeof (*utimer_info)); - utimer_info =memdup_user (_utimer_info,sizeof (*utimer_info));if (IS_ERR (utimer_info))return PTR_ERR (utimer_info);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 220/781 ALSA: vmaster: Relax __free() variable declarations
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
[ Upstream commit 3b7c7bda39e1e48f926fb3d280a5f5d20a939857 ]
We used to have a variable declaration with __free() initialized with NULL. This was to keep the old coding style rule, but recently it's relaxed and rather recommends to follow the new rule to declare in place of use for __free() -- which avoids potential deadlocks or UAFs with nested cleanups.
Although the current code has no bug, per se, let's follow the new standard and move the declaration to the place of assignment (or directly assign the allocated result) instead of NULL initializations.
--- sound/core/vmaster.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
sound/core/vmaster.c +6 -6
@@ -56,10 +56,10 @@ struct link_follower {static int follower_update (struct link_follower *follower) { - struct snd_ctl_elem_value *uctl __free(kfree) = NULL;int err, ch; + struct snd_ctl_elem_value *uctl __free(kfree) = +kzalloc (sizeof (*uctl),GFP_KERNEL ); - uctl =kzalloc (sizeof (*uctl),GFP_KERNEL );if (!uctl)return -ENOMEM ; uctl->id = follower->follower.id;
@@ -74,7 +74,6 @@ static int follower_update(struct link_follower *follower)/* get the follower ctl info and save the initial values */ static int follower_init (struct link_follower *follower) { - struct snd_ctl_elem_info *uinfo __free(kfree) = NULL;int err;if (follower->info.count) {
@@ -84,7 +83,8 @@ static int follower_init(struct link_follower *follower)return 0 ; } - uinfo =kmalloc (sizeof (*uinfo),GFP_KERNEL ); + struct snd_ctl_elem_info *uinfo __free(kfree) = +kmalloc (sizeof (*uinfo),GFP_KERNEL );if (!uinfo)return -ENOMEM ; uinfo->id = follower->follower.id;
@@ -341,9 +341,9 @@ static int master_get(struct snd_kcontrol *kcontrol,static int sync_followers (struct link_master *master,int old_val,int new_val) {struct link_follower *follower; - struct snd_ctl_elem_value *uval __free(kfree) = NULL; + struct snd_ctl_elem_value *uval __free(kfree) = +kmalloc (sizeof (*uval),GFP_KERNEL ); - uval =kmalloc (sizeof (*uval),GFP_KERNEL );if (!uval)return -ENOMEM ;list_for_each_entry (follower, &master->followers, list) {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 221/781 ALSA: hda: Relax __free() variable declarations
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
[ Upstream commit 04c654624f41d3c3eee48e9837a52d8a2bbc7332 ]
We used to have a variable declaration with __free() initialized with NULL. This was to keep the old coding style rule, but recently it's relaxed and rather recommends to follow the new rule to declare in place of use for __free() -- which avoids potential deadlocks or UAFs with nested cleanups.
Although the current code has no bug, per se, let's follow the new standard and move the declaration to the place of assignment (or directly assign the allocated result) instead of NULL initializations.
--- sound/hda/codecs/generic.c | 4 ++-- sound/hda/codecs/realtek/alc269.c | 4 ++-- sound/hda/codecs/realtek/realtek.c | 5 +++-- sound/hda/common/codec.c | 4 ++-- sound/hda/common/sysfs.c | 5 +++-- 5 files changed, 12 insertions(+), 10 deletions(-)
sound/hda/codecs/generic.c +2 -2
@@ -1984,15 +1984,15 @@ static int parse_output_paths(struct hda_codec *codec) {struct hda_gen_spec *spec = codec->spec;struct auto_pin_cfg *cfg = &spec->autocfg; - struct auto_pin_cfg *best_cfg __free(kfree) = NULL;unsigned int val;int best_badness =INT_MAX ;int badness;bool fill_hardwired = true, fill_mio_first = true;bool best_wired = true, best_mio = true;bool hp_spk_swapped = false; + struct auto_pin_cfg *best_cfg __free(kfree) = +kmalloc (sizeof (*best_cfg),GFP_KERNEL ); - best_cfg =kmalloc (sizeof (*best_cfg),GFP_KERNEL );if (!best_cfg)return -ENOMEM ; *best_cfg = *cfg;
sound/hda/codecs/realtek/alc269.c +2 -2
@@ -2916,7 +2916,6 @@ static void find_cirrus_companion_amps(struct hda_codec *cdc) {struct device *dev =hda_codec_dev (cdc);struct acpi_device *adev; - struct fwnode_handle *fwnode __free(fwnode_handle) = NULL;const char *bus =NULL ; static const struct { const char *hid;
@@ -2946,7 +2945,8 @@ static void find_cirrus_companion_amps(struct hda_codec *cdc) bus ="spi" ; } - fwnode =fwnode_handle_get (acpi_fwnode_handle (adev)); + struct fwnode_handle *fwnode __free(fwnode_handle) = +fwnode_handle_get (acpi_fwnode_handle (adev));acpi_dev_put (adev);if (!bus) {
sound/hda/codecs/realtek/realtek.c +3 -2
@@ -215,12 +215,13 @@ void alc_update_knob_master(struct hda_codec *codec, {unsigned int val;struct snd_kcontrol *kctl; - struct snd_ctl_elem_value *uctl __free(kfree) = NULL; kctl =snd_hda_find_mixer_ctl (codec,"Master Playback Volume" );if (!kctl)return ; - uctl =kzalloc (sizeof (*uctl),GFP_KERNEL ); + + struct snd_ctl_elem_value *uctl __free(kfree) = +kzalloc (sizeof (*uctl),GFP_KERNEL );if (!uctl)return ; val = snd_hda_codec_read(codec, jack->nid, 0,
sound/hda/common/codec.c +2 -2
@@ -1854,9 +1854,9 @@ static int check_follower_present(struct hda_codec *codec,/* call kctl->put with the given value(s) */ static int put_kctl_with_value (struct snd_kcontrol *kctl,int val) { - struct snd_ctl_elem_value *ucontrol __free(kfree) = NULL; + struct snd_ctl_elem_value *ucontrol __free(kfree) = +kzalloc (sizeof (*ucontrol),GFP_KERNEL ); - ucontrol =kzalloc (sizeof (*ucontrol),GFP_KERNEL );if (!ucontrol)return -ENOMEM ; ucontrol->value.integer.value[0 ] = val;
sound/hda/common/sysfs.c +3 -2
@@ -299,7 +299,6 @@ static void remove_trail_spaces(char *str)static int parse_hints (struct hda_codec *codec,const char *buf) { - char *key __free(kfree) = NULL;char *val;struct hda_hint *hint;
@@ -308,7 +307,9 @@ static int parse_hints(struct hda_codec *codec, const char *buf)return 0 ;if (*buf =='=' )return -EINVAL ; - key =kstrndup_noeol (buf,1024 ); + + char *key __free(kfree) = +kstrndup_noeol (buf,1024 );if (!key)return -ENOMEM ;/* extract key and val */
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 222/781 ALSA: usx2y: Relax __free() variable declarations
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
[ Upstream commit 43cc944c8e28d26f152198278f81cf7f9955ff85 ]
We used to have a variable declaration with __free() initialized with NULL. This was to keep the old coding style rule, but recently it's relaxed and rather recommends to follow the new rule to declare in place of use for __free() -- which avoids potential deadlocks or UAFs with nested cleanups.
Although the current code has no bug, per se, let's follow the new standard and move the declaration to the place of assignment (or directly assign the allocated result) instead of NULL initializations.
--- sound/usb/usx2y/us144mkii.c | 4 ++-- sound/usb/usx2y/us144mkii_controls.c | 4 ++-- sound/usb/usx2y/us144mkii_pcm.c | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-)
sound/usb/usx2y/us144mkii.c +2 -2
@@ -412,7 +412,6 @@ static int tascam_probe(struct usb_interface *intf,struct snd_card *card;struct tascam_card *tascam;int err; - char *handshake_buf __free(kfree) = NULL;if (dev->speed !=USB_SPEED_HIGH ) dev_info(
@@ -439,7 +438,8 @@ static int tascam_probe(struct usb_interface *intf,return -ENOENT ; } - handshake_buf =kmalloc (1 ,GFP_KERNEL ); + char *handshake_buf __free(kfree) = +kmalloc (1 ,GFP_KERNEL );if (!handshake_buf)return -ENOMEM ;
sound/usb/usx2y/us144mkii_controls.c +2 -2
@@ -373,7 +373,6 @@ static int tascam_samplerate_get(struct snd_kcontrol *kcontrol, {struct tascam_card *tascam = (struct tascam_card *)snd_kcontrol_chip (kcontrol); - u8 *buf __free(kfree) = NULL;int err;u32 rate =0 ;
@@ -384,7 +383,8 @@ static int tascam_samplerate_get(struct snd_kcontrol *kcontrol, } } - buf =kmalloc (3 ,GFP_KERNEL ); + u8 *buf __free(kfree) = +kmalloc (3 ,GFP_KERNEL );if (!buf)return -ENOMEM ;
sound/usb/usx2y/us144mkii_pcm.c +2 -2
@@ -115,7 +115,6 @@ void process_capture_routing_us144mkii(struct tascam_card *tascam,int us144mkii_configure_device_for_rate (struct tascam_card *tascam,int rate) {struct usb_device *dev = tascam->dev; - u8 *rate_payload_buf __free(kfree) = NULL;u16 rate_vendor_wValue;int err =0 ;const u8 *current_payload_src;
@@ -148,7 +147,8 @@ int us144mkii_configure_device_for_rate(struct tascam_card *tascam, int rate)return -EINVAL ; } - rate_payload_buf =kmemdup (current_payload_src,3 ,GFP_KERNEL ); + u8 *rate_payload_buf __free(kfree) = +kmemdup (current_payload_src,3 ,GFP_KERNEL );if (!rate_payload_buf)return -ENOMEM ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 223/781 ALSA: usb-audio: Relax __free() variable declarations
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
[ Upstream commit 03f705b9ca58b91c6dffe64875ea3d9a38cad9b5 ]
We used to have a variable declaration with __free() initialized with NULL. This was to keep the old coding style rule, but recently it's relaxed and rather recommends to follow the new rule to declare in place of use for __free() -- which avoids potential deadlocks or UAFs with nested cleanups.
Although the current code has no bug, per se, let's follow the new standard and move the declaration to the place of assignment (or directly assign the allocated result) instead of NULL initializations.
Note that there are still a few remaining __free(kfree) with NULL initializations; they are because of the code complexity (the data size calculation).
--- sound/usb/fcp.c | 36 ++++++++++++++++++------------------ sound/usb/mixer_scarlett2.c | 21 ++++++++++----------- sound/usb/quirks.c | 13 ++++++------- 3 files changed, 34 insertions(+), 36 deletions(-)
sound/usb/fcp.c +18 -18
@@ -182,10 +182,6 @@ static int fcp_usb(struct usb_mixer_interface *mixer, u32 opcode, {struct fcp_data *private = mixer->private_data;struct usb_device *dev = mixer->chip->dev; - struct fcp_usb_packet *req __free(kfree) = NULL; - struct fcp_usb_packet *resp __free(kfree) = NULL; -size_t req_buf_size =struct_size (req, data, req_size); -size_t resp_buf_size =struct_size (resp, data, resp_size);int retries =0 ;const int max_retries =5 ;int err;
@@ -193,10 +189,14 @@ static int fcp_usb(struct usb_mixer_interface *mixer, u32 opcode,if (!mixer->urb)return -ENODEV ; + struct fcp_usb_packet *req __free(kfree) = NULL; +size_t req_buf_size =struct_size (req, data, req_size); req =kmalloc (req_buf_size,GFP_KERNEL );if (!req)return -ENOMEM ; + struct fcp_usb_packet *resp __free(kfree) = NULL; +size_t resp_buf_size =struct_size (resp, data, resp_size); resp =kmalloc (resp_buf_size,GFP_KERNEL );if (!resp)return -ENOMEM ;
@@ -300,16 +300,17 @@ static int fcp_usb(struct usb_mixer_interface *mixer, u32 opcode,static int fcp_reinit (struct usb_mixer_interface *mixer) {struct fcp_data *private = mixer->private_data; - void *step0_resp __free(kfree) = NULL; - void *step2_resp __free(kfree) = NULL;if (mixer->urb)return 0 ; - step0_resp =kmalloc (private->step0_resp_size,GFP_KERNEL ); + void *step0_resp __free(kfree) = +kmalloc (private->step0_resp_size,GFP_KERNEL );if (!step0_resp)return -ENOMEM ; - step2_resp =kmalloc (private->step2_resp_size,GFP_KERNEL ); + + void *step2_resp __free(kfree) = +kmalloc (private->step2_resp_size,GFP_KERNEL );if (!step2_resp)return -ENOMEM ;
@@ -464,7 +465,6 @@ static int fcp_ioctl_init(struct usb_mixer_interface *mixer,struct fcp_init init;struct usb_device *dev = mixer->chip->dev;struct fcp_data *private = mixer->private_data; - void *resp __free(kfree) = NULL;void *step2_resp;int err, buf_size;
@@ -485,7 +485,8 @@ static int fcp_ioctl_init(struct usb_mixer_interface *mixer,/* Allocate response buffer */ buf_size = init.step0_resp_size + init.step2_resp_size; - resp =kmalloc (buf_size,GFP_KERNEL ); + void *resp __free(kfree) = +kmalloc (buf_size,GFP_KERNEL );if (!resp)return -ENOMEM ;
@@ -619,7 +620,6 @@ static int fcp_ioctl_set_meter_map(struct usb_mixer_interface *mixer, {struct fcp_meter_map map;struct fcp_data *private = mixer->private_data; - s16 *tmp_map __free(kfree) = NULL;int err;if (copy_from_user (&map, arg,sizeof (map)))
@@ -641,7 +641,8 @@ static int fcp_ioctl_set_meter_map(struct usb_mixer_interface *mixer,return -EINVAL ;/* Allocate and copy the map data */ - tmp_map =memdup_array_user (arg->map, map.map_size,sizeof (s16)); + s16 *tmp_map __free(kfree) = +memdup_array_user (arg->map, map.map_size,sizeof (s16));if (IS_ERR (tmp_map))return PTR_ERR (tmp_map);
@@ -651,17 +652,16 @@ static int fcp_ioctl_set_meter_map(struct usb_mixer_interface *mixer,/* If the control doesn't exist, create it */ if (!private->meter_ctl) { - s16 *new_map __free(kfree) = NULL; - __le32 *meter_levels __free(kfree) = NULL; -/* Allocate buffer for the map */ - new_map =kmalloc_array (map.map_size,sizeof (s16),GFP_KERNEL ); + s16 *new_map __free(kfree) = +kmalloc_array (map.map_size,sizeof (s16),GFP_KERNEL );if (!new_map)return -ENOMEM ;/* Allocate buffer for reading meter levels */ - meter_levels =kmalloc_array (map.meter_slots,sizeof (__le32), -GFP_KERNEL ); + __le32 *meter_levels __free(kfree) = +kmalloc_array (map.meter_slots,sizeof (__le32), +GFP_KERNEL );if (!meter_levels)return -ENOMEM ;
sound/usb/mixer_scarlett2.c +10 -11
@@ -2377,18 +2377,18 @@ static int scarlett2_usb( {struct scarlett2_data *private = mixer->private_data;struct usb_device *dev = mixer->chip->dev; - struct scarlett2_usb_packet *req __free(kfree) = NULL; - struct scarlett2_usb_packet *resp __free(kfree) = NULL; -size_t req_buf_size =struct_size (req, data, req_size); -size_t resp_buf_size =struct_size (resp, data, resp_size);int retries =0 ;const int max_retries =5 ;int err; + struct scarlett2_usb_packet *req __free(kfree) = NULL; +size_t req_buf_size =struct_size (req, data, req_size); req =kmalloc (req_buf_size,GFP_KERNEL );if (!req)return -ENOMEM ; + struct scarlett2_usb_packet *resp __free(kfree) = NULL; +size_t resp_buf_size =struct_size (resp, data, resp_size); resp =kmalloc (resp_buf_size,GFP_KERNEL );if (!resp)return -ENOMEM ;
@@ -3919,9 +3919,9 @@ static int scarlett2_input_select_ctl_info(struct scarlett2_data *private = mixer->private_data;int inputs = private->info->gain_input_count;int i, err; - char **values __free(kfree) = NULL; + char **values __free(kfree) = +kcalloc (inputs,sizeof (char *),GFP_KERNEL ); - values =kcalloc (inputs,sizeof (char *),GFP_KERNEL );if (!values)return -ENOMEM ;
@@ -9083,8 +9083,6 @@ static long scarlett2_hwdep_read(struct snd_hwdep *hw,__le32 len; }__packed req; - u8 *resp __free(kfree) = NULL; -/* Flash segment must first be selected */ if (private->flash_write_state !=SCARLETT2_FLASH_WRITE_STATE_SELECTED )return -EINVAL ;
@@ -9122,7 +9120,8 @@ static long scarlett2_hwdep_read(struct snd_hwdep *hw, req.offset =cpu_to_le32 (*offset); req.len =cpu_to_le32 (count); - resp =kzalloc (count,GFP_KERNEL ); + u8 *resp __free(kfree) = +kzalloc (count,GFP_KERNEL );if (!resp)return -ENOMEM ;
@@ -9267,7 +9266,6 @@ static ssize_t scarlett2_devmap_read( loff_t pos) {struct usb_mixer_interface *mixer = entry->private_data; - u8 *resp_buf __free(kfree) = NULL;const size_t block_size =SCARLETT2_DEVMAP_BLOCK_SIZE ;size_t copied =0 ;
@@ -9277,7 +9275,8 @@ static ssize_t scarlett2_devmap_read(if (pos + count > entry->size) count = entry->size - pos; - resp_buf =kmalloc (block_size,GFP_KERNEL ); + u8 *resp_buf __free(kfree) = +kmalloc (block_size,GFP_KERNEL );if (!resp_buf)return -ENOMEM ;
sound/usb/quirks.c +6 -7
@@ -555,7 +555,6 @@ int snd_usb_create_quirk(struct snd_usb_audio *chip,static int snd_usb_extigy_boot_quirk (struct usb_device *dev,struct usb_interface *intf) {struct usb_host_config *config = dev->actconfig; - struct usb_device_descriptor *new_device_descriptor __free(kfree) = NULL;int err; if (le16_to_cpu(get_cfg_desc(config)->wTotalLength) == EXTIGY_FIRMWARE_SIZE_OLD ||
@@ -566,8 +565,8 @@ static int snd_usb_extigy_boot_quirk(struct usb_device *dev, struct usb_interfac 0x10, 0x43, 0x0001, 0x000a, NULL, 0);if (err <0 )dev_dbg (&dev->dev,"error sending boot message: %d\n" , err); - - new_device_descriptor =kmalloc (sizeof (*new_device_descriptor),GFP_KERNEL ); + struct usb_device_descriptor *new_device_descriptor __free(kfree) = +kmalloc (sizeof (*new_device_descriptor),GFP_KERNEL );if (!new_device_descriptor)return -ENOMEM ; err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
@@ -910,7 +909,6 @@ static void mbox2_setup_48_24_magic(struct usb_device *dev)static int snd_usb_mbox2_boot_quirk (struct usb_device *dev) {struct usb_host_config *config = dev->actconfig; - struct usb_device_descriptor *new_device_descriptor __free(kfree) = NULL;int err;u8 bootresponse[0x12 ];int fwsize;
@@ -945,7 +943,8 @@ static int snd_usb_mbox2_boot_quirk(struct usb_device *dev)dev_dbg (&dev->dev,"device initialised!\n" ); - new_device_descriptor =kmalloc (sizeof (*new_device_descriptor),GFP_KERNEL ); + struct usb_device_descriptor *new_device_descriptor __free(kfree) = +kmalloc (sizeof (*new_device_descriptor),GFP_KERNEL );if (!new_device_descriptor)return -ENOMEM ;
@@ -1267,7 +1266,6 @@ static void mbox3_setup_defaults(struct usb_device *dev)static int snd_usb_mbox3_boot_quirk (struct usb_device *dev) {struct usb_host_config *config = dev->actconfig; - struct usb_device_descriptor *new_device_descriptor __free(kfree) = NULL;int err;int descriptor_size;
@@ -1280,7 +1278,8 @@ static int snd_usb_mbox3_boot_quirk(struct usb_device *dev)dev_dbg (&dev->dev,"MBOX3: device initialised!\n" ); - new_device_descriptor =kmalloc (sizeof (*new_device_descriptor),GFP_KERNEL ); + struct usb_device_descriptor *new_device_descriptor __free(kfree) = +kmalloc (sizeof (*new_device_descriptor),GFP_KERNEL );if (!new_device_descriptor)return -ENOMEM ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 224/781 ASoC: SDCA: Allow sample width wild cards in set_usage()
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Simon Trimmer <[email protected]>
[ Upstream commit 87783532d34050e2bff6749a4fe9860e624a0540 ]
The SDCA spec allows the sample rate and width to be wild cards, but the current implementation of set_usage() only checked for a wild card of the sample rate.
--- sound/soc/sdca/sdca_asoc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/soc/sdca/sdca_asoc.c +1 -1
@@ -1478,7 +1478,7 @@ static int set_usage(struct device *dev, struct regmap *regmap,unsigned int rate =sdca_range (range,SDCA_USAGE_SAMPLE_RATE , i);unsigned int width =sdca_range (range,SDCA_USAGE_SAMPLE_WIDTH , i); -if ((!rate || rate == target_rate) && width == target_width) { +if ((!rate || rate == target_rate) && (!width || width == target_width)) {unsigned int usage =sdca_range (range,SDCA_USAGE_NUMBER , i);unsigned int reg =SDW_SDCA_CTL (function->desc->adr, entity->id, sel,0 );
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 225/781 drm/panthor: Fix NULL pointer dereference on panthor_fw_unplug
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Karunika Choo <[email protected]>
[ Upstream commit 920c6af98e98e6afedf6318a75bac95af8415c6c ]
This patch removes the MCU halt and wait for halt procedures during panthor_fw_unplug() as the MCU can be in a variety of states or the FW may not even be loaded/initialized at all, the latter of which can lead to a NULL pointer dereference.
It should be safe on unplug to just disable the MCU without waiting for it to halt as it may not be able to.
--- drivers/gpu/drm/panthor/panthor_fw.c | 4 ---- 1 file changed, 4 deletions(-)
drivers/gpu/drm/panthor/panthor_fw.c +0 -4
@@ -1260,10 +1260,6 @@ void panthor_fw_unplug(struct panthor_device *ptdev)if (ptdev->fw->irq.irq)panthor_job_irq_suspend (&ptdev->fw->irq); -panthor_fw_halt_mcu (ptdev); -if (!panthor_fw_wait_mcu_halted (ptdev)) -drm_warn (&ptdev->base,"Failed to halt MCU on unplug" ); -panthor_fw_stop (ptdev); }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 226/781 drm/i915/colorop: do not include headers from headers
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jani Nikula <[email protected]>
[ Upstream commit 6a3591522930897c3fdb326c5d48b906b5c30b71 ]
drm_colorop.h doesn't need the intel_display_types.h include for anything. Don't include headers from headers if it can be avoided.
--- drivers/gpu/drm/i915/display/intel_colorop.c | 2 ++ drivers/gpu/drm/i915/display/intel_colorop.h | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-)
drivers/gpu/drm/i915/display/intel_colorop.c +2 -0
@@ -2,7 +2,9 @@/* * Copyright © 2025 Intel Corporation */ +#include "intel_colorop.h" +#include "intel_display_types.h" struct intel_colorop *to_intel_colorop (struct drm_colorop *colorop) {
drivers/gpu/drm/i915/display/intel_colorop.h +3 -1
@@ -6,7 +6,9 @@#ifndef __INTEL_COLOROP_H__#define __INTEL_COLOROP_H__ -#include "intel_display_types.h" +enum intel_color_block ; +struct drm_colorop ; +struct intel_colorop ;struct intel_colorop *to_intel_colorop (struct drm_colorop *colorop);struct intel_colorop *intel_colorop_alloc (void );
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 227/781 drm/panthor: Evict groups before VM termination
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ketil Johnsen <[email protected]>
[ Upstream commit 565ed40b5fc1242f7538a016fce5a85f802d4fb5 ]
Ensure all related groups are evicted and suspended before VM destruction takes place.
This fixes an issue where panthor_vm_destroy() destroys and unmaps the heap context while there are still on slot groups using this. The FW will do a write out to the heap context when a CSG (group) is suspended, so a premature unmap of the heap context will cause a GPU page fault.
This page fault is quite harmless, and do not affect the continued operation of the GPU.
--- drivers/gpu/drm/panthor/panthor_mmu.c | 4 ++++ drivers/gpu/drm/panthor/panthor_sched.c | 14 ++++++++++++++ drivers/gpu/drm/panthor/panthor_sched.h | 1 + 3 files changed, 19 insertions(+)
drivers/gpu/drm/panthor/panthor_mmu.c +4 -0
@@ -1503,6 +1503,10 @@ static void panthor_vm_destroy(struct panthor_vm *vm) vm->destroyed = true; +/* Tell scheduler to stop all GPU work related to this VM */ +if (refcount_read (&vm->as.active_cnt) >0 ) +panthor_sched_prepare_for_vm_destruction (vm->ptdev); +mutex_lock (&vm->heaps.lock);panthor_heap_pool_destroy (vm->heaps.pool); vm->heaps.pool =NULL ;
drivers/gpu/drm/panthor/panthor_sched.c +14 -0
@@ -2805,6 +2805,20 @@ void panthor_sched_report_mmu_fault(struct panthor_device *ptdev)panthor_sched_immediate_tick (ptdev); } +void panthor_sched_prepare_for_vm_destruction (struct panthor_device *ptdev) +{ +/* FW can write out internal state, like the heap context, during CSG +* suspend. It is therefore important that the scheduler has fully +* evicted any pending and related groups before VM destruction can +* safely continue. Failure to do so can lead to GPU page faults. +* A controlled termination of a Panthor instance involves destroying +* the group(s) before the VM. This means any relevant group eviction +* has already been initiated by this point, and we just need to +* ensure that any pending tick_work() has been completed. +*/ +flush_work (&ptdev->scheduler->tick_work.work); +} +void panthor_sched_resume (struct panthor_device *ptdev) {/* Force a tick to re-evaluate after a resume. */
drivers/gpu/drm/panthor/panthor_sched.h +1 -0
@@ -50,6 +50,7 @@ void panthor_sched_suspend(struct panthor_device *ptdev);void panthor_sched_resume (struct panthor_device *ptdev);void panthor_sched_report_mmu_fault (struct panthor_device *ptdev); +void panthor_sched_prepare_for_vm_destruction (struct panthor_device *ptdev);void panthor_sched_report_fw_events (struct panthor_device *ptdev,u32 events);void panthor_fdinfo_gather_group_samples (struct panthor_file *pfile);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 228/781 drm/display/dp_mst: Add protection against 0 vcpi
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Suraj Kandpal <[email protected]>
[ Upstream commit 342ccffd9f77fc29fe1c05fd145e4d842bd2feaa ]
When releasing a timeslot there is a slight chance we may end up with the wrong payload mask due to overflow if the delayed_destroy_work ends up coming into play after a DP 2.1 monitor gets disconnected which causes vcpi to become 0 then we try to make the payload = ~BIT(vcpi - 1) which is a negative shift. VCPI id should never really be 0 hence skip changing the payload mask if VCPI is 0.
Otherwise it leads to
<7> [515.287237] xe 0000:03:00.0: [drm:drm_dp_mst_get_port_malloc [drm_display_helper]] port ffff888126ce9000 (3)
<4> [515.287267] -----------[ cut here ]-----------
<3> [515.287268] UBSAN: shift-out-of-bounds in ../drivers/gpu/drm/display/drm_dp_mst_topology.c:4575:36
<3> [515.287271] shift exponent -1 is negative
<4> [515.287275] CPU: 7 UID: 0 PID: 3108 Comm: kworker/u64:33 Tainted: G S U 6.17.0-rc6-lgci-xe-xe-3795-3e79699fa1b216e92+ #1 PREEMPT(voluntary) <4> [515.287279] Tainted: [S]=CPU_OUT_OF_SPEC, [U]=USER
<4> [515.287279] Hardware name: ASUS System Product Name/PRIME Z790-P WIFI, BIOS 1645 03/15/2024
<4> [515.287281] Workqueue: drm_dp_mst_wq drm_dp_delayed_destroy_work [drm_display_helper]
<4> [515.287303] Call Trace:
<4> [515.287304] <TASK>
<4> [515.287306] dump_stack_lvl+0xc1/0xf0
<4> [515.287313] dump_stack+0x10/0x20
<4> [515.287316] __ubsan_handle_shift_out_of_bounds+0x133/0x2e0 <4> [515.287324] ? drm_atomic_get_private_obj_state+0x186/0x1d0 <4> [515.287333] drm_dp_atomic_release_time_slots.cold+0x17/0x3d [drm_display_helper]
<4> [515.287355] mst_connector_atomic_check+0x159/0x180 [xe] <4> [515.287546] drm_atomic_helper_check_modeset+0x4d9/0xfa0 <4> [515.287550] ? __ww_mutex_lock.constprop.0+0x6f/0x1a60 <4> [515.287562] intel_atomic_check+0x119/0x2b80 [xe]
<4> [515.287740] ? find_held_lock+0x31/0x90
<4> [515.287747] ? lock_release+0xce/0x2a0
<4> [515.287754] drm_atomic_check_only+0x6a2/0xb40
<4> [515.287758] ? drm_atomic_add_affected_connectors+0x12b/0x140 <4> [515.287765] drm_atomic_commit+0x6e/0xf0
<4> [515.287766] ? _pfx__drm_printfn_info+0x10/0x10
<4> [515.287774] drm_client_modeset_commit_atomic+0x25c/0x2b0 <4> [515.287794] drm_client_modeset_commit_locked+0x60/0x1b0 <4> [515.287795] ? mutex_lock_nested+0x1b/0x30
<4> [515.287801] drm_client_modeset_commit+0x26/0x50
<4> [515.287804] __drm_fb_helper_restore_fbdev_mode_unlocked+0xdc/0x110 <4> [515.287810] drm_fb_helper_hotplug_event+0x120/0x140
<4> [515.287814] drm_fbdev_client_hotplug+0x28/0xd0
<4> [515.287819] drm_client_hotplug+0x6c/0xf0
<4> [515.287824] drm_client_dev_hotplug+0x9e/0xd0
<4> [515.287829] drm_kms_helper_hotplug_event+0x1a/0x30
<4> [515.287834] drm_dp_delayed_destroy_work+0x3df/0x410 [drm_display_helper]
<4> [515.287861] process_one_work+0x22b/0x6f0
<4> [515.287874] worker_thread+0x1e8/0x3d0
<4> [515.287879] ? __pfx_worker_thread+0x10/0x10
<4> [515.287882] kthread+0x11c/0x250
<4> [515.287886] ? __pfx_kthread+0x10/0x10
<4> [515.287890] ret_from_fork+0x2d7/0x310
<4> [515.287894] ? __pfx_kthread+0x10/0x10
<4> [515.287897] ret_from_fork_asm+0x1a/0x30
Stable-dep-of: e05b08d7d016 ("drm/atomic: convert drm_atomic_get_{old, new}_colorop_state() into proper functions")
--- drivers/gpu/drm/display/drm_dp_mst_topology.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/display/drm_dp_mst_topology.c +2 -1
@@ -4572,7 +4572,8 @@ int drm_dp_atomic_release_time_slots(struct drm_atomic_state *state,if (!payload->delete) { payload->pbn =0 ; payload->delete = true; - topology_state->payload_mask &= ~BIT (payload->vcpi -1 ); +if (payload->vcpi >0 ) + topology_state->payload_mask &= ~BIT (payload->vcpi -1 ); }return 0 ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 229/781 drm/atomic: convert drm_atomic_get_{old, new}_colorop_state() into proper functions
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jani Nikula <[email protected]>
[ Upstream commit e05b08d7d0162cf77fff119367fb1a2d5ab3e669 ]
There is no real reason to include drm_colorop.h from drm_atomic.h, as drm_atomic_get_{old,new}_colorop_state() have no real reason to be static inline.
Convert the static inlines to proper functions, and drop the include to reduce the include dependencies and improve data hiding.
v2: Fix vkms build failures (Alex)
--- .../amd/display/amdgpu_dm/amdgpu_dm_color.c | 3 ++ drivers/gpu/drm/drm_atomic.c | 32 +++++++++++++++ drivers/gpu/drm/drm_atomic_helper.c | 1 + .../drm/i915/display/intel_display_types.h | 1 + drivers/gpu/drm/vkms/vkms_composer.c | 1 + drivers/gpu/drm/vkms/vkms_drv.c | 1 + include/drm/drm_atomic.h | 39 ++++--------------- 7 files changed, 47 insertions(+), 31 deletions(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c +3 -0
@@ -23,6 +23,9 @@* Authors: AMD * */ + +#include <drm/drm_colorop.h> +#include "amdgpu.h" #include "amdgpu_mode.h" #include "amdgpu_dm.h"
drivers/gpu/drm/drm_atomic.c +32 -0
@@ -641,6 +641,38 @@ drm_atomic_get_colorop_state(struct drm_atomic_state *state, }EXPORT_SYMBOL (drm_atomic_get_colorop_state); +/** +* drm_atomic_get_old_colorop_state - get colorop state, if it exists +* @state: global atomic state object +* @colorop: colorop to grab +* +* This function returns the old colorop state for the given colorop, or +* NULL if the colorop is not part of the global atomic state. +*/ +struct drm_colorop_state * +drm_atomic_get_old_colorop_state (struct drm_atomic_state *state, +struct drm_colorop *colorop) +{ +return state->colorops[drm_colorop_index (colorop)].old_state; +} +EXPORT_SYMBOL (drm_atomic_get_old_colorop_state); + +/** +* drm_atomic_get_new_colorop_state - get colorop state, if it exists +* @state: global atomic state object +* @colorop: colorop to grab +* +* This function returns the new colorop state for the given colorop, or +* NULL if the colorop is not part of the global atomic state. +*/ +struct drm_colorop_state * +drm_atomic_get_new_colorop_state (struct drm_atomic_state *state, +struct drm_colorop *colorop) +{ +return state->colorops[drm_colorop_index (colorop)].new_state; +} +EXPORT_SYMBOL (drm_atomic_get_new_colorop_state); +static bool plane_switching_crtc (const struct drm_plane_state *old_plane_state,const struct drm_plane_state *new_plane_state)
drivers/gpu/drm/drm_atomic_helper.c +1 -0
@@ -34,6 +34,7 @@#include <drm/drm_atomic_uapi.h> #include <drm/drm_blend.h> #include <drm/drm_bridge.h> +#include <drm/drm_colorop.h> #include <drm/drm_damage_helper.h> #include <drm/drm_device.h> #include <drm/drm_drv.h>
drivers/gpu/drm/i915/display/intel_display_types.h +1 -0
@@ -34,6 +34,7 @@#include <drm/display/drm_dp_tunnel.h> #include <drm/display/drm_dsc.h> #include <drm/drm_atomic.h> +#include <drm/drm_colorop.h> #include <drm/drm_crtc.h> #include <drm/drm_encoder.h> #include <drm/drm_framebuffer.h>
drivers/gpu/drm/vkms/vkms_composer.c +1 -0
@@ -5,6 +5,7 @@#include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_blend.h> +#include <drm/drm_colorop.h> #include <drm/drm_fourcc.h> #include <drm/drm_fixed.h> #include <drm/drm_gem_framebuffer_helper.h>
drivers/gpu/drm/vkms/vkms_drv.c +1 -0
@@ -17,6 +17,7 @@#include <drm/drm_gem.h> #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_colorop.h> #include <drm/drm_drv.h> #include <drm/drm_fbdev_shmem.h> #include <drm/drm_file.h>
include/drm/drm_atomic.h +8 -31
@@ -30,7 +30,6 @@#include <drm/drm_crtc.h> #include <drm/drm_util.h> -#include <drm/drm_colorop.h> /** * struct drm_crtc_commit - track modeset commits on a CRTC
@@ -707,6 +706,14 @@ drm_atomic_get_plane_state(struct drm_atomic_state *state,struct drm_colorop_state *drm_atomic_get_colorop_state (struct drm_atomic_state *state,struct drm_colorop *colorop); + +struct drm_colorop_state * +drm_atomic_get_old_colorop_state (struct drm_atomic_state *state, +struct drm_colorop *colorop); +struct drm_colorop_state * +drm_atomic_get_new_colorop_state (struct drm_atomic_state *state, +struct drm_colorop *colorop); +struct drm_connector_state *__must_check drm_atomic_get_connector_state (struct drm_atomic_state *state,struct drm_connector *connector);
@@ -803,36 +810,6 @@ drm_atomic_get_new_plane_state(const struct drm_atomic_state *state,return state->planes[drm_plane_index (plane)].new_state; } -/** -* drm_atomic_get_old_colorop_state - get colorop state, if it exists -* @state: global atomic state object -* @colorop: colorop to grab -* -* This function returns the old colorop state for the given colorop, or -* NULL if the colorop is not part of the global atomic state. -*/ -static inline struct drm_colorop_state * -drm_atomic_get_old_colorop_state (struct drm_atomic_state *state, -struct drm_colorop *colorop) -{ -return state->colorops[drm_colorop_index (colorop)].old_state; -} - -/** -* drm_atomic_get_new_colorop_state - get colorop state, if it exists -* @state: global atomic state object -* @colorop: colorop to grab -* -* This function returns the new colorop state for the given colorop, or -* NULL if the colorop is not part of the global atomic state. -*/ -static inline struct drm_colorop_state * -drm_atomic_get_new_colorop_state (struct drm_atomic_state *state, -struct drm_colorop *colorop) -{ -return state->colorops[drm_colorop_index (colorop)].new_state; -} -/** * drm_atomic_get_old_connector_state - get connector state, if it exists * @state: global atomic state object
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 230/781 ima: Fix stack-out-of-bounds in is_bprm_creds_for_exec()
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chris J Arges <[email protected]>
[ Upstream commit 377cae9851e8559e9d8b82a78c1ac0abeb18839c ]
KASAN reported a stack-out-of-bounds access in ima_appraise_measurement from is_bprm_creds_for_exec:
BUG: KASAN: stack-out-of-bounds in ima_appraise_measurement+0x12dc/0x16a0 Read of size 1 at addr ffffc9000160f940 by task sudo/550 The buggy address belongs to stack of task sudo/550
and is located at offset 24 in frame:
ima_appraise_measurement+0x0/0x16a0
This frame has 2 objects:
[48, 56) 'file'
[80, 148) 'hash'
This is caused by using container_of on the *file pointer. This offset calculation is what triggers the stack-out-of-bounds error.
In order to fix this, pass in a bprm_is_check boolean which can be set depending on how process_measurement is called. If the caller has a linux_binprm pointer and the function is BPRM_CHECK we can determine is_check and set it then. Otherwise set it to false.
--- security/integrity/ima/ima.h | 6 ++++-- security/integrity/ima/ima_appraise.c | 16 +++------------- security/integrity/ima/ima_main.c | 22 +++++++++++++--------- 3 files changed, 20 insertions(+), 24 deletions(-)
security/integrity/ima/ima.h +4 -2
@@ -441,7 +441,8 @@ int ima_check_blacklist(struct ima_iint_cache *iint,int ima_appraise_measurement (enum ima_hooks func,struct ima_iint_cache *iint,struct file *file,const unsigned char *filename,struct evm_ima_xattr_data *xattr_value, -int xattr_len,const struct modsig *modsig); +int xattr_len,const struct modsig *modsig, +bool bprm_is_check);int ima_must_appraise (struct mnt_idmap *idmap,struct inode *inode,int mask,enum ima_hooks func);void ima_update_xattr (struct ima_iint_cache *iint,struct file *file);
@@ -466,7 +467,8 @@ static inline int ima_appraise_measurement(enum ima_hooks func,const unsigned char *filename, struct evm_ima_xattr_data *xattr_value, int xattr_len, - const struct modsig *modsig) + const struct modsig *modsig, + bool bprm_is_check) { return INTEGRITY_UNKNOWN; }
security/integrity/ima/ima_appraise.c +3 -13
@@ -470,17 +470,6 @@ int ima_check_blacklist(struct ima_iint_cache *iint,return rc; } -static bool is_bprm_creds_for_exec (enum ima_hooks func,struct file *file) -{ -struct linux_binprm *bprm; - -if (func ==BPRM_CHECK ) { - bprm = container_of(&file, struct linux_binprm, file); -return bprm->is_check; - } -return false; -} -/* * ima_appraise_measurement - appraise file measurement *
@@ -492,7 +481,8 @@ static bool is_bprm_creds_for_exec(enum ima_hooks func, struct file *file)int ima_appraise_measurement (enum ima_hooks func,struct ima_iint_cache *iint,struct file *file,const unsigned char *filename,struct evm_ima_xattr_data *xattr_value, -int xattr_len,const struct modsig *modsig) +int xattr_len,const struct modsig *modsig, +bool bprm_is_check) {static const char op[] ="appraise_data" ;int audit_msgno =AUDIT_INTEGRITY_DATA ;
@@ -514,7 +504,7 @@ int ima_appraise_measurement(enum ima_hooks func, struct ima_iint_cache *iint,* of the script interpreter(userspace). Differentiate kernel and * userspace enforced integrity audit messages. */ -if (is_bprm_creds_for_exec (func, file)) +if (bprm_is_check) audit_msgno =AUDIT_INTEGRITY_USERSPACE ;/* If reading the xattr failed and there's no modsig, error out. */
security/integrity/ima/ima_main.c +13 -9
@@ -236,7 +236,8 @@ static void ima_file_free(struct file *file)static int process_measurement (struct file *file,const struct cred *cred,struct lsm_prop *prop,char *buf,loff_t size,int mask,enum ima_hooks func, -enum kernel_read_file_id read_id) +enum kernel_read_file_id read_id, +bool bprm_is_check) {struct inode *real_inode, *inode =file_inode (file);struct ima_iint_cache *iint =NULL ;
@@ -426,7 +427,8 @@ static int process_measurement(struct file *file, const struct cred *cred,inode_lock (inode); rc =ima_appraise_measurement (func, iint, file, pathname, xattr_value, - xattr_len, modsig); + xattr_len, modsig, + bprm_is_check);inode_unlock (inode); }if (!rc)
@@ -493,14 +495,15 @@ static int ima_file_mmap(struct file *file, unsigned long reqprot,if (reqprot &PROT_EXEC ) { ret =process_measurement (file,current_cred (), &prop,NULL , -0 ,MAY_EXEC ,MMAP_CHECK_REQPROT ,0 ); +0 ,MAY_EXEC ,MMAP_CHECK_REQPROT ,0 , + false);if (ret)return ret; }if (prot &PROT_EXEC )return process_measurement (file,current_cred (), &prop,NULL , -0 ,MAY_EXEC ,MMAP_CHECK ,0 ); +0 ,MAY_EXEC ,MMAP_CHECK ,0 , false);return 0 ; }
@@ -584,7 +587,8 @@ static int ima_bprm_check(struct linux_binprm *bprm)security_current_getlsmprop_subj (&prop);return process_measurement (bprm->file,current_cred (), - &prop,NULL ,0 ,MAY_EXEC ,BPRM_CHECK ,0 ); + &prop,NULL ,0 ,MAY_EXEC ,BPRM_CHECK ,0 , + bprm->is_check); }/**
@@ -614,7 +618,7 @@ static int ima_creds_check(struct linux_binprm *bprm, const struct file *file)security_current_getlsmprop_subj (&prop);return process_measurement ((struct file *)file, bprm->cred, &prop,NULL , -0 ,MAY_EXEC ,CREDS_CHECK ,0 ); +0 ,MAY_EXEC ,CREDS_CHECK ,0 , false); }/**
@@ -662,7 +666,7 @@ static int ima_file_check(struct file *file, int mask)security_current_getlsmprop_subj (&prop);return process_measurement (file,current_cred (), &prop,NULL ,0 , mask & (MAY_READ |MAY_WRITE |MAY_EXEC | -MAY_APPEND ),FILE_CHECK ,0 ); +MAY_APPEND ),FILE_CHECK ,0 , false); } static int __ima_inode_hash(struct inode *inode, struct file *file, char *buf,
@@ -881,7 +885,7 @@ static int ima_read_file(struct file *file, enum kernel_read_file_id read_id, func = read_idmap[read_id] ?:FILE_CHECK ;security_current_getlsmprop_subj (&prop);return process_measurement (file,current_cred (), &prop,NULL ,0 , -MAY_READ , func,0 ); +MAY_READ , func,0 , false); }const int read_idmap[READING_MAX_ID ] = {
@@ -925,7 +929,7 @@ static int ima_post_read_file(struct file *file, char *buf, loff_t size, func = read_idmap[read_id] ?:FILE_CHECK ;security_current_getlsmprop_subj (&prop);return process_measurement (file,current_cred (), &prop, buf, size, -MAY_READ , func, read_id); +MAY_READ , func, read_id, false); }/**
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 231/781 smack: /smack/doi must be > 0
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Konstantin Andreev <[email protected]>
[ Upstream commit 19c013e1551bf51e1493da1270841d60e4fd3f15 ]
/smack/doi allows writing and keeping negative doi values. Correct values are 0 < doi <= (max 32-bit positive integer)
(2008-02-04, Casey Schaufler)
--- security/smack/smackfs.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
security/smack/smackfs.c +7 -5
@@ -141,7 +141,7 @@ struct smack_parsed_rule {int smk_access2; }; -static int smk_cipso_doi_value =SMACK_CIPSO_DOI_DEFAULT ; +static u32 smk_cipso_doi_value =SMACK_CIPSO_DOI_DEFAULT ;/* * Values for parsing cipso rules
@@ -1562,7 +1562,7 @@ static ssize_t smk_read_doi(struct file *filp, char __user *buf,if (*ppos !=0 )return 0 ; -sprintf (temp,"%d" , smk_cipso_doi_value); +sprintf (temp,"%lu" , (unsigned long )smk_cipso_doi_value); rc =simple_read_from_buffer (buf, count, ppos, temp,strlen (temp));return rc;
@@ -1581,7 +1581,7 @@ static ssize_t smk_write_doi(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { char temp[80]; -int i; +unsigned long u;if (!smack_privileged (CAP_MAC_ADMIN ))return -EPERM ;
@@ -1594,10 +1594,12 @@ static ssize_t smk_write_doi(struct file *file, const char __user *buf, temp[count] ='\0' ; -if (sscanf (temp,"%d" , &i) !=1 ) +if (kstrtoul (temp,10 , &u))return -EINVAL ; - smk_cipso_doi_value = i; +if (u ==CIPSO_V4_DOI_UNKNOWN || u >U32_MAX ) +return -EINVAL ; + smk_cipso_doi_value = u;smk_cipso_doi ();
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 232/781 smack: /smack/doi: accept previously used values
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Konstantin Andreev <[email protected]>
[ Upstream commit 33d589ed60ae433b483761987b85e0d24e54584e ]
Writing to /smack/doi a value that has ever been written there in the past disables networking for non-ambient labels.
E.g.
# cat /smack/doi
3
# netlabelctl -p cipso list
Configured CIPSO mappings (1)
DOI value : 3
mapping type : PASS_THROUGH
# netlabelctl -p map list
Configured NetLabel domain mappings (3)
domain: "_" (IPv4)
protocol: UNLABELED
domain: DEFAULT (IPv4)
protocol: CIPSO, DOI = 3
domain: DEFAULT (IPv6)
protocol: UNLABELED # cat /smack/ambient
_
# cat /proc/$$/attr/smack/current
_
# ping -c1 10.1.95.12
64 bytes from 10.1.95.12: icmp_seq=1 ttl=64 time=0.964 ms
# echo foo >/proc/$$/attr/smack/current
# ping -c1 10.1.95.12
64 bytes from 10.1.95.12: icmp_seq=1 ttl=64 time=0.956 ms
unknown option 86 # echo 4 >/smack/doi
# echo 3 >/smack/doi
!> [ 214.050395] smk_cipso_doi:691 cipso add rc = -17
# echo 3 >/smack/doi
!> [ 249.402261] smk_cipso_doi:678 remove rc = -2
!> [ 249.402261] smk_cipso_doi:691 cipso add rc = -17# ping -c1 10.1.95.12 !!> ping: 10.1.95.12: Address family for hostname not supported
# echo _ >/proc/$$/attr/smack/current
# ping -c1 10.1.95.12
64 bytes from 10.1.95.12: icmp_seq=1 ttl=64 time=0.617 msThis happens because Smack keeps decommissioned DOIs, fails to re-add them, and consequently refuses to add the “default” domain map:
# netlabelctl -p cipso list
Configured CIPSO mappings (2)
DOI value : 3
mapping type : PASS_THROUGH
DOI value : 4
mapping type : PASS_THROUGH
# netlabelctl -p map list
Configured NetLabel domain mappings (2)
domain: "_" (IPv4)
protocol: UNLABELED
!> (no ipv4 map for default domain here)
domain: DEFAULT (IPv6)
protocol: UNLABELEDFix by clearing decommissioned DOI definitions and serializing concurrent DOI updates with a new lock.
Also:
- allow /smack/doi to live unconfigured, since adding a map (netlbl_cfg_cipsov4_map_add) may fail. CIPSO_V4_DOI_UNKNOWN(0) indicates the unconfigured DOI
- add new DOI before removing the old default map, so the old map remains if the add fails
(2008-02-04, Casey Schaufler)
--- security/smack/smackfs.c | 71 +++++++++++++++++++++++++--------------- 1 file changed, 45 insertions(+), 26 deletions(-)
security/smack/smackfs.c +45 -26
@@ -70,6 +70,7 @@ enum smk_inos {static DEFINE_MUTEX (smack_cipso_lock);static DEFINE_MUTEX (smack_ambient_lock);static DEFINE_MUTEX (smk_net4addr_lock); +static DEFINE_MUTEX (smk_cipso_doi_lock);#if IS_ENABLED (CONFIG_IPV6 )static DEFINE_MUTEX (smk_net6addr_lock);#endif /* CONFIG_IPV6 */
@@ -141,7 +142,7 @@ struct smack_parsed_rule {int smk_access2; }; -static u32 smk_cipso_doi_value =SMACK_CIPSO_DOI_DEFAULT ; +static u32 smk_cipso_doi_value =CIPSO_V4_DOI_UNKNOWN ;/* * Values for parsing cipso rules
@@ -663,43 +664,60 @@ static const struct file_operations smk_load_ops = { };/** -* smk_cipso_doi - initialize the CIPSO domain +* smk_cipso_doi - set netlabel maps +* @ndoi: new value for our CIPSO DOI +* @gfp_flags: kmalloc allocation context */ -static void smk_cipso_doi (void ) +static int +smk_cipso_doi (u32 ndoi,gfp_t gfp_flags) { -int rc; +int rc =0 ;struct cipso_v4_doi *doip;struct netlbl_audit nai; -smk_netlabel_audit_set (&nai); +mutex_lock (&smk_cipso_doi_lock); - rc =netlbl_cfg_map_del (NULL ,PF_INET ,NULL ,NULL , &nai); -if (rc !=0 ) -printk (KERN_WARNING "%s:%d remove rc = %d\n" , - __func__, __LINE__, rc); +if (smk_cipso_doi_value == ndoi) + goto clr_doi_lock; + +smk_netlabel_audit_set (&nai); - doip =kmalloc (sizeof (struct cipso_v4_doi ),GFP_KERNEL | __GFP_NOFAIL); + doip =kmalloc (sizeof (struct cipso_v4_doi ), gfp_flags); +if (!doip) { + rc = -ENOMEM ; + goto clr_doi_lock; + } doip->map.std =NULL ; - doip->doi = smk_cipso_doi_value; + doip->doi = ndoi; doip->type =CIPSO_V4_MAP_PASS ; doip->tags[0 ] =CIPSO_V4_TAG_RBITMAP ;for (rc =1 ; rc <CIPSO_V4_TAG_MAXCNT ; rc++) doip->tags[rc] =CIPSO_V4_TAG_INVALID ; rc =netlbl_cfg_cipsov4_add (doip, &nai); -if (rc !=0 ) { -printk (KERN_WARNING "%s:%d cipso add rc = %d\n" , - __func__, __LINE__, rc); +if (rc) {kfree (doip); -return ; + goto clr_doi_lock; } - rc =netlbl_cfg_cipsov4_map_add (doip->doi,NULL ,NULL ,NULL , &nai); -if (rc !=0 ) { -printk (KERN_WARNING "%s:%d map add rc = %d\n" , - __func__, __LINE__, rc); -netlbl_cfg_cipsov4_del (doip->doi, &nai); -return ; + +if (smk_cipso_doi_value !=CIPSO_V4_DOI_UNKNOWN ) { + rc =netlbl_cfg_map_del (NULL ,PF_INET ,NULL ,NULL , &nai); +if (rc && rc != -ENOENT ) + goto clr_ndoi_def; + +netlbl_cfg_cipsov4_del (smk_cipso_doi_value, &nai); } + + rc =netlbl_cfg_cipsov4_map_add (ndoi,NULL ,NULL ,NULL , &nai); +if (rc) { + smk_cipso_doi_value =CIPSO_V4_DOI_UNKNOWN ;// no default map +clr_ndoi_def:netlbl_cfg_cipsov4_del (ndoi, &nai); + }else + smk_cipso_doi_value = ndoi; + +clr_doi_lock: +mutex_unlock (&smk_cipso_doi_lock); +return rc; }/**
@@ -1599,11 +1617,8 @@ static ssize_t smk_write_doi(struct file *file, const char __user *buf,if (u ==CIPSO_V4_DOI_UNKNOWN || u >U32_MAX )return -EINVAL ; - smk_cipso_doi_value = u; - -smk_cipso_doi (); -return count; +return smk_cipso_doi (u,GFP_KERNEL ) ? : count; }static const struct file_operations smk_doi_ops = {
@@ -2984,6 +2999,7 @@ int __init init_smk_fs(void) {int err;int rc; +struct netlbl_audit nai;if (smack_enabled ==0 )return 0 ;
@@ -3002,7 +3018,10 @@ int __init init_smk_fs(void) } } -smk_cipso_doi (); +smk_netlabel_audit_set (&nai); + (void )netlbl_cfg_map_del (NULL ,PF_INET ,NULL ,NULL , &nai); + (void )smk_cipso_doi (SMACK_CIPSO_DOI_DEFAULT , +GFP_KERNEL | __GFP_NOFAIL);smk_unlbl_ambient (NULL ); rc =smack_populate_secattr (&smack_known_floor);
Signature · 1 line
2.51.0