5.10.94-rc1 review
Subsystems (9)
Greg Kroah-Hartman
maintainerPATCH 137/563 bpf: Disallow BPF_LOG_KERNEL log level for bpf(BPF_BTF_LOAD)
In reply to Greg Kroah-HartmanFrom: Hou Tao <[email protected]>
[ Upstream commit 866de407444398bc8140ea70de1dba5f91cc34ac ]
BPF_LOG_KERNEL is only used internally, so disallow bpf_btf_load() to set log level as BPF_LOG_KERNEL. The same checking has already been done in bpf_check(), so factor out a helper to check the validity of log attributes and use it in both places.
--- include/linux/bpf_verifier.h | 7 +++++++ kernel/bpf/btf.c | 3 +-- kernel/bpf/verifier.c | 6 +++--- 3 files changed, 11 insertions(+), 5 deletions(-)
include/linux/bpf_verifier.h +7 -0
@@ -367,6 +367,13 @@ static inline bool bpf_verifier_log_needed(const struct bpf_verifier_log *log) log->level == BPF_LOG_KERNEL); } +static inline bool +bpf_verifier_log_attr_valid (const struct bpf_verifier_log *log) +{ +return log->len_total >=128 && log->len_total <=UINT_MAX >>2 && + log->level && log->ubuf && !(log->level & ~BPF_LOG_MASK ); +} +#define BPF_MAX_SUBPROGS 256struct bpf_subprog_info {
kernel/bpf/btf.c +1 -2
@@ -4135,8 +4135,7 @@ static struct btf *btf_parse(void __user *btf_data, u32 btf_data_size, log->len_total = log_size;/* log attributes have to be sane */ -if (log->len_total <128 || log->len_total >UINT_MAX >>2 || - !log->level || !log->ubuf) { +if (!bpf_verifier_log_attr_valid (log)) { err = -EINVAL ; goto errout; }
kernel/bpf/verifier.c +3 -3
@@ -12349,11 +12349,11 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, log->ubuf = (char __user *) (unsigned long ) attr->log_buf; log->len_total = attr->log_size; - ret = -EINVAL ;/* log attributes have to be sane */ -if (log->len_total <128 || log->len_total >UINT_MAX >>2 || - !log->level || !log->ubuf || log->level & ~BPF_LOG_MASK ) +if (!bpf_verifier_log_attr_valid (log)) { + ret = -EINVAL ; goto err_unlock; + } }if (IS_ERR (btf_vmlinux)) {
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 138/563 bpf: Remove config check to enable bpf support for branch records
In reply to Greg Kroah-HartmanFrom: Kajol Jain <[email protected]>
[ Upstream commit db52f57211b4e45f0ebb274e2c877b211dc18591 ]
Branch data available to BPF programs can be very useful to get stack traces out of userspace application.
Commit fff7b64355ea ("bpf: Add bpf_read_branch_records() helper") added BPF support to capture branch records in x86. Enable this feature also for other architectures as well by removing checks specific to x86.
If an architecture doesn't support branch records, bpf_read_branch_records() still has appropriate checks and it will return an -EINVAL in that scenario. Based on UAPI helper doc in include/uapi/linux/bpf.h, unsupported architectures should return -ENOENT in such case. Hence, update the appropriate check to return -ENOENT instead.
Selftest 'perf_branches' result on power9 machine which has the branch stacks support:
- Before this patch:
[command]# ./test_progs -t perf_branches
#88/1 perf_branches/perf_branches_hw:FAIL
#88/2 perf_branches/perf_branches_no_hw:OK
#88 perf_branches:FAIL
Summary: 0/1 PASSED, 0 SKIPPED, 1 FAILED
- After this patch:
[command]# ./test_progs -t perf_branches
#88/1 perf_branches/perf_branches_hw:OK
#88/2 perf_branches/perf_branches_no_hw:OK
#88 perf_branches:OK
Summary: 1/2 PASSED, 0 SKIPPED, 0 FAILED
Selftest 'perf_branches' result on power9 machine which doesn't have branch stack report:
- After this patch:
[command]# ./test_progs -t perf_branches
#88/1 perf_branches/perf_branches_hw:SKIP
#88/2 perf_branches/perf_branches_no_hw:OK
#88 perf_branches:OK
Summary: 1/1 PASSED, 1 SKIPPED, 0 FAILED
--- kernel/trace/bpf_trace.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-)
kernel/trace/bpf_trace.c +1 -5
@@ -1517,9 +1517,6 @@ static const struct bpf_func_proto bpf_perf_prog_read_value_proto = { BPF_CALL_4(bpf_read_branch_records, struct bpf_perf_event_data_kern *, ctx, void *, buf, u32, size, u64, flags) { -#ifndef CONFIG_X86 -return -ENOENT ; -#else static const u32 br_entry_size =sizeof (struct perf_branch_entry );struct perf_branch_stack *br_stack = ctx->data->br_stack;u32 to_copy;
@@ -1528,7 +1525,7 @@ BPF_CALL_4(bpf_read_branch_records, struct bpf_perf_event_data_kern *, ctx,return -EINVAL ;if (unlikely (!br_stack)) -return -EINVAL ; +return -ENOENT ;if (flags &BPF_F_GET_BRANCH_RECORDS_SIZE )return br_stack->nr * br_entry_size;
@@ -1540,7 +1537,6 @@ BPF_CALL_4(bpf_read_branch_records, struct bpf_perf_event_data_kern *, ctx,memcpy (buf, br_stack->entries, to_copy);return to_copy; -#endif }static const struct bpf_func_proto bpf_read_branch_records_proto = {
Signature · 1 line
2.34.1
Re: [PATCH 5.10 138/563] bpf: Remove config check to enable bpf support for branch records
Hi!
Quoted 35 lines
Branch data available to BPF programs can be very useful to get stack traces out of userspace application.
Commit
fff7b64355ea("bpf: Addbpf_read_branch_records()helper") added BPF support to capture branch records in x86. Enable this feature also for other architectures as well by removing checks specific to x86.If an architecture doesn't support branch records,
bpf_read_branch_records()still has appropriate checks and it will return an-EINVALin that scenario. Based on UAPI helper doc ininclude/uapi/linux/bpf.h, unsupported architectures should return-ENOENTin such case. Hence, update the appropriate check to return-ENOENTinstead.Selftest '
perf_branches' result on power9 machine which has the branch stacks support:- Before this patch:
[command]# ./test_progs -t
perf_branches
#88/1 perf_branches/perf_branches_hw:FAIL
#88/2 perf_branches/perf_branches_no_hw:OK
#88 perf_branches:FAIL
Summary: 0/1 PASSED, 0 SKIPPED, 1 FAILED- After this patch:
[command]# ./test_progs -t
perf_branches
#88/1 perf_branches/perf_branches_hw:OK
#88/2 perf_branches/perf_branches_no_hw:OK
#88 perf_branches:OK
Summary: 1/2 PASSED, 0 SKIPPED, 0 FAILEDSelftest '
perf_branches' result on power9 machine which doesn't have branch stack report:
Quoted 7 lines
- After this patch:
[command]# ./test_progs -t
perf_branches
#88/1 perf_branches/perf_branches_hw:SKIP
#88/2 perf_branches/perf_branches_no_hw:OK
#88 perf_branches:OK
Summary: 1/1 PASSED, 1 SKIPPED, 0 FAILED
This makes me nervous, it is not really a bugfix and probably noone tested it on the stable branch. It would be safer to keep it disabled.
Best regards,
Pavel
Signature · 2 lines
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Greg Kroah-Hartman
maintainerPATCH 139/563 arm64: lib: Annotate {clear, copy}_page() as position-independent
In reply to Greg Kroah-HartmanFrom: Will Deacon <[email protected]>
[ Upstream commit 8d9902055c57548bb342dc3ca78caa21e9643024 ]
clear_page() and copy_page() are suitable for use outside of the kernel address space, so annotate them as position-independent code.
--- arch/arm64/lib/clear_page.S | 4 ++-- arch/arm64/lib/copy_page.S | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-)
arch/arm64/lib/clear_page.S +2 -2
@@ -14,7 +14,7 @@ * Parameters: * x0 - dest */ -SYM_FUNC_START(clear_page) +SYM_FUNC_START_PI(clear_page) mrs x1, dczid_el0 and w1, w1, #0xf mov x2, #4
@@ -25,5 +25,5 @@ SYM_FUNC_START(clear_page) tst x0, #(PAGE_SIZE - 1) b.ne 1b ret -SYM_FUNC_END(clear_page) +SYM_FUNC_END_PI(clear_page) EXPORT_SYMBOL(clear_page)
arch/arm64/lib/copy_page.S +2 -2
@@ -17,7 +17,7 @@ * x0 - dest * x1 - src */ -SYM_FUNC_START(copy_page) +SYM_FUNC_START_PI(copy_page) alternative_if ARM64_HAS_NO_HW_PREFETCH // Prefetch three cache lines ahead. prfm pldl1strm, [x1, #128]
@@ -75,5 +75,5 @@ alternative_else_nop_endif stnp x16, x17, [x0, #112 - 256] ret -SYM_FUNC_END(copy_page) +SYM_FUNC_END_PI(copy_page) EXPORT_SYMBOL(copy_page)
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 140/563 arm64: clear_page() shouldnt use DC ZVA when DCZID_EL0.DZP == 1
In reply to Greg Kroah-HartmanFrom: Reiji Watanabe <[email protected]>
[ Upstream commit f0616abd4e67143b45b04b565839148458857347 ]
Currently, clear_page() uses DC ZVA instruction unconditionally. But it should make sure that DCZID_EL0.DZP, which indicates whether or not use of DC ZVA instruction is prohibited, is zero when using the instruction. Use STNP instead when DCZID_EL0.DZP == 1.
--- arch/arm64/lib/clear_page.S | 10 ++++++++++ 1 file changed, 10 insertions(+)
arch/arm64/lib/clear_page.S +10 -0
@@ -16,6 +16,7 @@ */ SYM_FUNC_START_PI(clear_page) mrs x1, dczid_el0 + tbnz x1, #4, 2f /* Branch if DC ZVA is prohibited */ and w1, w1, #0xf mov x2, #4 lsl x1, x2, x1
@@ -25,5 +26,14 @@ SYM_FUNC_START_PI(clear_page) tst x0, #(PAGE_SIZE - 1) b.ne 1b ret + +2: stnp xzr, xzr, [x0] + stnp xzr, xzr, [x0, #16] + stnp xzr, xzr, [x0, #32] + stnp xzr, xzr, [x0, #48] + add x0, x0, #64 + tst x0, #(PAGE_SIZE - 1) + b.ne 2b + ret SYM_FUNC_END_PI(clear_page) EXPORT_SYMBOL(clear_page)
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 141/563 media: dib8000: Fix a memleak in dib8000_init()
In reply to Greg Kroah-HartmanFrom: Zhou Qingyang <[email protected]>
[ Upstream commit 8dbdcc7269a83305ee9d677b75064d3530a48ee2 ]
In dib8000_init(), the variable fe is not freed or passed out on the failure of dib8000_identify(&state->i2c), which could lead to a memleak.
Fix this bug by adding a kfree of fe in the error path.
This bug was found by a static analyzer. The analysis employs differential checking to identify inconsistent security operations (e.g., checks or kfrees) between two code paths and confirms that the inconsistent operations are not recovered in the current function or the callers, so they constitute bugs.
Note that, as a bug found by static analysis, it can be a false positive or hard to trigger. Multiple researchers have cross-reviewed the bug.
Builds with CONFIG_DVB_DIB8000=m show no new warnings, and our static analyzer no longer warns about this code.
--- drivers/media/dvb-frontends/dib8000.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/media/dvb-frontends/dib8000.c +3 -1
@@ -4473,8 +4473,10 @@ static struct dvb_frontend *dib8000_init(struct i2c_adapter *i2c_adap, u8 i2c_ad state->timf_default = cfg->pll->timf; -if (dib8000_identify (&state->i2c) ==0 ) +if (dib8000_identify (&state->i2c) ==0 ) { +kfree (fe); goto error; + }dibx000_init_i2c_master (&state->i2c_master,DIB8000 , state->i2c.adap, state->i2c.addr);
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 142/563 media: saa7146: mxb: Fix a NULL pointer dereference in mxb_attach()
In reply to Greg Kroah-HartmanFrom: Zhou Qingyang <[email protected]>
[ Upstream commit 0407c49ebe330333478440157c640fffd986f41b ]
In mxb_attach(dev, info), saa7146_vv_init() is called to allocate a new memory for dev->vv_data. saa7146_vv_release() will be called on failure of mxb_probe(dev). There is a dereference of dev->vv_data in saa7146_vv_release(), which could lead to a NULL pointer dereference on failure of saa7146_vv_init().
Fix this bug by adding a check of saa7146_vv_init().
This bug was found by a static analyzer. The analysis employs differential checking to identify inconsistent security operations (e.g., checks or kfrees) between two code paths and confirms that the inconsistent operations are not recovered in the current function or the callers, so they constitute bugs.
Note that, as a bug found by static analysis, it can be a false positive or hard to trigger. Multiple researchers have cross-reviewed the bug.
Builds with CONFIG_VIDEO_MXB=m show no new warnings, and our static analyzer no longer warns about this code.
--- drivers/media/pci/saa7146/mxb.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/media/pci/saa7146/mxb.c +7 -1
@@ -683,10 +683,16 @@ static struct saa7146_ext_vv vv_data;static int mxb_attach (struct saa7146_dev *dev,struct saa7146_pci_extension_data *info) {struct mxb *mxb; +int ret;DEB_EE ("dev:%p\n" , dev); -saa7146_vv_init (dev, &vv_data); + ret =saa7146_vv_init (dev, &vv_data); +if (ret) { +ERR ("Error in saa7146_vv_init()" ); +return ret; + } +if (mxb_probe (dev)) {saa7146_vv_release (dev);return -1 ;
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 143/563 media: si2157: Fix "warm" tuner state detection
In reply to Greg Kroah-HartmanFrom: Robert Schlabbach <[email protected]>
[ Upstream commit a6441ea29cb2c9314654e093a1cd8020b9b851c8 ]
Commit e955f959ac52 ("media: si2157: Better check for running tuner in init") completely broke the "warm" tuner detection of the si2157 driver due to a simple endian error: The Si2157 CRYSTAL_TRIM property code is 0x0402 and needs to be transmitted LSB first. However, it was inserted MSB first, causing the warm detection to always fail and spam the kernel log with tuner initialization messages each time the DVB frontend device was closed and reopened:
[ 312.215682] si2157 16-0060: found a 'Silicon Labs Si2157-A30' [ 312.264334] si2157 16-0060: firmware version: 3.0.5 [ 342.248593] si2157 16-0060: found a 'Silicon Labs Si2157-A30' [ 342.295743] si2157 16-0060: firmware version: 3.0.5 [ 372.328574] si2157 16-0060: found a 'Silicon Labs Si2157-A30' [ 372.385035] si2157 16-0060: firmware version: 3.0.5
Also, the reinitializations were observed disturb _other_ tuners on multi-tuner cards such as the Hauppauge WinTV-QuadHD, leading to missed or errored packets when one of the other DVB frontend devices on that card was opened.
Fix the order of the property code bytes to make the warm detection work again, also reducing the tuner initialization message in the kernel log to once per power-on, as well as fixing the interference with other tuners.
--- drivers/media/tuners/si2157.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/media/tuners/si2157.c +1 -1
@@ -90,7 +90,7 @@ static int si2157_init(struct dvb_frontend *fe)dev_dbg (&client->dev,"\n" );/* Try to get Xtal trim property, to verify tuner still running */ -memcpy (cmd.args,"\x15\x00\x04\x02" ,4 ); +memcpy (cmd.args,"\x15\x00\x02\x04" ,4 ); cmd.wlen =4 ; cmd.rlen =4 ; ret =si2157_cmd_execute (client, &cmd);
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 144/563 wireless: iwlwifi: Fix a double free in iwl_txq_dyn_alloc_dma
In reply to Greg Kroah-HartmanFrom: Lv Yunlong <[email protected]>
[ Upstream commit f973795a8d19cbf3d03807704eb7c6ff65788d5a ]
In iwl_txq_dyn_alloc_dma, txq->tfds is freed at first time by:
iwl_txq_alloc()->goto err_free_tfds->dma_free_coherent(). But it forgot to set txq->tfds to NULL.
Then the txq->tfds is freed again in iwl_txq_dyn_alloc_dma by:
goto error->iwl_txq_gen2_free_memory()->dma_free_coherent().
My patch sets txq->tfds to NULL after the first free to avoid the double free.
--- drivers/net/wireless/intel/iwlwifi/queue/tx.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/wireless/intel/iwlwifi/queue/tx.c +1 -0
@@ -1148,6 +1148,7 @@ int iwl_txq_alloc(struct iwl_trans *trans, struct iwl_txq *txq, int slots_num,return 0 ; err_free_tfds:dma_free_coherent (trans->dev, tfd_sz, txq->tfds, txq->dma_addr); + txq->tfds =NULL ; error:if (txq->entries && cmd_queue)for (i =0 ; i < slots_num; i++)
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 145/563 sched/rt: Try to restart rt period timer when rt runtime exceeded
In reply to Greg Kroah-HartmanFrom: Li Hua <[email protected]>
[ Upstream commit 9b58e976b3b391c0cf02e038d53dd0478ed3013c ]
When rt_runtime is modified from -1 to a valid control value, it may cause the task to be throttled all the time. Operations like the following will trigger the bug. E.g:
1. echo -1 > /proc/sys/kernel/sched_rt_runtime_us
2. Run a FIFO task named A that executes while(1)
3. echo 950000 > /proc/sys/kernel/sched_rt_runtime_us
When rt_runtime is -1, The rt period timer will not be activated when task A enqueued. And then the task will be throttled after setting rt_runtime to 950,000. The task will always be throttled because the rt period timer is not activated.
--- kernel/sched/rt.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-)
kernel/sched/rt.c +18 -5
@@ -52,11 +52,8 @@ void init_rt_bandwidth(struct rt_bandwidth *rt_b, u64 period, u64 runtime) rt_b->rt_period_timer.function = sched_rt_period_timer; } -static void start_rt_bandwidth (struct rt_bandwidth *rt_b) +static inline void do_start_rt_bandwidth (struct rt_bandwidth *rt_b) { -if (!rt_bandwidth_enabled () || rt_b->rt_runtime ==RUNTIME_INF ) -return ; -raw_spin_lock (&rt_b->rt_runtime_lock);if (!rt_b->rt_period_active) { rt_b->rt_period_active =1 ;
@@ -75,6 +72,14 @@ static void start_rt_bandwidth(struct rt_bandwidth *rt_b)raw_spin_unlock (&rt_b->rt_runtime_lock); } +static void start_rt_bandwidth (struct rt_bandwidth *rt_b) +{ +if (!rt_bandwidth_enabled () || rt_b->rt_runtime ==RUNTIME_INF ) +return ; + +do_start_rt_bandwidth (rt_b); +} +void init_rt_rq (struct rt_rq *rt_rq) {struct rt_prio_array *array;
@@ -1022,13 +1027,17 @@ static void update_curr_rt(struct rq *rq)for_each_sched_rt_entity (rt_se) {struct rt_rq *rt_rq =rt_rq_of_se (rt_se); +int exceeded;if (sched_rt_runtime (rt_rq) !=RUNTIME_INF ) {raw_spin_lock (&rt_rq->rt_runtime_lock); rt_rq->rt_time += delta_exec; -if (sched_rt_runtime_exceeded (rt_rq)) + exceeded =sched_rt_runtime_exceeded (rt_rq); +if (exceeded)resched_curr (rq);raw_spin_unlock (&rt_rq->rt_runtime_lock); +if (exceeded) +do_start_rt_bandwidth (sched_rt_bandwidth (rt_rq)); } } }
@@ -2727,8 +2736,12 @@ static int sched_rt_global_validate(void)static void sched_rt_do_global (void ) { +unsigned long flags; + +raw_spin_lock_irqsave (&def_rt_bandwidth.rt_runtime_lock, flags); def_rt_bandwidth.rt_runtime =global_rt_runtime (); def_rt_bandwidth.rt_period =ns_to_ktime (global_rt_period ()); +raw_spin_unlock_irqrestore (&def_rt_bandwidth.rt_runtime_lock, flags); } int sched_rt_handler(struct ctl_table *table, int write, void *buffer,
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 146/563 drm/msm/dp: displayPort driver need algorithm rational
In reply to Greg Kroah-HartmanFrom: Jackie Liu <[email protected]>
[ Upstream commit 53d22794711ad630f40d59dd726bd260d77d585f ]
Let's select RATIONAL with dp driver. avoid like:
[...]
x86_64-linux-gnu-ld: drivers/gpu/drm/msm/dp/dp_catalog.o: in function `dp_catalog_ctrl_config_msa':
dp_catalog.c:(.text+0x57e): undefined reference to `rational_best_approximation'
--- drivers/gpu/drm/msm/Kconfig | 1 + 1 file changed, 1 insertion(+)
drivers/gpu/drm/msm/Kconfig +1 -0
@@ -60,6 +60,7 @@ config DRM_MSM_HDMI_HDCP config DRM_MSM_DP bool "Enable DisplayPort support in MSM DRM driver" depends on DRM_MSM + select RATIONAL default y help Compile in support for DP driver in MSM DRM driver. DP external
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 147/563 rcu/exp: Mark current CPU as exp-QS in IPI loop second pass
In reply to Greg Kroah-HartmanFrom: Frederic Weisbecker <[email protected]>
[ Upstream commit 81f6d49cce2d2fe507e3fddcc4a6db021d9c2e7b ]
Expedited RCU grace periods invoke sync_rcu_exp_select_node_cpus(), which takes two passes over the leaf rcu_node structure's CPUs. The first pass gathers up the current CPU and CPUs that are in dynticks idle mode. The workqueue will report a quiescent state on their behalf later. The second pass sends IPIs to the rest of the CPUs, but excludes the current CPU, incorrectly assuming it has been included in the first pass's list of CPUs.
Unfortunately the current CPU may have changed between the first and second pass, due to the fact that the various rcu_node structures' ->lock fields have been dropped, thus momentarily enabling preemption. This means that if the second pass's CPU was not on the first pass's list, it will be ignored completely. There will be no IPI sent to it, and there will be no reporting of quiescent states on its behalf. Unfortunately, the expedited grace period will nevertheless be waiting for that CPU to report a quiescent state, but with that CPU having no reason to believe that such a report is needed.
The result will be an expedited grace period stall.
Fix this by no longer excluding the current CPU from consideration during the second pass.
--- kernel/rcu/tree_exp.h | 1 + 1 file changed, 1 insertion(+)
kernel/rcu/tree_exp.h +1 -0
@@ -387,6 +387,7 @@ retry_ipi:continue ; }if (get_cpu () == cpu) { + mask_ofl_test |= mask;put_cpu ();continue ; }
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 148/563 mwifiex: Fix possible ABBA deadlock
In reply to Greg Kroah-HartmanFrom: Brian Norris <[email protected]>
[ Upstream commit 1b8bb8919ef81bfc8873d223b9361f1685f2106d ]
Quoting Jia-Ju Bai <[email protected]>:
mwifiex_dequeue_tx_packet()
spin_lock_bh(&priv->wmm.ra_list_spinlock); --> Line 1432 (Lock A)
mwifiex_send_addba()
spin_lock_bh(&priv->sta_list_spinlock); --> Line 608 (Lock B) mwifiex_process_sta_tx_pause()
spin_lock_bh(&priv->sta_list_spinlock); --> Line 398 (Lock B)
mwifiex_update_ralist_tx_pause()
spin_lock_bh(&priv->wmm.ra_list_spinlock); --> Line 941 (Lock A)Similar report for mwifiex_process_uap_tx_pause().
While the locking expectations in this driver are a bit unclear, the Fixed commit only intended to protect the sta_ptr, so we can drop the lock as soon as we're done with it.
IIUC, this deadlock cannot actually happen, because command event processing (which calls mwifiex_process_sta_tx_pause()) is sequentialized with TX packet processing (e.g., mwifiex_dequeue_tx_packet()) via the main loop (mwifiex_main_process()). But it's good not to leave this potential issue lurking.
--- drivers/net/wireless/marvell/mwifiex/sta_event.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/net/wireless/marvell/mwifiex/sta_event.c +6 -2
@@ -364,10 +364,12 @@ static void mwifiex_process_uap_tx_pause(struct mwifiex_private *priv, sta_ptr =mwifiex_get_sta_entry (priv, tp->peermac);if (sta_ptr && sta_ptr->tx_pause != tp->tx_pause) { sta_ptr->tx_pause = tp->tx_pause; +spin_unlock_bh (&priv->sta_list_spinlock);mwifiex_update_ralist_tx_pause (priv, tp->peermac, tp->tx_pause); + }else { +spin_unlock_bh (&priv->sta_list_spinlock); } -spin_unlock_bh (&priv->sta_list_spinlock); } }
@@ -399,11 +401,13 @@ static void mwifiex_process_sta_tx_pause(struct mwifiex_private *priv, sta_ptr =mwifiex_get_sta_entry (priv, tp->peermac);if (sta_ptr && sta_ptr->tx_pause != tp->tx_pause) { sta_ptr->tx_pause = tp->tx_pause; +spin_unlock_bh (&priv->sta_list_spinlock);mwifiex_update_ralist_tx_pause (priv, tp->peermac, tp->tx_pause); + }else { +spin_unlock_bh (&priv->sta_list_spinlock); } -spin_unlock_bh (&priv->sta_list_spinlock); } } }
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 149/563 xfrm: fix a small bug in xfrm_sa_len()
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit 7770a39d7c63faec6c4f33666d49a8cb664d0482 ]
copy_user_offload() will actually push a struct struct xfrm_user_offload, which is different than (struct xfrm_state *)->xso
(struct xfrm_state_offload)
--- net/xfrm/xfrm_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/xfrm/xfrm_user.c +1 -1
@@ -2898,7 +2898,7 @@ static inline unsigned int xfrm_sa_len(struct xfrm_state *x)if (x->props.extra_flags) l +=nla_total_size (sizeof (x->props.extra_flags));if (x->xso.dev) - l +=nla_total_size (sizeof (x->xso)); + l +=nla_total_size (sizeof (struct xfrm_user_offload ));if (x->props.smark.v | x->props.smark.m) { l +=nla_total_size (sizeof (x->props.smark.v)); l +=nla_total_size (sizeof (x->props.smark.m));
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 150/563 x86/uaccess: Move variable into switch case statement
In reply to Greg Kroah-HartmanFrom: Kees Cook <[email protected]>
[ Upstream commit 61646ca83d3889696f2772edaff122dd96a2935e ]
When building with automatic stack variable initialization, GCC 12 complains about variables defined outside of switch case statements. Move the variable into the case that uses it, which silences the warning:
./arch/x86/include/asm/uaccess.h:317:23: warning: statement will never be executed [-Wswitch-unreachable]
317 | unsigned char x_u8__; \
| ^~~~~~
--- arch/x86/include/asm/uaccess.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
arch/x86/include/asm/uaccess.h +3 -2
@@ -314,11 +314,12 @@ do { \ do { \ __chk_user_ptr(ptr); \ switch (size) { \ - unsigned char x_u8__; \ - case 1: \ + case 1: { \ + unsigned char x_u8__; \ __get_user_asm(x_u8__, ptr, "b", "=q", label); \ (x) = x_u8__; \ break; \ + } \ case 2: \ __get_user_asm(x, ptr, "w", "=r", label); \ break; \
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 151/563 selftests: clone3: clone3: add case CLONE3_ARGS_NO_TEST
In reply to Greg Kroah-HartmanFrom: Anders Roxell <[email protected]>
[ Upstream commit a531b0c23c0fc68ad758cc31a74cf612a4dafeb0 ]
Building selftests/clone3 with clang warns about enumeration not handled in switch case:
clone3.c:54:10: warning: enumeration value 'CLONE3_ARGS_NO_TEST' not handled in switch [-Wswitch]
switch (test_mode) {
^Add the missing switch case with a comment.
--- tools/testing/selftests/clone3/clone3.c | 6 ++++++ 1 file changed, 6 insertions(+)
tools/testing/selftests/clone3/clone3.c +6 -0
@@ -52,6 +52,12 @@ static int call_clone3(uint64_t flags, size_t size, enum test_mode test_mode) size =sizeof (struct __clone_args );switch (test_mode) { +case CLONE3_ARGS_NO_TEST : +/* +* Uses default 'flags' and 'SIGCHLD' +* assignment. +*/ +break ;case CLONE3_ARGS_ALL_0 : args.flags =0 ; args.exit_signal =0 ;
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 152/563 selftests: harness: avoid false negatives if test has no ASSERTs
In reply to Greg Kroah-HartmanFrom: Jakub Kicinski <[email protected]>
[ Upstream commit 3abedf4646fdc0036fcb8ebbc3b600667167fafe ]
Test can fail either immediately when ASSERT() failed or at the end if one or more EXPECT() was not met. The exact return code is decided based on the number of successful ASSERT()s.
If test has no ASSERT()s, however, the return code will be 0, as if the test did not fail. Start counting ASSERT()s from 1.
--- tools/testing/selftests/kselftest_harness.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/testing/selftests/kselftest_harness.h +1 -1
@@ -965,7 +965,7 @@ void __run_test(struct __fixture_metadata *f, t->passed =1 ; t->skip =0 ; t->trigger =0 ; - t->step =0 ; + t->step =1 ; t->no_print =0 ;memset (t->results->reason,0 ,sizeof (t->results->reason));
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 153/563 crypto: stm32 - Fix last sparse warning in stm32_cryp_check_ctr_counter
In reply to Greg Kroah-HartmanFrom: Herbert Xu <[email protected]>
[ Upstream commit 81064c96d88180ad6995d52419e94a78968308a2 ]
This patch changes the cast in stm32_cryp_check_ctr_counter from u32 to __be32 to match the prototype of stm32_cryp_hw_write_iv correctly.
--- drivers/crypto/stm32/stm32-cryp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/crypto/stm32/stm32-cryp.c +1 -1
@@ -1229,7 +1229,7 @@ static void stm32_cryp_check_ctr_counter(struct stm32_cryp *cryp) cr =stm32_cryp_read (cryp,CRYP_CR );stm32_cryp_write (cryp,CRYP_CR , cr & ~CR_CRYPEN ); -stm32_cryp_hw_write_iv (cryp, (u32 *)cryp->last_ctr); +stm32_cryp_hw_write_iv (cryp, (__be32 *)cryp->last_ctr);stm32_cryp_write (cryp,CRYP_CR , cr); }
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 154/563 crypto: stm32/cryp - fix CTR counter carry
In reply to Greg Kroah-HartmanFrom: Nicolas Toromanoff <[email protected]>
[ Upstream commit 41c76690b0990efacd15d35cfb4e77318cd80ebb ]
STM32 CRYP hardware doesn't manage CTR counter bigger than max U32, as a workaround, at each block the current IV is saved, if the saved IV lower u32 is 0xFFFFFFFF, the full IV is manually incremented, and set in hardware.
--- drivers/crypto/stm32/stm32-cryp.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-)
drivers/crypto/stm32/stm32-cryp.c +13 -14
@@ -163,7 +163,7 @@ struct stm32_cryp {struct scatter_walk in_walk;struct scatter_walk out_walk; -u32 last_ctr[4 ]; +__be32 last_ctr[4 ];u32 gcm_ctr; };
@@ -1217,27 +1217,26 @@ static void stm32_cryp_check_ctr_counter(struct stm32_cryp *cryp) {u32 cr; -if (unlikely (cryp->last_ctr[3 ] ==0xFFFFFFFF )) { - cryp->last_ctr[3 ] =0 ; - cryp->last_ctr[2 ]++; -if (!cryp->last_ctr[2 ]) { - cryp->last_ctr[1 ]++; -if (!cryp->last_ctr[1 ]) - cryp->last_ctr[0 ]++; - } +if (unlikely (cryp->last_ctr[3 ] ==cpu_to_be32 (0xFFFFFFFF ))) { +/* +* In this case, we need to increment manually the ctr counter, +* as HW doesn't handle the U32 carry. +*/ +crypto_inc ((u8 *)cryp->last_ctr,sizeof (cryp->last_ctr)); cr =stm32_cryp_read (cryp,CRYP_CR );stm32_cryp_write (cryp,CRYP_CR , cr & ~CR_CRYPEN ); -stm32_cryp_hw_write_iv (cryp, (__be32 *)cryp->last_ctr); +stm32_cryp_hw_write_iv (cryp, cryp->last_ctr);stm32_cryp_write (cryp,CRYP_CR , cr); } - cryp->last_ctr[0 ] =stm32_cryp_read (cryp,CRYP_IV0LR ); - cryp->last_ctr[1 ] =stm32_cryp_read (cryp,CRYP_IV0RR ); - cryp->last_ctr[2 ] =stm32_cryp_read (cryp,CRYP_IV1LR ); - cryp->last_ctr[3 ] =stm32_cryp_read (cryp,CRYP_IV1RR ); +/* The IV registers are BE */ + cryp->last_ctr[0 ] =cpu_to_be32 (stm32_cryp_read (cryp,CRYP_IV0LR )); + cryp->last_ctr[1 ] =cpu_to_be32 (stm32_cryp_read (cryp,CRYP_IV0RR )); + cryp->last_ctr[2 ] =cpu_to_be32 (stm32_cryp_read (cryp,CRYP_IV1LR )); + cryp->last_ctr[3 ] =cpu_to_be32 (stm32_cryp_read (cryp,CRYP_IV1RR )); }static bool stm32_cryp_irq_read_data (struct stm32_cryp *cryp)
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 155/563 crypto: stm32/cryp - fix xts and race condition in crypto_engine requests
In reply to Greg Kroah-HartmanFrom: Nicolas Toromanoff <[email protected]>
[ Upstream commit d703c7a994ee34b7fa89baf21631fca0aa9f17fc ]
Don't erase key:
If key is erased before the crypto_finalize_.*_request() call, some pending process will run with a key={ 0 }.
Moreover if the key is reset at end of request, it breaks xts chaining mode, as for last xts block (in case input len is not a multiple of block) a new AES request is started without calling again set_key().
--- drivers/crypto/stm32/stm32-cryp.c | 2 -- 1 file changed, 2 deletions(-)
drivers/crypto/stm32/stm32-cryp.c +0 -2
@@ -674,8 +674,6 @@ static void stm32_cryp_finish_req(struct stm32_cryp *cryp, int err)else crypto_finalize_skcipher_request (cryp->engine, cryp->req, err); - -memset (cryp->ctx->key,0 , cryp->ctx->keylen); }static int stm32_cryp_cpu_start (struct stm32_cryp *cryp)
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 156/563 crypto: stm32/cryp - check early input data
In reply to Greg Kroah-HartmanFrom: Nicolas Toromanoff <[email protected]>
[ Upstream commit 39e6e699c7fb92bdb2617b596ca4a4ea35c5d2a7 ]
Some auto tests failed because driver wasn't returning the expected error with some input size/iv value/tag size.
Now:
Return 0 early for empty buffer. (We don't need to start the engine for an empty input buffer).
Accept any valid authsize for gcm(aes).
Return -EINVAL if iv for ccm(aes) is invalid.
Return -EINVAL if buffer size is a not a multiple of algorithm block size.
--- drivers/crypto/stm32/stm32-cryp.c | 114 +++++++++++++++++++++++++++++- 1 file changed, 113 insertions(+), 1 deletion(-)
drivers/crypto/stm32/stm32-cryp.c +113 -1
@@ -799,7 +799,20 @@ static int stm32_cryp_aes_aead_setkey(struct crypto_aead *tfm, const u8 *key,static int stm32_cryp_aes_gcm_setauthsize (struct crypto_aead *tfm,unsigned int authsize) { -return authsize ==AES_BLOCK_SIZE ?0 : -EINVAL ; +switch (authsize) { +case 4 : +case 8 : +case 12 : +case 13 : +case 14 : +case 15 : +case 16 : +break ; +default : +return -EINVAL ; + } + +return 0 ; } static int stm32_cryp_aes_ccm_setauthsize(struct crypto_aead *tfm,
@@ -823,31 +836,61 @@ static int stm32_cryp_aes_ccm_setauthsize(struct crypto_aead *tfm,static int stm32_cryp_aes_ecb_encrypt (struct skcipher_request *req) { +if (req->cryptlen %AES_BLOCK_SIZE ) +return -EINVAL ; + +if (req->cryptlen ==0 ) +return 0 ; +return stm32_cryp_crypt (req,FLG_AES |FLG_ECB |FLG_ENCRYPT ); }static int stm32_cryp_aes_ecb_decrypt (struct skcipher_request *req) { +if (req->cryptlen %AES_BLOCK_SIZE ) +return -EINVAL ; + +if (req->cryptlen ==0 ) +return 0 ; +return stm32_cryp_crypt (req,FLG_AES |FLG_ECB ); }static int stm32_cryp_aes_cbc_encrypt (struct skcipher_request *req) { +if (req->cryptlen %AES_BLOCK_SIZE ) +return -EINVAL ; + +if (req->cryptlen ==0 ) +return 0 ; +return stm32_cryp_crypt (req,FLG_AES |FLG_CBC |FLG_ENCRYPT ); }static int stm32_cryp_aes_cbc_decrypt (struct skcipher_request *req) { +if (req->cryptlen %AES_BLOCK_SIZE ) +return -EINVAL ; + +if (req->cryptlen ==0 ) +return 0 ; +return stm32_cryp_crypt (req,FLG_AES |FLG_CBC ); }static int stm32_cryp_aes_ctr_encrypt (struct skcipher_request *req) { +if (req->cryptlen ==0 ) +return 0 ; +return stm32_cryp_crypt (req,FLG_AES |FLG_CTR |FLG_ENCRYPT ); }static int stm32_cryp_aes_ctr_decrypt (struct skcipher_request *req) { +if (req->cryptlen ==0 ) +return 0 ; +return stm32_cryp_crypt (req,FLG_AES |FLG_CTR ); }
@@ -861,53 +904,122 @@ static int stm32_cryp_aes_gcm_decrypt(struct aead_request *req)return stm32_cryp_aead_crypt (req,FLG_AES |FLG_GCM ); } +static inline int crypto_ccm_check_iv (const u8 *iv) +{ +/* 2 <= L <= 8, so 1 <= L' <= 7. */ +if (iv[0 ] <1 || iv[0 ] >7 ) +return -EINVAL ; + +return 0 ; +} +static int stm32_cryp_aes_ccm_encrypt (struct aead_request *req) { +int err; + + err =crypto_ccm_check_iv (req->iv); +if (err) +return err; +return stm32_cryp_aead_crypt (req,FLG_AES |FLG_CCM |FLG_ENCRYPT ); }static int stm32_cryp_aes_ccm_decrypt (struct aead_request *req) { +int err; + + err =crypto_ccm_check_iv (req->iv); +if (err) +return err; +return stm32_cryp_aead_crypt (req,FLG_AES |FLG_CCM ); }static int stm32_cryp_des_ecb_encrypt (struct skcipher_request *req) { +if (req->cryptlen %DES_BLOCK_SIZE ) +return -EINVAL ; + +if (req->cryptlen ==0 ) +return 0 ; +return stm32_cryp_crypt (req,FLG_DES |FLG_ECB |FLG_ENCRYPT ); }static int stm32_cryp_des_ecb_decrypt (struct skcipher_request *req) { +if (req->cryptlen %DES_BLOCK_SIZE ) +return -EINVAL ; + +if (req->cryptlen ==0 ) +return 0 ; +return stm32_cryp_crypt (req,FLG_DES |FLG_ECB ); }static int stm32_cryp_des_cbc_encrypt (struct skcipher_request *req) { +if (req->cryptlen %DES_BLOCK_SIZE ) +return -EINVAL ; + +if (req->cryptlen ==0 ) +return 0 ; +return stm32_cryp_crypt (req,FLG_DES |FLG_CBC |FLG_ENCRYPT ); }static int stm32_cryp_des_cbc_decrypt (struct skcipher_request *req) { +if (req->cryptlen %DES_BLOCK_SIZE ) +return -EINVAL ; + +if (req->cryptlen ==0 ) +return 0 ; +return stm32_cryp_crypt (req,FLG_DES |FLG_CBC ); }static int stm32_cryp_tdes_ecb_encrypt (struct skcipher_request *req) { +if (req->cryptlen %DES_BLOCK_SIZE ) +return -EINVAL ; + +if (req->cryptlen ==0 ) +return 0 ; +return stm32_cryp_crypt (req,FLG_TDES |FLG_ECB |FLG_ENCRYPT ); }static int stm32_cryp_tdes_ecb_decrypt (struct skcipher_request *req) { +if (req->cryptlen %DES_BLOCK_SIZE ) +return -EINVAL ; + +if (req->cryptlen ==0 ) +return 0 ; +return stm32_cryp_crypt (req,FLG_TDES |FLG_ECB ); }static int stm32_cryp_tdes_cbc_encrypt (struct skcipher_request *req) { +if (req->cryptlen %DES_BLOCK_SIZE ) +return -EINVAL ; + +if (req->cryptlen ==0 ) +return 0 ; +return stm32_cryp_crypt (req,FLG_TDES |FLG_CBC |FLG_ENCRYPT ); }static int stm32_cryp_tdes_cbc_decrypt (struct skcipher_request *req) { +if (req->cryptlen %DES_BLOCK_SIZE ) +return -EINVAL ; + +if (req->cryptlen ==0 ) +return 0 ; +return stm32_cryp_crypt (req,FLG_TDES |FLG_CBC ); }
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 157/563 crypto: stm32/cryp - fix double pm exit
In reply to Greg Kroah-HartmanFrom: Nicolas Toromanoff <[email protected]>
[ Upstream commit 6c12e742785bf9333faf60bfb96575bdd763448e ]
Delete extraneous lines in probe error handling code: pm was disabled twice.
--- drivers/crypto/stm32/stm32-cryp.c | 2 -- 1 file changed, 2 deletions(-)
drivers/crypto/stm32/stm32-cryp.c +0 -2
@@ -2134,8 +2134,6 @@ err_engine1:list_del (&cryp->list);spin_unlock (&cryp_list.lock); -pm_runtime_disable (dev); -pm_runtime_put_noidle (dev);pm_runtime_disable (dev);pm_runtime_put_noidle (dev);
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 158/563 crypto: stm32/cryp - fix lrw chaining mode
In reply to Greg Kroah-HartmanFrom: Nicolas Toromanoff <[email protected]>
[ Upstream commit fa97dc2d48b476ea98199d808d3248d285987e99 ]
This fixes the lrw autotest if lrw uses the CRYP as the AES block cipher provider (as ecb(aes)). At end of request, CRYP should not update the IV in case of ECB chaining mode. Indeed the ECB chaining mode never uses the IV, but the software LRW chaining mode uses the IV field as a counter and due to the (unexpected) update done by CRYP while the AES block process, the counter get a wrong value when the IV overflow.
--- drivers/crypto/stm32/stm32-cryp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/crypto/stm32/stm32-cryp.c +1 -1
@@ -644,7 +644,7 @@ static void stm32_cryp_finish_req(struct stm32_cryp *cryp, int err)/* Phase 4 : output tag */ err =stm32_cryp_read_auth_tag (cryp); -if (!err && (!(is_gcm (cryp) ||is_ccm (cryp)))) +if (!err && (!(is_gcm (cryp) ||is_ccm (cryp) ||is_ecb (cryp))))stm32_cryp_get_iv (cryp);if (cryp->sgs_copied) {
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 159/563 crypto: stm32/cryp - fix bugs and crash in tests
In reply to Greg Kroah-HartmanFrom: Nicolas Toromanoff <[email protected]>
[ Upstream commit 4b898d5cfa4d9a0ad5bc82cb5eafdc092394c6a9 ]
Extra crypto manager auto test were crashing or failling due to 2 reasons:
- block in a dead loop (dues to issues in cipher end process management)
- crash due to read/write unmapped memory (this crash was also reported when using openssl afalg engine)
Rework interrupt management, interrupts are masked as soon as they are no more used: if input buffer is fully consumed, "Input FIFO not full" interrupt is masked and if output buffer is full, "Output FIFO not empty" interrupt is masked.
And crypto request finish when input *and* outpout buffer are fully read/write.
About the crash due to unmapped memory, using scatterwalk_copychunks() that will map and copy each block fix the issue.
Using this api and copying full block will also fix unaligned data access, avoid early copy of in/out buffer, and make useless the extra alignment constraint.
--- drivers/crypto/stm32/stm32-cryp.c | 790 +++++++++--------------------- 1 file changed, 243 insertions(+), 547 deletions(-)
drivers/crypto/stm32/stm32-cryp.c +243 -547
@@ -37,7 +37,6 @@/* Mode mask = bits [15..0] */ #define FLG_MODE_MASK GENMASK(15, 0)/* Bit [31..16] status */ -#define FLG_CCM_PADDED_WA BIT(16)/* Registers */ #define CRYP_CR 0x00000000
@@ -105,8 +104,6 @@/* Misc */ #define AES_BLOCK_32 (AES_BLOCK_SIZE / sizeof(u32))#define GCM_CTR_INIT 2 -#define _walked_in (cryp->in_walk.offset - cryp->in_sg->offset) -#define _walked_out (cryp->out_walk.offset - cryp->out_sg->offset)#define CRYP_AUTOSUSPEND_DELAY 50struct stm32_cryp_caps {
@@ -144,21 +141,11 @@ struct stm32_cryp {size_t authsize;size_t hw_blocksize; -size_t total_in; -size_t total_in_save; -size_t total_out; -size_t total_out_save; +size_t payload_in; +size_t header_in; +size_t payload_out; -struct scatterlist *in_sg;struct scatterlist *out_sg; -struct scatterlist *out_sg_save; - -struct scatterlist in_sgl; -struct scatterlist out_sgl; -bool sgs_copied; - -int in_sg_len; -int out_sg_len;struct scatter_walk in_walk;struct scatter_walk out_walk;
@@ -262,6 +249,7 @@ static inline int stm32_cryp_wait_output(struct stm32_cryp *cryp) }static int stm32_cryp_read_auth_tag (struct stm32_cryp *cryp); +static void stm32_cryp_finish_req (struct stm32_cryp *cryp,int err);static struct stm32_cryp *stm32_cryp_find_dev (struct stm32_cryp_ctx *ctx) {
@@ -283,103 +271,6 @@ static struct stm32_cryp *stm32_cryp_find_dev(struct stm32_cryp_ctx *ctx)return cryp; } -static int stm32_cryp_check_aligned (struct scatterlist *sg,size_t total, -size_t align) -{ -int len =0 ; - -if (!total) -return 0 ; - -if (!IS_ALIGNED (total, align)) -return -EINVAL ; - -while (sg) { -if (!IS_ALIGNED (sg->offset,sizeof (u32))) -return -EINVAL ; - -if (!IS_ALIGNED (sg->length, align)) -return -EINVAL ; - - len += sg->length; - sg =sg_next (sg); - } - -if (len != total) -return -EINVAL ; - -return 0 ; -} - -static int stm32_cryp_check_io_aligned (struct stm32_cryp *cryp) -{ -int ret; - - ret =stm32_cryp_check_aligned (cryp->in_sg, cryp->total_in, - cryp->hw_blocksize); -if (ret) -return ret; - - ret =stm32_cryp_check_aligned (cryp->out_sg, cryp->total_out, - cryp->hw_blocksize); - -return ret; -} - -static void sg_copy_buf (void *buf,struct scatterlist *sg, -unsigned int start,unsigned int nbytes,int out) -{ -struct scatter_walk walk; - -if (!nbytes) -return ; - -scatterwalk_start (&walk, sg); -scatterwalk_advance (&walk, start); -scatterwalk_copychunks (buf, &walk, nbytes, out); -scatterwalk_done (&walk, out,0 ); -} - -static int stm32_cryp_copy_sgs (struct stm32_cryp *cryp) -{ -void *buf_in, *buf_out; -int pages, total_in, total_out; - -if (!stm32_cryp_check_io_aligned (cryp)) { - cryp->sgs_copied =0 ; -return 0 ; - } - - total_in =ALIGN (cryp->total_in, cryp->hw_blocksize); - pages = total_in ?get_order (total_in) :1 ; - buf_in = (void *)__get_free_pages (GFP_ATOMIC , pages); - - total_out =ALIGN (cryp->total_out, cryp->hw_blocksize); - pages = total_out ?get_order (total_out) :1 ; - buf_out = (void *)__get_free_pages (GFP_ATOMIC , pages); - -if (!buf_in || !buf_out) { -dev_err (cryp->dev,"Can't allocate pages when unaligned\n" ); - cryp->sgs_copied =0 ; -return -EFAULT ; - } - -sg_copy_buf (buf_in, cryp->in_sg,0 , cryp->total_in,0 ); - -sg_init_one (&cryp->in_sgl, buf_in, total_in); - cryp->in_sg = &cryp->in_sgl; - cryp->in_sg_len =1 ; - -sg_init_one (&cryp->out_sgl, buf_out, total_out); - cryp->out_sg_save = cryp->out_sg; - cryp->out_sg = &cryp->out_sgl; - cryp->out_sg_len =1 ; - - cryp->sgs_copied =1 ; - -return 0 ; -} -static void stm32_cryp_hw_write_iv (struct stm32_cryp *cryp,__be32 *iv) {if (!iv)
@@ -481,16 +372,99 @@ static int stm32_cryp_gcm_init(struct stm32_cryp *cryp, u32 cfg)/* Wait for end of processing */ ret =stm32_cryp_wait_enable (cryp); -if (ret) +if (ret) {dev_err (cryp->dev,"Timeout (gcm init)\n" ); +return ret; + } -return ret; +/* Prepare next phase */ +if (cryp->areq->assoclen) { + cfg |=CR_PH_HEADER ; +stm32_cryp_write (cryp,CRYP_CR , cfg); + }else if (stm32_cryp_get_input_text_len (cryp)) { + cfg |=CR_PH_PAYLOAD ; +stm32_cryp_write (cryp,CRYP_CR , cfg); + } + +return 0 ; +} + +static void stm32_crypt_gcmccm_end_header (struct stm32_cryp *cryp) +{ +u32 cfg; +int err; + +/* Check if whole header written */ +if (!cryp->header_in) { +/* Wait for completion */ + err =stm32_cryp_wait_busy (cryp); +if (err) { +dev_err (cryp->dev,"Timeout (gcm/ccm header)\n" ); +stm32_cryp_write (cryp,CRYP_IMSCR ,0 ); +stm32_cryp_finish_req (cryp, err); +return ; + } + +if (stm32_cryp_get_input_text_len (cryp)) { +/* Phase 3 : payload */ + cfg =stm32_cryp_read (cryp,CRYP_CR ); + cfg &= ~CR_CRYPEN ; +stm32_cryp_write (cryp,CRYP_CR , cfg); + + cfg &= ~CR_PH_MASK ; + cfg |=CR_PH_PAYLOAD |CR_CRYPEN ; +stm32_cryp_write (cryp,CRYP_CR , cfg); + }else { +/* +* Phase 4 : tag. +* Nothing to read, nothing to write, caller have to +* end request +*/ + } + } +} + +static void stm32_cryp_write_ccm_first_header (struct stm32_cryp *cryp) +{ +unsigned int i; +size_t written; +size_t len; +u32 alen = cryp->areq->assoclen; +u32 block[AES_BLOCK_32 ] = {0 }; +u8 *b8 = (u8 *)block; + +if (alen <=65280 ) { +/* Write first u32 of B1 */ + b8[0 ] = (alen >>8 ) &0xFF ; + b8[1 ] = alen &0xFF ; + len =2 ; + }else { +/* Build the two first u32 of B1 */ + b8[0 ] =0xFF ; + b8[1 ] =0xFE ; + b8[2 ] = (alen &0xFF000000 ) >>24 ; + b8[3 ] = (alen &0x00FF0000 ) >>16 ; + b8[4 ] = (alen &0x0000FF00 ) >>8 ; + b8[5 ] = alen &0x000000FF ; + len =6 ; + } + + written =min_t (size_t,AES_BLOCK_SIZE - len, alen); + +scatterwalk_copychunks ((char *)block + len, &cryp->in_walk, written,0 ); +for (i =0 ; i <AES_BLOCK_32 ; i++) +stm32_cryp_write (cryp,CRYP_DIN , block[i]); + + cryp->header_in -= written; + +stm32_crypt_gcmccm_end_header (cryp); }static int stm32_cryp_ccm_init (struct stm32_cryp *cryp,u32 cfg) {int ret; -u8 iv[AES_BLOCK_SIZE ], b0[AES_BLOCK_SIZE ]; +u32 iv_32[AES_BLOCK_32 ], b0_32[AES_BLOCK_32 ]; +u8 *iv = (u8 *)iv_32, *b0 = (u8 *)b0_32;__be32 *bd;u32 *d;unsigned int i, textlen;
@@ -531,17 +505,30 @@ static int stm32_cryp_ccm_init(struct stm32_cryp *cryp, u32 cfg)/* Wait for end of processing */ ret =stm32_cryp_wait_enable (cryp); -if (ret) +if (ret) {dev_err (cryp->dev,"Timeout (ccm init)\n" ); +return ret; + } -return ret; +/* Prepare next phase */ +if (cryp->areq->assoclen) { + cfg |=CR_PH_HEADER |CR_CRYPEN ; +stm32_cryp_write (cryp,CRYP_CR , cfg); + +/* Write first (special) block (may move to next phase [payload]) */ +stm32_cryp_write_ccm_first_header (cryp); + }else if (stm32_cryp_get_input_text_len (cryp)) { + cfg |=CR_PH_PAYLOAD ; +stm32_cryp_write (cryp,CRYP_CR , cfg); + } + +return 0 ; }static int stm32_cryp_hw_init (struct stm32_cryp *cryp) {int ret;u32 cfg, hw_mode; -pm_runtime_resume_and_get (cryp->dev);/* Disable interrupt */
@@ -605,16 +592,6 @@ static int stm32_cryp_hw_init(struct stm32_cryp *cryp)if (ret)return ret; -/* Phase 2 : header (authenticated data) */ -if (cryp->areq->assoclen) { - cfg |=CR_PH_HEADER ; - }else if (stm32_cryp_get_input_text_len (cryp)) { - cfg |=CR_PH_PAYLOAD ; -stm32_cryp_write (cryp,CRYP_CR , cfg); - }else { - cfg |=CR_PH_INIT ; - } -break ;case CR_DES_CBC :
@@ -633,8 +610,6 @@ static int stm32_cryp_hw_init(struct stm32_cryp *cryp)stm32_cryp_write (cryp,CRYP_CR , cfg); - cryp->flags &= ~FLG_CCM_PADDED_WA ; -return 0 ; }
@@ -647,25 +622,6 @@ static void stm32_cryp_finish_req(struct stm32_cryp *cryp, int err)if (!err && (!(is_gcm (cryp) ||is_ccm (cryp) ||is_ecb (cryp))))stm32_cryp_get_iv (cryp); -if (cryp->sgs_copied) { -void *buf_in, *buf_out; -int pages, len; - - buf_in =sg_virt (&cryp->in_sgl); - buf_out =sg_virt (&cryp->out_sgl); - -sg_copy_buf (buf_out, cryp->out_sg_save,0 , - cryp->total_out_save,1 ); - - len =ALIGN (cryp->total_in_save, cryp->hw_blocksize); - pages = len ?get_order (len) :1 ; -free_pages ((unsigned long )buf_in, pages); - - len =ALIGN (cryp->total_out_save, cryp->hw_blocksize); - pages = len ?get_order (len) :1 ; -free_pages ((unsigned long )buf_out, pages); - } -pm_runtime_mark_last_busy (cryp->dev);pm_runtime_put_autosuspend (cryp->dev);
@@ -1029,6 +985,7 @@ static int stm32_cryp_prepare_req(struct skcipher_request *req,struct stm32_cryp_ctx *ctx;struct stm32_cryp *cryp;struct stm32_cryp_reqctx *rctx; +struct scatterlist *in_sg;int ret;if (!req && !areq)
@@ -1054,76 +1011,55 @@ static int stm32_cryp_prepare_req(struct skcipher_request *req,if (req) { cryp->req = req; cryp->areq =NULL ; - cryp->total_in = req->cryptlen; - cryp->total_out = cryp->total_in; + cryp->header_in =0 ; + cryp->payload_in = req->cryptlen; + cryp->payload_out = req->cryptlen; + cryp->authsize =0 ; }else {/* * Length of input and output data: * Encryption case: -* INPUT = AssocData || PlainText +* INPUT = AssocData || PlainText * <- assoclen -> <- cryptlen -> -* <------- total_in -----------> * -* OUTPUT = AssocData || CipherText || AuthTag -* <- assoclen -> <- cryptlen -> <- authsize -> -* <---------------- total_out -----------------> +* OUTPUT = AssocData || CipherText || AuthTag +* <- assoclen -> <-- cryptlen --> <- authsize -> * * Decryption case: -* INPUT = AssocData || CipherText || AuthTag -* <- assoclen -> <--------- cryptlen ---------> -* <- authsize -> -* <---------------- total_in ------------------> +* INPUT = AssocData || CipherTex || AuthTag +* <- assoclen ---> <---------- cryptlen ----------> * -* OUTPUT = AssocData || PlainText -* <- assoclen -> <- crypten - authsize -> -* <---------- total_out -----------------> +* OUTPUT = AssocData || PlainText +* <- assoclen -> <- cryptlen - authsize -> */ cryp->areq = areq; cryp->req =NULL ; cryp->authsize =crypto_aead_authsize (crypto_aead_reqtfm (areq)); - cryp->total_in = areq->assoclen + areq->cryptlen; -if (is_encrypt (cryp)) -/* Append auth tag to output */ - cryp->total_out = cryp->total_in + cryp->authsize; -else -/* No auth tag in output */ - cryp->total_out = cryp->total_in - cryp->authsize; +if (is_encrypt (cryp)) { + cryp->payload_in = areq->cryptlen; + cryp->header_in = areq->assoclen; + cryp->payload_out = areq->cryptlen; + }else { + cryp->payload_in = areq->cryptlen - cryp->authsize; + cryp->header_in = areq->assoclen; + cryp->payload_out = cryp->payload_in; + } } - cryp->total_in_save = cryp->total_in; - cryp->total_out_save = cryp->total_out; + in_sg = req ? req->src : areq->src; +scatterwalk_start (&cryp->in_walk, in_sg); - cryp->in_sg = req ? req->src : areq->src; cryp->out_sg = req ? req->dst : areq->dst; - cryp->out_sg_save = cryp->out_sg; - - cryp->in_sg_len =sg_nents_for_len (cryp->in_sg, cryp->total_in); -if (cryp->in_sg_len <0 ) { -dev_err (cryp->dev,"Cannot get in_sg_len\n" ); - ret = cryp->in_sg_len; -return ret; - } - - cryp->out_sg_len =sg_nents_for_len (cryp->out_sg, cryp->total_out); -if (cryp->out_sg_len <0 ) { -dev_err (cryp->dev,"Cannot get out_sg_len\n" ); - ret = cryp->out_sg_len; -return ret; - } - - ret =stm32_cryp_copy_sgs (cryp); -if (ret) -return ret; - -scatterwalk_start (&cryp->in_walk, cryp->in_sg);scatterwalk_start (&cryp->out_walk, cryp->out_sg);if (is_gcm (cryp) ||is_ccm (cryp)) {/* In output, jump after assoc data */ -scatterwalk_advance (&cryp->out_walk, cryp->areq->assoclen); - cryp->total_out -= cryp->areq->assoclen; +scatterwalk_copychunks (NULL , &cryp->out_walk, cryp->areq->assoclen,2 ); } +if (is_ctr (cryp)) +memset (cryp->last_ctr,0 ,sizeof (cryp->last_ctr)); + ret =stm32_cryp_hw_init (cryp);return ret; }
@@ -1171,8 +1107,7 @@ static int stm32_cryp_aead_one_req(struct crypto_engine *engine, void *areq)if (!cryp)return -ENODEV ; -if (unlikely (!cryp->areq->assoclen && - !stm32_cryp_get_input_text_len (cryp))) { +if (unlikely (!cryp->payload_in && !cryp->header_in)) {/* No input data to process: get tag and finish */ stm32_cryp_finish_req (cryp,0 );return 0 ;
@@ -1181,43 +1116,10 @@ static int stm32_cryp_aead_one_req(struct crypto_engine *engine, void *areq)return stm32_cryp_cpu_start (cryp); } -static u32 *stm32_cryp_next_out (struct stm32_cryp *cryp,u32 *dst, -unsigned int n) -{ -scatterwalk_advance (&cryp->out_walk, n); - -if (unlikely (cryp->out_sg->length == _walked_out)) { - cryp->out_sg =sg_next (cryp->out_sg); -if (cryp->out_sg) { -scatterwalk_start (&cryp->out_walk, cryp->out_sg); -return (sg_virt (cryp->out_sg) + _walked_out); - } - } - -return (u32 *)((u8 *)dst + n); -} - -static u32 *stm32_cryp_next_in (struct stm32_cryp *cryp,u32 *src, -unsigned int n) -{ -scatterwalk_advance (&cryp->in_walk, n); - -if (unlikely (cryp->in_sg->length == _walked_in)) { - cryp->in_sg =sg_next (cryp->in_sg); -if (cryp->in_sg) { -scatterwalk_start (&cryp->in_walk, cryp->in_sg); -return (sg_virt (cryp->in_sg) + _walked_in); - } - } - -return (u32 *)((u8 *)src + n); -} -static int stm32_cryp_read_auth_tag (struct stm32_cryp *cryp) { -u32 cfg, size_bit, *dst, d32; -u8 *d8; -unsigned int i, j; +u32 cfg, size_bit; +unsigned int i;int ret =0 ;/* Update Config */
@@ -1240,7 +1142,7 @@ static int stm32_cryp_read_auth_tag(struct stm32_cryp *cryp)stm32_cryp_write (cryp,CRYP_DIN , size_bit); size_bit =is_encrypt (cryp) ? cryp->areq->cryptlen : - cryp->areq->cryptlen -AES_BLOCK_SIZE ; + cryp->areq->cryptlen - cryp->authsize; size_bit *=8 ;if (cryp->caps->swap_final) size_bit = (__force u32 )cpu_to_be32 (size_bit);
@@ -1249,11 +1151,9 @@ static int stm32_cryp_read_auth_tag(struct stm32_cryp *cryp)stm32_cryp_write (cryp,CRYP_DIN , size_bit); }else {/* CCM: write CTR0 */ -u8 iv[AES_BLOCK_SIZE ]; -u32 *iv32 = (u32 *)iv; -__be32 *biv; - - biv = (void *)iv; +u32 iv32[AES_BLOCK_32 ]; +u8 *iv = (u8 *)iv32; +__be32 *biv = (__be32 *)iv32;memcpy (iv, cryp->areq->iv,AES_BLOCK_SIZE );memset (iv +AES_BLOCK_SIZE -1 - iv[0 ],0 , iv[0 ] +1 );
@@ -1275,39 +1175,18 @@ static int stm32_cryp_read_auth_tag(struct stm32_cryp *cryp) }if (is_encrypt (cryp)) { +u32 out_tag[AES_BLOCK_32 ]; +/* Get and write tag */ - dst =sg_virt (cryp->out_sg) + _walked_out; +for (i =0 ; i <AES_BLOCK_32 ; i++) + out_tag[i] =stm32_cryp_read (cryp,CRYP_DOUT ); -for (i =0 ; i <AES_BLOCK_32 ; i++) { -if (cryp->total_out >=sizeof (u32)) { -/* Read a full u32 */ - *dst =stm32_cryp_read (cryp,CRYP_DOUT ); - - dst =stm32_cryp_next_out (cryp, dst, -sizeof (u32)); - cryp->total_out -=sizeof (u32); - }else if (!cryp->total_out) { -/* Empty fifo out (data from input padding) */ -stm32_cryp_read (cryp,CRYP_DOUT ); - }else { -/* Read less than an u32 */ - d32 =stm32_cryp_read (cryp,CRYP_DOUT ); - d8 = (u8 *)&d32; - -for (j =0 ; j < cryp->total_out; j++) { - *((u8 *)dst) = *(d8++); - dst =stm32_cryp_next_out (cryp, dst,1 ); - } - cryp->total_out =0 ; - } - } +scatterwalk_copychunks (out_tag, &cryp->out_walk, cryp->authsize,1 ); }else {/* Get and check tag */ u32 in_tag[AES_BLOCK_32 ], out_tag[AES_BLOCK_32 ]; -scatterwalk_map_and_copy (in_tag, cryp->in_sg, - cryp->total_in_save - cryp->authsize, - cryp->authsize,0 ); +scatterwalk_copychunks (in_tag, &cryp->in_walk, cryp->authsize,0 );for (i =0 ; i <AES_BLOCK_32 ; i++) out_tag[i] =stm32_cryp_read (cryp,CRYP_DOUT );
@@ -1349,92 +1228,37 @@ static void stm32_cryp_check_ctr_counter(struct stm32_cryp *cryp) cryp->last_ctr[3 ] =cpu_to_be32 (stm32_cryp_read (cryp,CRYP_IV1RR )); } -static bool stm32_cryp_irq_read_data (struct stm32_cryp *cryp) +static void stm32_cryp_irq_read_data (struct stm32_cryp *cryp) { -unsigned int i, j; -u32 d32, *dst; -u8 *d8; -size_t tag_size; - -/* Do no read tag now (if any) */ -if (is_encrypt (cryp) && (is_gcm (cryp) ||is_ccm (cryp))) - tag_size = cryp->authsize; -else - tag_size =0 ; - - dst =sg_virt (cryp->out_sg) + _walked_out; - -for (i =0 ; i < cryp->hw_blocksize /sizeof (u32); i++) { -if (likely (cryp->total_out - tag_size >=sizeof (u32))) { -/* Read a full u32 */ - *dst =stm32_cryp_read (cryp,CRYP_DOUT ); +unsigned int i; +u32 block[AES_BLOCK_32 ]; - dst =stm32_cryp_next_out (cryp, dst,sizeof (u32)); - cryp->total_out -=sizeof (u32); - }else if (cryp->total_out == tag_size) { -/* Empty fifo out (data from input padding) */ - d32 =stm32_cryp_read (cryp,CRYP_DOUT ); - }else { -/* Read less than an u32 */ - d32 =stm32_cryp_read (cryp,CRYP_DOUT ); - d8 = (u8 *)&d32; - -for (j =0 ; j < cryp->total_out - tag_size; j++) { - *((u8 *)dst) = *(d8++); - dst =stm32_cryp_next_out (cryp, dst,1 ); - } - cryp->total_out = tag_size; - } - } +for (i =0 ; i < cryp->hw_blocksize /sizeof (u32); i++) + block[i] =stm32_cryp_read (cryp,CRYP_DOUT ); -return !(cryp->total_out - tag_size) || !cryp->total_in; +scatterwalk_copychunks (block, &cryp->out_walk,min_t (size_t, cryp->hw_blocksize, + cryp->payload_out),1 ); + cryp->payload_out -=min_t (size_t, cryp->hw_blocksize, + cryp->payload_out); }static void stm32_cryp_irq_write_block (struct stm32_cryp *cryp) { -unsigned int i, j; -u32 *src; -u8 d8[4 ]; -size_t tag_size; - -/* Do no write tag (if any) */ -if (is_decrypt (cryp) && (is_gcm (cryp) ||is_ccm (cryp))) - tag_size = cryp->authsize; -else - tag_size =0 ; - - src =sg_virt (cryp->in_sg) + _walked_in; +unsigned int i; +u32 block[AES_BLOCK_32 ] = {0 }; -for (i =0 ; i < cryp->hw_blocksize /sizeof (u32); i++) { -if (likely (cryp->total_in - tag_size >=sizeof (u32))) { -/* Write a full u32 */ -stm32_cryp_write (cryp,CRYP_DIN , *src); +scatterwalk_copychunks (block, &cryp->in_walk,min_t (size_t, cryp->hw_blocksize, + cryp->payload_in),0 ); +for (i =0 ; i < cryp->hw_blocksize /sizeof (u32); i++) +stm32_cryp_write (cryp,CRYP_DIN , block[i]); - src =stm32_cryp_next_in (cryp, src,sizeof (u32)); - cryp->total_in -=sizeof (u32); - }else if (cryp->total_in == tag_size) { -/* Write padding data */ -stm32_cryp_write (cryp,CRYP_DIN ,0 ); - }else { -/* Write less than an u32 */ -memset (d8,0 ,sizeof (u32)); -for (j =0 ; j < cryp->total_in - tag_size; j++) { - d8[j] = *((u8 *)src); - src =stm32_cryp_next_in (cryp, src,1 ); - } - -stm32_cryp_write (cryp,CRYP_DIN , *(u32 *)d8); - cryp->total_in = tag_size; - } - } + cryp->payload_in -=min_t (size_t, cryp->hw_blocksize, cryp->payload_in); }static void stm32_cryp_irq_write_gcm_padded_data (struct stm32_cryp *cryp) {int err; -u32 cfg, tmp[AES_BLOCK_32 ]; -size_t total_in_ori = cryp->total_in; -struct scatterlist *out_sg_ori = cryp->out_sg; +u32 cfg, block[AES_BLOCK_32 ] = {0 };unsigned int i;/* 'Special workaround' procedure described in the datasheet */
@@ -1459,18 +1283,25 @@ static void stm32_cryp_irq_write_gcm_padded_data(struct stm32_cryp *cryp)/* b) pad and write the last block */ stm32_cryp_irq_write_block (cryp); - cryp->total_in = total_in_ori; +/* wait end of process */ err =stm32_cryp_wait_output (cryp);if (err) { -dev_err (cryp->dev,"Timeout (write gcm header)\n" ); +dev_err (cryp->dev,"Timeout (write gcm last data)\n" );return stm32_cryp_finish_req (cryp, err); }/* c) get and store encrypted data */ -stm32_cryp_irq_read_data (cryp); -scatterwalk_map_and_copy (tmp, out_sg_ori, - cryp->total_in_save - total_in_ori, - total_in_ori,0 ); +/* +* Same code as stm32_cryp_irq_read_data(), but we want to store +* block value +*/ +for (i =0 ; i < cryp->hw_blocksize /sizeof (u32); i++) + block[i] =stm32_cryp_read (cryp,CRYP_DOUT ); + +scatterwalk_copychunks (block, &cryp->out_walk,min_t (size_t, cryp->hw_blocksize, + cryp->payload_out),1 ); + cryp->payload_out -=min_t (size_t, cryp->hw_blocksize, + cryp->payload_out);/* d) change mode back to AES GCM */ cfg &= ~CR_ALGO_MASK ;
@@ -1483,19 +1314,13 @@ static void stm32_cryp_irq_write_gcm_padded_data(struct stm32_cryp *cryp)stm32_cryp_write (cryp,CRYP_CR , cfg);/* f) write padded data */ -for (i =0 ; i <AES_BLOCK_32 ; i++) { -if (cryp->total_in) -stm32_cryp_write (cryp,CRYP_DIN , tmp[i]); -else -stm32_cryp_write (cryp,CRYP_DIN ,0 ); - - cryp->total_in -=min_t (size_t,sizeof (u32), cryp->total_in); - } +for (i =0 ; i <AES_BLOCK_32 ; i++) +stm32_cryp_write (cryp,CRYP_DIN , block[i]);/* g) Empty fifo out */ err =stm32_cryp_wait_output (cryp);if (err) { -dev_err (cryp->dev,"Timeout (write gcm header)\n" ); +dev_err (cryp->dev,"Timeout (write gcm padded data)\n" );return stm32_cryp_finish_req (cryp, err); }
@@ -1508,16 +1333,14 @@ static void stm32_cryp_irq_write_gcm_padded_data(struct stm32_cryp *cryp)static void stm32_cryp_irq_set_npblb (struct stm32_cryp *cryp) { -u32 cfg, payload_bytes; +u32 cfg;/* disable ip, set NPBLB and reneable ip */ cfg =stm32_cryp_read (cryp,CRYP_CR ); cfg &= ~CR_CRYPEN ;stm32_cryp_write (cryp,CRYP_CR , cfg); - payload_bytes =is_decrypt (cryp) ? cryp->total_in - cryp->authsize : - cryp->total_in; - cfg |= (cryp->hw_blocksize - payload_bytes) <<CR_NBPBL_SHIFT ; + cfg |= (cryp->hw_blocksize - cryp->payload_in) <<CR_NBPBL_SHIFT ; cfg |=CR_CRYPEN ;stm32_cryp_write (cryp,CRYP_CR , cfg); }
@@ -1526,13 +1349,11 @@ static void stm32_cryp_irq_write_ccm_padded_data(struct stm32_cryp *cryp) {int err =0 ;u32 cfg, iv1tmp; -u32 cstmp1[AES_BLOCK_32 ], cstmp2[AES_BLOCK_32 ], tmp[AES_BLOCK_32 ]; -size_t last_total_out, total_in_ori = cryp->total_in; -struct scatterlist *out_sg_ori = cryp->out_sg; +u32 cstmp1[AES_BLOCK_32 ], cstmp2[AES_BLOCK_32 ]; +u32 block[AES_BLOCK_32 ] = {0 };unsigned int i;/* 'Special workaround' procedure described in the datasheet */ - cryp->flags |=FLG_CCM_PADDED_WA ;/* a) disable ip */ stm32_cryp_write (cryp,CRYP_IMSCR ,0 );
@@ -1562,7 +1383,7 @@ static void stm32_cryp_irq_write_ccm_padded_data(struct stm32_cryp *cryp)/* b) pad and write the last block */ stm32_cryp_irq_write_block (cryp); - cryp->total_in = total_in_ori; +/* wait end of process */ err =stm32_cryp_wait_output (cryp);if (err) {dev_err (cryp->dev,"Timeout (wite ccm padded data)\n" );
@@ -1570,13 +1391,16 @@ static void stm32_cryp_irq_write_ccm_padded_data(struct stm32_cryp *cryp) }/* c) get and store decrypted data */ - last_total_out = cryp->total_out; -stm32_cryp_irq_read_data (cryp); +/* +* Same code as stm32_cryp_irq_read_data(), but we want to store +* block value +*/ +for (i =0 ; i < cryp->hw_blocksize /sizeof (u32); i++) + block[i] =stm32_cryp_read (cryp,CRYP_DOUT ); -memset (tmp,0 ,sizeof (tmp)); -scatterwalk_map_and_copy (tmp, out_sg_ori, - cryp->total_out_save - last_total_out, - last_total_out,0 ); +scatterwalk_copychunks (block, &cryp->out_walk,min_t (size_t, cryp->hw_blocksize, + cryp->payload_out),1 ); + cryp->payload_out -=min_t (size_t, cryp->hw_blocksize, cryp->payload_out);/* d) Load again CRYP_CSGCMCCMxR */ for (i =0 ; i <ARRAY_SIZE (cstmp2); i++)
@@ -1593,10 +1417,10 @@ static void stm32_cryp_irq_write_ccm_padded_data(struct stm32_cryp *cryp)stm32_cryp_write (cryp,CRYP_CR , cfg);/* g) XOR and write padded data */ -for (i =0 ; i <ARRAY_SIZE (tmp); i++) { - tmp[i] ^= cstmp1[i]; - tmp[i] ^= cstmp2[i]; -stm32_cryp_write (cryp,CRYP_DIN , tmp[i]); +for (i =0 ; i <ARRAY_SIZE (block); i++) { + block[i] ^= cstmp1[i]; + block[i] ^= cstmp2[i]; +stm32_cryp_write (cryp,CRYP_DIN , block[i]); }/* h) wait for completion */
@@ -1610,30 +1434,34 @@ static void stm32_cryp_irq_write_ccm_padded_data(struct stm32_cryp *cryp)static void stm32_cryp_irq_write_data (struct stm32_cryp *cryp) { -if (unlikely (!cryp->total_in)) { +if (unlikely (!cryp->payload_in)) {dev_warn (cryp->dev,"No more data to process\n" );return ; } -if (unlikely (cryp->total_in <AES_BLOCK_SIZE && +if (unlikely (cryp->payload_in <AES_BLOCK_SIZE && (stm32_cryp_get_hw_mode (cryp) ==CR_AES_GCM ) &&is_encrypt (cryp))) {/* Padding for AES GCM encryption */ -if (cryp->caps->padding_wa) +if (cryp->caps->padding_wa) {/* Special case 1 */ -return stm32_cryp_irq_write_gcm_padded_data (cryp); +stm32_cryp_irq_write_gcm_padded_data (cryp); +return ; + }/* Setting padding bytes (NBBLB) */ stm32_cryp_irq_set_npblb (cryp); } -if (unlikely ((cryp->total_in - cryp->authsize <AES_BLOCK_SIZE ) && +if (unlikely ((cryp->payload_in <AES_BLOCK_SIZE ) && (stm32_cryp_get_hw_mode (cryp) ==CR_AES_CCM ) &&is_decrypt (cryp))) {/* Padding for AES CCM decryption */ -if (cryp->caps->padding_wa) +if (cryp->caps->padding_wa) {/* Special case 2 */ -return stm32_cryp_irq_write_ccm_padded_data (cryp); +stm32_cryp_irq_write_ccm_padded_data (cryp); +return ; + }/* Setting padding bytes (NBBLB) */ stm32_cryp_irq_set_npblb (cryp);
@@ -1645,192 +1473,60 @@ static void stm32_cryp_irq_write_data(struct stm32_cryp *cryp)stm32_cryp_irq_write_block (cryp); } -static void stm32_cryp_irq_write_gcm_header (struct stm32_cryp *cryp) +static void stm32_cryp_irq_write_gcmccm_header (struct stm32_cryp *cryp) { -int err; -unsigned int i, j; -u32 cfg, *src; - - src =sg_virt (cryp->in_sg) + _walked_in; - -for (i =0 ; i <AES_BLOCK_32 ; i++) { -stm32_cryp_write (cryp,CRYP_DIN , *src); - - src =stm32_cryp_next_in (cryp, src,sizeof (u32)); - cryp->total_in -=min_t (size_t,sizeof (u32), cryp->total_in); - -/* Check if whole header written */ -if ((cryp->total_in_save - cryp->total_in) == - cryp->areq->assoclen) { -/* Write padding if needed */ -for (j = i +1 ; j <AES_BLOCK_32 ; j++) -stm32_cryp_write (cryp,CRYP_DIN ,0 ); - -/* Wait for completion */ - err =stm32_cryp_wait_busy (cryp); -if (err) { -dev_err (cryp->dev,"Timeout (gcm header)\n" ); -return stm32_cryp_finish_req (cryp, err); - } - -if (stm32_cryp_get_input_text_len (cryp)) { -/* Phase 3 : payload */ - cfg =stm32_cryp_read (cryp,CRYP_CR ); - cfg &= ~CR_CRYPEN ; -stm32_cryp_write (cryp,CRYP_CR , cfg); - - cfg &= ~CR_PH_MASK ; - cfg |=CR_PH_PAYLOAD ; - cfg |=CR_CRYPEN ; -stm32_cryp_write (cryp,CRYP_CR , cfg); - }else { -/* Phase 4 : tag */ -stm32_cryp_write (cryp,CRYP_IMSCR ,0 ); -stm32_cryp_finish_req (cryp,0 ); - } - -break ; - } - -if (!cryp->total_in) -break ; - } -} +unsigned int i; +u32 block[AES_BLOCK_32 ] = {0 }; +size_t written; -static void stm32_cryp_irq_write_ccm_header (struct stm32_cryp *cryp) -{ -int err; -unsigned int i =0 , j, k; -u32 alen, cfg, *src; -u8 d8[4 ]; - - src =sg_virt (cryp->in_sg) + _walked_in; - alen = cryp->areq->assoclen; - -if (!_walked_in) { -if (cryp->areq->assoclen <=65280 ) { -/* Write first u32 of B1 */ - d8[0 ] = (alen >>8 ) &0xFF ; - d8[1 ] = alen &0xFF ; - d8[2 ] = *((u8 *)src); - src =stm32_cryp_next_in (cryp, src,1 ); - d8[3 ] = *((u8 *)src); - src =stm32_cryp_next_in (cryp, src,1 ); - -stm32_cryp_write (cryp,CRYP_DIN , *(u32 *)d8); - i++; - - cryp->total_in -=min_t (size_t,2 , cryp->total_in); - }else { -/* Build the two first u32 of B1 */ - d8[0 ] =0xFF ; - d8[1 ] =0xFE ; - d8[2 ] = alen &0xFF000000 ; - d8[3 ] = alen &0x00FF0000 ; - -stm32_cryp_write (cryp,CRYP_DIN , *(u32 *)d8); - i++; - - d8[0 ] = alen &0x0000FF00 ; - d8[1 ] = alen &0x000000FF ; - d8[2 ] = *((u8 *)src); - src =stm32_cryp_next_in (cryp, src,1 ); - d8[3 ] = *((u8 *)src); - src =stm32_cryp_next_in (cryp, src,1 ); - -stm32_cryp_write (cryp,CRYP_DIN , *(u32 *)d8); - i++; - - cryp->total_in -=min_t (size_t,2 , cryp->total_in); - } - } + written =min_t (size_t,AES_BLOCK_SIZE , cryp->header_in); -/* Write next u32 */ -for (; i <AES_BLOCK_32 ; i++) { -/* Build an u32 */ -memset (d8,0 ,sizeof (u32)); -for (k =0 ; k <sizeof (u32); k++) { - d8[k] = *((u8 *)src); - src =stm32_cryp_next_in (cryp, src,1 ); - - cryp->total_in -=min_t (size_t,1 , cryp->total_in); -if ((cryp->total_in_save - cryp->total_in) == alen) -break ; - } +scatterwalk_copychunks (block, &cryp->in_walk, written,0 ); +for (i =0 ; i <AES_BLOCK_32 ; i++) +stm32_cryp_write (cryp,CRYP_DIN , block[i]); -stm32_cryp_write (cryp,CRYP_DIN , *(u32 *)d8); - -if ((cryp->total_in_save - cryp->total_in) == alen) { -/* Write padding if needed */ -for (j = i +1 ; j <AES_BLOCK_32 ; j++) -stm32_cryp_write (cryp,CRYP_DIN ,0 ); - -/* Wait for completion */ - err =stm32_cryp_wait_busy (cryp); -if (err) { -dev_err (cryp->dev,"Timeout (ccm header)\n" ); -return stm32_cryp_finish_req (cryp, err); - } - -if (stm32_cryp_get_input_text_len (cryp)) { -/* Phase 3 : payload */ - cfg =stm32_cryp_read (cryp,CRYP_CR ); - cfg &= ~CR_CRYPEN ; -stm32_cryp_write (cryp,CRYP_CR , cfg); - - cfg &= ~CR_PH_MASK ; - cfg |=CR_PH_PAYLOAD ; - cfg |=CR_CRYPEN ; -stm32_cryp_write (cryp,CRYP_CR , cfg); - }else { -/* Phase 4 : tag */ -stm32_cryp_write (cryp,CRYP_IMSCR ,0 ); -stm32_cryp_finish_req (cryp,0 ); - } + cryp->header_in -= written; -break ; - } - } +stm32_crypt_gcmccm_end_header (cryp); }static irqreturn_t stm32_cryp_irq_thread (int irq,void *arg) {struct stm32_cryp *cryp = arg;u32 ph; +u32 it_mask =stm32_cryp_read (cryp,CRYP_IMSCR );if (cryp->irq_status &MISR_OUT )/* Output FIFO IRQ: read data */ -if (unlikely (stm32_cryp_irq_read_data (cryp))) { -/* All bytes processed, finish */ -stm32_cryp_write (cryp,CRYP_IMSCR ,0 ); -stm32_cryp_finish_req (cryp,0 ); -return IRQ_HANDLED ; - } +stm32_cryp_irq_read_data (cryp);if (cryp->irq_status &MISR_IN ) { -if (is_gcm (cryp)) { - ph =stm32_cryp_read (cryp,CRYP_CR ) &CR_PH_MASK ; -if (unlikely (ph ==CR_PH_HEADER )) -/* Write Header */ -stm32_cryp_irq_write_gcm_header (cryp); -else -/* Input FIFO IRQ: write data */ -stm32_cryp_irq_write_data (cryp); - cryp->gcm_ctr++; - }else if (is_ccm (cryp)) { +if (is_gcm (cryp) ||is_ccm (cryp)) { ph =stm32_cryp_read (cryp,CRYP_CR ) &CR_PH_MASK ;if (unlikely (ph ==CR_PH_HEADER ))/* Write Header */ -stm32_cryp_irq_write_ccm_header (cryp); +stm32_cryp_irq_write_gcmccm_header (cryp);else /* Input FIFO IRQ: write data */ stm32_cryp_irq_write_data (cryp); +if (is_gcm (cryp)) + cryp->gcm_ctr++; }else {/* Input FIFO IRQ: write data */ stm32_cryp_irq_write_data (cryp); } } +/* Mask useless interrupts */ +if (!cryp->payload_in && !cryp->header_in) + it_mask &= ~IMSCR_IN ; +if (!cryp->payload_out) + it_mask &= ~IMSCR_OUT ; +stm32_cryp_write (cryp,CRYP_IMSCR , it_mask); + +if (!cryp->payload_in && !cryp->header_in && !cryp->payload_out) +stm32_cryp_finish_req (cryp,0 ); +return IRQ_HANDLED ; }
@@ -1851,7 +1547,7 @@ static struct skcipher_alg crypto_algs[] = { .base.cra_flags = CRYPTO_ALG_ASYNC, .base.cra_blocksize = AES_BLOCK_SIZE, .base.cra_ctxsize = sizeof(struct stm32_cryp_ctx), - .base.cra_alignmask = 0xf, + .base.cra_alignmask = 0, .base.cra_module = THIS_MODULE, .init = stm32_cryp_init_tfm,
@@ -1868,7 +1564,7 @@ static struct skcipher_alg crypto_algs[] = { .base.cra_flags = CRYPTO_ALG_ASYNC, .base.cra_blocksize = AES_BLOCK_SIZE, .base.cra_ctxsize = sizeof(struct stm32_cryp_ctx), - .base.cra_alignmask = 0xf, + .base.cra_alignmask = 0, .base.cra_module = THIS_MODULE, .init = stm32_cryp_init_tfm,
@@ -1886,7 +1582,7 @@ static struct skcipher_alg crypto_algs[] = { .base.cra_flags = CRYPTO_ALG_ASYNC, .base.cra_blocksize = 1, .base.cra_ctxsize = sizeof(struct stm32_cryp_ctx), - .base.cra_alignmask = 0xf, + .base.cra_alignmask = 0, .base.cra_module = THIS_MODULE, .init = stm32_cryp_init_tfm,
@@ -1904,7 +1600,7 @@ static struct skcipher_alg crypto_algs[] = { .base.cra_flags = CRYPTO_ALG_ASYNC, .base.cra_blocksize = DES_BLOCK_SIZE, .base.cra_ctxsize = sizeof(struct stm32_cryp_ctx), - .base.cra_alignmask = 0xf, + .base.cra_alignmask = 0, .base.cra_module = THIS_MODULE, .init = stm32_cryp_init_tfm,
@@ -1921,7 +1617,7 @@ static struct skcipher_alg crypto_algs[] = { .base.cra_flags = CRYPTO_ALG_ASYNC, .base.cra_blocksize = DES_BLOCK_SIZE, .base.cra_ctxsize = sizeof(struct stm32_cryp_ctx), - .base.cra_alignmask = 0xf, + .base.cra_alignmask = 0, .base.cra_module = THIS_MODULE, .init = stm32_cryp_init_tfm,
@@ -1939,7 +1635,7 @@ static struct skcipher_alg crypto_algs[] = { .base.cra_flags = CRYPTO_ALG_ASYNC, .base.cra_blocksize = DES_BLOCK_SIZE, .base.cra_ctxsize = sizeof(struct stm32_cryp_ctx), - .base.cra_alignmask = 0xf, + .base.cra_alignmask = 0, .base.cra_module = THIS_MODULE, .init = stm32_cryp_init_tfm,
@@ -1956,7 +1652,7 @@ static struct skcipher_alg crypto_algs[] = { .base.cra_flags = CRYPTO_ALG_ASYNC, .base.cra_blocksize = DES_BLOCK_SIZE, .base.cra_ctxsize = sizeof(struct stm32_cryp_ctx), - .base.cra_alignmask = 0xf, + .base.cra_alignmask = 0, .base.cra_module = THIS_MODULE, .init = stm32_cryp_init_tfm,
@@ -1986,7 +1682,7 @@ static struct aead_alg aead_algs[] = { .cra_flags = CRYPTO_ALG_ASYNC, .cra_blocksize = 1, .cra_ctxsize = sizeof(struct stm32_cryp_ctx), - .cra_alignmask = 0xf, + .cra_alignmask = 0, .cra_module = THIS_MODULE, }, },
@@ -2006,7 +1702,7 @@ static struct aead_alg aead_algs[] = { .cra_flags = CRYPTO_ALG_ASYNC, .cra_blocksize = 1, .cra_ctxsize = sizeof(struct stm32_cryp_ctx), - .cra_alignmask = 0xf, + .cra_alignmask = 0, .cra_module = THIS_MODULE, }, },
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 160/563 crypto: stm32 - Revert broken pm_runtime_resume_and_get changes
In reply to Greg Kroah-HartmanFrom: Herbert Xu <[email protected]>
[ Upstream commit 3d6b661330a7954d8136df98160d525eb04dcd6a ]
We should not call pm_runtime_resume_and_get where the reference count is expected to be incremented unconditionally. This patch reverts these calls to the original unconditional get_sync call.
--- drivers/crypto/stm32/stm32-cryp.c | 3 ++- drivers/crypto/stm32/stm32-hash.c | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-)
drivers/crypto/stm32/stm32-cryp.c +2 -1
@@ -529,7 +529,8 @@ static int stm32_cryp_hw_init(struct stm32_cryp *cryp) {int ret;u32 cfg, hw_mode; -pm_runtime_resume_and_get (cryp->dev); + +pm_runtime_get_sync (cryp->dev);/* Disable interrupt */ stm32_cryp_write (cryp,CRYP_IMSCR ,0 );
drivers/crypto/stm32/stm32-hash.c +3 -3
@@ -812,7 +812,7 @@ static void stm32_hash_finish_req(struct ahash_request *req, int err)static int stm32_hash_hw_init (struct stm32_hash_dev *hdev,struct stm32_hash_request_ctx *rctx) { -pm_runtime_resume_and_get (hdev->dev); +pm_runtime_get_sync (hdev->dev);if (!(HASH_FLAGS_INIT & hdev->flags)) {stm32_hash_write (hdev,HASH_CR ,HASH_CR_INIT );
@@ -961,7 +961,7 @@ static int stm32_hash_export(struct ahash_request *req, void *out)u32 *preg;unsigned int i; -pm_runtime_resume_and_get (hdev->dev); +pm_runtime_get_sync (hdev->dev);while ((stm32_hash_read (hdev,HASH_SR ) &HASH_SR_BUSY ))cpu_relax ();
@@ -999,7 +999,7 @@ static int stm32_hash_import(struct ahash_request *req, const void *in) preg = rctx->hw_context; -pm_runtime_resume_and_get (hdev->dev); +pm_runtime_get_sync (hdev->dev);stm32_hash_write (hdev,HASH_IMR , *preg++);stm32_hash_write (hdev,HASH_STR , *preg++);
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 161/563 ath11k: Fix deleting uninitialized kernel timer during fragment cache flush
In reply to Greg Kroah-HartmanFrom: Rameshkumar Sundaram <[email protected]>
[ Upstream commit ba53ee7f7f38cf0592b8be1dcdabaf8f7535f8c1 ]
frag_timer will be created & initialized for stations when they associate and will be deleted during every key installation while flushing old fragments.
For AP interface self peer will be created and Group keys will be installed for this peer, but there will be no real Station entry & hence frag_timer won't be created and initialized, deleting such uninitialized kernel timers causes below warnings and backtraces printed with CONFIG_DEBUG_OBJECTS_TIMERS enabled.
[ 177.828008] ODEBUG: assert_init not available (active state 0) object type: timer_list hint: 0x0 [ 177.836833] WARNING: CPU: 3 PID: 188 at lib/debugobjects.c:508 debug_print_object+0xb0/0xf0 [ 177.845185] Modules linked in: ath11k_pci ath11k qmi_helpers qrtr_mhi qrtr ns mhi [ 177.852679] CPU: 3 PID: 188 Comm: hostapd Not tainted 5.14.0-rc3-32919-g4034139e1838-dirty #14 [ 177.865805] pstate: 60000005 (nZCv daif -PAN -UAO -TCO BTYPE=--) [ 177.871804] pc : debug_print_object+0xb0/0xf0 [ 177.876155] lr : debug_print_object+0xb0/0xf0 [ 177.880505] sp : ffffffc01169b5a0 [ 177.883810] x29: ffffffc01169b5a0 x28: ffffff80081c2320 x27: ffffff80081c4078 [ 177.890942] x26: ffffff8003fe8f28 x25: ffffff8003de9890 x24: ffffffc01134d738 [ 177.898075] x23: ffffffc010948f20 x22: ffffffc010b2d2e0 x21: ffffffc01169b628 [ 177.905206] x20: ffffffc01134d700 x19: ffffffc010c80d98 x18: 00000000000003f6 [ 177.912339] x17: 203a657079742074 x16: 63656a626f202930 x15: 0000000000000152 [ 177.919471] x14: 0000000000000152 x13: 00000000ffffffea x12: ffffffc010d732e0 [ 177.926603] x11: 0000000000000003 x10: ffffffc010d432a0 x9 : ffffffc010d432f8 [ 177.933735] x8 : 000000000002ffe8 x7 : c0000000ffffdfff x6 : 0000000000000001 [ 177.940866] x5 : 0000000000000000 x4 : 0000000000000000 x3 : 00000000ffffffff [ 177.947997] x2 : ffffffc010c93240 x1 : ffffff80023624c0 x0 : 0000000000000054 [ 177.955130] Call trace: [ 177.957567] debug_print_object+0xb0/0xf0 [ 177.961570] debug_object_assert_init+0x124/0x178 [ 177.966269] try_to_del_timer_sync+0x1c/0x70 [ 177.970536] del_timer_sync+0x30/0x50 [ 177.974192] ath11k_peer_frags_flush+0x34/0x68 [ath11k] [ 177.979439] ath11k_mac_op_set_key+0x1e4/0x338 [ath11k] [ 177.984673] ieee80211_key_enable_hw_accel+0xc8/0x3d0 [ 177.989722] ieee80211_key_replace+0x360/0x740 [ 177.994160] ieee80211_key_link+0x16c/0x210 [ 177.998337] ieee80211_add_key+0x138/0x338 [ 178.002426] nl80211_new_key+0xfc/0x258 [ 178.006257] genl_family_rcv_msg_doit.isra.17+0xd8/0x120 [ 178.011565] genl_rcv_msg+0xd8/0x1c8 [ 178.015134] netlink_rcv_skb+0x38/0xf8 [ 178.018877] genl_rcv+0x34/0x48 [ 178.022012] netlink_unicast+0x174/0x230 [ 178.025928] netlink_sendmsg+0x188/0x388 [ 178.029845] ____sys_sendmsg+0x218/0x250 [ 178.033763] ___sys_sendmsg+0x68/0x90 [ 178.037418] __sys_sendmsg+0x44/0x88 [ 178.040988] __arm64_sys_sendmsg+0x20/0x28 [ 178.045077] invoke_syscall.constprop.5+0x54/0xe0 [ 178.049776] do_el0_svc+0x74/0xc0 [ 178.053084] el0_svc+0x10/0x18 [ 178.056133] el0t_64_sync_handler+0x88/0xb0 [ 178.060310] el0t_64_sync+0x148/0x14c [ 178.063966] ---[ end trace 8a5cf0bf9d34a058 ]---
Add changes to not to delete frag timer for peers during group key installation.
Tested on: IPQ8074 hw2.0 AHB WLAN.HK.2.5.0.1-01092-QCAHKSWPL_SILICONZ-1
--- drivers/net/wireless/ath/ath11k/mac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/ath/ath11k/mac.c +1 -1
@@ -2531,7 +2531,7 @@ static int ath11k_mac_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,/* flush the fragments cache during key (re)install to * ensure all frags in the new frag list belong to the same key. */ -if (peer && cmd ==SET_KEY ) +if (peer && sta && cmd ==SET_KEY )ath11k_peer_frags_flush (ar, peer);spin_unlock_bh (&ab->base_lock);
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 162/563 ARM: dts: gemini: NAS4220-B: fis-index-block with 128 KiB sectors
In reply to Greg Kroah-HartmanFrom: Christian Lamparter <[email protected]>
[ Upstream commit 4754eab7e5a78bdefe7a960c5c260c95ebbb5fa6 ]
Steven Maddox reported in the OpenWrt bugzilla, that his RaidSonic IB-NAS4220-B was no longer booting with the new OpenWrt 21.02 (uses linux 5.10's device-tree). However, it was working with the previous OpenWrt 19.07 series (uses 4.14).
|[ 5.548038] No RedBoot partition table detected in 30000000.flash |[ 5.618553] Searching for RedBoot partition table in 30000000.flash at offset 0x0 |[ 5.739093] No RedBoot partition table detected in 30000000.flash |... |[ 7.039504] Waiting for root device /dev/mtdblock3...
The provided bootlog shows that the RedBoot partition parser was looking for the partition table "at offset 0x0". Which is strange since the comment in the device-tree says it should be at 0xfe0000.
Further digging on the internet led to a review site that took some useful PCB pictures of their review unit back in February 2009. Their picture shows a Spansion S29GL128N11TFI01 flash chip.
Quoted 1 line
From Spansion's Datasheet:
"S29GL128N: One hundred twenty-eight 64 Kword (128 Kbyte) sectors" Steven also provided a "cat /sys/class/mtd/mtd0/erasesize" from his
unit: "131072".
With the 128 KiB Sector/Erasesize in mind. This patch changes the fis-index-block property to (0xfe0000 / 0x20000) = 0x7f.
Bugzilla: https://bugs.openwrt.org/index.php?do=details&task_id=4137
--- arch/arm/boot/dts/gemini-nas4220b.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/boot/dts/gemini-nas4220b.dts +1 -1
@@ -84,7 +84,7 @@ partitions { compatible = "redboot-fis"; /* Eraseblock at 0xfe0000 */ - fis-index-block = <0x1fc>; + fis-index-block = <0x7f>; }; };
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 163/563 media: dw2102: Fix use after free
In reply to Greg Kroah-HartmanFrom: Anton Vasilyev <[email protected]>
[ Upstream commit 589a9f0eb799f77de2c09583bf5bad221fa5d685 ]
dvb_usb_device_init stores parts of properties at d->props and d->desc and uses it on dvb_usb_device_exit. Free of properties on module probe leads to use after free.
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=204597
The patch makes properties static instead of allocated on heap to prevent memleak and use after free.
Also fixes s421_properties.devices initialization to have 2 element instead of 6 copied from p7500_properties.
--- drivers/media/usb/dvb-usb/dw2102.c | 338 ++++++++++++++++++----------- 1 file changed, 215 insertions(+), 123 deletions(-)
drivers/media/usb/dvb-usb/dw2102.c +215 -123
@@ -2148,46 +2148,153 @@ static struct dvb_usb_device_properties s6x0_properties = { } }; -static const struct dvb_usb_device_description d1100 = { -"Prof 1100 USB " , - {&dw2102_table[PROF_1100 ],NULL }, - {NULL }, -}; +static struct dvb_usb_device_properties p1100_properties = { + .caps =DVB_USB_IS_AN_I2C_ADAPTER , + .usb_ctrl =DEVICE_SPECIFIC , + .size_of_priv =sizeof (struct dw2102_state ), + .firmware =P1100_FIRMWARE , + .no_reconnect =1 , -static const struct dvb_usb_device_description d660 = { -"TeVii S660 USB" , - {&dw2102_table[TEVII_S660 ],NULL }, - {NULL }, -}; + .i2c_algo = &s6x0_i2c_algo, + .rc.core = { + .rc_interval =150 , + .rc_codes =RC_MAP_TBS_NEC , + .module_name ="dw2102" , + .allowed_protos =RC_PROTO_BIT_NEC , + .rc_query = prof_rc_query, + }, -static const struct dvb_usb_device_description d480_1 = { -"TeVii S480.1 USB" , - {&dw2102_table[TEVII_S480_1 ],NULL }, - {NULL }, + .generic_bulk_ctrl_endpoint =0x81 , + .num_adapters =1 , + .download_firmware = dw2102_load_firmware, + .read_mac_address = s6x0_read_mac_address, + .adapter = { + { + .num_frontends =1 , + .fe = {{ + .frontend_attach = stv0288_frontend_attach, + .stream = { + .type =USB_BULK , + .count =8 , + .endpoint =0x82 , + .u = { + .bulk = { + .buffersize =4096 , + } + } + }, + } }, + } + }, + .num_device_descs =1 , + .devices = { + {"Prof 1100 USB " , + {&dw2102_table[PROF_1100 ],NULL }, + {NULL }, + }, + } }; -static const struct dvb_usb_device_description d480_2 = { -"TeVii S480.2 USB" , - {&dw2102_table[TEVII_S480_2 ],NULL }, - {NULL }, -}; +static struct dvb_usb_device_properties s660_properties = { + .caps =DVB_USB_IS_AN_I2C_ADAPTER , + .usb_ctrl =DEVICE_SPECIFIC , + .size_of_priv =sizeof (struct dw2102_state ), + .firmware =S660_FIRMWARE , + .no_reconnect =1 , -static const struct dvb_usb_device_description d7500 = { -"Prof 7500 USB DVB-S2" , - {&dw2102_table[PROF_7500 ],NULL }, - {NULL }, -}; + .i2c_algo = &s6x0_i2c_algo, + .rc.core = { + .rc_interval =150 , + .rc_codes =RC_MAP_TEVII_NEC , + .module_name ="dw2102" , + .allowed_protos =RC_PROTO_BIT_NEC , + .rc_query = dw2102_rc_query, + }, -static const struct dvb_usb_device_description d421 = { -"TeVii S421 PCI" , - {&dw2102_table[TEVII_S421 ],NULL }, - {NULL }, + .generic_bulk_ctrl_endpoint =0x81 , + .num_adapters =1 , + .download_firmware = dw2102_load_firmware, + .read_mac_address = s6x0_read_mac_address, + .adapter = { + { + .num_frontends =1 , + .fe = {{ + .frontend_attach = ds3000_frontend_attach, + .stream = { + .type =USB_BULK , + .count =8 , + .endpoint =0x82 , + .u = { + .bulk = { + .buffersize =4096 , + } + } + }, + } }, + } + }, + .num_device_descs =3 , + .devices = { + {"TeVii S660 USB" , + {&dw2102_table[TEVII_S660 ],NULL }, + {NULL }, + }, + {"TeVii S480.1 USB" , + {&dw2102_table[TEVII_S480_1 ],NULL }, + {NULL }, + }, + {"TeVii S480.2 USB" , + {&dw2102_table[TEVII_S480_2 ],NULL }, + {NULL }, + }, + } }; -static const struct dvb_usb_device_description d632 = { -"TeVii S632 USB" , - {&dw2102_table[TEVII_S632 ],NULL }, - {NULL }, +static struct dvb_usb_device_properties p7500_properties = { + .caps =DVB_USB_IS_AN_I2C_ADAPTER , + .usb_ctrl =DEVICE_SPECIFIC , + .size_of_priv =sizeof (struct dw2102_state ), + .firmware =P7500_FIRMWARE , + .no_reconnect =1 , + + .i2c_algo = &s6x0_i2c_algo, + .rc.core = { + .rc_interval =150 , + .rc_codes =RC_MAP_TBS_NEC , + .module_name ="dw2102" , + .allowed_protos =RC_PROTO_BIT_NEC , + .rc_query = prof_rc_query, + }, + + .generic_bulk_ctrl_endpoint =0x81 , + .num_adapters =1 , + .download_firmware = dw2102_load_firmware, + .read_mac_address = s6x0_read_mac_address, + .adapter = { + { + .num_frontends =1 , + .fe = {{ + .frontend_attach = prof_7500_frontend_attach, + .stream = { + .type =USB_BULK , + .count =8 , + .endpoint =0x82 , + .u = { + .bulk = { + .buffersize =4096 , + } + } + }, + } }, + } + }, + .num_device_descs =1 , + .devices = { + {"Prof 7500 USB DVB-S2" , + {&dw2102_table[PROF_7500 ],NULL }, + {NULL }, + }, + } };static struct dvb_usb_device_properties su3000_properties = {
@@ -2267,6 +2374,59 @@ static struct dvb_usb_device_properties su3000_properties = { } }; +static struct dvb_usb_device_properties s421_properties = { + .caps =DVB_USB_IS_AN_I2C_ADAPTER , + .usb_ctrl =DEVICE_SPECIFIC , + .size_of_priv =sizeof (struct dw2102_state ), + .power_ctrl = su3000_power_ctrl, + .num_adapters =1 , + .identify_state = su3000_identify_state, + .i2c_algo = &su3000_i2c_algo, + + .rc.core = { + .rc_interval =150 , + .rc_codes =RC_MAP_SU3000 , + .module_name ="dw2102" , + .allowed_protos =RC_PROTO_BIT_RC5 , + .rc_query = su3000_rc_query, + }, + + .read_mac_address = su3000_read_mac_address, + + .generic_bulk_ctrl_endpoint =0x01 , + + .adapter = { + { + .num_frontends =1 , + .fe = {{ + .streaming_ctrl = su3000_streaming_ctrl, + .frontend_attach = m88rs2000_frontend_attach, + .stream = { + .type =USB_BULK , + .count =8 , + .endpoint =0x82 , + .u = { + .bulk = { + .buffersize =4096 , + } + } + } + } }, + } + }, + .num_device_descs =2 , + .devices = { + {"TeVii S421 PCI" , + { &dw2102_table[TEVII_S421 ],NULL }, + {NULL }, + }, + {"TeVii S632 USB" , + { &dw2102_table[TEVII_S632 ],NULL }, + {NULL }, + }, + } +}; +static struct dvb_usb_device_properties t220_properties = { .caps =DVB_USB_IS_AN_I2C_ADAPTER , .usb_ctrl =DEVICE_SPECIFIC ,
@@ -2384,101 +2544,33 @@ static struct dvb_usb_device_properties tt_s2_4600_properties = {static int dw2102_probe (struct usb_interface *intf,const struct usb_device_id *id) { -int retval = -ENOMEM ; -struct dvb_usb_device_properties *p1100; -struct dvb_usb_device_properties *s660; -struct dvb_usb_device_properties *p7500; -struct dvb_usb_device_properties *s421; - - p1100 =kmemdup (&s6x0_properties, -sizeof (struct dvb_usb_device_properties ),GFP_KERNEL ); -if (!p1100) - goto err0; - -/* copy default structure */ -/* fill only different fields */ - p1100->firmware =P1100_FIRMWARE ; - p1100->devices[0 ] = d1100; - p1100->rc.core.rc_query = prof_rc_query; - p1100->rc.core.rc_codes =RC_MAP_TBS_NEC ; - p1100->adapter->fe[0 ].frontend_attach = stv0288_frontend_attach; - - s660 =kmemdup (&s6x0_properties, -sizeof (struct dvb_usb_device_properties ),GFP_KERNEL ); -if (!s660) - goto err1; - - s660->firmware =S660_FIRMWARE ; - s660->num_device_descs =3 ; - s660->devices[0 ] = d660; - s660->devices[1 ] = d480_1; - s660->devices[2 ] = d480_2; - s660->adapter->fe[0 ].frontend_attach = ds3000_frontend_attach; - - p7500 =kmemdup (&s6x0_properties, -sizeof (struct dvb_usb_device_properties ),GFP_KERNEL ); -if (!p7500) - goto err2; - - p7500->firmware =P7500_FIRMWARE ; - p7500->devices[0 ] = d7500; - p7500->rc.core.rc_query = prof_rc_query; - p7500->rc.core.rc_codes =RC_MAP_TBS_NEC ; - p7500->adapter->fe[0 ].frontend_attach = prof_7500_frontend_attach; - - - s421 =kmemdup (&su3000_properties, -sizeof (struct dvb_usb_device_properties ),GFP_KERNEL ); -if (!s421) - goto err3; - - s421->num_device_descs =2 ; - s421->devices[0 ] = d421; - s421->devices[1 ] = d632; - s421->adapter->fe[0 ].frontend_attach = m88rs2000_frontend_attach; - -if (0 ==dvb_usb_device_init (intf, &dw2102_properties, -THIS_MODULE ,NULL , adapter_nr) || -0 ==dvb_usb_device_init (intf, &dw2104_properties, -THIS_MODULE ,NULL , adapter_nr) || -0 ==dvb_usb_device_init (intf, &dw3101_properties, -THIS_MODULE ,NULL , adapter_nr) || -0 ==dvb_usb_device_init (intf, &s6x0_properties, -THIS_MODULE ,NULL , adapter_nr) || -0 ==dvb_usb_device_init (intf, p1100, -THIS_MODULE ,NULL , adapter_nr) || -0 ==dvb_usb_device_init (intf, s660, -THIS_MODULE ,NULL , adapter_nr) || -0 ==dvb_usb_device_init (intf, p7500, -THIS_MODULE ,NULL , adapter_nr) || -0 ==dvb_usb_device_init (intf, s421, -THIS_MODULE ,NULL , adapter_nr) || -0 ==dvb_usb_device_init (intf, &su3000_properties, -THIS_MODULE ,NULL , adapter_nr) || -0 ==dvb_usb_device_init (intf, &t220_properties, -THIS_MODULE ,NULL , adapter_nr) || -0 ==dvb_usb_device_init (intf, &tt_s2_4600_properties, -THIS_MODULE ,NULL , adapter_nr)) { - -/* clean up copied properties */ -kfree (s421); -kfree (p7500); -kfree (s660); -kfree (p1100); +if (!(dvb_usb_device_init (intf, &dw2102_properties, +THIS_MODULE ,NULL , adapter_nr) && +dvb_usb_device_init (intf, &dw2104_properties, +THIS_MODULE ,NULL , adapter_nr) && +dvb_usb_device_init (intf, &dw3101_properties, +THIS_MODULE ,NULL , adapter_nr) && +dvb_usb_device_init (intf, &s6x0_properties, +THIS_MODULE ,NULL , adapter_nr) && +dvb_usb_device_init (intf, &p1100_properties, +THIS_MODULE ,NULL , adapter_nr) && +dvb_usb_device_init (intf, &s660_properties, +THIS_MODULE ,NULL , adapter_nr) && +dvb_usb_device_init (intf, &p7500_properties, +THIS_MODULE ,NULL , adapter_nr) && +dvb_usb_device_init (intf, &s421_properties, +THIS_MODULE ,NULL , adapter_nr) && +dvb_usb_device_init (intf, &su3000_properties, +THIS_MODULE ,NULL , adapter_nr) && +dvb_usb_device_init (intf, &t220_properties, +THIS_MODULE ,NULL , adapter_nr) && +dvb_usb_device_init (intf, &tt_s2_4600_properties, +THIS_MODULE ,NULL , adapter_nr))) {return 0 ; } - retval = -ENODEV ; -kfree (s421); -err3: -kfree (p7500); -err2: -kfree (s660); -err1: -kfree (p1100); -err0: -return retval; +return -ENODEV ; }static void dw2102_disconnect (struct usb_interface *intf)
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 164/563 media: msi001: fix possible null-ptr-deref in msi001_probe()
In reply to Greg Kroah-HartmanFrom: Wang Hai <[email protected]>
[ Upstream commit 3d5831a40d3464eea158180eb12cbd81c5edfb6a ]
I got a null-ptr-deref report:
BUG: kernel NULL pointer dereference, address: 0000000000000060 ... RIP: 0010:v4l2_ctrl_auto_cluster+0x57/0x270 ... Call Trace: msi001_probe+0x13b/0x24b [msi001] spi_probe+0xeb/0x130
...
do_syscall_64+0x35/0xb0
In msi001_probe(), if the creation of control for bandwidth_auto fails, there will be a null-ptr-deref issue when it is used in v4l2_ctrl_auto_cluster().
Check dev->hdl.error before v4l2_ctrl_auto_cluster() to fix this bug.
--- drivers/media/tuners/msi001.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/media/tuners/msi001.c +7 -0
@@ -442,6 +442,13 @@ static int msi001_probe(struct spi_device *spi) V4L2_CID_RF_TUNER_BANDWIDTH_AUTO, 0, 1, 1, 1); dev->bandwidth =v4l2_ctrl_new_std (&dev->hdl, &msi001_ctrl_ops,V4L2_CID_RF_TUNER_BANDWIDTH ,200000 ,8000000 ,1 ,200000 ); +if (dev->hdl.error) { + ret = dev->hdl.error; +dev_err (&spi->dev,"Could not initialize controls\n" ); +/* control init failed, free handler */ + goto err_ctrl_handler_free; + } +v4l2_ctrl_auto_cluster (2 , &dev->bandwidth_auto,0 , false); dev->lna_gain =v4l2_ctrl_new_std (&dev->hdl, &msi001_ctrl_ops,V4L2_CID_RF_TUNER_LNA_GAIN ,0 ,1 ,1 ,1 );
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 165/563 media: coda/imx-vdoa: Handle dma_set_coherent_mask error codes
In reply to Greg Kroah-HartmanFrom: Jiasheng Jiang <[email protected]>
[ Upstream commit 43f0633f89947df57fe0b5025bdd741768007708 ]
The return value of dma_set_coherent_mask() is not always 0. To catch the exception in case that dma is not support the mask.
--- drivers/media/platform/coda/imx-vdoa.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/media/platform/coda/imx-vdoa.c +5 -1
@@ -287,7 +287,11 @@ static int vdoa_probe(struct platform_device *pdev)struct resource *res;int ret; -dma_set_coherent_mask (&pdev->dev,DMA_BIT_MASK (32 )); + ret =dma_set_coherent_mask (&pdev->dev,DMA_BIT_MASK (32 )); +if (ret) { +dev_err (&pdev->dev,"DMA enable failed\n" ); +return ret; + } vdoa =devm_kzalloc (&pdev->dev,sizeof (*vdoa),GFP_KERNEL );if (!vdoa)
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 166/563 ath11k: Fix a NULL pointer dereference in ath11k_mac_op_hw_scan()
In reply to Greg Kroah-HartmanFrom: Zhou Qingyang <[email protected]>
[ Upstream commit eccd25136386a04ebf46a64f3a34e8e0fab6d9e1 ]
In ath11k_mac_op_hw_scan(), the return value of kzalloc() is directly used in memcpy(), which may lead to a NULL pointer dereference on failure of kzalloc().
Fix this bug by adding a check of arg.extraie.ptr.
This bug was found by a static analyzer. The analysis employs differential checking to identify inconsistent security operations (e.g., checks or kfrees) between two code paths and confirms that the inconsistent operations are not recovered in the current function or the callers, so they constitute bugs.
Note that, as a bug found by static analysis, it can be a false positive or hard to trigger. Multiple researchers have cross-reviewed the bug.
Builds with CONFIG_ATH11K=m show no new warnings, and our static analyzer no longer warns about this code.
--- drivers/net/wireless/ath/ath11k/mac.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/net/wireless/ath/ath11k/mac.c +5 -2
@@ -2320,9 +2320,12 @@ static int ath11k_mac_op_hw_scan(struct ieee80211_hw *hw, arg.scan_id =ATH11K_SCAN_ID ;if (req->ie_len) { + arg.extraie.ptr =kmemdup (req->ie, req->ie_len,GFP_KERNEL ); +if (!arg.extraie.ptr) { + ret = -ENOMEM ; + goto exit; + } arg.extraie.len = req->ie_len; - arg.extraie.ptr =kzalloc (req->ie_len,GFP_KERNEL ); -memcpy (arg.extraie.ptr, req->ie, req->ie_len); }if (req->n_ssids) {
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 167/563 arm64: dts: qcom: c630: Fix soundcard setup
In reply to Greg Kroah-HartmanFrom: Srinivas Kandagatla <[email protected]>
[ Upstream commit c02b360ca67ebeb9de07b47b2fe53f964c2561d1 ]
Currently Soundcard has 1 rx device for headset and SoundWire Speaker Playback.
This setup has issues, ex if we try to play on headset the audio stream is also sent to SoundWire Speakers and we will hear sound in both headsets and speakers.
Make a separate device for Speakers and Headset so that the streams are different and handled properly.
--- .../boot/dts/qcom/sdm850-lenovo-yoga-c630.dts | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+)
arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts +27 -0
@@ -365,6 +365,10 @@ dai@1 { reg = <1>; }; + + dai@2 { + reg = <2>; + }; }; &sound {
@@ -377,6 +381,7 @@ "SpkrLeft IN", "SPK1 OUT", "SpkrRight IN", "SPK2 OUT", "MM_DL1", "MultiMedia1 Playback", + "MM_DL3", "MultiMedia3 Playback", "MultiMedia2 Capture", "MM_UL2"; mm1-dai-link {
@@ -393,6 +398,13 @@ }; }; + mm3-dai-link { + link-name = "MultiMedia3"; + cpu { + sound-dai = <&q6asmdai MSM_FRONTEND_DAI_MULTIMEDIA3>; + }; + }; + slim-dai-link { link-name = "SLIM Playback"; cpu {
@@ -422,6 +434,21 @@ sound-dai = <&wcd9340 1>; }; }; + + slim-wcd-dai-link { + link-name = "SLIM WCD Playback"; + cpu { + sound-dai = <&q6afedai SLIMBUS_1_RX>; + }; + + platform { + sound-dai = <&q6routing>; + }; + + codec { + sound-dai = <&wcd9340 2>; + }; + }; }; &tlmm {
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 168/563 arm64: dts: qcom: ipq6018: Fix gpio-ranges property
In reply to Greg Kroah-HartmanFrom: Baruch Siach <[email protected]>
[ Upstream commit 72cb4c48a46a7cfa58eb5842c0d3672ddd5bd9ad ]
There must be three parameters in gpio-ranges property. Fixes this not very helpful error message:
OF: /soc/pinctrl@1000000: (null) = 3 found 3
--- arch/arm64/boot/dts/qcom/ipq6018.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/qcom/ipq6018.dtsi +1 -1
@@ -221,7 +221,7 @@ interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>; gpio-controller; #gpio-cells = <2>; - gpio-ranges = <&tlmm 0 80>; + gpio-ranges = <&tlmm 0 0 80>; interrupt-controller; #interrupt-cells = <2>;
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 169/563 drm/msm/dpu: fix safe status debugfs file
In reply to Greg Kroah-HartmanFrom: Dmitry Baryshkov <[email protected]>
[ Upstream commit f31b0e24d31e18b4503eeaf0032baeacc0beaff6 ]
Make safe_status debugfs fs file actually return safe status rather than danger status data.
--- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +2 -2
@@ -71,8 +71,8 @@ static int _dpu_danger_signal_status(struct seq_file *s, &status); }else {seq_puts (s,"\nSafe signal status:\n" ); -if (kms->hw_mdp->ops.get_danger_status) - kms->hw_mdp->ops.get_danger_status (kms->hw_mdp, +if (kms->hw_mdp->ops.get_safe_status) + kms->hw_mdp->ops.get_safe_status (kms->hw_mdp, &status); }pm_runtime_put_sync (&kms->pdev->dev);
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 170/563 drm/bridge: ti-sn65dsi86: Set max register for regmap
In reply to Greg Kroah-HartmanFrom: Stephen Boyd <[email protected]>
[ Upstream commit 0b665d4af35837f0a0ae63135b84a3c187c1db3b ]
Set the maximum register to 0xff so we can dump the registers for this device in debugfs.
--- drivers/gpu/drm/bridge/ti-sn65dsi86.c | 1 + 1 file changed, 1 insertion(+)
drivers/gpu/drm/bridge/ti-sn65dsi86.c +1 -0
@@ -171,6 +171,7 @@ static const struct regmap_config ti_sn_bridge_regmap_config = { .val_bits = 8, .volatile_table = &ti_sn_bridge_volatile_table, .cache_type = REGCACHE_NONE, + .max_register = 0xFF, }; static void ti_sn_bridge_write_u16(struct ti_sn_bridge *pdata,
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 171/563 drm/tegra: vic: Fix DMA API misuse
In reply to Greg Kroah-HartmanFrom: Robin Murphy <[email protected]>
[ Upstream commit 5566174cb10a5167d59b0793871cab7990b149b8 ]
Upon failure, dma_alloc_coherent() returns NULL. If that does happen, passing some uninitialised stack contents to dma_mapping_error() - which belongs to a different API in the first place - has precious little chance of detecting it.
Also include the correct header, because the fragile transitive inclusion currently providing it is going to break soon.
--- drivers/gpu/drm/tegra/vic.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
drivers/gpu/drm/tegra/vic.c +3 -4
@@ -5,6 +5,7 @@#include <linux/clk.h> #include <linux/delay.h> +#include <linux/dma-mapping.h> #include <linux/host1x.h> #include <linux/iommu.h> #include <linux/module.h>
@@ -265,10 +266,8 @@ static int vic_load_firmware(struct vic *vic)if (!client->group) { virt =dma_alloc_coherent (vic->dev, size, &iova,GFP_KERNEL ); - - err =dma_mapping_error (vic->dev, iova); -if (err <0 ) -return err; +if (!virt) +return -ENOMEM ; }else { virt =tegra_drm_alloc (tegra, size, &iova); }
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 172/563 media: hantro: Fix probe func error path
In reply to Greg Kroah-HartmanFrom: Jernej Skrabec <[email protected]>
[ Upstream commit 37af43b250fda6162005d47bf7c959c70d52b107 ]
If clocks for some reason couldn't be enabled, probe function returns immediately, without disabling PM. This obviously leaves PM ref counters unbalanced.
Fix that by jumping to appropriate error path, so effects of PM functions are reversed.
--- drivers/staging/media/hantro/hantro_drv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/staging/media/hantro/hantro_drv.c +2 -1
@@ -829,7 +829,7 @@ static int hantro_probe(struct platform_device *pdev) ret =clk_bulk_prepare (vpu->variant->num_clocks, vpu->clocks);if (ret) {dev_err (&pdev->dev,"Failed to prepare clocks\n" ); -return ret; + goto err_pm_disable; } ret =v4l2_device_register (&pdev->dev, &vpu->v4l2_dev);
@@ -885,6 +885,7 @@ err_v4l2_unreg:v4l2_device_unregister (&vpu->v4l2_dev); err_clk_unprepare:clk_bulk_unprepare (vpu->variant->num_clocks, vpu->clocks); +err_pm_disable:pm_runtime_dont_use_autosuspend (vpu->dev);pm_runtime_disable (vpu->dev);return ret;
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 173/563 xfrm: interface with if_id 0 should return error
In reply to Greg Kroah-HartmanFrom: Antony Antony <[email protected]>
[ Upstream commit 8dce43919566f06e865f7e8949f5c10d8c2493f5 ]
xfrm interface if_id = 0 would cause xfrm policy lookup errors since Commit 9f8550e4bd9d.
Now explicitly fail to create an xfrm interface when if_id = 0
With this commit:
ip link add ipsec0 type xfrm dev lo if_id 0
Error: if_id must be non zero.
v1->v2 change:
- add Fixes: tag
--- net/xfrm/xfrm_interface.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
net/xfrm/xfrm_interface.c +12 -2
@@ -643,11 +643,16 @@ static int xfrmi_newlink(struct net *src_net, struct net_device *dev, struct netlink_ext_ack *extack) {struct net *net =dev_net (dev); -struct xfrm_if_parms p; +struct xfrm_if_parms p = {};struct xfrm_if *xi;int err;xfrmi_netlink_parms (data, &p); +if (!p.if_id) { +NL_SET_ERR_MSG (extack,"if_id must be non zero" ); +return -EINVAL ; + } + xi =xfrmi_locate (net, &p);if (xi)return -EEXIST ;
@@ -672,7 +677,12 @@ static int xfrmi_changelink(struct net_device *dev, struct nlattr *tb[], {struct xfrm_if *xi =netdev_priv (dev);struct net *net = xi->net; -struct xfrm_if_parms p; +struct xfrm_if_parms p = {}; + +if (!p.if_id) { +NL_SET_ERR_MSG (extack,"if_id must be non zero" ); +return -EINVAL ; + }xfrmi_netlink_parms (data, &p); xi =xfrmi_locate (net, &p);
Signature · 1 line
2.34.1
Re: [PATCH 5.10 173/563] xfrm: interface with if_id 0 should return error
Hi!
Quoted 6 lines
[ Upstream commit
8dce43919566f06e865f7e8949f5c10d8c2493f5]xfrm interface
if_id= 0 would cause xfrm policy lookup errors since Commit9f8550e4bd9d.Now explicitly fail to create an xfrm interface when
if_id= 0
This will break changelink completely, AFAICT.
Quoted 4 lines
(quoted diff) +0
-0@@ -672,7 +677,12 @@ static int xfrmi_changelink(struct net_device *dev, struct nlattr *tb[], { struct xfrm_if *xi = netdev_priv(dev); struct net *net = xi->net;
Review static int xfrmi_changelink(struct net_device *dev, struct nlattr *tb[], · line 688
Quoted 10 lines
(quoted diff) +6
-1- struct xfrm_if_parms p; + struct xfrm_if_parms p = {}; + + if (!p.if_id) { + NL_SET_ERR_MSG(extack, "if_id must be non zero"); + return -EINVAL; + } xfrmi_netlink_parms(data, &p); xi = xfrmi_locate(net, &p);
if_id will be always 0, because it was not yet initialized.
Best regards,
Pavel
net/xfrm/xfrm_interface.c +1 -2
@@ -673,12 +673,11 @@ static int xfrmi_changelink(struct net_device *dev, struct nlattr *tb[],struct net *net = xi->net;struct xfrm_if_parms p = {}; +xfrmi_netlink_parms (data, &p);if (!p.if_id) {NL_SET_ERR_MSG (extack,"if_id must be non zero" );return -EINVAL ; } - -xfrmi_netlink_parms (data, &p); xi =xfrmi_locate (net, &p);if (!xi) { xi =netdev_priv (dev);
Signature · 2 lines
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Steffen Klassert
maintainerRe: [PATCH 5.10 173/563] xfrm: interface with if_id 0 should return error
Quoted 28 lines · Pavel Machek
Hi!
Quoted 6 lines
[ Upstream commit
8dce43919566f06e865f7e8949f5c10d8c2493f5]xfrm interface
if_id= 0 would cause xfrm policy lookup errors since Commit9f8550e4bd9d.Now explicitly fail to create an xfrm interface when
if_id= 0This will break changelink completely, AFAICT.
Quoted 4 lines
(quoted diff) +0
-0@@ -672,7 +677,12 @@ static int xfrmi_changelink(struct net_device *dev, struct nlattr *tb[], { struct xfrm_if *xi = netdev_priv(dev); struct net *net = xi->net;Review static int xfrmi_changelink(struct net_device *dev, struct nlattr *tb[], · line 688
Quoted 10 lines
(quoted diff) +6
-1- struct xfrm_if_parms p; + struct xfrm_if_parms p = {}; + + if (!p.if_id) { + NL_SET_ERR_MSG(extack, "if_id must be non zero"); + return -EINVAL; + } xfrmi_netlink_parms(data, &p); xi = xfrmi_locate(net, &p);
if_idwill be always 0, because it was not yet initialized.
Quoted 4 lines
Best regards,
PavelSigned-off-by Pavel Machek <[email protected]>
Can you please resend this with proper commit message and 'Fixes:' tag?
Thanks!
PATCH 1/1 xfrm: fix the if_id check in changelink
In reply to Pavel Machekif_id will be always 0, because it was not yet initialized.
--- net/xfrm/xfrm_interface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/xfrm/xfrm_interface.c +1 -1
@@ -673,12 +673,12 @@ static int xfrmi_changelink(struct net_device *dev, struct nlattr *tb[],struct net *net = xi->net;struct xfrm_if_parms p = {}; +xfrmi_netlink_parms (data, &p);if (!p.if_id) {NL_SET_ERR_MSG (extack,"if_id must be non zero" );return -EINVAL ; } -xfrmi_netlink_parms (data, &p); xi =xfrmi_locate (net, &p);if (!xi) { xi =netdev_priv (dev);
--
2.30.2
Greg Kroah-Hartman
maintainerRe: [PATCH] xfrm: fix the if_id check in changelink
Quoted 8 lines · Antony Antony
if_idwill be always 0, because it was not yet initialized.Fixes 8dce43919566 ("xfrm: interface with if_id 0 should return error")Reported-by Pavel Machek <[email protected]>Signed-off-by Antony Antony <[email protected]>--- net/xfrm/xfrm_interface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
<formletter>
This is not the correct way to submit patches for inclusion in the stable kernel tree. Please read:
https://www.kernel.org/doc/html/latest/process/stable-kernel-rules.html
for how to do this properly.
</formletter>
Re: [PATCH] xfrm: fix the if_id check in changelink
In reply to Antony AntonyQuoted 5 lines · Antony Antony
if_idwill be always 0, because it was not yet initialized.Fixes 8dce43919566 ("xfrm: interface with if_id 0 should return error")Reported-by Pavel Machek <[email protected]>Signed-off-by Antony Antony <[email protected]>
Applied, thanks a lot Antony!
Greg Kroah-Hartman
maintainerPATCH 174/563 xfrm: state and policy should fail if XFRMA_IF_ID 0
In reply to Greg Kroah-HartmanFrom: Antony Antony <[email protected]>
[ Upstream commit 68ac0f3810e76a853b5f7b90601a05c3048b8b54 ]
xfrm ineterface does not allow xfrm if_id = 0
fail to create or update xfrm state and policy.
With this commit:
ip xfrm policy add src 192.0.2.1 dst 192.0.2.2 dir out if_id 0 RTNETLINK answers: Invalid argument
ip xfrm state add src 192.0.2.1 dst 192.0.2.2 proto esp spi 1 \
reqid 1 mode tunnel aead 'rfc4106(gcm(aes))' \
0x1111111111111111111111111111111111111111 96 if_id 0RTNETLINK answers: Invalid argument
v1->v2 change:
- add Fixes: tag
--- net/xfrm/xfrm_user.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-)
net/xfrm/xfrm_user.c +18 -3
@@ -621,8 +621,13 @@ static struct xfrm_state *xfrm_state_construct(struct net *net,xfrm_smark_init (attrs, &x->props.smark); -if (attrs[XFRMA_IF_ID ]) +if (attrs[XFRMA_IF_ID ]) { x->if_id =nla_get_u32 (attrs[XFRMA_IF_ID ]); +if (!x->if_id) { + err = -EINVAL ; + goto error; + } + } err =__xfrm_init_state (x, false, attrs[XFRMA_OFFLOAD_DEV ]);if (err)
@@ -1353,8 +1358,13 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh, mark =xfrm_mark_get (attrs, &m); -if (attrs[XFRMA_IF_ID ]) +if (attrs[XFRMA_IF_ID ]) { if_id =nla_get_u32 (attrs[XFRMA_IF_ID ]); +if (!if_id) { + err = -EINVAL ; + goto out_noput; + } + }if (p->info.seq) { x =xfrm_find_acq_byseq (net, mark, p->info.seq);
@@ -1667,8 +1677,13 @@ static struct xfrm_policy *xfrm_policy_construct(struct net *net, struct xfrm_usxfrm_mark_get (attrs, &xp->mark); -if (attrs[XFRMA_IF_ID ]) +if (attrs[XFRMA_IF_ID ]) { xp->if_id =nla_get_u32 (attrs[XFRMA_IF_ID ]); +if (!xp->if_id) { + err = -EINVAL ; + goto error; + } + }return xp; error:
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 175/563 ARM: 9159/1: decompressor: Avoid UNPREDICTABLE NOP encoding
In reply to Greg Kroah-HartmanFrom: Andre Przywara <[email protected]>
[ Upstream commit a92882a4d270fbcc021ee6848de5e48b7f0d27f3 ]
In the decompressor's head.S we need to start with an instruction that is some kind of NOP, but also mimics as the PE/COFF header, when the kernel is linked as an UEFI application. The clever solution here is "tstne r0, #0x4d000", which in the worst case just clobbers the condition flags, and bears the magic "MZ" signature in the lowest 16 bits.
However the encoding used (0x13105a4d) is actually not valid, since bits [15:12] are supposed to be 0 (written as "(0)" in the ARM ARM). Violating this is UNPREDICTABLE, and *can* trigger an UNDEFINED exception. Common Cortex cores seem to ignore those bits, but QEMU chooses to trap, so the code goes fishing because of a missing exception handler at this point. We are just saved by the fact that commonly (with -kernel or when running from U-Boot) the "Z" bit is set, so the instruction is never executed. See [0] for more details.
To make things more robust and avoid UNPREDICTABLE behaviour in the kernel code, lets replace this with a "two-instruction NOP":
The first instruction is an exclusive OR, the effect of which the second instruction reverts. This does not leave any trace, neither in a register nor in the condition flags. Also it's a perfectly valid encoding. Kudos to Peter Maydell for coming up with this gem.
[0] https://lore.kernel.org/qemu-devel/YTPIdbUCmwagL5%[email protected]/T/
--- arch/arm/boot/compressed/efi-header.S | 22 ++++++++++++++-------- arch/arm/boot/compressed/head.S | 3 ++- 2 files changed, 16 insertions(+), 9 deletions(-)
arch/arm/boot/compressed/efi-header.S +14 -8
@@ -9,16 +9,22 @@ #include <linux/sizes.h> .macro __nop -#ifdef CONFIG_EFI_STUB - @ This is almost but not quite a NOP, since it does clobber the - @ condition flags. But it is the best we can do for EFI, since - @ PE/COFF expects the magic string "MZ" at offset 0, while the - @ ARM/Linux boot protocol expects an executable instruction - @ there. - .inst MZ_MAGIC | (0x1310 << 16) @ tstne r0, #0x4d000 -#else AR_CLASS( mov r0, r0 ) M_CLASS( nop.w ) + .endm + + .macro __initial_nops +#ifdef CONFIG_EFI_STUB + @ This is a two-instruction NOP, which happens to bear the + @ PE/COFF signature "MZ" in the first two bytes, so the kernel + @ is accepted as an EFI binary. Booting via the UEFI stub + @ will not execute those instructions, but the ARM/Linux + @ boot protocol does, so we need some NOPs here. + .inst MZ_MAGIC | (0xe225 << 16) @ eor r5, r5, 0x4d000 + eor r5, r5, 0x4d000 @ undo previous insn +#else + __nop + __nop #endif .endm
arch/arm/boot/compressed/head.S +2 -1
@@ -190,7 +190,8 @@ start: * were patching the initial instructions of the kernel, i.e * had started to exploit this "patch area". */ - .rept 7 + __initial_nops + .rept 5 __nop .endr #ifndef CONFIG_THUMB2_KERNEL
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 176/563 usb: ftdi-elan: fix memory leak on device disconnect
In reply to Greg Kroah-HartmanFrom: Wei Yongjun <[email protected]>
[ Upstream commit 1646566b5e0c556f779180a8514e521ac735de1e ]
'ftdi' is alloced when probe device, but not free on device disconnect, this cause a memory leak as follows:
unreferenced object 0xffff88800d584000 (size 8400):
comm "kworker/0:2", pid 3809, jiffies 4295453055 (age 13.784s) hex dump (first 32 bytes):
00 40 58 0d 80 88 ff ff 00 40 58 0d 80 88 ff ff .@X......@X.....
00 00 00 00 00 00 00 00 00 00 00 00 ad 4e ad de .............N..
backtrace:
[<000000000d47f947>] kmalloc_order_trace+0x19/0x110 mm/slab_common.c:960
[<000000008548ac68>] ftdi_elan_probe+0x8c/0x880 drivers/usb/misc/ftdi-elan.c:2647
[<000000007f73e422>] usb_probe_interface+0x31b/0x800 drivers/usb/core/driver.c:396
[<00000000fe8d07fc>] really_probe+0x299/0xc30 drivers/base/dd.c:517
[<0000000005da7d32>] __driver_probe_device+0x357/0x500 drivers/base/dd.c:751
[<000000003c2c9579>] driver_probe_device+0x4e/0x140 drivers/base/dd.c:781Fix it by freeing 'ftdi' after nobody use it.
--- drivers/usb/misc/ftdi-elan.c | 1 + 1 file changed, 1 insertion(+)
drivers/usb/misc/ftdi-elan.c +1 -0
@@ -202,6 +202,7 @@ static void ftdi_elan_delete(struct kref *kref)mutex_unlock (&ftdi_module_lock);kfree (ftdi->bulk_in_buffer); ftdi->bulk_in_buffer =NULL ; +kfree (ftdi); }static void ftdi_elan_put_kref (struct usb_ftdi *ftdi)
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 177/563 arm64: dts: marvell: cn9130: add GPIO and SPI aliases
In reply to Greg Kroah-HartmanFrom: Robert Marko <[email protected]>
[ Upstream commit effd42600b987c1e95f946b14fefc1c7639e7439 ]
CN9130 has one CP115 built in, which like the CP110 has 2 GPIO and 2 SPI controllers built-in.
However, unlike the Armada 7k and 8k the SoC DTSI doesn't add the required aliases as both the Orion SPI driver and MVEBU GPIO drivers require the aliases to be present.
So add the required aliases for GPIO and SPI controllers.
--- arch/arm64/boot/dts/marvell/cn9130.dtsi | 7 +++++++ 1 file changed, 7 insertions(+)
arch/arm64/boot/dts/marvell/cn9130.dtsi +7 -0
@@ -11,6 +11,13 @@ model = "Marvell Armada CN9130 SoC"; compatible = "marvell,cn9130", "marvell,armada-ap807-quad", "marvell,armada-ap807"; + + aliases { + gpio1 = &cp0_gpio1; + gpio2 = &cp0_gpio2; + spi1 = &cp0_spi0; + spi2 = &cp0_spi1; + }; }; /*
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 178/563 arm64: dts: marvell: cn9130: enable CP0 GPIO controllers
In reply to Greg Kroah-HartmanFrom: Robert Marko <[email protected]>
[ Upstream commit 0734f8311ce72c9041e5142769eff2083889c172 ]
CN9130 has a built-in CP115 which has 2 GPIO controllers, but unlike in Armada 7k and 8k both are left disabled by the SoC DTSI.
This first of all makes no sense as they are always present due to being SoC built-in and its an issue as boards like CN9130-CRB use the CPO GPIO2 pins for regulators and SD card support without enabling them first.
So, enable both of them like Armada 7k and 8k do.
--- arch/arm64/boot/dts/marvell/cn9130.dtsi | 8 ++++++++ 1 file changed, 8 insertions(+)
arch/arm64/boot/dts/marvell/cn9130.dtsi +8 -0
@@ -42,3 +42,11 @@ #undef CP11X_PCIE0_BASE #undef CP11X_PCIE1_BASE #undef CP11X_PCIE2_BASE + +&cp0_gpio1 { + status = "okay"; +}; + +&cp0_gpio2 { + status = "okay"; +};
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 179/563 ARM: dts: armada-38x: Add generic compatible to UART nodes
In reply to Greg Kroah-HartmanFrom: Marek Behún <[email protected]>
[ Upstream commit 62480772263ab6b52e758f2346c70a526abd1d28 ]
Add generic compatible string "ns16550a" to serial port nodes of Armada 38x.
This makes it possible to use earlycon.
--- arch/arm/boot/dts/armada-38x.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm/boot/dts/armada-38x.dtsi +2 -2
@@ -168,7 +168,7 @@ }; uart0: serial@12000 { - compatible = "marvell,armada-38x-uart"; + compatible = "marvell,armada-38x-uart", "ns16550a"; reg = <0x12000 0x100>; reg-shift = <2>; interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
@@ -178,7 +178,7 @@ }; uart1: serial@12100 { - compatible = "marvell,armada-38x-uart"; + compatible = "marvell,armada-38x-uart", "ns16550a"; reg = <0x12100 0x100>; reg-shift = <2>; interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 180/563 iwlwifi: mvm: fix 32-bit build in FTM
In reply to Greg Kroah-HartmanFrom: Johannes Berg <[email protected]>
[ Upstream commit 8b0f92549f2c2458200935c12a2e2a6e80234cf5 ]
On a 32-bit build, the division here needs to be done using do_div(), otherwise the compiler will try to call a function that doesn't exist, thus failing to build.
--- drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c +2 -1
@@ -967,7 +967,8 @@ static void iwl_mvm_ftm_rtt_smoothing(struct iwl_mvm *mvm, overshoot =IWL_MVM_FTM_INITIATOR_SMOOTH_OVERSHOOT ; alpha =IWL_MVM_FTM_INITIATOR_SMOOTH_ALPHA ; - rtt_avg = (alpha * rtt + (100 - alpha) * resp->rtt_avg) /100 ; + rtt_avg = alpha * rtt + (100 - alpha) * resp->rtt_avg; +do_div (rtt_avg,100 ); IWL_DEBUG_INFO(mvm, "%pM: prev rtt_avg=%lld, new rtt_avg=%lld, rtt=%lld\n",
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 181/563 iwlwifi: mvm: test roc running status bits before removing the sta
In reply to Greg Kroah-HartmanFrom: Nathan Errera <[email protected]>
[ Upstream commit 998e1aba6e5eb35370eaf30ccc1823426ec11f90 ]
In some cases the sta is being removed twice since we do not test the roc aux running before removing it. Start looking at the bit before removing the sta.
--- .../net/wireless/intel/iwlwifi/mvm/time-event.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-)
drivers/net/wireless/intel/iwlwifi/mvm/time-event.c +12 -3
@@ -98,14 +98,13 @@ void iwl_mvm_roc_done_wk(struct work_struct *wk) struct iwl_mvm *mvm = container_of(wk, struct iwl_mvm, roc_done_wk);/* -* Clear the ROC_RUNNING /ROC_AUX_RUNNING status bit. +* Clear the ROC_RUNNING status bit. * This will cause the TX path to drop offchannel transmissions. * That would also be done by mac80211, but it is racy, in particular * in the case that the time event actually completed in the firmware * (which is handled in iwl_mvm_te_handle_notif). */ clear_bit (IWL_MVM_STATUS_ROC_RUNNING , &mvm->status); -clear_bit (IWL_MVM_STATUS_ROC_AUX_RUNNING , &mvm->status);synchronize_net ();
@@ -131,9 +130,19 @@ void iwl_mvm_roc_done_wk(struct work_struct *wk) mvmvif =iwl_mvm_vif_from_mac80211 (mvm->p2p_device_vif);iwl_mvm_flush_sta (mvm, &mvmvif->bcast_sta, true); } - }else { + } + +/* +* Clear the ROC_AUX_RUNNING status bit. +* This will cause the TX path to drop offchannel transmissions. +* That would also be done by mac80211, but it is racy, in particular +* in the case that the time event actually completed in the firmware +* (which is handled in iwl_mvm_te_handle_notif). +*/ +if (test_and_clear_bit (IWL_MVM_STATUS_ROC_AUX_RUNNING , &mvm->status)) {/* do the same in case of hot spot 2.0 */ iwl_mvm_flush_sta (mvm, &mvm->aux_sta, true); +/* In newer version of this command an aux station is added only * in cases of dedicated tx queue and need to be removed in end * of use */
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 182/563 mmc: meson-mx-sdhc: add IRQ check
In reply to Greg Kroah-HartmanFrom: Sergey Shtylyov <[email protected]>
[ Upstream commit 77bed755e0f06135faccdd3948863703f9a6e640 ]
The driver neglects to check the result of platform_get_irq()'s call and blithely passes the negative error codes to devm_request_threaded_irq() (which takes *unsigned* IRQ #), causing it to fail with -EINVAL, overriding an original error code. Stop calling devm_request_threaded_irq() with the invalid IRQ #s.
--- drivers/mmc/host/meson-mx-sdhc-mmc.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/mmc/host/meson-mx-sdhc-mmc.c +5 -0
@@ -854,6 +854,11 @@ static int meson_mx_sdhc_probe(struct platform_device *pdev) goto err_disable_pclk; irq =platform_get_irq (pdev,0 ); +if (irq <0 ) { + ret = irq; + goto err_disable_pclk; + } + ret =devm_request_threaded_irq (dev, irq, meson_mx_sdhc_irq, meson_mx_sdhc_irq_thread,IRQF_ONESHOT ,NULL , host);
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 183/563 mmc: meson-mx-sdio: add IRQ check
In reply to Greg Kroah-HartmanFrom: Sergey Shtylyov <[email protected]>
[ Upstream commit 8fc9a77bc64e1f23d07953439817d8402ac9706f ]
The driver neglects to check the result of platform_get_irq()'s call and blithely passes the negative error codes to devm_request_threaded_irq() (which takes *unsigned* IRQ #), causing it to fail with -EINVAL, overriding an original error code. Stop calling devm_request_threaded_irq() with the invalid IRQ #s.
--- drivers/mmc/host/meson-mx-sdio.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/mmc/host/meson-mx-sdio.c +5 -0
@@ -663,6 +663,11 @@ static int meson_mx_mmc_probe(struct platform_device *pdev) } irq =platform_get_irq (pdev,0 ); +if (irq <0 ) { + ret = irq; + goto error_free_mmc; + } + ret = devm_request_threaded_irq(host->controller_dev, irq, meson_mx_mmc_irq, meson_mx_mmc_irq_thread, IRQF_ONESHOT,
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 184/563 selinux: fix potential memleak in selinux_add_opt()
In reply to Greg Kroah-HartmanFrom: Bernard Zhao <[email protected]>
[ Upstream commit 2e08df3c7c4e4e74e3dd5104c100f0bf6288aaa8 ]
This patch try to fix potential memleak in error branch.
--- security/selinux/hooks.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
security/selinux/hooks.c +10 -2
@@ -947,18 +947,22 @@ out:static int selinux_add_opt (int token,const char *s,void **mnt_opts) {struct selinux_mnt_opts *opts = *mnt_opts; +bool is_alloc_opts = false;if (token == Opt_seclabel)/* eaten and completely ignored */ return 0 ; +if (!s) +return -ENOMEM ; +if (!opts) { opts =kzalloc (sizeof (struct selinux_mnt_opts ),GFP_KERNEL );if (!opts)return -ENOMEM ; *mnt_opts = opts; + is_alloc_opts = true; } -if (!s) -return -ENOMEM ; +switch (token) {case Opt_context:if (opts->context || opts->defcontext)
@@ -983,6 +987,10 @@ static int selinux_add_opt(int token, const char *s, void **mnt_opts) }return 0 ; Einval: +if (is_alloc_opts) { +kfree (opts); + *mnt_opts =NULL ; + }pr_warn (SEL_MOUNT_FAIL_MSG );return -EINVAL ; }
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 185/563 um: fix ndelay/udelay defines
In reply to Greg Kroah-HartmanFrom: Johannes Berg <[email protected]>
[ Upstream commit 5f8539e2ff962e25b57742ca7106456403abbc94 ]
Many places in the kernel use 'udelay' as an identifier, and are broken with the current "#define udelay um_udelay". Fix this by adding an argument to the macro, and do the same to 'ndelay' as well, just in case.
--- arch/um/include/asm/delay.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/um/include/asm/delay.h +2 -2
@@ -14,7 +14,7 @@ static inline void um_ndelay(unsigned long nsecs)ndelay (nsecs); }#undef ndelay -#define ndelay um_ndelay +#define ndelay (n) um_ndelay(n)static inline void um_udelay (unsigned long usecs) {
@@ -26,5 +26,5 @@ static inline void um_udelay(unsigned long usecs) udelay(usecs); }#undef udelay -#define udelay um_udelay +#define udelay (n) um_udelay(n)#endif /* __UM_DELAY_H */
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 186/563 um: virtio_uml: Fix time-travel external time propagation
In reply to Greg Kroah-HartmanFrom: Johannes Berg <[email protected]>
[ Upstream commit 85e73968a040c642fd38f6cba5b73b61f5d0f052 ]
When creating an external event, the current time needs to be propagated to other participants of a simulation. This is done in the places here where we kick a virtq etc.
However, it must be done for _all_ external events, and that includes making the initial socket connection and later closing it. Call time_travel_propagate_time() to do this before making or closing the socket connection.
Apparently, at least for the initial connection creation, due to the remote side in my use cases using microseconds (rather than nanoseconds), this wasn't a problem yet; only started failing between 5.14-rc1 and 5.15-rc1 (didn't test others much), or possibly depending on the configuration, where more delays happen before the virtio devices are initialized.
--- arch/um/drivers/virtio_uml.c | 4 ++++ 1 file changed, 4 insertions(+)
arch/um/drivers/virtio_uml.c +4 -0
@@ -1076,6 +1076,8 @@ static void virtio_uml_release_dev(struct device *d) container_of(d, struct virtio_device, dev);struct virtio_uml_device *vu_dev =to_virtio_uml_device (vdev); +time_travel_propagate_time (); +/* might not have been opened due to not negotiating the feature */ if (vu_dev->req_fd >=0 ) {um_free_irq (VIRTIO_IRQ , vu_dev);
@@ -1109,6 +1111,8 @@ static int virtio_uml_probe(struct platform_device *pdev) vu_dev->pdev = pdev; vu_dev->req_fd =-1 ; +time_travel_propagate_time (); +do { rc =os_connect_socket (pdata->socket_path); }while (rc == -EINTR );
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 187/563 Bluetooth: L2CAP: Fix using wrong mode
In reply to Greg Kroah-HartmanFrom: Luiz Augusto von Dentz <[email protected]>
[ Upstream commit 30d57722732d9736554f85f75f9d7ad5402d192e ]
If user has a set to use SOCK_STREAM the socket would default to L2CAP_MODE_ERTM which later needs to be adjusted if the destination address is LE which doesn't support such mode.
--- net/bluetooth/l2cap_sock.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
net/bluetooth/l2cap_sock.c +10 -2
@@ -161,7 +161,11 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)break ; } -if (chan->psm &&bdaddr_type_is_le (chan->src_type)) +/* Use L2CAP_MODE_LE_FLOWCTL (CoC) in case of LE address and +* L2CAP_MODE_EXT_FLOWCTL (ECRED) has not been set. +*/ +if (chan->psm &&bdaddr_type_is_le (chan->src_type) && + chan->mode !=L2CAP_MODE_EXT_FLOWCTL ) chan->mode =L2CAP_MODE_LE_FLOWCTL ; chan->state =BT_BOUND ;
@@ -255,7 +259,11 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr,return -EINVAL ; } -if (chan->psm &&bdaddr_type_is_le (chan->src_type) && !chan->mode) +/* Use L2CAP_MODE_LE_FLOWCTL (CoC) in case of LE address and +* L2CAP_MODE_EXT_FLOWCTL (ECRED) has not been set. +*/ +if (chan->psm &&bdaddr_type_is_le (chan->src_type) && + chan->mode !=L2CAP_MODE_EXT_FLOWCTL ) chan->mode =L2CAP_MODE_LE_FLOWCTL ;l2cap_sock_init_pid (sk);
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 188/563 bpftool: Enable line buffering for stdout
In reply to Greg Kroah-HartmanFrom: Paul Chaignon <[email protected]>
[ Upstream commit 1a1a0b0364ad291bd8e509da104ac8b5b1afec5d ]
The output of bpftool prog tracelog is currently buffered, which is inconvenient when piping the output into other commands. A simple tracelog | grep will typically not display anything. This patch fixes it by enabling line buffering on stdout for the whole bpftool binary.
--- tools/bpf/bpftool/main.c | 2 ++ 1 file changed, 2 insertions(+)
tools/bpf/bpftool/main.c +2 -0
@@ -396,6 +396,8 @@ int main(int argc, char **argv) };int opt, ret; +setlinebuf (stdout); + last_do_help = do_help; pretty_output = false; json_output = false;
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 189/563 backlight: qcom-wled: Validate enabled string indices in DT
In reply to Greg Kroah-HartmanFrom: Marijn Suijten <[email protected]>
[ Upstream commit c05b21ebc5bce3ecc78c2c71afd76d92c790a2ac ]
The strings passed in DT may possibly cause out-of-bounds register accesses and should be validated before use.
--- drivers/video/backlight/qcom-wled.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-)
drivers/video/backlight/qcom-wled.c +17 -1
@@ -1528,12 +1528,28 @@ static int wled_configure(struct wled *wled) string_len =of_property_count_elems_of_size (dev->of_node,"qcom,enabled-strings" ,sizeof (u32)); -if (string_len >0 ) +if (string_len >0 ) { +if (string_len > wled->max_string_count) { +dev_err (dev,"Cannot have more than %d strings\n" , + wled->max_string_count); +return -EINVAL ; + } +of_property_read_u32_array (dev->of_node,"qcom,enabled-strings" , wled->cfg.enabled_strings,sizeof (u32)); +for (i =0 ; i < string_len; ++i) { +if (wled->cfg.enabled_strings[i] >= wled->max_string_count) { +dev_err (dev, +"qcom,enabled-strings index %d at %d is out of bounds\n" , + wled->cfg.enabled_strings[i], i); +return -EINVAL ; + } + } + } +return 0 ; }
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 190/563 backlight: qcom-wled: Pass number of elements to read to read_u32_array
In reply to Greg Kroah-HartmanFrom: Marijn Suijten <[email protected]>
[ Upstream commit e29e24bdabfeddbf8b1a4ecac1af439a85150438 ]
of_property_read_u32_array takes the number of elements to read as last argument. This does not always need to be 4 (sizeof(u32)) but should instead be the size of the array in DT as read just above with of_property_count_elems_of_size.
To not make such an error go unnoticed again the driver now bails accordingly when of_property_read_u32_array returns an error. Surprisingly the indentation of newlined arguments is lining up again after prepending rc = .
--- drivers/video/backlight/qcom-wled.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
drivers/video/backlight/qcom-wled.c +7 -2
@@ -1535,10 +1535,15 @@ static int wled_configure(struct wled *wled)return -EINVAL ; } -of_property_read_u32_array (dev->of_node, + rc =of_property_read_u32_array (dev->of_node,"qcom,enabled-strings" , wled->cfg.enabled_strings, -sizeof (u32)); + string_len); +if (rc) { +dev_err (dev,"Failed to read %d elements from qcom,enabled-strings: %d\n" , + string_len, rc); +return rc; + }for (i =0 ; i < string_len; ++i) {if (wled->cfg.enabled_strings[i] >= wled->max_string_count) {
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 191/563 backlight: qcom-wled: Fix off-by-one maximum with default num_strings
In reply to Greg Kroah-HartmanFrom: Marijn Suijten <[email protected]>
[ Upstream commit 5ada78b26f935f8751852dffa24f6b545b1d2517 ]
When not specifying num-strings in the DT the default is used, but +1 is added to it which turns WLED3 into 4 and WLED4/5 into 5 strings instead of 3 and 4 respectively, causing out-of-bounds reads and register read/writes. This +1 exists for a deficiency in the DT parsing code, and is simply omitted entirely - solving this oob issue - by parsing the property separately much like qcom,enabled-strings.
This also enables more stringent checks on the maximum value when qcom,enabled-strings is provided in the DT, by parsing num-strings after enabled-strings to allow it to check against (and in a subsequent patch override) the length of enabled-strings: it is invalid to set num-strings higher than that.
The DT currently utilizes it to get around an incorrect fixed read of four elements from that array (has been addressed in a prior patch) by setting a lower num-strings where desired.
--- drivers/video/backlight/qcom-wled.c | 48 ++++++++++------------------- 1 file changed, 16 insertions(+), 32 deletions(-)
drivers/video/backlight/qcom-wled.c +16 -32
@@ -1256,21 +1256,6 @@ static const struct wled_var_cfg wled5_ovp_cfg = { .size = 16, }; -static u32 wled3_num_strings_values_fn (u32 idx) -{ -return idx +1 ; -} - -static const struct wled_var_cfg wled3_num_strings_cfg = { - .fn = wled3_num_strings_values_fn, - .size =3 , -}; - -static const struct wled_var_cfg wled4_num_strings_cfg = { - .fn = wled3_num_strings_values_fn, - .size =4 , -}; -static u32 wled3_switch_freq_values_fn (u32 idx) {return 19200 / (2 * (1 + idx));
@@ -1344,11 +1329,6 @@ static int wled_configure(struct wled *wled) .val_ptr = &cfg->switch_freq, .cfg = &wled3_switch_freq_cfg, }, - { - .name = "qcom,num-strings", - .val_ptr = &cfg->num_strings, - .cfg = &wled3_num_strings_cfg, - }, }; const struct wled_u32_opts wled4_opts[] = {
@@ -1372,11 +1352,6 @@ static int wled_configure(struct wled *wled) .val_ptr = &cfg->switch_freq, .cfg = &wled3_switch_freq_cfg, }, - { - .name = "qcom,num-strings", - .val_ptr = &cfg->num_strings, - .cfg = &wled4_num_strings_cfg, - }, }; const struct wled_u32_opts wled5_opts[] = {
@@ -1400,11 +1375,6 @@ static int wled_configure(struct wled *wled) .val_ptr = &cfg->switch_freq, .cfg = &wled3_switch_freq_cfg, }, - { - .name = "qcom,num-strings", - .val_ptr = &cfg->num_strings, - .cfg = &wled4_num_strings_cfg, - }, { .name = "qcom,modulator-sel", .val_ptr = &cfg->mod_sel,
@@ -1523,8 +1493,6 @@ static int wled_configure(struct wled *wled) *bool_opts[i].val_ptr = true; } - cfg->num_strings = cfg->num_strings +1 ; - string_len =of_property_count_elems_of_size (dev->of_node,"qcom,enabled-strings" ,sizeof (u32));
@@ -1555,6 +1523,22 @@ static int wled_configure(struct wled *wled) } } + rc =of_property_read_u32 (dev->of_node,"qcom,num-strings" , &val); +if (!rc) { +if (val <1 || val > wled->max_string_count) { +dev_err (dev,"qcom,num-strings must be between 1 and %d\n" , + wled->max_string_count); +return -EINVAL ; + } + +if (string_len >0 && val > string_len) { +dev_err (dev,"qcom,num-strings exceeds qcom,enabled-strings\n" ); +return -EINVAL ; + } + + cfg->num_strings = val; + } +return 0 ; }
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 192/563 backlight: qcom-wled: Override default length with qcom,enabled-strings
In reply to Greg Kroah-HartmanFrom: Marijn Suijten <[email protected]>
[ Upstream commit 2b4b49602f9feca7b7a84eaa33ad9e666c8aa695 ]
The length of qcom,enabled-strings as property array is enough to determine the number of strings to be enabled, without needing to set qcom,num-strings to override the default number of strings when less than the default (which is also the maximum) is provided in DT.
This also introduces an extra warning when qcom,num-strings is set, denoting that it is not necessary to set both anymore. It is usually more concise to set just qcom,num-length when a zero-based, contiguous range of strings is needed (the majority of the cases), or to only set qcom,enabled-strings when a specific set of indices is desired.
--- drivers/video/backlight/qcom-wled.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
drivers/video/backlight/qcom-wled.c +9 -3
@@ -1521,6 +1521,8 @@ static int wled_configure(struct wled *wled)return -EINVAL ; } } + + cfg->num_strings = string_len; } rc =of_property_read_u32 (dev->of_node,"qcom,num-strings" , &val);
@@ -1531,9 +1533,13 @@ static int wled_configure(struct wled *wled)return -EINVAL ; } -if (string_len >0 && val > string_len) { -dev_err (dev,"qcom,num-strings exceeds qcom,enabled-strings\n" ); -return -EINVAL ; +if (string_len >0 ) { +dev_warn (dev,"Only one of qcom,num-strings or qcom,enabled-strings" +" should be set\n" ); +if (val > string_len) { +dev_err (dev,"qcom,num-strings exceeds qcom,enabled-strings\n" ); +return -EINVAL ; + } } cfg->num_strings = val;
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 193/563 backlight: qcom-wled: Use cpu_to_le16 macro to perform conversion
In reply to Greg Kroah-HartmanFrom: Marijn Suijten <[email protected]>
[ Upstream commit 0a139358548968b2ff308257b4fbeec7badcc3e1 ]
The kernel already provides appropriate primitives to perform endianness conversion which should be used in favour of manual bit-wrangling.
--- drivers/video/backlight/qcom-wled.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-)
drivers/video/backlight/qcom-wled.c +11 -12
@@ -231,14 +231,14 @@ struct wled {static int wled3_set_brightness (struct wled *wled,u16 brightness) {int rc, i; -u8 v[2 ]; +__le16 v; - v[0 ] = brightness &0xff ; - v[1 ] = (brightness >>8 ) &0xf ; + v =cpu_to_le16 (brightness &WLED3_SINK_REG_BRIGHT_MAX );for (i =0 ; i < wled->cfg.num_strings; ++i) { rc =regmap_bulk_write (wled->regmap, wled->ctrl_addr + -WLED3_SINK_REG_BRIGHT (i), v,2 ); +WLED3_SINK_REG_BRIGHT (i), + &v,sizeof (v));if (rc <0 )return rc; }
@@ -250,18 +250,18 @@ static int wled4_set_brightness(struct wled *wled, u16 brightness) {int rc, i;u16 low_limit = wled->max_brightness *4 /1000 ; -u8 v[2 ]; +__le16 v;/* WLED4's lower limit of operation is 0.4% */ if (brightness >0 && brightness < low_limit) brightness = low_limit; - v[0 ] = brightness &0xff ; - v[1 ] = (brightness >>8 ) &0xf ; + v =cpu_to_le16 (brightness &WLED3_SINK_REG_BRIGHT_MAX );for (i =0 ; i < wled->cfg.num_strings; ++i) { rc =regmap_bulk_write (wled->regmap, wled->sink_addr + -WLED4_SINK_REG_BRIGHT (i), v,2 ); +WLED4_SINK_REG_BRIGHT (i), + &v,sizeof (v));if (rc <0 )return rc; }
@@ -273,21 +273,20 @@ static int wled5_set_brightness(struct wled *wled, u16 brightness) {int rc, offset;u16 low_limit = wled->max_brightness *1 /1000 ; -u8 v[2 ]; +__le16 v;/* WLED5's lower limit is 0.1% */ if (brightness < low_limit) brightness = low_limit; - v[0 ] = brightness &0xff ; - v[1 ] = (brightness >>8 ) &0x7f ; + v =cpu_to_le16 (brightness &WLED5_SINK_REG_BRIGHT_MAX_15B ); offset = (wled->cfg.mod_sel ==MOD_A ) ?WLED5_SINK_REG_MOD_A_BRIGHTNESS_LSB :WLED5_SINK_REG_MOD_B_BRIGHTNESS_LSB ; rc =regmap_bulk_write (wled->regmap, wled->sink_addr + offset, - v,2 ); + &v,sizeof (v));return rc; }
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 194/563 backlight: qcom-wled: Respect enabled-strings in set_brightness
In reply to Greg Kroah-HartmanFrom: Marijn Suijten <[email protected]>
[ Upstream commit ec961cf3241153e0f27d850f1bf0f172e7d27a21 ]
The hardware is capable of controlling any non-contiguous sequence of LEDs specified in the DT using qcom,enabled-strings as u32 array, and this also follows from the DT-bindings documentation. The numbers specified in this array represent indices of the LED strings that are to be enabled and disabled.
Its value is appropriately used to setup and enable string modules, but completely disregarded in the set_brightness paths which only iterate over the number of strings linearly.
Take an example where only string 2 is enabled with qcom,enabled_strings=<2>: this string is appropriately enabled but subsequent brightness changes would have only touched the zero'th brightness register because num_strings is 1 here. This is simply addressed by looking up the string for this index in the enabled_strings array just like the other codepaths that iterate over num_strings.
Likewise enabled_strings is now also used in the autodetection path for consistent behaviour: when a list of strings is specified in DT only those strings will be probed for autodetection, analogous to how the number of strings that need to be probed is already bound by qcom,num-strings. After all autodetection uses the set_brightness helpers to set an initial value, which could otherwise end up changing brightness on a different set of strings.
--- drivers/video/backlight/qcom-wled.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-)
drivers/video/backlight/qcom-wled.c +12 -10
@@ -237,7 +237,7 @@ static int wled3_set_brightness(struct wled *wled, u16 brightness)for (i =0 ; i < wled->cfg.num_strings; ++i) { rc =regmap_bulk_write (wled->regmap, wled->ctrl_addr + -WLED3_SINK_REG_BRIGHT (i), +WLED3_SINK_REG_BRIGHT (wled->cfg.enabled_strings[i]), &v,sizeof (v));if (rc <0 )return rc;
@@ -260,7 +260,7 @@ static int wled4_set_brightness(struct wled *wled, u16 brightness)for (i =0 ; i < wled->cfg.num_strings; ++i) { rc =regmap_bulk_write (wled->regmap, wled->sink_addr + -WLED4_SINK_REG_BRIGHT (i), +WLED4_SINK_REG_BRIGHT (wled->cfg.enabled_strings[i]), &v,sizeof (v));if (rc <0 )return rc;
@@ -571,7 +571,7 @@ unlock_mutex:static void wled_auto_string_detection (struct wled *wled) { -int rc =0 , i, delay_time_us; +int rc =0 , i, j, delay_time_us;u32 sink_config =0 ;u8 sink_test =0 , sink_valid =0 , val;bool fault_set;
@@ -618,14 +618,15 @@ static void wled_auto_string_detection(struct wled *wled)/* Iterate through the strings one by one */ for (i =0 ; i < wled->cfg.num_strings; i++) { - sink_test =BIT ((WLED4_SINK_REG_CURR_SINK_SHFT + i)); + j = wled->cfg.enabled_strings[i]; + sink_test =BIT ((WLED4_SINK_REG_CURR_SINK_SHFT + j));/* Enable feedback control */ rc =regmap_write (wled->regmap, wled->ctrl_addr + -WLED3_CTRL_REG_FEEDBACK_CONTROL , i +1 ); +WLED3_CTRL_REG_FEEDBACK_CONTROL , j +1 );if (rc <0 ) {dev_err (wled->dev,"Failed to enable feedback for SINK %d rc = %d\n" , - i +1 , rc); + j +1 , rc); goto failed_detect; }
@@ -634,7 +635,7 @@ static void wled_auto_string_detection(struct wled *wled) WLED4_SINK_REG_CURR_SINK, sink_test);if (rc <0 ) {dev_err (wled->dev,"Failed to configure SINK %d rc=%d\n" , - i +1 , rc); + j +1 , rc); goto failed_detect; }
@@ -661,7 +662,7 @@ static void wled_auto_string_detection(struct wled *wled)if (fault_set)dev_dbg (wled->dev,"WLED OVP fault detected with SINK %d\n" , - i +1 ); + j +1 );else sink_valid |= sink_test;
@@ -701,15 +702,16 @@ static void wled_auto_string_detection(struct wled *wled)/* Enable valid sinks */ if (wled->version ==4 ) {for (i =0 ; i < wled->cfg.num_strings; i++) { + j = wled->cfg.enabled_strings[i];if (sink_config & -BIT (WLED4_SINK_REG_CURR_SINK_SHFT + i)) +BIT (WLED4_SINK_REG_CURR_SINK_SHFT + j)) val =WLED4_SINK_REG_STR_MOD_MASK ;else /* Disable modulator_en for unused sink */ val =0 ; rc =regmap_write (wled->regmap, wled->sink_addr + -WLED4_SINK_REG_STR_MOD_EN (i), val); +WLED4_SINK_REG_STR_MOD_EN (j), val);if (rc <0 ) {dev_err (wled->dev,"Failed to configure MODULATOR_EN rc=%d\n" , rc);
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 195/563 software node: fix wrong node passed to find nargs_prop
In reply to Greg Kroah-HartmanFrom: Clément Léger <[email protected]>
[ Upstream commit c5fc5ba8b6b7bebc05e45036a33405b4c5036c2f ]
nargs_prop refers to a property located in the reference that is found within the nargs property. Use the correct reference node in call to property_entry_read_int_array() to retrieve the correct nargs value.
--- drivers/base/swnode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/base/swnode.c +1 -1
@@ -519,7 +519,7 @@ software_node_get_reference_args(const struct fwnode_handle *fwnode,return -ENOENT ;if (nargs_prop) { - error =property_entry_read_int_array (swnode->node->properties, + error =property_entry_read_int_array (ref->node->properties, nargs_prop,sizeof (u32), &nargs_prop_val,1 );if (error)
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 196/563 Bluetooth: hci_qca: Stop IBS timer during BT OFF
In reply to Greg Kroah-HartmanFrom: Panicker Harish <[email protected]>
[ Upstream commit df1e5c51492fd93ffc293acdcc6f00698d19fedc ]
The IBS timers are not stopped properly once BT OFF is triggered. we could see IBS commands being sent along with version command, so stopped IBS timers while Bluetooth is off.
--- drivers/bluetooth/hci_qca.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/bluetooth/hci_qca.c +3 -0
@@ -1844,6 +1844,9 @@ static int qca_power_off(struct hci_dev *hdev) hu->hdev->hw_error =NULL ; hu->hdev->cmd_timeout =NULL ; +del_timer_sync (&qca->wake_retrans_timer); +del_timer_sync (&qca->tx_idle_timer); +/* Stop sending shutdown command if soc crashes. */ if (soc_type !=QCA_ROME && qca->memdump_state ==QCA_MEMDUMP_IDLE ) {
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 197/563 x86/boot/compressed: Move CLANG_FLAGS to beginning of KBUILD_CFLAGS
In reply to Greg Kroah-HartmanFrom: Nathan Chancellor <[email protected]>
[ Upstream commit 5fe392ff9d1f7254a1fbb3f72d9893088e4d23eb ]
When cross compiling i386_defconfig on an arm64 host with clang, there are a few instances of '-Waddress-of-packed-member' and '-Wgnu-variable-sized-type-not-at-end' in arch/x86/boot/compressed/, which should both be disabled with the cc-disable-warning calls in that directory's Makefile, which indicates that cc-disable-warning is failing at the point of testing these flags.
The cc-disable-warning calls fail because at the point that the flags are tested, KBUILD_CFLAGS has '-march=i386' without $(CLANG_FLAGS), which has the '--target=' flag to tell clang what architecture it is targeting. Without the '--target=' flag, the host architecture (arm64) is used and i386 is not a valid value for '-march=' in that case. This error can be seen by adding some logging to try-run:
clang-14: error: the clang compiler does not support '-march=i386'
Invoking the compiler has to succeed prior to calling cc-option or cc-disable-warning in order to accurately test whether or not the flag is supported; if it doesn't, the requested flag can never be added to the compiler flags. Move $(CLANG_FLAGS) to the beginning of KBUILD_FLAGS so that any new flags that might be added in the future can be accurately tested.
--- arch/x86/boot/compressed/Makefile | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
arch/x86/boot/compressed/Makefile +5 -2
@@ -28,7 +28,11 @@ KCOV_INSTRUMENT := n targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma \ vmlinux.bin.xz vmlinux.bin.lzo vmlinux.bin.lz4 vmlinux.bin.zst -KBUILD_CFLAGS := -m$(BITS) -O2 +# CLANG_FLAGS must come before any cc-disable-warning or cc-option calls in +# case of cross compiling, as it has the '--target=' flag, which is needed to +# avoid errors with '-march=i386', and future flags may depend on the target to +# be valid. +KBUILD_CFLAGS := -m$(BITS) -O2 $(CLANG_FLAGS) KBUILD_CFLAGS += -fno-strict-aliasing -fPIE KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING cflags-$(CONFIG_X86_32) := -march=i386
@@ -46,7 +50,6 @@ KBUILD_CFLAGS += -D__DISABLE_EXPORTS # Disable relocation relaxation in case the link is not PIE. KBUILD_CFLAGS += $(call as-option,-Wa$(comma)-mrelax-relocations=no) KBUILD_CFLAGS += -include $(srctree)/include/linux/hidden.h -KBUILD_CFLAGS += $(CLANG_FLAGS) # sev-es.c indirectly inludes inat-table.h which is generated during # compilation and stored in $(objtree). Add the directory to the includes so
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 198/563 hwmon: (mr75203) fix wrong power-up delay value
In reply to Greg Kroah-HartmanFrom: Arseny Demidov <[email protected]>
[ Upstream commit a8d6d4992ad9d92356619ac372906bd29687bb46 ]
In the file mr75203.c we have a macro named POWER_DELAY_CYCLE_256, the correct value should be 0x100. The register ip_tmr is expressed in units of IP clk cycles, in accordance with the datasheet. Typical power-up delays for Temperature Sensor are 256 cycles i.e. 0x100.
--- drivers/hwmon/mr75203.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/hwmon/mr75203.c +1 -1
@@ -93,7 +93,7 @@#define VM_CH_REQ BIT(21)#define IP_TMR 0x05 -#define POWER_DELAY_CYCLE_256 0x80 +#define POWER_DELAY_CYCLE_256 0x100#define POWER_DELAY_CYCLE_64 0x40#define PVT_POLL_DELAY_US 20
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 199/563 x86/mce/inject: Avoid out-of-bounds write when setting flags
In reply to Greg Kroah-HartmanFrom: Zhang Zixun <[email protected]>
[ Upstream commit de768416b203ac84e02a757b782a32efb388476f ]
A contrived zero-length write, for example, by using write(2):
... ret = write(fd, str, 0); ...
to the "flags" file causes:
BUG: KASAN: stack-out-of-bounds in flags_write Write of size 1 at addr ffff888019be7ddf by task writefile/3787 CPU: 4 PID: 3787 Comm: writefile Not tainted 5.16.0-rc7+ #12 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-2 04/01/2014
due to accessing buf one char before its start.
Prevent such out-of-bounds access.
[ bp: Productize into a proper patch. Link below is the next best
thing because the original mail didn't get archived on lore. ]
--- arch/x86/kernel/cpu/mce/inject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/kernel/cpu/mce/inject.c +1 -1
@@ -347,7 +347,7 @@ static ssize_t flags_write(struct file *filp, const char __user *ubuf,char buf[MAX_FLAG_OPT_SIZE ], *__buf;int err; -if (cnt >MAX_FLAG_OPT_SIZE ) +if (!cnt || cnt >MAX_FLAG_OPT_SIZE )return -EINVAL ;if (copy_from_user (&buf, ubuf, cnt))
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 200/563 ACPI: scan: Create platform device for BCM4752 and LNV4752 ACPI nodes
In reply to Greg Kroah-HartmanFrom: Hans de Goede <[email protected]>
[ Upstream commit f85196bdd5a50da74670250564740fc852b3c239 ]
BCM4752 and LNV4752 ACPI nodes describe a Broadcom 4752 GPS module attached to an UART of the system.
The GPS modules talk a custom protocol which only works with a closed- source Android gpsd daemon which knows this protocol.
The ACPI nodes also describe GPIOs to turn the GPS on/off these are handled by the net/rfkill/rfkill-gpio.c code. This handling predates the addition of enumeration of ACPI instantiated serdevs to the kernel and was broken by that addition, because the ACPI scan code now no longer instantiates platform_device-s for these nodes.
Rename the i2c_multi_instantiate_ids HID list to ignore_serial_bus_ids and add the BCM4752 and LNV4752 HIDs, so that rfkill-gpio gets a platform_device to bind to again; and so that a tty cdev for gpsd gets created for these.
--- drivers/acpi/scan.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
drivers/acpi/scan.c +10 -3
@@ -1577,6 +1577,7 @@ static bool acpi_device_enumeration_by_parent(struct acpi_device *device) {struct list_head resource_list;bool is_serial_bus_slave = false; +static const struct acpi_device_id ignore_serial_bus_ids[] = {/* * These devices have multiple I2cSerialBus resources and an i2c-client * must be instantiated for each, each with its own i2c_device_id.
@@ -1585,11 +1586,18 @@ static bool acpi_device_enumeration_by_parent(struct acpi_device *device)* drivers/platform/x86/i2c-multi-instantiate.c driver, which knows * which i2c_device_id to use for each resource. */ -static const struct acpi_device_id i2c_multi_instantiate_ids[] = { {"BSG1160", }, {"BSG2150", }, {"INT33FE", }, {"INT3515", }, + /* + * HIDs of device with an UartSerialBusV2 resource for which userspace + * expects a regular tty cdev to be created (instead of the in kernel + * serdev) and which have a kernel driver which expects a platform_dev + * such as the rfkill-gpio driver. + */ + {"BCM4752", }, + {"LNV4752", }, {} };
@@ -1603,8 +1611,7 @@ static bool acpi_device_enumeration_by_parent(struct acpi_device *device) fwnode_property_present(&device->fwnode, "baud")))return true; -/* Instantiate a pdev for the i2c-multi-instantiate drv to bind to */ -if (!acpi_match_device_ids (device, i2c_multi_instantiate_ids)) +if (!acpi_match_device_ids (device, ignore_serial_bus_ids))return false;INIT_LIST_HEAD (&resource_list);
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 201/563 pcmcia: rsrc_nonstatic: Fix a NULL pointer dereference in __nonstatic_find_io_region()
In reply to Greg Kroah-HartmanFrom: Zhou Qingyang <[email protected]>
[ Upstream commit ca0fe0d7c35c97528bdf621fdca75f13157c27af ]
In __nonstatic_find_io_region(), pcmcia_make_resource() is assigned to res and used in pci_bus_alloc_resource(). There is a dereference of res in pci_bus_alloc_resource(), which could lead to a NULL pointer dereference on failure of pcmcia_make_resource().
Fix this bug by adding a check of res.
This bug was found by a static analyzer. The analysis employs differential checking to identify inconsistent security operations (e.g., checks or kfrees) between two code paths and confirms that the inconsistent operations are not recovered in the current function or the callers, so they constitute bugs.
Note that, as a bug found by static analysis, it can be a false positive or hard to trigger. Multiple researchers have cross-reviewed the bug.
Builds with CONFIG_PCCARD_NONSTATIC=y show no new warnings, and our static analyzer no longer warns about this code.
--- drivers/pcmcia/rsrc_nonstatic.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/pcmcia/rsrc_nonstatic.c +3 -0
@@ -690,6 +690,9 @@ static struct resource *__nonstatic_find_io_region(struct pcmcia_socket *s,unsigned long min = base;int ret; +if (!res) +return NULL ; + data.mask = align -1 ; data.offset = base & data.mask; data.map = &s_data->io_db;
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 202/563 pcmcia: rsrc_nonstatic: Fix a NULL pointer dereference in nonstatic_find_mem_region()
In reply to Greg Kroah-HartmanFrom: Zhou Qingyang <[email protected]>
[ Upstream commit 977d2e7c63c3d04d07ba340b39987742e3241554 ]
In nonstatic_find_mem_region(), pcmcia_make_resource() is assigned to res and used in pci_bus_alloc_resource(). There a dereference of res in pci_bus_alloc_resource(), which could lead to a NULL pointer dereference on failure of pcmcia_make_resource().
Fix this bug by adding a check of res.
This bug was found by a static analyzer. The analysis employs differential checking to identify inconsistent security operations (e.g., checks or kfrees) between two code paths and confirms that the inconsistent operations are not recovered in the current function or the callers, so they constitute bugs.
Note that, as a bug found by static analysis, it can be a false positive or hard to trigger. Multiple researchers have cross-reviewed the bug.
Builds with CONFIG_PCCARD_NONSTATIC=y show no new warnings, and our static analyzer no longer warns about this code.
--- drivers/pcmcia/rsrc_nonstatic.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/pcmcia/rsrc_nonstatic.c +3 -0
@@ -812,6 +812,9 @@ static struct resource *nonstatic_find_mem_region(u_long base, u_long num,unsigned long min, max;int ret, i, j; +if (!res) +return NULL ; + low = low || !(s->features &SS_CAP_PAGE_REGS ); data.mask = align -1 ;
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 203/563 power: reset: mt6397: Check for null res pointer
In reply to Greg Kroah-HartmanFrom: Jiasheng Jiang <[email protected]>
[ Upstream commit 1c1348bf056dee665760a3bd1cd30b0be7554fc2 ]
The return value of platform_get_resource() needs to be checked. To avoid use of error pointer in case that there is no suitable resource.
--- drivers/power/reset/mt6323-poweroff.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/power/reset/mt6323-poweroff.c +3 -0
@@ -57,6 +57,9 @@ static int mt6323_pwrc_probe(struct platform_device *pdev)return -ENOMEM ; res =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); +if (!res) +return -EINVAL ; + pwrc->base = res->start; pwrc->regmap = mt6397_chip->regmap; pwrc->dev = &pdev->dev;
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 204/563 netfilter: ipt_CLUSTERIP: fix refcount leak in clusterip_tg_check()
In reply to Greg Kroah-HartmanFrom: Xin Xiong <[email protected]>
[ Upstream commit d94a69cb2cfa77294921aae9afcfb866e723a2da ]
The issue takes place in one error path of clusterip_tg_check(). When memcmp() returns nonzero, the function simply returns the error code, forgetting to decrease the reference count of a clusterip_config object, which is bumped earlier by clusterip_config_find_get(). This may incur reference count leak.
Fix this issue by decrementing the refcount of the object in specific error path.
--- net/ipv4/netfilter/ipt_CLUSTERIP.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
net/ipv4/netfilter/ipt_CLUSTERIP.c +4 -1
@@ -505,8 +505,11 @@ static int clusterip_tg_check(const struct xt_tgchk_param *par)if (IS_ERR (config))return PTR_ERR (config); } - }else if (memcmp (&config->clustermac, &cipinfo->clustermac,ETH_ALEN )) + }else if (memcmp (&config->clustermac, &cipinfo->clustermac,ETH_ALEN )) { +clusterip_config_entry_put (config); +clusterip_config_put (config);return -EINVAL ; + } ret =nf_ct_netns_get (par->net, par->family);if (ret <0 ) {
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 205/563 bpf: Dont promote bogus looking registers after null check.
In reply to Greg Kroah-HartmanFrom: Daniel Borkmann <[email protected]>
[ Upstream commit e60b0d12a95dcf16a63225cead4541567f5cb517 ]
If we ever get to a point again where we convert a bogus looking <ptr>_or_null typed register containing a non-zero fixed or variable offset, then lets not reset these bounds to zero since they are not and also don't promote the register to a <ptr> type, but instead leave it as <ptr>_or_null. Converting to a unknown register could be an avenue as well, but then if we run into this case it would allow to leak a kernel pointer this way.
--- kernel/bpf/verifier.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
kernel/bpf/verifier.c +6 -6
@@ -7725,15 +7725,15 @@ static void mark_ptr_or_null_reg(struct bpf_func_state *state, {if (reg_type_may_be_null (reg->type) && reg->id == id && !WARN_ON_ONCE (!reg->id)) { -/* Old offset (both fixed and variable parts) should -* have been known-zero, because we don't allow pointer -* arithmetic on pointers that might be NULL. -*/ if (WARN_ON_ONCE (reg->smin_value || reg->smax_value || !tnum_equals_const (reg->var_off,0 ) || reg->off)) { -__mark_reg_known_zero (reg); - reg->off =0 ; +/* Old offset (both fixed and variable parts) should +* have been known-zero, because we don't allow pointer +* arithmetic on pointers that might be NULL. If we +* see this happening, don't convert the register. +*/ +return ; }if (is_null) { reg->type =SCALAR_VALUE ;
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 206/563 bpf: Fix SO_RCVBUF/SO_SNDBUF handling in _bpf_setsockopt().
In reply to Greg Kroah-HartmanFrom: Kuniyuki Iwashima <[email protected]>
[ Upstream commit 04c350b1ae6bdb12b84009a4d0bf5ab4e621c47b ]
The commit 4057765f2dee ("sock: consistent handling of extreme SO_SNDBUF/SO_RCVBUF values") added a change to prevent underflow in setsockopt() around SO_SNDBUF/SO_RCVBUF.
This patch adds the same change to _bpf_setsockopt().
--- net/core/filter.c | 2 ++ 1 file changed, 2 insertions(+)
net/core/filter.c +2 -0
@@ -4711,12 +4711,14 @@ static int _bpf_setsockopt(struct sock *sk, int level, int optname,switch (optname) {case SO_RCVBUF : val =min_t (u32, val, sysctl_rmem_max); + val =min_t (int, val,INT_MAX /2 ); sk->sk_userlocks |=SOCK_RCVBUF_LOCK ;WRITE_ONCE (sk->sk_rcvbuf,max_t (int, val *2 ,SOCK_MIN_RCVBUF ));break ;case SO_SNDBUF : val =min_t (u32, val, sysctl_wmem_max); + val =min_t (int, val,INT_MAX /2 ); sk->sk_userlocks |=SOCK_SNDBUF_LOCK ;WRITE_ONCE (sk->sk_sndbuf,max_t (int, val *2 ,SOCK_MIN_SNDBUF ));
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 207/563 netfilter: nft_set_pipapo: allocate pcpu scratch maps on clone
In reply to Greg Kroah-HartmanFrom: Florian Westphal <[email protected]>
[ Upstream commit 23c54263efd7cb605e2f7af72717a2a951999217 ]
This is needed in case a new transaction is made that doesn't insert any new elements into an already existing set.
Else, after second 'nft -f ruleset.txt', lookups in such a set will fail because ->lookup() encounters raw_cpu_ptr(m->scratch) == NULL.
For the initial rule load, insertion of elements takes care of the allocation, but for rule reloads this isn't guaranteed: we might not have additions to the set.
--- net/netfilter/nft_set_pipapo.c | 8 ++++++++ 1 file changed, 8 insertions(+)
net/netfilter/nft_set_pipapo.c +8 -0
@@ -1290,6 +1290,11 @@ static struct nft_pipapo_match *pipapo_clone(struct nft_pipapo_match *old)if (!new->scratch_aligned) goto out_scratch;#endif +for_each_possible_cpu (i) + *per_cpu_ptr (new->scratch, i) =NULL ; + +if (pipapo_realloc_scratch (new, old->bsize_max)) + goto out_scratch_realloc;rcu_head_init (&new->rcu);
@@ -1334,6 +1339,9 @@ out_lt:kvfree (dst->lt); dst--; } +out_scratch_realloc: +for_each_possible_cpu (i) +kfree (*per_cpu_ptr (new->scratch, i));#ifdef NFT_PIPAPO_ALIGN free_percpu (new->scratch_aligned);#endif
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 208/563 ppp: ensure minimum packet size in ppp_write()
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit 44073187990d5629804ce0627525f6ea5cfef171 ]
It seems pretty clear ppp layer assumed user space would always be kind to provide enough data in their write() to a ppp device.
This patch makes sure user provides at least 2 bytes.
It adds PPP_PROTO_LEN macro that could replace in net-next many occurrences of hard-coded 2 value.
I replaced only one occurrence to ease backports to stable kernels.
The bug manifests in the following report:
BUG: KMSAN: uninit-value in ppp_send_frame+0x28d/0x27c0 drivers/net/ppp/ppp_generic.c:1740 ppp_send_frame+0x28d/0x27c0 drivers/net/ppp/ppp_generic.c:1740 __ppp_xmit_process+0x23e/0x4b0 drivers/net/ppp/ppp_generic.c:1640 ppp_xmit_process+0x1fe/0x480 drivers/net/ppp/ppp_generic.c:1661 ppp_write+0x5cb/0x5e0 drivers/net/ppp/ppp_generic.c:513 do_iter_write+0xb0c/0x1500 fs/read_write.c:853 vfs_writev fs/read_write.c:924 [inline] do_writev+0x645/0xe00 fs/read_write.c:967 __do_sys_writev fs/read_write.c:1040 [inline] __se_sys_writev fs/read_write.c:1037 [inline] __x64_sys_writev+0xe5/0x120 fs/read_write.c:1037 do_syscall_x64 arch/x86/entry/common.c:51 [inline] do_syscall_64+0x54/0xd0 arch/x86/entry/common.c:82 entry_SYSCALL_64_after_hwframe+0x44/0xae
Uninit was created at:
slab_post_alloc_hook mm/slab.h:524 [inline] slab_alloc_node mm/slub.c:3251 [inline] __kmalloc_node_track_caller+0xe0c/0x1510 mm/slub.c:4974 kmalloc_reserve net/core/skbuff.c:354 [inline] __alloc_skb+0x545/0xf90 net/core/skbuff.c:426 alloc_skb include/linux/skbuff.h:1126 [inline] ppp_write+0x11d/0x5e0 drivers/net/ppp/ppp_generic.c:501 do_iter_write+0xb0c/0x1500 fs/read_write.c:853 vfs_writev fs/read_write.c:924 [inline] do_writev+0x645/0xe00 fs/read_write.c:967 __do_sys_writev fs/read_write.c:1040 [inline] __se_sys_writev fs/read_write.c:1037 [inline] __x64_sys_writev+0xe5/0x120 fs/read_write.c:1037 do_syscall_x64 arch/x86/entry/common.c:51 [inline] do_syscall_64+0x54/0xd0 arch/x86/entry/common.c:82 entry_SYSCALL_64_after_hwframe+0x44/0xae
--- drivers/net/ppp/ppp_generic.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/net/ppp/ppp_generic.c +6 -1
@@ -69,6 +69,8 @@#define MPHDRLEN 6/* multilink protocol header length */ #define MPHDRLEN_SSN 4/* ditto with short sequence numbers */ +#define PPP_PROTO_LEN 2 +/* * An instance of /dev/ppp can be associated with either a ppp * interface unit or a ppp channel. In both cases, file->private_data
@@ -496,6 +498,9 @@ static ssize_t ppp_write(struct file *file, const char __user *buf,if (!pf)return -ENXIO ; +/* All PPP packets should start with the 2-byte protocol */ +if (count <PPP_PROTO_LEN ) +return -EINVAL ; ret = -ENOMEM ; skb =alloc_skb (count + pf->hdrlen,GFP_KERNEL );if (!skb)
@@ -1632,7 +1637,7 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb) } ++ppp->stats64.tx_packets; - ppp->stats64.tx_bytes += skb->len -2 ; + ppp->stats64.tx_bytes += skb->len -PPP_PROTO_LEN ;switch (proto) {case PPP_IP :
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 209/563 rocker: fix a sleeping in atomic bug
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit 43d012123122cc69feacab55b71369f386c19566 ]
This code is holding the &ofdpa->flow_tbl_lock spinlock so it is not allowed to sleep. That means we have to pass the OFDPA_OP_FLAG_NOWAIT flag to ofdpa_flow_tbl_del().
--- drivers/net/ethernet/rocker/rocker_ofdpa.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/ethernet/rocker/rocker_ofdpa.c +2 -1
@@ -2795,7 +2795,8 @@ static void ofdpa_fib4_abort(struct rocker *rocker)if (!ofdpa_port)continue ; nh->fib_nh_flags &= ~RTNH_F_OFFLOAD ; -ofdpa_flow_tbl_del (ofdpa_port,OFDPA_OP_FLAG_REMOVE , +ofdpa_flow_tbl_del (ofdpa_port, +OFDPA_OP_FLAG_REMOVE |OFDPA_OP_FLAG_NOWAIT , flow_entry); }spin_unlock_irqrestore (&ofdpa->flow_tbl_lock, flags);
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 210/563 staging: greybus: audio: Check null pointer
In reply to Greg Kroah-HartmanFrom: Jiasheng Jiang <[email protected]>
[ Upstream commit 2e81948177d769106754085c3e03534e6cc1f623 ]
As the possible alloc failure of devm_kcalloc(), it could return null pointer.
Therefore, 'strings' should be checked and return NULL if alloc fails to prevent the dereference of the NULL pointer.
Also, the caller should also deal with the return value of the gb_generate_enum_strings() and return -ENOMEM if returns NULL. Moreover, because the memory allocated with devm_kzalloc() will be freed automatically when the last reference to the device is dropped, the 'gbe' in gbaudio_tplg_create_enum_kctl() and gbaudio_tplg_create_enum_ctl() do not need to free manually. But the 'control' in gbaudio_tplg_create_widget() and gbaudio_tplg_process_kcontrols() has a specially error handle to cleanup.
So it should be better to cleanup 'control' when fails.
--- drivers/staging/greybus/audio_topology.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
drivers/staging/greybus/audio_topology.c +15 -0
@@ -147,6 +147,9 @@ static const char **gb_generate_enum_strings(struct gbaudio_module_info *gb, items =le32_to_cpu (gbenum->items); strings =devm_kcalloc (gb->dev, items,sizeof (char *),GFP_KERNEL ); +if (!strings) +return NULL ; + data = gbenum->names;for (i =0 ; i < items; i++) {
@@ -655,6 +658,8 @@ static int gbaudio_tplg_create_enum_kctl(struct gbaudio_module_info *gb,/* since count=1, and reg is dummy */ gbe->items =le32_to_cpu (gb_enum->items); gbe->texts =gb_generate_enum_strings (gb, gb_enum); +if (!gbe->texts) +return -ENOMEM ;/* debug enum info */ dev_dbg(gb->dev, "Max:%d, name_length:%d\n", gbe->items,
@@ -862,6 +867,8 @@ static int gbaudio_tplg_create_enum_ctl(struct gbaudio_module_info *gb,/* since count=1, and reg is dummy */ gbe->items =le32_to_cpu (gb_enum->items); gbe->texts =gb_generate_enum_strings (gb, gb_enum); +if (!gbe->texts) +return -ENOMEM ;/* debug enum info */ dev_dbg(gb->dev, "Max:%d, name_length:%d\n", gbe->items,
@@ -1072,6 +1079,10 @@ static int gbaudio_tplg_create_widget(struct gbaudio_module_info *module, csize +=le16_to_cpu (gbenum->names_length); control->texts = (const char *const *)gb_generate_enum_strings (module, gbenum); +if (!control->texts) { + ret = -ENOMEM ; + goto error; + } control->items =le32_to_cpu (gbenum->items); }else { csize =sizeof (struct gb_audio_control );
@@ -1181,6 +1192,10 @@ static int gbaudio_tplg_process_kcontrols(struct gbaudio_module_info *module, csize +=le16_to_cpu (gbenum->names_length); control->texts = (const char *const *)gb_generate_enum_strings (module, gbenum); +if (!control->texts) { + ret = -ENOMEM ; + goto error; + } control->items =le32_to_cpu (gbenum->items); }else { csize =sizeof (struct gb_audio_control );
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 211/563 fsl/fman: Check for null pointer after calling devm_ioremap
In reply to Greg Kroah-HartmanFrom: Jiasheng Jiang <[email protected]>
[ Upstream commit d5a73ec96cc57cf67e51b12820fc2354e7ca46f8 ]
As the possible failure of the allocation, the devm_ioremap() may return NULL pointer.
Take tgec_initialization() as an example.
If allocation fails, the params->base_addr will be NULL pointer and will be assigned to tgec->regs in tgec_config().
Then it will cause the dereference of NULL pointer in set_mac_address(), which is called by tgec_init().
Therefore, it should be better to add the sanity check after the calling of the devm_ioremap().
--- drivers/net/ethernet/freescale/fman/mac.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-)
drivers/net/ethernet/freescale/fman/mac.c +16 -5
@@ -94,14 +94,17 @@ static void mac_exception(void *handle, enum fman_mac_exceptions ex) __func__, ex); } -static void set_fman_mac_params (struct mac_device *mac_dev, -struct fman_mac_params *params) +static int set_fman_mac_params (struct mac_device *mac_dev, +struct fman_mac_params *params) {struct mac_priv_s *priv = mac_dev->priv; params->base_addr = (typeof(params->base_addr))devm_ioremap (priv->dev, mac_dev->res->start,resource_size (mac_dev->res)); +if (!params->base_addr) +return -ENOMEM ; +memcpy (¶ms->addr, mac_dev->addr,sizeof (mac_dev->addr)); params->max_speed = priv->max_speed; params->phy_if = mac_dev->phy_if;
@@ -112,6 +115,8 @@ static void set_fman_mac_params(struct mac_device *mac_dev, params->event_cb = mac_exception; params->dev_id = mac_dev; params->internal_phy_node = priv->internal_phy_node; + +return 0 ; }static int tgec_initialization (struct mac_device *mac_dev)
@@ -123,7 +128,9 @@ static int tgec_initialization(struct mac_device *mac_dev) priv = mac_dev->priv; -set_fman_mac_params (mac_dev, ¶ms); + err =set_fman_mac_params (mac_dev, ¶ms); +if (err) + goto _return; mac_dev->fman_mac =tgec_config (¶ms);if (!mac_dev->fman_mac) {
@@ -169,7 +176,9 @@ static int dtsec_initialization(struct mac_device *mac_dev) priv = mac_dev->priv; -set_fman_mac_params (mac_dev, ¶ms); + err =set_fman_mac_params (mac_dev, ¶ms); +if (err) + goto _return; mac_dev->fman_mac =dtsec_config (¶ms);if (!mac_dev->fman_mac) {
@@ -218,7 +227,9 @@ static int memac_initialization(struct mac_device *mac_dev) priv = mac_dev->priv; -set_fman_mac_params (mac_dev, ¶ms); + err =set_fman_mac_params (mac_dev, ¶ms); +if (err) + goto _return;if (priv->max_speed ==SPEED_10000 ) params.phy_if =PHY_INTERFACE_MODE_XGMII ;
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 212/563 Bluetooth: hci_bcm: Check for error irq
In reply to Greg Kroah-HartmanFrom: Jiasheng Jiang <[email protected]>
[ Upstream commit b38cd3b42fba66cc538edb9cf77e07881f43f8e2 ]
For the possible failure of the platform_get_irq(), the returned irq could be error number and will finally cause the failure of the request_irq().
Consider that platform_get_irq() can now in certain cases return -EPROBE_DEFER, and the consequences of letting request_irq() effectively convert that into -EINVAL, even at probe time rather than later on. So it might be better to check just now.
--- drivers/bluetooth/hci_bcm.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/bluetooth/hci_bcm.c +6 -1
@@ -1164,7 +1164,12 @@ static int bcm_probe(struct platform_device *pdev)return -ENOMEM ; dev->dev = &pdev->dev; - dev->irq =platform_get_irq (pdev,0 ); + + ret =platform_get_irq (pdev,0 ); +if (ret <0 ) +return ret; + + dev->irq = ret;/* Initialize routing field to an unused value */ dev->pcm_int_params[0 ] =0xff ;
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 213/563 Bluetooth: hci_qca: Fix NULL vs IS_ERR_OR_NULL check in qca_serdev_probe
In reply to Greg Kroah-HartmanFrom: Miaoqian Lin <[email protected]>
[ Upstream commit 6845667146a28c09b5dfc401c1ad112374087944 ]
The function devm_gpiod_get_index() return error pointers on error. Thus devm_gpiod_get_index_optional() could return NULL and error pointers. The same as devm_gpiod_get_optional() function. Using IS_ERR_OR_NULL() check to catch error pointers.
--- drivers/bluetooth/hci_qca.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/bluetooth/hci_qca.c +1 -1
@@ -1990,7 +1990,7 @@ static int qca_serdev_probe(struct serdev_device *serdev) qcadev->bt_en =devm_gpiod_get_optional (&serdev->dev,"enable" ,GPIOD_OUT_LOW ); -if (!qcadev->bt_en) { +if (IS_ERR_OR_NULL (qcadev->bt_en)) {dev_warn (&serdev->dev,"failed to acquire enable gpio\n" ); power_ctrl_enabled = false; }
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 214/563 usb: dwc3: qcom: Fix NULL vs IS_ERR checking in dwc3_qcom_probe
In reply to Greg Kroah-HartmanFrom: Miaoqian Lin <[email protected]>
[ Upstream commit b52fe2dbb3e655eb1483000adfab68a219549e13 ]
Since the acpi_create_platform_device() function may return error pointers, dwc3_qcom_create_urs_usb_platdev() function may return error pointers too. Using IS_ERR_OR_NULL() to check the return value to fix this.
--- drivers/usb/dwc3/dwc3-qcom.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/usb/dwc3/dwc3-qcom.c +5 -2
@@ -764,9 +764,12 @@ static int dwc3_qcom_probe(struct platform_device *pdev)if (qcom->acpi_pdata->is_urs) { qcom->urs_usb =dwc3_qcom_create_urs_usb_platdev (dev); -if (!qcom->urs_usb) { +if (IS_ERR_OR_NULL (qcom->urs_usb)) {dev_err (dev,"failed to create URS USB platdev\n" ); -return -ENODEV ; +if (!qcom->urs_usb) +return -ENODEV ; +else +return PTR_ERR (qcom->urs_usb); } } }
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 215/563 HID: hid-uclogic-params: Invalid parameter check in uclogic_params_init
In reply to Greg Kroah-HartmanFrom: José Expósito <[email protected]>
[ Upstream commit f364c571a5c77e96de2d32062ff019d6b8d2e2bc ]
The function performs a check on its input parameters, however, the hdev parameter is used before the check.
Initialize the stack variables after checking the input parameters to avoid a possible NULL pointer dereference.
Addresses-Coverity-ID: 1443831 ("Null pointer dereference")
--- drivers/hid/hid-uclogic-params.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
drivers/hid/hid-uclogic-params.c +9 -4
@@ -832,10 +832,10 @@ int uclogic_params_init(struct uclogic_params *params, struct hid_device *hdev) {int rc; -struct usb_device *udev =hid_to_usb_dev (hdev); -__u8 bNumInterfaces = udev->config->desc.bNumInterfaces; -struct usb_interface *iface =to_usb_interface (hdev->dev.parent); -__u8 bInterfaceNumber = iface->cur_altsetting->desc.bInterfaceNumber; +struct usb_device *udev; +__u8 bNumInterfaces; +struct usb_interface *iface; +__u8 bInterfaceNumber;bool found;/* The resulting parameters (noop) */ struct uclogic_params p = {0 , };
@@ -846,6 +846,11 @@ int uclogic_params_init(struct uclogic_params *params, goto cleanup; } + udev =hid_to_usb_dev (hdev); + bNumInterfaces = udev->config->desc.bNumInterfaces; + iface =to_usb_interface (hdev->dev.parent); + bInterfaceNumber = iface->cur_altsetting->desc.bInterfaceNumber; +/* * Set replacement report descriptor if the original matches the * specified size. Otherwise keep interface unchanged.
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 216/563 HID: hid-uclogic-params: Invalid parameter check in uclogic_params_get_str_desc
In reply to Greg Kroah-HartmanFrom: José Expósito <[email protected]>
[ Upstream commit 0a94131d6920916ccb6a357037c535533af08819 ]
The function performs a check on the hdev input parameters, however, it is used before the check.
Initialize the udev variable after the sanity check to avoid a possible NULL pointer dereference.
Addresses-Coverity-ID: 1443827 ("Null pointer dereference")
--- drivers/hid/hid-uclogic-params.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/hid/hid-uclogic-params.c +3 -1
@@ -65,7 +65,7 @@ static int uclogic_params_get_str_desc(__u8 **pbuf, struct hid_device *hdev, __u8 idx, size_t len) {int rc; -struct usb_device *udev =hid_to_usb_dev (hdev); +struct usb_device *udev;__u8 *buf =NULL ;/* Check arguments */
@@ -74,6 +74,8 @@ static int uclogic_params_get_str_desc(__u8 **pbuf, struct hid_device *hdev, goto cleanup; } + udev =hid_to_usb_dev (hdev); + buf =kmalloc (len,GFP_KERNEL );if (buf ==NULL ) { rc = -ENOMEM ;
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 217/563 HID: hid-uclogic-params: Invalid parameter check in uclogic_params_huion_init
In reply to Greg Kroah-HartmanFrom: José Expósito <[email protected]>
[ Upstream commit ff6b548afe4d9d1ff3a0f6ef79e8cbca25d8f905 ]
The function performs a check on its input parameters, however, the hdev parameter is used before the check.
Initialize the stack variables after checking the input parameters to avoid a possible NULL pointer dereference.
Addresses-Coverity-ID: 1443804 ("Null pointer dereference")
--- drivers/hid/hid-uclogic-params.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
drivers/hid/hid-uclogic-params.c +7 -3
@@ -707,9 +707,9 @@ static int uclogic_params_huion_init(struct uclogic_params *params, struct hid_device *hdev) {int rc; -struct usb_device *udev =hid_to_usb_dev (hdev); -struct usb_interface *iface =to_usb_interface (hdev->dev.parent); -__u8 bInterfaceNumber = iface->cur_altsetting->desc.bInterfaceNumber; +struct usb_device *udev; +struct usb_interface *iface; +__u8 bInterfaceNumber;bool found;/* The resulting parameters (noop) */ struct uclogic_params p = {0 , };
@@ -723,6 +723,10 @@ static int uclogic_params_huion_init(struct uclogic_params *params, goto cleanup; } + udev =hid_to_usb_dev (hdev); + iface =to_usb_interface (hdev->dev.parent); + bInterfaceNumber = iface->cur_altsetting->desc.bInterfaceNumber; +/* If it's not a pen interface */ if (bInterfaceNumber !=0 ) {/* TODO: Consider marking the interface invalid */
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 218/563 HID: hid-uclogic-params: Invalid parameter check in uclogic_params_frame_init_v1_buttonpad
In reply to Greg Kroah-HartmanFrom: José Expósito <[email protected]>
[ Upstream commit aa320fdbbbb482c19100f51461bd0069753ce3d7 ]
The function performs a check on the hdev input parameters, however, it is used before the check.
Initialize the udev variable after the sanity check to avoid a possible NULL pointer dereference.
Addresses-Coverity-ID: 1443763 ("Null pointer dereference")
--- drivers/hid/hid-uclogic-params.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/hid/hid-uclogic-params.c +3 -1
@@ -451,7 +451,7 @@ static int uclogic_params_frame_init_v1_buttonpad( {int rc;bool found = false; -struct usb_device *usb_dev =hid_to_usb_dev (hdev); +struct usb_device *usb_dev;char *str_buf =NULL ;const size_t str_len =16 ;
@@ -461,6 +461,8 @@ static int uclogic_params_frame_init_v1_buttonpad( goto cleanup; } + usb_dev =hid_to_usb_dev (hdev); +/* * Enable generic button mode */
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 219/563 debugfs: lockdown: Allow reading debugfs files that are not world readable
In reply to Greg Kroah-HartmanFrom: Michal Suchanek <[email protected]>
[ Upstream commit 358fcf5ddbec4e6706405847d6a666f5933a6c25 ]
When the kernel is locked down the kernel allows reading only debugfs files with mode 444. Mode 400 is also valid but is not allowed.
Make the 444 into a mask.
--- fs/debugfs/file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/debugfs/file.c +1 -1
@@ -147,7 +147,7 @@ static int debugfs_locked_down(struct inode *inode, struct file *filp, const struct file_operations *real_fops) { - if ((inode->i_mode & 07777) == 0444 && + if ((inode->i_mode & 07777 & ~0444) == 0 && !(filp->f_mode & FMODE_WRITE) && !real_fops->unlocked_ioctl && !real_fops->compat_ioctl &&
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 220/563 net/mlx5e: Fix page DMA map/unmap attributes
In reply to Greg Kroah-HartmanFrom: Aya Levin <[email protected]>
[ Upstream commit 0b7cfa4082fbf550595bc0e40f05614bd83bf0cd ]
Driver initiates DMA sync, hence it may skip CPU sync. Add DMA_ATTR_SKIP_CPU_SYNC as input attribute both to dma_map_page and dma_unmap_page to avoid redundant sync with the CPU.
When forcing the device to work with SWIOTLB, the extra sync might cause data corruption. The driver unmaps the whole page while the hardware used just a part of the bounce buffer. So syncing overrides the entire page with bounce buffer that only partially contains real data.
--- drivers/net/ethernet/mellanox/mlx5/core/en/xsk/pool.c | 4 ++-- drivers/net/ethernet/mellanox/mlx5/core/en_rx.c | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en/xsk/pool.c +2 -2
@@ -11,13 +11,13 @@ static int mlx5e_xsk_map_pool(struct mlx5e_priv *priv, {struct device *dev =mlx5_core_dma_dev (priv->mdev); -return xsk_pool_dma_map (pool, dev,0 ); +return xsk_pool_dma_map (pool, dev,DMA_ATTR_SKIP_CPU_SYNC ); }static void mlx5e_xsk_unmap_pool (struct mlx5e_priv *priv,struct xsk_buff_pool *pool) { -return xsk_pool_dma_unmap (pool,0 ); +return xsk_pool_dma_unmap (pool,DMA_ATTR_SKIP_CPU_SYNC ); }static int mlx5e_xsk_get_pools (struct mlx5e_xsk *xsk)
drivers/net/ethernet/mellanox/mlx5/core/en_rx.c +4 -3
@@ -276,8 +276,8 @@ static inline int mlx5e_page_alloc_pool(struct mlx5e_rq *rq,if (unlikely (!dma_info->page))return -ENOMEM ; - dma_info->addr =dma_map_page (rq->pdev, dma_info->page,0 , -PAGE_SIZE , rq->buff.map_dir); + dma_info->addr =dma_map_page_attrs (rq->pdev, dma_info->page,0 ,PAGE_SIZE , + rq->buff.map_dir,DMA_ATTR_SKIP_CPU_SYNC );if (unlikely (dma_mapping_error (rq->pdev, dma_info->addr))) {page_pool_recycle_direct (rq->page_pool, dma_info->page); dma_info->page =NULL ;
@@ -298,7 +298,8 @@ static inline int mlx5e_page_alloc(struct mlx5e_rq *rq,void mlx5e_page_dma_unmap (struct mlx5e_rq *rq,struct mlx5e_dma_info *dma_info) { -dma_unmap_page (rq->pdev, dma_info->addr,PAGE_SIZE , rq->buff.map_dir); +dma_unmap_page_attrs (rq->pdev, dma_info->addr,PAGE_SIZE , rq->buff.map_dir, +DMA_ATTR_SKIP_CPU_SYNC ); } void mlx5e_page_release_dynamic(struct mlx5e_rq *rq,
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 221/563 net/mlx5e: Dont block routes with nexthop objects in SW
In reply to Greg Kroah-HartmanFrom: Maor Dickman <[email protected]>
[ Upstream commit 9e72a55a3c9d54b38a704bb7292d984574a81d9d ]
Routes with nexthop objects is currently not supported by multipath offload and any attempts to use it is blocked, however this also block adding SW routes with nexthop.
Resolve this by returning NOTIFY_DONE instead of an error which will allow such a route to be created in SW but not offloaded.
This fix also solve an issue which block adding such routes on different devices due to missing check if the route FIB device is one of multipath devices.
--- drivers/net/ethernet/mellanox/mlx5/core/lag_mp.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/lag_mp.c +2 -4
@@ -265,10 +265,8 @@ static int mlx5_lag_fib_event(struct notifier_block *nb, fen_info = container_of(info, struct fib_entry_notifier_info, info); fi = fen_info->fi; -if (fi->nh) { -NL_SET_ERR_MSG_MOD (info->extack,"IPv4 route with nexthop objects is not supported" ); -return notifier_from_errno (-EINVAL ); - } +if (fi->nh) +return NOTIFY_DONE ; fib_dev =fib_info_nh (fen_info->fi,0 )->fib_nh_dev;if (fib_dev != ldev->pf[MLX5_LAG_P1 ].netdev && fib_dev != ldev->pf[MLX5_LAG_P2 ].netdev) {
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 222/563 Revert "net/mlx5e: Block offload of outer header csum for UDP tunnels"
In reply to Greg Kroah-HartmanFrom: Aya Levin <[email protected]>
[ Upstream commit 64050cdad0983ad8060e33c3f4b5aee2366bcebd ]
This reverts commit 6d6727dddc7f93fcc155cb8d0c49c29ae0e71122.
Although the NIC doesn't support offload of outer header CSUM, using gso_partial_features allows offloading the tunnel's segmentation. The driver relies on the stack CSUM calculation of the outer header. For this, NETIF_F_GSO_UDP_TUNNEL_CSUM must be a member of the device's features.
--- drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en_main.c +7 -3
@@ -5024,9 +5024,13 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev) }if (mlx5_vxlan_allowed (mdev->vxlan) ||mlx5_geneve_tx_allowed (mdev)) { - netdev->hw_features |=NETIF_F_GSO_UDP_TUNNEL ; - netdev->hw_enc_features |=NETIF_F_GSO_UDP_TUNNEL ; - netdev->vlan_features |=NETIF_F_GSO_UDP_TUNNEL ; + netdev->hw_features |=NETIF_F_GSO_UDP_TUNNEL | +NETIF_F_GSO_UDP_TUNNEL_CSUM ; + netdev->hw_enc_features |=NETIF_F_GSO_UDP_TUNNEL | +NETIF_F_GSO_UDP_TUNNEL_CSUM ; + netdev->gso_partial_features =NETIF_F_GSO_UDP_TUNNEL_CSUM ; + netdev->vlan_features |=NETIF_F_GSO_UDP_TUNNEL | +NETIF_F_GSO_UDP_TUNNEL_CSUM ; }if (mlx5e_tunnel_proto_supported (mdev,IPPROTO_GRE )) {
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 223/563 net/mlx5: Set command entry semaphore up once got index free
In reply to Greg Kroah-HartmanFrom: Moshe Shemesh <[email protected]>
[ Upstream commit 8e715cd613a1e872b9d918e912d90b399785761a ]
Avoid a race where command work handler may fail to allocate command entry index, by holding the command semaphore down till command entry index is being freed.
--- drivers/net/ethernet/mellanox/mlx5/core/cmd.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/cmd.c +6 -9
@@ -147,8 +147,12 @@ static void cmd_ent_put(struct mlx5_cmd_work_ent *ent)if (!refcount_dec_and_test (&ent->refcnt))return ; -if (ent->idx >=0 ) -cmd_free_index (ent->cmd, ent->idx); +if (ent->idx >=0 ) { +struct mlx5_cmd *cmd = ent->cmd; + +cmd_free_index (cmd, ent->idx); +up (ent->page_queue ? &cmd->pages_sem : &cmd->sem); + }cmd_free_ent (ent); }
@@ -1582,8 +1586,6 @@ static void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vec, bool force vector = vec &0xffffffff ;for (i =0 ; i < (1 << cmd->log_sz); i++) {if (test_bit (i, &vector)) { -struct semaphore *sem; - ent = cmd->ent_arr[i];/* if we already completed the command, ignore it */
@@ -1606,10 +1608,6 @@ static void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vec, bool force dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR)cmd_ent_put (ent); -if (ent->page_queue) - sem = &cmd->pages_sem; -else - sem = &cmd->sem; ent->ts2 =ktime_get_ns ();memcpy (ent->out->first.data, ent->lay->out,sizeof (ent->lay->out));dump_command (dev, ent,0 );
@@ -1663,7 +1661,6 @@ static void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vec, bool force*/ complete (&ent->done); } -up (sem); } } }
Signature · 1 line
2.34.1
Hi!
Quoted 4 lines
This is the start of the stable review cycle for the 5.10.94 release. There are 563 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Our tests are unhappy, and it is more than gmp.h problem:
https://gitlab.com/cip-project/cip-testing/linux-stable-rc-ci/-/tree/linux-5.10.y
arm64_ctj:
https://gitlab.com/cip-project/cip-testing/linux-stable-rc-ci/-/jobs/2010070033
arch/arm64/mm/extable.c: In function 'fixup_exception':1095arch/arm64/mm/extable.c:17:6: error: implicit declaration of function 'in_bpf_jit' [-Werror=implicit-function-declaration] 1096 if (in_bpf_jit(regs))
1097 ^~~~~~~~~~
1098cc1: some warnings being treated as errors
1099scripts/Makefile.build:280: recipe for target 'arch/arm64/mm/extable.o' failed
1100make[2]: *** [arch/arm64/mm/extable.o] Error 1
1101make[2]: *** Waiting for unfinished jobs....
1102 CC kernel/sched/loadavg.o 1103 CC arch/arm64/kernel/entry-common.o
1104
arm64_defconfig:
https://gitlab.com/cip-project/cip-testing/linux-stable-rc-ci/-/jobs/2010070044
arch/arm64/mm/extable.c: In function 'fixup_exception':1129arch/arm64/mm/extable.c:17:6: error: implicit declaration of function 'in_bpf_jit' [-Werror=implicit-function-declaration] 1130 if (in_bpf_jit(regs))
1131 ^~~~~~~~~~
1132 CC arch/arm64/crypto/ghash-ce-glue.o
1133cc1: some warnings being treated as errors
1134scripts/Makefile.build:280: recipe for target 'arch/arm64/mm/extable.o' failed
1135make[2]: *** [arch/arm64/mm/extable.o] Error 1
1136make[2]: *** Waiting for unfinished jobs....
1137 CC arch/arm64/kvm/hyp/vhe/sysreg-sr.o
1138
Best regards,
Pavel
Signature · 2 lines
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Greg Kroah-Hartman
maintainerQuoted 43 lines · Pavel Machek
Hi!
Quoted 4 lines
This is the start of the stable review cycle for the 5.10.94 release. There are 563 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Our tests are unhappy, and it is more than
gmp.hproblem:https://gitlab.com/cip-project/cip-testing/linux-stable-rc-ci/-/tree/linux-5.10.y
arm64_ctj:https://gitlab.com/cip-project/cip-testing/linux-stable-rc-ci/-/jobs/2010070033
arch/arm64/mm/extable.c: In function 'fixup_exception':1095arch/arm64/mm/extable.c:17:6: error: implicit declaration of function 'in_bpf_jit' [-Werror=implicit-function-declaration] 1096 if (in_bpf_jit(regs))
1097 ^~~~~~~~~~
1098cc1: some warnings being treated as errors
1099scripts/Makefile.build:280: recipe for target 'arch/arm64/mm/extable.o' failed
1100make[2]: *** [arch/arm64/mm/extable.o] Error 1
1101make[2]: *** Waiting for unfinished jobs....1102 CC kernel/sched/loadavg.o 1103 CC arch/arm64/kernel/entry-common.o1104
arm64_defconfig:https://gitlab.com/cip-project/cip-testing/linux-stable-rc-ci/-/jobs/2010070044
arch/arm64/mm/extable.c: In function 'fixup_exception':1129arch/arm64/mm/extable.c:17:6: error: implicit declaration of function 'in_bpf_jit' [-Werror=implicit-function-declaration] 1130 if (in_bpf_jit(regs))
1131 ^~~~~~~~~~
1132 CCarch/arm64/crypto/ghash-ce-glue.o
1133cc1: some warnings being treated as errors
1134scripts/Makefile.build:280: recipe for target 'arch/arm64/mm/extable.o' failed
1135make[2]: *** [arch/arm64/mm/extable.o] Error 1
1136make[2]: *** Waiting for unfinished jobs....
1137 CCarch/arm64/kvm/hyp/vhe/sysreg-sr.o
1138
Quoted 1 line
Best regards,
Found the offending commit, will fix this in -rc2, thanks.
greg k-h
Greg Kroah-Hartman
maintainerPATCH 224/563 lib/mpi: Add the return value check of kcalloc()
In reply to Greg Kroah-HartmanFrom: Zizhuang Deng <[email protected]>
[ Upstream commit dd827abe296fe4249b2f8c9b95f72f814ea8348c ]
Add the return value check of kcalloc() to avoid potential NULL ptr dereference.
--- lib/mpi/mpi-mod.c | 2 ++ 1 file changed, 2 insertions(+)
lib/mpi/mpi-mod.c +2 -0
@@ -40,6 +40,8 @@ mpi_barrett_t mpi_barrett_init(MPI m, int copy)mpi_normalize (m); ctx =kcalloc (1 ,sizeof (*ctx),GFP_KERNEL ); +if (!ctx) +return NULL ;if (copy) { ctx->m =mpi_copy (m);
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 225/563 Bluetooth: L2CAP: uninitialized variables in l2cap_sock_setsockopt()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit 2b70d4f9b20635ac328836e50d183632e1930f94 ]
The "opt" variable is a u32, but on some paths only the top bytes were initialized and the others contained random stack data.
--- net/bluetooth/l2cap_sock.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
net/bluetooth/l2cap_sock.c +8 -6
@@ -903,6 +903,8 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,struct l2cap_conn *conn;int len, err =0 ;u32 opt; +u16 mtu; +u8 mode;BT_DBG ("sk %p" , sk);
@@ -1085,16 +1087,16 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,break ; } -if (copy_from_sockptr (&opt, optval,sizeof (u16))) { +if (copy_from_sockptr (&mtu, optval,sizeof (u16))) { err = -EFAULT ;break ; }if (chan->mode ==L2CAP_MODE_EXT_FLOWCTL && sk->sk_state ==BT_CONNECTED ) - err =l2cap_chan_reconfigure (chan, opt); + err =l2cap_chan_reconfigure (chan, mtu);else - chan->imtu = opt; + chan->imtu = mtu;break ;
@@ -1116,14 +1118,14 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,break ; } -if (copy_from_sockptr (&opt, optval,sizeof (u8))) { +if (copy_from_sockptr (&mode, optval,sizeof (u8))) { err = -EFAULT ;break ; } -BT_DBG ("opt %u" , opt); +BT_DBG ("mode %u" , mode); - err =l2cap_set_mode (chan, opt); + err =l2cap_set_mode (chan, mode);if (err)break ;
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 226/563 spi: spi-meson-spifc: Add missing pm_runtime_disable() in meson_spifc_probe
In reply to Greg Kroah-HartmanFrom: Miaoqian Lin <[email protected]>
[ Upstream commit 69c1b87516e327a60b39f96b778fe683259408bf ]
If the probe fails, we should use pm_runtime_disable() to balance pm_runtime_enable().
Add missing pm_runtime_disable() for meson_spifc_probe.
--- drivers/spi/spi-meson-spifc.c | 1 + 1 file changed, 1 insertion(+)
drivers/spi/spi-meson-spifc.c +1 -0
@@ -349,6 +349,7 @@ static int meson_spifc_probe(struct platform_device *pdev)return 0 ; out_clk:clk_disable_unprepare (spifc->clk); +pm_runtime_disable (spifc->dev); out_err:spi_master_put (master);return ret;
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 227/563 ax25: uninitialized variable in ax25_setsockopt()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit 9371937092d5fd502032c1bb4475b36b39b1f1b3 ]
The "opt" variable is unsigned long but we only copy 4 bytes from the user so the lower 4 bytes are uninitialized.
I have changed the integer overflow checks from ULONG to UINT as well. This is a slight API change but I don't expect it to break anything.
--- net/ax25/af_ax25.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
net/ax25/af_ax25.c +5 -5
@@ -536,7 +536,7 @@ static int ax25_setsockopt(struct socket *sock, int level, int optname,ax25_cb *ax25;struct net_device *dev;char devname[IFNAMSIZ ]; -unsigned long opt; +unsigned int opt;int res =0 ;if (level !=SOL_AX25 )
@@ -568,7 +568,7 @@ static int ax25_setsockopt(struct socket *sock, int level, int optname,break ;case AX25_T1 : -if (opt <1 || opt >ULONG_MAX /HZ ) { +if (opt <1 || opt >UINT_MAX /HZ ) { res = -EINVAL ;break ; }
@@ -577,7 +577,7 @@ static int ax25_setsockopt(struct socket *sock, int level, int optname,break ;case AX25_T2 : -if (opt <1 || opt >ULONG_MAX /HZ ) { +if (opt <1 || opt >UINT_MAX /HZ ) { res = -EINVAL ;break ; }
@@ -593,7 +593,7 @@ static int ax25_setsockopt(struct socket *sock, int level, int optname,break ;case AX25_T3 : -if (opt <1 || opt >ULONG_MAX /HZ ) { +if (opt <1 || opt >UINT_MAX /HZ ) { res = -EINVAL ;break ; }
@@ -601,7 +601,7 @@ static int ax25_setsockopt(struct socket *sock, int level, int optname,break ;case AX25_IDLE : -if (opt >ULONG_MAX / (60 *HZ )) { +if (opt >UINT_MAX / (60 *HZ )) { res = -EINVAL ;break ; }
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 228/563 netrom: fix api breakage in nr_setsockopt()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit dc35616e6c2907b0c0c391a205802d8880f7fd85 ]
This needs to copy an unsigned int from user space instead of a long to avoid breaking user space with an API change.
I have updated all the integer overflow checks from ULONG to UINT as well. This is a slight API change but I do not expect it to affect anything in real life.
--- net/netrom/af_netrom.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
net/netrom/af_netrom.c +6 -6
@@ -298,7 +298,7 @@ static int nr_setsockopt(struct socket *sock, int level, int optname, {struct sock *sk = sock->sk;struct nr_sock *nr =nr_sk (sk); -unsigned long opt; +unsigned int opt;if (level !=SOL_NETROM )return -ENOPROTOOPT ;
@@ -306,18 +306,18 @@ static int nr_setsockopt(struct socket *sock, int level, int optname,if (optlen <sizeof (unsigned int ))return -EINVAL ; -if (copy_from_sockptr (&opt, optval,sizeof (unsigned long ))) +if (copy_from_sockptr (&opt, optval,sizeof (opt)))return -EFAULT ;switch (optname) {case NETROM_T1 : -if (opt <1 || opt >ULONG_MAX /HZ ) +if (opt <1 || opt >UINT_MAX /HZ )return -EINVAL ; nr->t1 = opt *HZ ;return 0 ;case NETROM_T2 : -if (opt <1 || opt >ULONG_MAX /HZ ) +if (opt <1 || opt >UINT_MAX /HZ )return -EINVAL ; nr->t2 = opt *HZ ;return 0 ;
@@ -329,13 +329,13 @@ static int nr_setsockopt(struct socket *sock, int level, int optname,return 0 ;case NETROM_T4 : -if (opt <1 || opt >ULONG_MAX /HZ ) +if (opt <1 || opt >UINT_MAX /HZ )return -EINVAL ; nr->t4 = opt *HZ ;return 0 ;case NETROM_IDLE : -if (opt >ULONG_MAX / (60 *HZ )) +if (opt >UINT_MAX / (60 *HZ ))return -EINVAL ; nr->idle = opt *60 *HZ ;return 0 ;
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 229/563 regmap: Call regmap_debugfs_exit() prior to _init()
In reply to Greg Kroah-HartmanFrom: Fabio Estevam <[email protected]>
[ Upstream commit 530792efa6cb86f5612ff093333fec735793b582 ]
Since commit cffa4b2122f5 ("regmap: debugfs: Fix a memory leak when calling regmap_attach_dev"), the following debugfs error is seen on i.MX boards:
debugfs: Directory 'dummy-iomuxc-gpr@20e0000' with parent 'regmap' already present!
In the attempt to fix the memory leak, the above commit added a NULL check for map->debugfs_name. For the first debufs entry, map->debugfs_name is NULL and then the new name is allocated via kasprintf().
For the second debugfs entry, map->debugfs_name() is no longer NULL, so it will keep using the old entry name and the duplicate name error is seen.
Quoting Mark Brown:
"That means that if the device gets freed we'll end up with the old debugfs file hanging around pointing at nothing.
...
To be more explicit this means we need a call to regmap_debugfs_exit() which will clean up all the existing debugfs stuff before we loose references to it."
Call regmap_debugfs_exit() prior to regmap_debugfs_init() to fix the problem.
Tested on i.MX6Q and i.MX6SX boards.
--- drivers/base/regmap/regmap.c | 1 + 1 file changed, 1 insertion(+)
drivers/base/regmap/regmap.c +1 -0
@@ -620,6 +620,7 @@ int regmap_attach_dev(struct device *dev, struct regmap *map,if (ret)return ret; +regmap_debugfs_exit (map);regmap_debugfs_init (map);/* Add a devres resource for dev_get_regmap() */
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 230/563 can: mcp251xfd: add missing newline to printed strings
In reply to Greg Kroah-HartmanFrom: Marc Kleine-Budde <[email protected]>
[ Upstream commit 3bd9d8ce6f8c5c43ee2f1106021db0f98882cc75 ]
This patch adds the missing newline to printed strings.
--- drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c +2 -2
@@ -2497,7 +2497,7 @@ static int mcp251xfd_register_chip_detect(struct mcp251xfd_priv *priv)if (!mcp251xfd_is_251X (priv) && priv->devtype_data.model != devtype_data->model) {netdev_info (ndev, -"Detected %s, but firmware specifies a %s. Fixing up." , +"Detected %s, but firmware specifies a %s. Fixing up.\n" ,__mcp251xfd_get_model_str (devtype_data->model),mcp251xfd_get_model_str (priv)); }
@@ -2534,7 +2534,7 @@ static int mcp251xfd_register_check_rx_int(struct mcp251xfd_priv *priv)return 0 ;netdev_info (priv->ndev, -"RX_INT active after softreset, disabling RX_INT support." ); +"RX_INT active after softreset, disabling RX_INT support.\n" );devm_gpiod_put (&priv->spi->dev, priv->rx_int); priv->rx_int =NULL ;
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 231/563 tpm: add request_locality before write TPM_INT_ENABLE
In reply to Greg Kroah-HartmanFrom: Chen Jun <[email protected]>
[ Upstream commit 0ef333f5ba7f24f5d8478425c163d3097f1c7afd ]
Locality is not appropriately requested before writing the int mask. Add the missing boilerplate.
--- drivers/char/tpm/tpm_tis_core.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/char/tpm/tpm_tis_core.c +8 -0
@@ -994,7 +994,15 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, intmask |=TPM_INTF_CMD_READY_INT |TPM_INTF_LOCALITY_CHANGE_INT |TPM_INTF_DATA_AVAIL_INT |TPM_INTF_STS_VALID_INT ; intmask &= ~TPM_GLOBAL_INT_ENABLE ; + + rc =request_locality (chip,0 ); +if (rc <0 ) { + rc = -ENODEV ; + goto out_err; + } +tpm_tis_write32 (priv,TPM_INT_ENABLE (priv->locality), intmask); +release_locality (chip,0 ); rc =tpm_chip_start (chip);if (rc)
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 232/563 tpm_tis: Fix an error handling path in tpm_tis_core_init()
In reply to Greg Kroah-HartmanFrom: Christophe Jaillet <[email protected]>
[ Upstream commit e96d52822f5ac0a25de78f95cd23421bcbc93584 ]
Commit 79ca6f74dae0 ("tpm: fix Atmel TPM crash caused by too frequent queries") has moved some code around without updating the error handling path.
This is now pointless to 'goto out_err' when neither 'clk_enable()' nor 'ioremap()' have been called yet.
Make a direct return instead to avoid undoing things that have not been done.
--- drivers/char/tpm/tpm_tis_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/char/tpm/tpm_tis_core.c +1 -1
@@ -952,7 +952,7 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, rc =tpm_tis_read32 (priv,TPM_DID_VID (0 ), &vendor);if (rc <0 ) - goto out_err; +return rc; priv->manufacturer_id = vendor;
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 233/563 can: softing: softing_startstop(): fix set but not used variable warning
In reply to Greg Kroah-HartmanFrom: Marc Kleine-Budde <[email protected]>
[ Upstream commit 370d988cc529598ebaec6487d4f84c2115dc696b ]
In the function softing_startstop() the variable error_reporting is assigned but not used. The code that uses this variable is commented out. Its stated that the functionality is not finally verified.
To fix the warning:
| drivers/net/can/softing/softing_fw.c:424:9: error: variable 'error_reporting' set but not used [-Werror,-Wunused-but-set-variable]
remove the comment, activate the code, but add a "0 &&" to the if expression and rely on the optimizer rather than the preprocessor to remove the code.
--- drivers/net/can/softing/softing_fw.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
drivers/net/can/softing/softing_fw.c +6 -5
@@ -565,18 +565,19 @@ int softing_startstop(struct net_device *dev, int up)if (ret <0 ) goto failed; } -/* enable_error_frame */ -/* + +/* enable_error_frame +* * Error reporting is switched off at the moment since * the receiving of them is not yet 100% verified * This should be enabled sooner or later -* -if (error_reporting) { +*/ +if (0 && error_reporting) { ret =softing_fct_cmd (card,51 ,"enable_error_frame" );if (ret <0 ) goto failed; } -*/ +/* initialize interface */ iowrite16 (1 , &card->dpram[DPRAM_FCT_PARAM +2 ]);iowrite16 (1 , &card->dpram[DPRAM_FCT_PARAM +4 ]);
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 234/563 can: xilinx_can: xcan_probe(): check for error irq
In reply to Greg Kroah-HartmanFrom: Jiasheng Jiang <[email protected]>
[ Upstream commit c6564c13dae25cd7f8e1de5127b4da4500ee5844 ]
For the possible failure of the platform_get_irq(), the returned irq could be error number and will finally cause the failure of the request_irq().
Consider that platform_get_irq() can now in certain cases return -EPROBE_DEFER, and the consequences of letting request_irq() effectively convert that into -EINVAL, even at probe time rather than later on. So it might be better to check just now.
--- drivers/net/can/xilinx_can.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/net/can/xilinx_can.c +6 -1
@@ -1762,7 +1762,12 @@ static int xcan_probe(struct platform_device *pdev)spin_lock_init (&priv->tx_lock);/* Get IRQ for the device */ - ndev->irq =platform_get_irq (pdev,0 ); + ret =platform_get_irq (pdev,0 ); +if (ret <0 ) + goto err_free; + + ndev->irq = ret; + ndev->flags |=IFF_ECHO ;/* We support local echo */ platform_set_drvdata (pdev, ndev);
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 235/563 pcmcia: fix setting of kthread task states
In reply to Greg Kroah-HartmanFrom: Dominik Brodowski <[email protected]>
[ Upstream commit fbb3485f1f931102d8ba606f1c28123f5b48afa3 ]
We need to set TASK_INTERRUPTIBLE before calling kthread_should_stop(). Otherwise, kthread_stop() might see that the pccardd thread is still in TASK_RUNNING state and fail to wake it up.
Additionally, we only need to set the state back to TASK_RUNNING if kthread_should_stop() breaks the loop.
--- drivers/pcmcia/cs.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-)
drivers/pcmcia/cs.c +3 -5
@@ -666,18 +666,16 @@ static int pccardd(void *__skt)if (events || sysfs_events)continue ; +set_current_state (TASK_INTERRUPTIBLE );if (kthread_should_stop ())break ; -set_current_state (TASK_INTERRUPTIBLE ); -schedule (); -/* make sure we are running */ -__set_current_state (TASK_RUNNING ); -try_to_freeze (); } +/* make sure we are running before we exit */ +__set_current_state (TASK_RUNNING );/* shut down socket, if a device is still present */ if (skt->state &SOCKET_PRESENT ) {
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 236/563 iwlwifi: mvm: Use div_s64 instead of do_div in iwl_mvm_ftm_rtt_smoothing()
In reply to Greg Kroah-HartmanFrom: Nathan Chancellor <[email protected]>
[ Upstream commit 4ccdcc8ffd955490feec05380223db6a48961eb5 ]
When building ARCH=arm allmodconfig:
drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c: In function ‘iwl_mvm_ftm_rtt_smoothing’:./include/asm-generic/div64.h:222:35: error: comparison of distinct pointer types lacks a cast [-Werror]
222 | (void)(((typeof((n)) *)0) == ((uint64_t *)0)); \
| ^~drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c:1070:9: note: in expansion of macro ‘do_div’
1070 | do_div(rtt_avg, 100);
| ^~~~~~do_div() has to be used with an unsigned 64-bit integer dividend but rtt_avg is a signed 64-bit integer.
div_s64() expects a signed 64-bit integer dividend and signed 32-bit divisor, which fits this scenario, so use that function here to fix the warning.
--- drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c +1 -2
@@ -967,8 +967,7 @@ static void iwl_mvm_ftm_rtt_smoothing(struct iwl_mvm *mvm, overshoot =IWL_MVM_FTM_INITIATOR_SMOOTH_OVERSHOOT ; alpha =IWL_MVM_FTM_INITIATOR_SMOOTH_ALPHA ; - rtt_avg = alpha * rtt + (100 - alpha) * resp->rtt_avg; -do_div (rtt_avg,100 ); + rtt_avg =div_s64 (alpha * rtt + (100 - alpha) * resp->rtt_avg,100 ); IWL_DEBUG_INFO(mvm, "%pM: prev rtt_avg=%lld, new rtt_avg=%lld, rtt=%lld\n",
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 237/563 net: mcs7830: handle usb read errors properly
In reply to Greg Kroah-HartmanFrom: Pavel Skripkin <[email protected]>
[ Upstream commit d668769eb9c52b150753f1653f7f5a0aeb8239d2 ]
Syzbot reported uninit value in mcs7830_bind(). The problem was in missing validation check for bytes read via usbnet_read_cmd().
usbnet_read_cmd() internally calls usb_control_msg(), that returns number of bytes read. Code should validate that requested number of bytes was actually read.
So, this patch adds missing size validation check inside mcs7830_get_reg() to prevent uninit value bugs
--- drivers/net/usb/mcs7830.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
drivers/net/usb/mcs7830.c +10 -2
@@ -108,8 +108,16 @@ static const char driver_name[] = "MOSCHIP usb-ethernet driver";static int mcs7830_get_reg (struct usbnet *dev,u16 index,u16 size,void *data) { -return usbnet_read_cmd (dev,MCS7830_RD_BREQ ,MCS7830_RD_BMREQ , -0x0000 , index, data, size); +int ret; + + ret =usbnet_read_cmd (dev,MCS7830_RD_BREQ ,MCS7830_RD_BMREQ , +0x0000 , index, data, size); +if (ret <0 ) +return ret; +else if (ret < size) +return -ENODATA ; + +return ret; }static int mcs7830_set_reg (struct usbnet *dev,u16 index,u16 size,const void *data)
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 238/563 ext4: avoid trim error on fs with small groups
In reply to Greg Kroah-HartmanFrom: Jan Kara <[email protected]>
[ Upstream commit 173b6e383d2a204c9921ffc1eca3b87aa2106c33 ]
A user reported FITRIM ioctl failing for him on ext4 on some devices without apparent reason. After some debugging we've found out that these devices (being LVM volumes) report rather large discard granularity of 42MB and the filesystem had 1k blocksize and thus group size of 8MB. Because ext4 FITRIM implementation puts discard granularity into minlen, ext4_trim_fs() declared the trim request as invalid. However just silently doing nothing seems to be a more appropriate reaction to such combination of parameters since user did not specify anything wrong.
--- fs/ext4/ioctl.c | 2 -- fs/ext4/mballoc.c | 8 ++++++++ 2 files changed, 8 insertions(+), 2 deletions(-)
fs/ext4/ioctl.c +0 -2
@@ -1123,8 +1123,6 @@ resizefs_out: sizeof(range)))return -EFAULT ; - range.minlen =max ((unsigned int )range.minlen, - q->limits.discard_granularity); ret =ext4_trim_fs (sb, &range);if (ret <0 )return ret;
fs/ext4/mballoc.c +8 -0
@@ -5815,6 +5815,7 @@ out:*/ int ext4_trim_fs (struct super_block *sb,struct fstrim_range *range) { +struct request_queue *q =bdev_get_queue (sb->s_bdev);struct ext4_group_info *grp;ext4_group_t group, first_group, last_group;ext4_grpblk_t cnt =0 , first_cluster, last_cluster;
@@ -5833,6 +5834,13 @@ int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range) start >= max_blks || range->len < sb->s_blocksize) return -EINVAL; +/* No point to try to trim less than discard granularity */ +if (range->minlen < q->limits.discard_granularity) { + minlen =EXT4_NUM_B2C (EXT4_SB (sb), + q->limits.discard_granularity >> sb->s_blocksize_bits); +if (minlen >EXT4_CLUSTERS_PER_GROUP (sb)) + goto out; + }if (end >= max_blks) end = max_blks -1 ;if (end <= first_data_blk)
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 239/563 ALSA: jack: Add missing rwsem around snd_ctl_remove() calls
In reply to Greg Kroah-HartmanFrom: Takashi Iwai <[email protected]>
[ Upstream commit 06764dc931848c3a9bc01a63bbf76a605408bb54 ]
snd_ctl_remove() has to be called with card->controls_rwsem held (when called after the card instantiation). This patch add the missing rwsem calls around it.
--- sound/core/jack.c | 3 +++ 1 file changed, 3 insertions(+)
sound/core/jack.c +3 -0
@@ -54,10 +54,13 @@ static int snd_jack_dev_free(struct snd_device *device)struct snd_card *card = device->card;struct snd_jack_kctl *jack_kctl, *tmp_jack_kctl; +down_write (&card->controls_rwsem);list_for_each_entry_safe (jack_kctl, tmp_jack_kctl, &jack->kctl_list, list) {list_del_init (&jack_kctl->list);snd_ctl_remove (card, jack_kctl->kctl); } +up_write (&card->controls_rwsem); +if (jack->private_free) jack->private_free (jack);
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 240/563 ALSA: PCM: Add missing rwsem around snd_ctl_remove() calls
In reply to Greg Kroah-HartmanFrom: Takashi Iwai <[email protected]>
[ Upstream commit 5471e9762e1af4b7df057a96bfd46cc250979b88 ]
snd_ctl_remove() has to be called with card->controls_rwsem held (when called after the card instantiation). This patch add the missing rwsem calls around it.
--- sound/core/pcm.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
sound/core/pcm.c +5 -1
@@ -810,7 +810,11 @@ EXPORT_SYMBOL(snd_pcm_new_internal);static void free_chmap (struct snd_pcm_str *pstr) {if (pstr->chmap_kctl) { -snd_ctl_remove (pstr->pcm->card, pstr->chmap_kctl); +struct snd_card *card = pstr->pcm->card; + +down_write (&card->controls_rwsem); +snd_ctl_remove (card, pstr->chmap_kctl); +up_write (&card->controls_rwsem); pstr->chmap_kctl =NULL ; } }
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 241/563 ALSA: hda: Add missing rwsem around snd_ctl_remove() calls
In reply to Greg Kroah-HartmanFrom: Takashi Iwai <[email protected]>
[ Upstream commit 80bd64af75b4bb11c0329bc66c35da2ddfb66d88 ]
snd_ctl_remove() has to be called with card->controls_rwsem held (when called after the card instantiation). This patch add the missing rwsem calls around it.
--- sound/pci/hda/hda_codec.c | 3 +++ 1 file changed, 3 insertions(+)
sound/pci/hda/hda_codec.c +3 -0
@@ -1727,8 +1727,11 @@ void snd_hda_ctls_clear(struct hda_codec *codec) {int i;struct hda_nid_item *items = codec->mixers.list; + +down_write (&codec->card->controls_rwsem);for (i =0 ; i < codec->mixers.used; i++)snd_ctl_remove (codec->card, items[i].kctl); +up_write (&codec->card->controls_rwsem);snd_array_free (&codec->mixers);snd_array_free (&codec->nids); }
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 242/563 RDMA/bnxt_re: Scan the whole bitmap when checking if "disabling RCFW with pending cmd-bit"
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit a917dfb66c0a1fa1caacf3d71edcafcab48e6ff0 ]
The 'cmdq->cmdq_bitmap' bitmap is 'rcfw->cmdq_depth' bits long. The size stored in 'cmdq->bmap_size' is the size of the bitmap in bytes.
Remove this erroneous 'bmap_size' and use 'rcfw->cmdq_depth' directly in 'bnxt_qplib_disable_rcfw_channel()'. Otherwise some error messages may be missing.
Other uses of 'cmdq_bitmap' already take into account 'rcfw->cmdq_depth' directly.
--- drivers/infiniband/hw/bnxt_re/qplib_rcfw.c | 6 ++---- drivers/infiniband/hw/bnxt_re/qplib_rcfw.h | 1 - 2 files changed, 2 insertions(+), 5 deletions(-)
drivers/infiniband/hw/bnxt_re/qplib_rcfw.c +2 -4
@@ -614,8 +614,6 @@ int bnxt_qplib_alloc_rcfw_channel(struct bnxt_qplib_res *res,if (!cmdq->cmdq_bitmap) goto fail; - cmdq->bmap_size = bmap_size; -/* Allocate one extra to hold the QP1 entries */ rcfw->qp_tbl_size = qp_tbl_sz +1 ; rcfw->qp_tbl = kcalloc(rcfw->qp_tbl_size, sizeof(struct bnxt_qplib_qp_node),
@@ -663,8 +661,8 @@ void bnxt_qplib_disable_rcfw_channel(struct bnxt_qplib_rcfw *rcfw)iounmap (cmdq->cmdq_mbox.reg.bar_reg);iounmap (creq->creq_db.reg.bar_reg); - indx =find_first_bit (cmdq->cmdq_bitmap, cmdq->bmap_size); -if (indx != cmdq->bmap_size) + indx =find_first_bit (cmdq->cmdq_bitmap, rcfw->cmdq_depth); +if (indx != rcfw->cmdq_depth)dev_err (&rcfw->pdev->dev,"disabling RCFW with pending cmd-bit %lx\n" , indx);
drivers/infiniband/hw/bnxt_re/qplib_rcfw.h +0 -1
@@ -150,7 +150,6 @@ struct bnxt_qplib_cmdq_ctx {wait_queue_head_t waitq;unsigned long flags;unsigned long *cmdq_bitmap; -u32 bmap_size;u32 seq_num; };
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 243/563 RDMA/hns: Validate the pkey index
In reply to Greg Kroah-HartmanFrom: Kamal Heib <[email protected]>
[ Upstream commit 2a67fcfa0db6b4075515bd23497750849b88850f ]
Before query pkey, make sure that the queried index is valid.
--- drivers/infiniband/hw/hns/hns_roce_main.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/infiniband/hw/hns/hns_roce_main.c +3 -0
@@ -279,6 +279,9 @@ static enum rdma_link_layer hns_roce_get_link_layer(struct ib_device *device,static int hns_roce_query_pkey (struct ib_device *ib_dev,u8 port,u16 index,u16 *pkey) { +if (index >0 ) +return -EINVAL ; + *pkey =PKEY_ID ;return 0 ;
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 244/563 scsi: pm80xx: Update WARN_ON check in pm8001_mpi_build_cmd()
In reply to Greg Kroah-HartmanFrom: Igor Pylypiv <[email protected]>
[ Upstream commit 606c54ae975ad3af540b505b46b55a687501711f ]
Starting from commit 05c6c029a44d ("scsi: pm80xx: Increase number of supported queues") driver initializes only max_q_num queues. Do not use an invalid queue if the WARN_ON condition is true.
--- drivers/scsi/pm8001/pm8001_hwi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/scsi/pm8001/pm8001_hwi.c +3 -1
@@ -1323,7 +1323,9 @@ int pm8001_mpi_build_cmd(struct pm8001_hba_info *pm8001_ha,int q_index = circularQ - pm8001_ha->inbnd_q_tbl;int rv =-1 ; -WARN_ON (q_index >=PM8001_MAX_INB_NUM ); +if (WARN_ON (q_index >= pm8001_ha->max_q_num)) +return -EINVAL ; +spin_lock_irqsave (&circularQ->iq_lock, flags); rv =pm8001_mpi_msg_free_get (circularQ, pm8001_ha->iomb_size, &pMessage);
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 245/563 clk: imx8mn: Fix imx8mn_clko1_sels
In reply to Greg Kroah-HartmanFrom: Adam Ford <[email protected]>
[ Upstream commit 570727e9acfac1c2330a01dd5e1272e9c3acec08 ]
When attempting to use sys_pll1_80m as the parent for clko1, the system hangs. This is due to the fact that the source select for sys_pll1_80m was incorrectly pointing to m7_alt_pll_clk, which doesn't yet exist.
According to Rev 3 of the TRM, The imx8mn_clko1_sels also incorrectly references an osc_27m which does not exist, nor does an entry for source select bits 010b. Fix both by inserting a dummy clock into the missing space in the table and renaming the incorrectly name clock with dummy.
--- drivers/clk/imx/clk-imx8mn.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/clk/imx/clk-imx8mn.c +3 -3
@@ -274,9 +274,9 @@ static const char * const imx8mn_pdm_sels[] = {"osc_24m", "sys_pll2_100m", "audistatic const char *const imx8mn_dram_core_sels[] = {"dram_pll_out" ,"dram_alt_root" , }; -static const char *const imx8mn_clko1_sels[] = {"osc_24m" ,"sys_pll1_800m" ,"osc_27m" , -"sys_pll1_200m" ,"audio_pll2_out" ,"vpu_pll" , -"sys_pll1_80m" , }; +static const char *const imx8mn_clko1_sels[] = {"osc_24m" ,"sys_pll1_800m" ,"dummy" , +"sys_pll1_200m" ,"audio_pll2_out" ,"sys_pll2_500m" , +"dummy" ,"sys_pll1_80m" , };static const char *const imx8mn_clko2_sels[] = {"osc_24m" ,"sys_pll2_200m" ,"sys_pll1_400m" ,"sys_pll2_166m" ,"sys_pll3_out" ,"audio_pll1_out" ,"video_pll1_out" ,"osc_32k" , };
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 246/563 powerpc/prom_init: Fix improper check of prom_getprop()
In reply to Greg Kroah-HartmanFrom: Peiwei Hu <[email protected]>
[ Upstream commit 869fb7e5aecbc163003f93f36dcc26d0554319f6 ]
prom_getprop() can return PROM_ERROR. Binary operator can not identify it.
--- arch/powerpc/kernel/prom_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/powerpc/kernel/prom_init.c +1 -1
@@ -2956,7 +2956,7 @@ static void __init fixup_device_tree_efika_add_phy(void)/* Check if the phy-handle property exists - bail if it does */ rv =prom_getprop (node,"phy-handle" , prop,sizeof (prop)); -if (!rv) +if (rv <=0 )return ;/*
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 247/563 ASoC: uniphier: drop selecting non-existing SND_SOC_UNIPHIER_AIO_DMA
In reply to Greg Kroah-HartmanFrom: Lukas Bulwahn <[email protected]>
[ Upstream commit 49f893253ab43566e34332a969324531fea463f6 ]
Commit f37fe2f9987b ("ASoC: uniphier: add support for UniPhier AIO common driver") adds configs SND_SOC_UNIPHIER_{LD11,PXS2}, which select the non-existing config SND_SOC_UNIPHIER_AIO_DMA.
Hence, ./scripts/checkkconfigsymbols.py warns:
SND_SOC_UNIPHIER_AIO_DMA
Referencing files: sound/soc/uniphier/Kconfig
Probably, there is actually no further config intended to be selected here. So, just drop selecting the non-existing config.
--- sound/soc/uniphier/Kconfig | 2 -- 1 file changed, 2 deletions(-)
sound/soc/uniphier/Kconfig +0 -2
@@ -23,7 +23,6 @@ config SND_SOC_UNIPHIER_LD11 tristate "UniPhier LD11/LD20 Device Driver" depends on SND_SOC_UNIPHIER select SND_SOC_UNIPHIER_AIO - select SND_SOC_UNIPHIER_AIO_DMA help This adds ASoC driver for Socionext UniPhier LD11/LD20 input and output that can be used with other codecs.
@@ -34,7 +33,6 @@ config SND_SOC_UNIPHIER_PXS2 tristate "UniPhier PXs2 Device Driver" depends on SND_SOC_UNIPHIER select SND_SOC_UNIPHIER_AIO - select SND_SOC_UNIPHIER_AIO_DMA help This adds ASoC driver for Socionext UniPhier PXs2 input and output that can be used with other codecs.
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 248/563 dt-bindings: thermal: Fix definition of cooling-maps contribution property
In reply to Greg Kroah-HartmanFrom: Niklas Söderlund <[email protected]>
[ Upstream commit 49bcb1506f2e095262c01bda7fd1c0db524c91e2 ]
When converting the thermal-zones bindings to yaml the definition of the contribution property changed. The intention is the same, an integer value expressing a ratio of a sum on how much cooling is provided by the device to the zone. But after the conversion the integer value is limited to the range 0 to 100 and expressed as a percentage.
This is problematic for two reasons.
- This do not match how the binding is used. Out of the 18 files that make use of the property only two (ste-dbx5x0.dtsi and ste-hrefv60plus.dtsi) sets it at a value that satisfy the binding,
100. The remaining 16 files set the value higher and fail to validate.
- Expressing the value as a percentage instead of a ratio of the sum is confusing as there is nothing to enforce the sum in the zone is not greater then 100.
This patch restore the pre yaml conversion description and removes the value limitation allowing the usage of the bindings to validate.
--- .../devicetree/bindings/thermal/thermal-zones.yaml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-)
Documentation/devicetree/bindings/thermal/thermal-zones.yaml +4 -5
@@ -199,12 +199,11 @@ patternProperties: contribution: $ref: /schemas/types.yaml#/definitions/uint32 - minimum: 0 - maximum: 100 description: - The percentage contribution of the cooling devices at the - specific trip temperature referenced in this map - to this thermal zone + The cooling contribution to the thermal zone of the referred + cooling device at the referred trip point. The contribution is + a ratio of the sum of all cooling contributions within a + thermal zone. required: - trip
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 249/563 powerpc/64s: Convert some cpu_setup() and cpu_restore() functions to C
In reply to Greg Kroah-HartmanFrom: Jordan Niethe <[email protected]>
[ Upstream commit 344fbab991a568dc33ad90711b489d870e18d26d ]
The only thing keeping the cpu_setup() and cpu_restore() functions used in the cputable entries for Power7, Power8, Power9 and Power10 in assembly was cpu_restore() being called before there was a stack in generic_secondary_smp_init(). Commit ("powerpc/64: Set up a kernel stack for secondaries before cpu_restore()") means that it is now possible to use C.
Rewrite the functions in C so they are a little bit easier to read. This is not changing their functionality.
--- arch/powerpc/include/asm/cpu_setup_power.h | 12 + arch/powerpc/kernel/cpu_setup_power.S | 252 ------------------- arch/powerpc/kernel/cpu_setup_power.c | 271 +++++++++++++++++++++ arch/powerpc/kernel/cputable.c | 12 +- 4 files changed, 287 insertions(+), 260 deletions(-) create mode 100644 arch/powerpc/include/asm/cpu_setup_power.h delete mode 100644 arch/powerpc/kernel/cpu_setup_power.S create mode 100644 arch/powerpc/kernel/cpu_setup_power.c
arch/powerpc/include/asm/cpu_setup_power.h new file +12 -0
@@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* +* Copyright (C) 2020 IBM Corporation +*/ +void __setup_cpu_power7 (unsigned long offset,struct cpu_spec *spec); +void __restore_cpu_power7 (void ); +void __setup_cpu_power8 (unsigned long offset,struct cpu_spec *spec); +void __restore_cpu_power8 (void ); +void __setup_cpu_power9 (unsigned long offset,struct cpu_spec *spec); +void __restore_cpu_power9 (void ); +void __setup_cpu_power10 (unsigned long offset,struct cpu_spec *spec); +void __restore_cpu_power10 (void );
arch/powerpc/kernel/cpu_setup_power.S deleted +0 -252
252 lines not on this page · raw message
arch/powerpc/kernel/cpu_setup_power.c new file +271 -0
271 lines not on this page · raw message
arch/powerpc/kernel/cputable.c +4 -8
@@ -60,19 +60,15 @@ extern void __setup_cpu_7410(unsigned long offset, struct cpu_spec* spec);extern void __setup_cpu_745x (unsigned long offset,struct cpu_spec * spec);#endif /* CONFIG_PPC32 */ #ifdef CONFIG_PPC64 +#include <asm/cpu_setup_power.h> extern void __setup_cpu_ppc970 (unsigned long offset,struct cpu_spec * spec);extern void __setup_cpu_ppc970MP (unsigned long offset,struct cpu_spec * spec);extern void __setup_cpu_pa6t (unsigned long offset,struct cpu_spec * spec);extern void __restore_cpu_pa6t (void );extern void __restore_cpu_ppc970 (void ); -extern void __setup_cpu_power7 (unsigned long offset,struct cpu_spec * spec); -extern void __restore_cpu_power7 (void ); -extern void __setup_cpu_power8 (unsigned long offset,struct cpu_spec * spec); -extern void __restore_cpu_power8 (void ); -extern void __setup_cpu_power9 (unsigned long offset,struct cpu_spec * spec); -extern void __restore_cpu_power9 (void ); -extern void __setup_cpu_power10 (unsigned long offset,struct cpu_spec * spec); -extern void __restore_cpu_power10 (void ); +extern long __machine_check_early_realmode_p7 (struct pt_regs *regs); +extern long __machine_check_early_realmode_p8 (struct pt_regs *regs); +extern long __machine_check_early_realmode_p9 (struct pt_regs *regs);#endif /* CONFIG_PPC64 */ #if defined(CONFIG_E500 )extern void __setup_cpu_e5500 (unsigned long offset,struct cpu_spec * spec);
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 250/563 powerpc/perf: MMCR0 control for PMU registers under PMCC=00
In reply to Greg Kroah-HartmanFrom: Athira Rajeev <[email protected]>
[ Upstream commit 91668ab7db4bcfae332e561df1de2401f3f18553 ]
PowerISA v3.1 introduces new control bit (PMCCEXT) for restricting access to group B PMU registers in problem state when MMCR0 PMCC=0b00. In problem state and when MMCR0 PMCC=0b00, setting the Monitor Mode Control Register bit 54 (MMCR0 PMCCEXT), will restrict read permission on Group B Performance Monitor Registers (SIER, SIAR, SDAR and MMCR1). When this bit is set to zero, group B registers will be readable. In other platforms (like power9), the older behaviour is retained where group B PMU SPRs are readable.
Patch adds support for MMCR0 PMCCEXT bit in power10 by enabling this bit during boot and during the PMU event enable/disable callback functions.
--- arch/powerpc/include/asm/reg.h | 1 + arch/powerpc/kernel/cpu_setup_power.c | 1 + arch/powerpc/kernel/dt_cpu_ftrs.c | 1 + arch/powerpc/perf/core-book3s.c | 4 ++++ arch/powerpc/perf/isa207-common.c | 8 ++++++++ 5 files changed, 15 insertions(+)
arch/powerpc/include/asm/reg.h +1 -0
@@ -865,6 +865,7 @@#define MMCR0_BHRBA 0x00200000UL/* BHRB Access allowed in userspace */ #define MMCR0_EBE 0x00100000UL/* Event based branch enable */ #define MMCR0_PMCC 0x000c0000UL/* PMC control */ +#define MMCR0_PMCCEXT ASM_CONST(0x00000200)/* PMCCEXT control */ #define MMCR0_PMCC_U6 0x00080000UL/* PMC1-6 are R/W by user (PR) */ #define MMCR0_PMC1CE 0x00008000UL/* PMC1 count enable*/ #define MMCR0_PMCjCE ASM_CONST(0x00004000)/* PMCj count enable*/
arch/powerpc/kernel/cpu_setup_power.c +1 -0
@@ -123,6 +123,7 @@ static void init_PMU_ISA31(void) {mtspr (SPRN_MMCR3 ,0 );mtspr (SPRN_MMCRA ,MMCRA_BHRB_DISABLE ); +mtspr (SPRN_MMCR0 ,MMCR0_PMCCEXT ); }/*
arch/powerpc/kernel/dt_cpu_ftrs.c +1 -0
@@ -454,6 +454,7 @@ static void init_pmu_power10(void)mtspr (SPRN_MMCR3 ,0 );mtspr (SPRN_MMCRA ,MMCRA_BHRB_DISABLE ); +mtspr (SPRN_MMCR0 ,MMCR0_PMCCEXT ); }static int __init feat_enable_pmu_power10 (struct dt_cpu_feature *f)
arch/powerpc/perf/core-book3s.c +4 -0
@@ -95,6 +95,7 @@ static unsigned int freeze_events_kernel = MMCR0_FCS;#define SPRN_SIER3 0#define MMCRA_SAMPLE_ENABLE 0#define MMCRA_BHRB_DISABLE 0 +#define MMCR0_PMCCEXT 0static inline unsigned long perf_ip_adjust (struct pt_regs *regs) {
@@ -1245,6 +1246,9 @@ static void power_pmu_disable(struct pmu *pmu) val |=MMCR0_FC ; val &= ~(MMCR0_EBE |MMCR0_BHRBA |MMCR0_PMCC |MMCR0_PMAO |MMCR0_FC56 ); +/* Set mmcr0 PMCCEXT for p10 */ +if (ppmu->flags &PPMU_ARCH_31 ) + val |=MMCR0_PMCCEXT ;/* * The barrier is to make sure the mtspr has been
arch/powerpc/perf/isa207-common.c +8 -0
@@ -561,6 +561,14 @@ int isa207_compute_mmcr(u64 event[], int n_ev,if (!(pmc_inuse &0x60 )) mmcr->mmcr0 |=MMCR0_FC56 ; +/* +* Set mmcr0 (PMCCEXT) for p10 which +* will restrict access to group B registers +* when MMCR0 PMCC=0b00. +*/ +if (cpu_has_feature (CPU_FTR_ARCH_31 )) + mmcr->mmcr0 |=MMCR0_PMCCEXT ; + mmcr->mmcr1 = mmcr1; mmcr->mmcra = mmcra; mmcr->mmcr2 = mmcr2;
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 251/563 powerpc/perf: move perf irq/nmi handling details into traps.c
In reply to Greg Kroah-HartmanFrom: Nicholas Piggin <[email protected]>
[ Upstream commit 156b5371a9c2482a9ad23ec82d1a4f89a3ab430d ]
This is required in order to allow more significant differences between NMI type interrupt handlers and regular asynchronous handlers.
--- arch/powerpc/kernel/traps.c | 31 +++++++++++++++++++++++++++- arch/powerpc/perf/core-book3s.c | 35 ++------------------------------ arch/powerpc/perf/core-fsl-emb.c | 25 ----------------------- 3 files changed, 32 insertions(+), 59 deletions(-)
arch/powerpc/kernel/traps.c +30 -1
@@ -1922,11 +1922,40 @@ void vsx_unavailable_tm(struct pt_regs *regs) }#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ -void performance_monitor_exception (struct pt_regs *regs) +static void performance_monitor_exception_nmi (struct pt_regs *regs) +{ +nmi_enter (); + +__this_cpu_inc (irq_stat.pmu_irqs); + +perf_irq (regs); + +nmi_exit (); +} + +static void performance_monitor_exception_async (struct pt_regs *regs) { +irq_enter (); +__this_cpu_inc (irq_stat.pmu_irqs);perf_irq (regs); + +irq_exit (); +} + +void performance_monitor_exception (struct pt_regs *regs) +{ +/* +* On 64-bit, if perf interrupts hit in a local_irq_disable +* (soft-masked) region, we consider them as NMIs. This is required to +* prevent hash faults on user addresses when reading callchains (and +* looks better from an irq tracing perspective). +*/ +if (IS_ENABLED (CONFIG_PPC64 ) &&unlikely (arch_irq_disabled_regs (regs))) +performance_monitor_exception_nmi (regs); +else +performance_monitor_exception_async (regs); }#ifdef CONFIG_PPC_ADV_DEBUG_REGS
arch/powerpc/perf/core-book3s.c +2 -33
@@ -110,10 +110,6 @@ static inline void perf_read_regs(struct pt_regs *regs) { regs->result =0 ; } -static inline int perf_intr_is_nmi (struct pt_regs *regs) -{ -return 0 ; -}static inline int siar_valid (struct pt_regs *regs) {
@@ -332,15 +328,6 @@ static inline void perf_read_regs(struct pt_regs *regs) regs->result = use_siar; } -/* -* If interrupts were soft-disabled when a PMU interrupt occurs, treat -* it as an NMI. -*/ -static inline int perf_intr_is_nmi (struct pt_regs *regs) -{ -return (regs->softe &IRQS_DISABLED ); -} -/* * On processors like P7+ that have the SIAR-Valid bit, marked instructions * must be sampled only if the SIAR-valid bit is set.
@@ -2254,7 +2241,6 @@ static void __perf_event_interrupt(struct pt_regs *regs)struct perf_event *event;unsigned long val[8 ];int found, active; -int nmi;if (cpuhw->n_limited) freeze_limited_counters(cpuhw, mfspr(SPRN_PMC5),
@@ -2262,18 +2248,6 @@ static void __perf_event_interrupt(struct pt_regs *regs)perf_read_regs (regs); -/* -* If perf interrupts hit in a local_irq_disable (soft-masked) region, -* we consider them as NMIs. This is required to prevent hash faults on -* user addresses when reading callchains. See the NMI test in -* do_hash_page. -*/ - nmi =perf_intr_is_nmi (regs); -if (nmi) -nmi_enter (); -else -irq_enter (); -/* Read all the PMCs since we'll need them a bunch of times */ for (i =0 ; i < ppmu->n_counter; ++i) val[i] =read_pmc (i +1 );
@@ -2319,8 +2293,8 @@ static void __perf_event_interrupt(struct pt_regs *regs) } } } -if (!found && !nmi &&printk_ratelimit ()) -printk (KERN_WARNING "Can't find PMC that caused IRQ\n" ); +if (unlikely (!found) && !arch_irq_disabled_regs (regs)) +printk_ratelimited (KERN_WARNING "Can't find PMC that caused IRQ\n" );/* * Reset MMCR0 to its normal value. This will set PMXE and
@@ -2330,11 +2304,6 @@ static void __perf_event_interrupt(struct pt_regs *regs)* we get back out of this interrupt. */ write_mmcr0 (cpuhw, cpuhw->mmcr.mmcr0); - -if (nmi) -nmi_exit (); -else -irq_exit (); }static void perf_event_interrupt (struct pt_regs *regs)
arch/powerpc/perf/core-fsl-emb.c +0 -25
@@ -31,19 +31,6 @@ static atomic_t num_events;/* Used to avoid races in calling reserve/release_pmc_hardware */ static DEFINE_MUTEX (pmc_reserve_mutex); -/* -* If interrupts were soft-disabled when a PMU interrupt occurs, treat -* it as an NMI. -*/ -static inline int perf_intr_is_nmi (struct pt_regs *regs) -{ -#ifdef __powerpc64__ -return (regs->softe &IRQS_DISABLED ); -#else -return 0 ; -#endif -} -static void perf_event_interrupt (struct pt_regs *regs);/*
@@ -659,13 +646,6 @@ static void perf_event_interrupt(struct pt_regs *regs)struct perf_event *event;unsigned long val;int found =0 ; -int nmi; - - nmi =perf_intr_is_nmi (regs); -if (nmi) -nmi_enter (); -else -irq_enter ();for (i =0 ; i < ppmu->n_counter; ++i) { event = cpuhw->event[i];
@@ -690,11 +670,6 @@ static void perf_event_interrupt(struct pt_regs *regs)mtmsr (mfmsr () |MSR_PMM );mtpmr (PMRN_PMGC0 ,PMGC0_PMIE |PMGC0_FCECE );isync (); - -if (nmi) -nmi_exit (); -else -irq_exit (); }void hw_perf_event_setup (int cpu)
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 252/563 powerpc/irq: Add helper to set regs->softe
In reply to Greg Kroah-HartmanFrom: Christophe Leroy <[email protected]>
[ Upstream commit fb5608fd117a8b48752d2b5a7e70847c1ed33d33 ]
regs->softe doesn't exist on PPC32.
Add irq_soft_mask_regs_set_state() helper to set regs->softe. This helper will void on PPC32.
--- arch/powerpc/include/asm/hw_irq.h | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
arch/powerpc/include/asm/hw_irq.h +9 -2
@@ -38,6 +38,8 @@#define PACA_IRQ_MUST_HARD_MASK (PACA_IRQ_EE)#endif +#endif /* CONFIG_PPC64 */ +/* * flags for paca->irq_soft_mask */
@@ -46,8 +48,6 @@#define IRQS_PMI_DISABLED 2#define IRQS_ALL_DISABLED (IRQS_DISABLED | IRQS_PMI_DISABLED) -#endif /* CONFIG_PPC64 */ -#ifndef __ASSEMBLY__extern void replay_system_reset (void );
@@ -296,6 +296,10 @@ extern void irq_set_pending_from_srr1(unsigned long srr1);extern void force_external_irq_replay (void ); +static inline void irq_soft_mask_regs_set_state (struct pt_regs *regs,unsigned long val) +{ + regs->softe = val; +}#else /* CONFIG_PPC64 */ static inline unsigned long arch_local_save_flags (void )
@@ -364,6 +368,9 @@ static inline bool arch_irq_disabled_regs(struct pt_regs *regs)static inline void may_hard_irq_enable (void ) { } +static inline void irq_soft_mask_regs_set_state (struct pt_regs *regs,unsigned long val) +{ +}#endif /* CONFIG_PPC64 */ #define ARCH_IRQ_INIT_FLAGS IRQ_NOREQUEST
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 253/563 powerpc/perf: Fix PMU callbacks to clear pending PMI before resetting an overflown PMC
In reply to Greg Kroah-HartmanFrom: Athira Rajeev <[email protected]>
[ Upstream commit 2c9ac51b850d84ee496b0a5d832ce66d411ae552 ]
Running perf fuzzer showed below in dmesg logs:
"Can't find PMC that caused IRQ"
This means a PMU exception happened, but none of the PMC's (Performance Monitor Counter) were found to be overflown. There are some corner cases that clears the PMCs after PMI gets masked. In such cases, the perf interrupt handler will not find the active PMC values that had caused the overflow and thus leads to this message while replaying.
Case 1: PMU Interrupt happens during replay of other interrupts and counter values gets cleared by PMU callbacks before replay:
During replay of interrupts like timer, __do_irq() and doorbell exception, we conditionally enable interrupts via may_hard_irq_enable(). This could potentially create a window to generate a PMI. Since irq soft mask is set to ALL_DISABLED, the PMI will get masked here. We could get IPIs run before perf interrupt is replayed and the PMU events could be deleted or stopped. This will change the PMU SPR values and resets the counters. Snippet of ftrace log showing PMU callbacks invoked in __do_irq():
<idle>-0 [051] dns. 132025441306354: __do_irq <-call_do_irq
<idle>-0 [051] dns. 132025441306430: irq_enter <-__do_irq
<idle>-0 [051] dns. 132025441306503: irq_enter_rcu <-__do_irq
<idle>-0 [051] dnH. 132025441306599: xive_get_irq <-__do_irq
<<>>
<idle>-0 [051] dnH. 132025441307770: generic_smp_call_function_single_interrupt <-smp_ipi_demux_relaxed <idle>-0 [051] dnH. 132025441307839: flush_smp_call_function_queue <-smp_ipi_demux_relaxed <idle>-0 [051] dnH. 132025441308057: _raw_spin_lock <-event_function
<idle>-0 [051] dnH. 132025441308206: power_pmu_disable <-perf_pmu_disable
<idle>-0 [051] dnH. 132025441308337: power_pmu_del <-event_sched_out
<idle>-0 [051] dnH. 132025441308407: power_pmu_read <-power_pmu_del
<idle>-0 [051] dnH. 132025441308477: read_pmc <-power_pmu_read
<idle>-0 [051] dnH. 132025441308590: isa207_disable_pmc <-power_pmu_del
<idle>-0 [051] dnH. 132025441308663: write_pmc <-power_pmu_del
<idle>-0 [051] dnH. 132025441308787: power_pmu_event_idx <-perf_event_update_userpage <idle>-0 [051] dnH. 132025441308859: rcu_read_unlock_strict <-perf_event_update_userpage <idle>-0 [051] dnH. 132025441308975: power_pmu_enable <-perf_pmu_enable
<<>>
<idle>-0 [051] dnH. 132025441311108: irq_exit <-__do_irq
<idle>-0 [051] dns. 132025441311319: performance_monitor_exception <-replay_soft_interrupts
Case 2: PMI's masked during local_* operations, example local_add(). If the local_add() operation happens within a local_irq_save(), replay of PMI will be during local_irq_restore(). Similar to case 1, this could also create a window before replay where PMU events gets deleted or stopped.
Fix it by updating the PMU callback function power_pmu_disable() to check for pending perf interrupt. If there is an overflown PMC and pending perf interrupt indicated in paca, clear the PMI bit in paca to drop that sample. Clearing of PMI bit is done in power_pmu_disable() since disable is invoked before any event gets deleted/stopped. With this fix, if there are more than one event running in the PMU, there is a chance that we clear the PMI bit for the event which is not getting deleted/stopped. The other events may still remain active. Hence to make sure we don't drop valid sample in such cases, another check is added in power_pmu_enable. This checks if there is an overflown PMC found among the active events and if so enable back the PMI bit. Two new helper functions are introduced to clear/set the PMI, ie clear_pmi_irq_pending() and set_pmi_irq_pending(). Helper function pmi_irq_pending() is introduced to give a warning if there is pending PMI bit in paca, but no PMC is overflown.
Also there are corner cases which result in performance monitor interrupts being triggered during power_pmu_disable(). This happens since PMXE bit is not cleared along with disabling of other MMCR0 bits in the pmu_disable. Such PMI's could leave the PMU running and could trigger PMI again which will set MMCR0 PMAO bit. This could lead to spurious interrupts in some corner cases. Example, a timer after power_pmu_del() which will re-enable interrupts and triggers a PMI again since PMAO bit is still set. But fails to find valid overflow since PMC was cleared in power_pmu_del(). Fix that by disabling PMXE along with disabling of other MMCR0 bits in power_pmu_disable().
We can't just replay PMI any time. Hence this approach is preferred rather than replaying PMI before resetting overflown PMC. Patch also documents core-book3s on a race condition which can trigger these PMC messages during idle path in PowerNV.
--- arch/powerpc/include/asm/hw_irq.h | 40 +++++++++++++++++++++ arch/powerpc/perf/core-book3s.c | 58 ++++++++++++++++++++++++++++++- 2 files changed, 97 insertions(+), 1 deletion(-)
arch/powerpc/include/asm/hw_irq.h +40 -0
@@ -175,6 +175,42 @@ static inline bool arch_irqs_disabled(void)return arch_irqs_disabled_flags (arch_local_save_flags ()); } +static inline void set_pmi_irq_pending (void ) +{ +/* +* Invoked from PMU callback functions to set PMI bit in the paca. +* This has to be called with irq's disabled (via hard_irq_disable()). +*/ +if (IS_ENABLED (CONFIG_PPC_IRQ_SOFT_MASK_DEBUG )) +WARN_ON_ONCE (mfmsr () &MSR_EE ); + +get_paca ()->irq_happened |=PACA_IRQ_PMI ; +} + +static inline void clear_pmi_irq_pending (void ) +{ +/* +* Invoked from PMU callback functions to clear the pending PMI bit +* in the paca. +*/ +if (IS_ENABLED (CONFIG_PPC_IRQ_SOFT_MASK_DEBUG )) +WARN_ON_ONCE (mfmsr () &MSR_EE ); + +get_paca ()->irq_happened &= ~PACA_IRQ_PMI ; +} + +static inline bool pmi_irq_pending (void ) +{ +/* +* Invoked from PMU callback functions to check if there is a pending +* PMI bit in the paca. +*/ +if (get_paca ()->irq_happened &PACA_IRQ_PMI ) +return true; + +return false; +} +#ifdef CONFIG_PPC_BOOK3S /* * To support disabling and enabling of irq with PMI, set of
@@ -368,6 +404,10 @@ static inline bool arch_irq_disabled_regs(struct pt_regs *regs)static inline void may_hard_irq_enable (void ) { } +static inline void clear_pmi_irq_pending (void ) { } +static inline void set_pmi_irq_pending (void ) { } +static inline bool pmi_irq_pending (void ) {return false; } +static inline void irq_soft_mask_regs_set_state (struct pt_regs *regs,unsigned long val) { }
arch/powerpc/perf/core-book3s.c +57 -1
98 lines not on this page · raw message
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 254/563 powerpc/32s: Fix shift-out-of-bounds in KASAN init
In reply to Greg Kroah-HartmanFrom: Christophe Leroy <[email protected]>
[ Upstream commit af11dee4361b3519981fa04d014873f9d9edd6ac ]
================================================================================
UBSAN: shift-out-of-bounds in arch/powerpc/mm/kasan/book3s_32.c:22:23 shift exponent -1 is negative CPU: 0 PID: 0 Comm: swapper Not tainted 5.15.5-gentoo-PowerMacG4 #9 Call Trace: [c214be60] [c0ba0048] dump_stack_lvl+0x80/0xb0 (unreliable) [c214be80] [c0b99288] ubsan_epilogue+0x10/0x5c [c214be90] [c0b98fe0] __ubsan_handle_shift_out_of_bounds+0x94/0x138 [c214bf00] [c1c0f010] kasan_init_region+0xd8/0x26c [c214bf30] [c1c0ed84] kasan_init+0xc0/0x198 [c214bf70] [c1c08024] setup_arch+0x18/0x54c [c214bfc0] [c1c037f0] start_kernel+0x90/0x33c
[c214bff0] [00003610] 0x3610
================================================================================
This happens when the directly mapped memory is a power of 2.
Fix it by checking the shift and set the result to 0 when shift is -1
--- arch/powerpc/mm/kasan/book3s_32.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
arch/powerpc/mm/kasan/book3s_32.c +2 -1
@@ -19,7 +19,8 @@ int __init kasan_init_region(void *start, size_t size) block =memblock_alloc (k_size, k_size_base);if (block && k_size_base >=SZ_128K && k_start ==ALIGN (k_start, k_size_base)) { -int k_size_more =1 << (ffs (k_size - k_size_base) -1 ); +int shift =ffs (k_size - k_size_base); +int k_size_more = shift ?1 << (shift -1 ) :0 ;setbat (-1 , k_start,__pa (block), k_size_base,PAGE_KERNEL );if (k_size_more >=SZ_128K )
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 255/563 clocksource: Reduce clocksource-skew threshold
In reply to Greg Kroah-HartmanFrom: Paul E. McKenney <[email protected]>
[ Upstream commit 2e27e793e280ff12cb5c202a1214c08b0d3a0f26 ]
Currently, WATCHDOG_THRESHOLD is set to detect a 62.5-millisecond skew in a 500-millisecond WATCHDOG_INTERVAL. This requires that clocks be skewed by more than 12.5% in order to be marked unstable. Except that a clock that is skewed by that much is probably destroying unsuspecting software right and left. And given that there are now checks for false-positive skews due to delays between reading the two clocks, it should be possible to greatly decrease WATCHDOG_THRESHOLD, at least for fine-grained clocks such as TSC.
Therefore, add a new uncertainty_margin field to the clocksource structure that contains the maximum uncertainty in nanoseconds for the corresponding clock. This field may be initialized manually, as it is for clocksource_tsc_early and clocksource_jiffies, which is copied to refined_jiffies. If the field is not initialized manually, it will be computed at clock-registry time as the period of the clock in question based on the scale and freq parameters to __clocksource_update_freq_scale() function. If either of those two parameters are zero, the tens-of-milliseconds WATCHDOG_THRESHOLD is used as a cowardly alternative to dividing by zero. No matter how the uncertainty_margin field is calculated, it is bounded below by twice WATCHDOG_MAX_SKEW, that is, by 100 microseconds.
Note that manually initialized uncertainty_margin fields are not adjusted, but there is a WARN_ON_ONCE() that triggers if any such field is less than twice WATCHDOG_MAX_SKEW. This WARN_ON_ONCE() is intended to discourage production use of the one-nanosecond uncertainty_margin values that are used to test the clock-skew code itself.
The actual clock-skew check uses the sum of the uncertainty_margin fields of the two clocksource structures being compared. Integer overflow is avoided because the largest computed value of the uncertainty_margin fields is one billion (10^9), and double that value fits into an unsigned int. However, if someone manually specifies (say) UINT_MAX, they will get what they deserve.
Note that the refined_jiffies uncertainty_margin field is initialized to TICK_NSEC, which means that skew checks involving this clocksource will be sufficently forgiving. In a similar vein, the clocksource_tsc_early uncertainty_margin field is initialized to 32*NSEC_PER_MSEC, which replicates the current behavior and allows custom setting if needed in order to address the rare skews detected for this clocksource in current mainline.
--- arch/x86/kernel/tsc.c | 1 + include/linux/clocksource.h | 3 +++ kernel/time/clocksource.c | 48 +++++++++++++++++++++++++++++-------- kernel/time/jiffies.c | 15 ++++++------ 4 files changed, 50 insertions(+), 17 deletions(-)
arch/x86/kernel/tsc.c +1 -0
@@ -1127,6 +1127,7 @@ static int tsc_cs_enable(struct clocksource *cs)static struct clocksource clocksource_tsc_early = { .name ="tsc-early" , .rating =299 , + .uncertainty_margin =32 *NSEC_PER_MSEC , .read = read_tsc, .mask =CLOCKSOURCE_MASK (64 ), .flags = CLOCK_SOURCE_IS_CONTINUOUS |
include/linux/clocksource.h +3 -0
@@ -42,6 +42,8 @@ struct module;* @shift: Cycle to nanosecond divisor (power of two) * @max_idle_ns: Maximum idle time permitted by the clocksource (nsecs) * @maxadj: Maximum adjustment value to mult (~11%) +* @uncertainty_margin: Maximum uncertainty in nanoseconds per half second. +* Zero says to use default WATCHDOG_THRESHOLD. * @archdata: Optional arch-specific data * @max_cycles: Maximum safe cycle value which won't overflow on * multiplication
@@ -93,6 +95,7 @@ struct clocksource {u32 shift;u64 max_idle_ns;u32 maxadj; +u32 uncertainty_margin;#ifdef CONFIG_ARCH_CLOCKSOURCE_DATA struct arch_clocksource_data archdata;#endif
kernel/time/clocksource.c +38 -10
80 lines not on this page · raw message
kernel/time/jiffies.c +8 -7
@@ -49,13 +49,14 @@ static u64 jiffies_read(struct clocksource *cs)* for "tick-less" systems. */ static struct clocksource clocksource_jiffies = { - .name ="jiffies" , - .rating =1 ,/* lowest valid rating*/ - .read = jiffies_read, - .mask =CLOCKSOURCE_MASK (32 ), - .mult =TICK_NSEC <<JIFFIES_SHIFT ,/* details above */ - .shift =JIFFIES_SHIFT , - .max_cycles =10 , + .name ="jiffies" , + .rating =1 ,/* lowest valid rating*/ + .uncertainty_margin =32 *NSEC_PER_MSEC , + .read = jiffies_read, + .mask =CLOCKSOURCE_MASK (32 ), + .mult =TICK_NSEC <<JIFFIES_SHIFT ,/* details above */ + .shift =JIFFIES_SHIFT , + .max_cycles =10 , };__cacheline_aligned_in_smp DEFINE_RAW_SPINLOCK (jiffies_lock );
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 256/563 clocksource: Avoid accidental unstable marking of clocksources
In reply to Greg Kroah-HartmanFrom: Waiman Long <[email protected]>
[ Upstream commit c86ff8c55b8ae68837b2fa59dc0c203907e9a15f ]
Since commit db3a34e17433 ("clocksource: Retry clock read if long delays detected") and commit 2e27e793e280 ("clocksource: Reduce clocksource-skew threshold"), it is found that tsc clocksource fallback to hpet can sometimes happen on both Intel and AMD systems especially when they are running stressful benchmarking workloads. Of the 23 systems tested with a v5.14 kernel, 10 of them have switched to hpet clock source during the test run.
The result of falling back to hpet is a drastic reduction of performance when running benchmarks. For example, the fio performance tests can drop up to 70% whereas the iperf3 performance can drop up to 80%.
4 hpet fallbacks happened during bootup. They were:
[ 8.749399] clocksource: timekeeping watchdog on CPU13: hpet read-back delay of 263750ns, attempt 4, marking unstable [ 12.044610] clocksource: timekeeping watchdog on CPU19: hpet read-back delay of 186166ns, attempt 4, marking unstable [ 17.336941] clocksource: timekeeping watchdog on CPU28: hpet read-back delay of 182291ns, attempt 4, marking unstable [ 17.518565] clocksource: timekeeping watchdog on CPU34: hpet read-back delay of 252196ns, attempt 4, marking unstable
Other fallbacks happen when the systems were running stressful benchmarks. For example:
[ 2685.867873] clocksource: timekeeping watchdog on CPU117: hpet read-back delay of 57269ns, attempt 4, marking unstable [46215.471228] clocksource: timekeeping watchdog on CPU8: hpet read-back delay of 61460ns, attempt 4, marking unstable
Commit 2e27e793e280 ("clocksource: Reduce clocksource-skew threshold"), changed the skew margin from 100us to 50us. I think this is too small and can easily be exceeded when running some stressful workloads on a thermally stressed system. So it is switched back to 100us.
Even a maximum skew margin of 100us may be too small in for some systems when booting up especially if those systems are under thermal stress. To eliminate the case that the large skew is due to the system being too busy slowing down the reading of both the watchdog and the clocksource, an extra consecutive read of watchdog clock is being done to check this.
The consecutive watchdog read delay is compared against WATCHDOG_MAX_SKEW/2. If the delay exceeds the limit, we assume that the system is just too busy. A warning will be printed to the console and the clock skew check is skipped for this round.
--- kernel/time/clocksource.c | 50 ++++++++++++++++++++++++++++++++------- 1 file changed, 41 insertions(+), 9 deletions(-)
kernel/time/clocksource.c +41 -9
@@ -105,7 +105,7 @@ static u64 suspend_start;* This delay could be due to SMIs, NMIs, or to VCPU preemptions. Used as * a lower bound for cs->uncertainty_margin values when registering clocks. */ -#define WATCHDOG_MAX_SKEW (50 * NSEC_PER_USEC) +#define WATCHDOG_MAX_SKEW (100 * NSEC_PER_USEC)#ifdef CONFIG_CLOCKSOURCE_WATCHDOG static void clocksource_watchdog_work (struct work_struct *work);
@@ -200,17 +200,24 @@ void clocksource_mark_unstable(struct clocksource *cs)static ulong max_cswd_read_retries =3 ;module_param (max_cswd_read_retries, ulong,0644 ); -static bool cs_watchdog_read (struct clocksource *cs,u64 *csnow,u64 *wdnow) +enum wd_read_status { +WD_READ_SUCCESS , +WD_READ_UNSTABLE , +WD_READ_SKIP +}; + +static enum wd_read_status cs_watchdog_read (struct clocksource *cs,u64 *csnow,u64 *wdnow) {unsigned int nretries; -u64 wd_end, wd_delta; -int64_t wd_delay; +u64 wd_end, wd_end2, wd_delta; +int64_t wd_delay, wd_seq_delay;for (nretries =0 ; nretries <= max_cswd_read_retries; nretries++) {local_irq_disable (); *wdnow = watchdog->read (watchdog); *csnow = cs->read (cs); wd_end = watchdog->read (watchdog); + wd_end2 = watchdog->read (watchdog);local_irq_enable (); wd_delta =clocksource_delta (wd_end, *wdnow, watchdog->mask);
@@ -221,13 +228,34 @@ static bool cs_watchdog_read(struct clocksource *cs, u64 *csnow, u64 *wdnow)pr_warn ("timekeeping watchdog on CPU%d: %s retried %d times before success\n" ,smp_processor_id (), watchdog->name, nretries); } -return true; +return WD_READ_SUCCESS ; } + +/* +* Now compute delay in consecutive watchdog read to see if +* there is too much external interferences that cause +* significant delay in reading both clocksource and watchdog. +* +* If consecutive WD read-back delay > WATCHDOG_MAX_SKEW/2, +* report system busy, reinit the watchdog and skip the current +* watchdog test. +*/ + wd_delta =clocksource_delta (wd_end2, wd_end, watchdog->mask); + wd_seq_delay =clocksource_cyc2ns (wd_delta, watchdog->mult, watchdog->shift); +if (wd_seq_delay >WATCHDOG_MAX_SKEW /2 ) + goto skip_test; }pr_warn ("timekeeping watchdog on CPU%d: %s read-back delay of %lldns, attempt %d, marking unstable\n" ,smp_processor_id (), watchdog->name, wd_delay, nretries); -return false; +return WD_READ_UNSTABLE ; + +skip_test: +pr_info ("timekeeping watchdog on CPU%d: %s wd-wd read-back delay of %lldns\n" , +smp_processor_id (), watchdog->name, wd_seq_delay); +pr_info ("wd-%s-wd read-back delay of %lldns, clock-skew test skipped!\n" , + cs->name, wd_delay); +return WD_READ_SKIP ; }static u64 csnow_mid;
@@ -290,6 +318,7 @@ static void clocksource_watchdog(struct timer_list *unused)int next_cpu, reset_pending;int64_t wd_nsec, cs_nsec;struct clocksource *cs; +enum wd_read_status read_ret;u32 md;spin_lock (&watchdog_lock);
@@ -307,9 +336,12 @@ static void clocksource_watchdog(struct timer_list *unused)continue ; } -if (!cs_watchdog_read (cs, &csnow, &wdnow)) { -/* Clock readout unreliable, so give it up. */ -__clocksource_unstable (cs); + read_ret =cs_watchdog_read (cs, &csnow, &wdnow); + +if (read_ret !=WD_READ_SUCCESS ) { +if (read_ret ==WD_READ_UNSTABLE ) +/* Clock readout unreliable, so give it up. */ +__clocksource_unstable (cs);continue ; }
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 257/563 ALSA: oss: fix compile error when OSS_DEBUG is enabled
In reply to Greg Kroah-HartmanFrom: Bixuan Cui <[email protected]>
[ Upstream commit 8e7daf318d97f25e18b2fc7eb5909e34cd903575 ]
Fix compile error when OSS_DEBUG is enabled:
sound/core/oss/pcm_oss.c: In function 'snd_pcm_oss_set_trigger':
sound/core/oss/pcm_oss.c:2055:10: error: 'substream' undeclared (first
use in this function); did you mean 'csubstream'?
pcm_dbg(substream->pcm, "pcm_oss: trigger = 0x%x\n", trigger);
^--- sound/core/oss/pcm_oss.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/core/oss/pcm_oss.c +1 -1
@@ -2056,7 +2056,7 @@ static int snd_pcm_oss_set_trigger(struct snd_pcm_oss_file *pcm_oss_file, int trint err, cmd;#ifdef OSS_DEBUG -pcm_dbg (substream->pcm,"pcm_oss: trigger = 0x%x\n" , trigger); +pr_debug ("pcm_oss: trigger = 0x%x\n" , trigger);#endif psubstream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK ];
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 258/563 ALSA: usb-audio: Drop superfluous 0 in Presonus Studio 1810cs ID
In reply to Greg Kroah-HartmanFrom: Takashi Iwai <[email protected]>
[ Upstream commit 1e583aef12aa74afd37c1418255cc4b74e023236 ]
The vendor ID of Presonus Studio 1810c had a superfluous '0' in its USB ID. Drop it.
--- sound/usb/format.c | 2 +- sound/usb/mixer_quirks.c | 2 +- sound/usb/quirks.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-)
sound/usb/format.c +1 -1
@@ -365,7 +365,7 @@ static int parse_uac2_sample_rate_range(struct snd_usb_audio *chip,for (rate = min; rate <= max; rate += res) {/* Filter out invalid rates on Presonus Studio 1810c */ -if (chip->usb_id ==USB_ID (0x0194f ,0x010c ) && +if (chip->usb_id ==USB_ID (0x194f ,0x010c ) && !s1810c_valid_sample_rate (fp, rate)) goto skip_rate;
sound/usb/mixer_quirks.c +1 -1
@@ -3033,7 +3033,7 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) err =snd_rme_controls_create (mixer);break ; -case USB_ID (0x0194f ,0x010c ):/* Presonus Studio 1810c */ +case USB_ID (0x194f ,0x010c ):/* Presonus Studio 1810c */ err =snd_sc1810_init_mixer (mixer);break ;case USB_ID (0x2a39 ,0x3fb0 ):/* RME Babyface Pro FS */
sound/usb/quirks.c +1 -1
@@ -1310,7 +1310,7 @@ int snd_usb_apply_interface_quirk(struct snd_usb_audio *chip,if (chip->usb_id ==USB_ID (0x0763 ,0x2012 ))return fasttrackpro_skip_setting_quirk (chip, iface, altno);/* presonus studio 1810c: skip altsets incompatible with device_setup */ -if (chip->usb_id ==USB_ID (0x0194f ,0x010c )) +if (chip->usb_id ==USB_ID (0x194f ,0x010c ))return s1810c_skip_setting_quirk (chip, iface, altno);
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 259/563 char/mwave: Adjust io port register size
In reply to Greg Kroah-HartmanFrom: Kees Cook <[email protected]>
[ Upstream commit f5912cc19acd7c24b2dbf65a6340bf194244f085 ]
Using MKWORD() on a byte-sized variable results in OOB read. Expand the size of the reserved area so both MKWORD and MKBYTE continue to work without overflow. Silences this warning on a -Warray-bounds build:
drivers/char/mwave/3780i.h:346:22: error: array subscript 'short unsigned int[0]' is partly outside array bounds of 'DSP_ISA_SLAVE_CONTROL[1]' [-Werror=array-bounds]
346 | #define MKWORD(var) (*((unsigned short *)(&var)))
| ~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/char/mwave/3780i.h:356:40: note: in definition of macro 'OutWordDsp'
356 | #define OutWordDsp(index,value) outw(value,usDspBaseIO+index)
| ^~~~~drivers/char/mwave/3780i.c:373:41: note: in expansion of macro 'MKWORD'
373 | OutWordDsp(DSP_IsaSlaveControl, MKWORD(rSlaveControl));
| ^~~~~~drivers/char/mwave/3780i.c:358:31: note: while referencing 'rSlaveControl'
358 | DSP_ISA_SLAVE_CONTROL rSlaveControl;
| ^~~~~~~~~~~~~--- drivers/char/mwave/3780i.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/char/mwave/3780i.h +1 -1
@@ -68,7 +68,7 @@ typedef struct { unsigned char ClockControl:1; /* RW: Clock control: 0=normal, 1=stop 3780i clocks */ unsigned char SoftReset:1; /* RW: Soft reset 0=normal, 1=soft reset active */ unsigned char ConfigMode:1; /* RW: Configuration mode, 0=normal, 1=config mode */ - unsigned char Reserved:5; /* 0: Reserved */ + unsigned short Reserved:13; /* 0: Reserved */ }DSP_ISA_SLAVE_CONTROL ;
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 260/563 binder: fix handling of error during copy
In reply to Greg Kroah-HartmanFrom: Todd Kjos <[email protected]>
[ Upstream commit fe6b1869243f23a485a106c214bcfdc7aa0ed593 ]
If a memory copy function fails to copy the whole buffer, a positive integar with the remaining bytes is returned. In binder_translate_fd_array() this can result in an fd being skipped due to the failed copy, but the loop continues processing fds since the early return condition expects a negative integer on error.
Fix by returning "ret > 0 ? -EINVAL : ret" to handle this case.
--- drivers/android/binder.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/android/binder.c +2 -2
@@ -2657,8 +2657,8 @@ static int binder_translate_fd_array(struct binder_fd_array_object *fda,if (!ret) ret =binder_translate_fd (fd, offset, t, thread, in_reply_to); -if (ret <0 ) -return ret; +if (ret) +return ret >0 ? -EINVAL : ret; }return 0 ; }
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 261/563 openrisc: Add clone3 ABI wrapper
In reply to Greg Kroah-HartmanFrom: Stafford Horne <[email protected]>
[ Upstream commit 433fe39f674d58bc7a3e8254a5d2ffc290b7e04e ]
Like fork and clone the clone3 syscall needs a wrapper to save callee saved registers, which is required by the OpenRISC ABI. This came up after auditing code following a discussion with Rob Landley and Arnd Bergmann [0].
Tested with the clone3 kselftests and there were no issues.
[0] https://lore.kernel.org/all/[email protected]/T/#m9c0cdb2703813b9df4da04cf6b30de1f1aa89944
--- arch/openrisc/include/asm/syscalls.h | 2 ++ arch/openrisc/kernel/entry.S | 5 +++++ 2 files changed, 7 insertions(+)
arch/openrisc/include/asm/syscalls.h +2 -0
@@ -22,9 +22,11 @@ asmlinkage long sys_or1k_atomic(unsigned long type, unsigned long *v1,asmlinkage long __sys_clone (unsigned long clone_flags,unsigned long newsp,void __user *parent_tid,void __user *child_tid,int tls); +asmlinkage long __sys_clone3 (struct clone_args __user *uargs,size_t size);asmlinkage long __sys_fork (void );#define sys_clone __sys_clone +#define sys_clone3 __sys_clone3#define sys_fork __sys_fork#endif /* __ASM_OPENRISC_SYSCALLS_H */
arch/openrisc/kernel/entry.S +5 -0
@@ -1170,6 +1170,11 @@ ENTRY(__sys_clone) l.j _fork_save_extra_regs_and_call l.nop +ENTRY(__sys_clone3) + l.movhi r29,hi(sys_clone3) + l.j _fork_save_extra_regs_and_call + l.ori r29,r29,lo(sys_clone3) + ENTRY(__sys_fork) l.movhi r29,hi(sys_fork) l.ori r29,r29,lo(sys_fork)
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 262/563 uio: uio_dmem_genirq: Catch the Exception
In reply to Greg Kroah-HartmanFrom: Jiasheng Jiang <[email protected]>
[ Upstream commit eec91694f927d1026974444eb6a3adccd4f1cbc2 ]
The return value of dma_set_coherent_mask() is not always 0. To catch the exception in case that dma is not support the mask.
--- drivers/uio/uio_dmem_genirq.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/uio/uio_dmem_genirq.c +5 -1
@@ -183,7 +183,11 @@ static int uio_dmem_genirq_probe(struct platform_device *pdev) goto bad0; } -dma_set_coherent_mask (&pdev->dev,DMA_BIT_MASK (32 )); + ret =dma_set_coherent_mask (&pdev->dev,DMA_BIT_MASK (32 )); +if (ret) { +dev_err (&pdev->dev,"DMA enable failed\n" ); +return ret; + } priv->uioinfo = uioinfo;spin_lock_init (&priv->lock);
Signature · 1 line
2.34.1
Re: [PATCH 5.10 262/563] uio: uio_dmem_genirq: Catch the Exception
Hi!
Quoted 12 lines
From: Jiasheng Jiang <[email protected]>
[ Upstream commit
eec91694f927d1026974444eb6a3adccd4f1cbc2]The return value of
dma_set_coherent_mask()is not always 0. To catch the exception in case that dma is not support the mask.Fixes 0a0c3b5a24bd ("Add new uio device for dynamic memory allocation")+++
b/drivers/uio/uio_dmem_genirq.c
Review static int uio_dmem_genirq_probe(struct platform_device *pdev) · line 190
Quoted 9 lines
(quoted diff) +5
-1@@ -183,7 +183,11 @@ static int uio_dmem_genirq_probe(struct platform_device *pdev) goto bad0; } - dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); + ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); + if (ret) { + dev_err(&pdev->dev, "DMA enable failed\n"); + return ret; + }
Handing errors is good, but you may not directly return here as it would leak the resources. Something like this?
Best regards,
Pavel
drivers/uio/uio_dmem_genirq.c +1 -1
@@ -186,7 +186,7 @@ static int uio_dmem_genirq_probe(struct platform_device *pdev) ret =dma_set_coherent_mask (&pdev->dev,DMA_BIT_MASK (32 ));if (ret) {dev_err (&pdev->dev,"DMA enable failed\n" ); -return ret; + goto bad0; } priv->uioinfo = uioinfo;
Signature · 2 lines
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Greg Kroah-Hartman
maintainerRe: [PATCH 5.10 262/563] uio: uio_dmem_genirq: Catch the Exception
Quoted 51 lines · Pavel Machek
Hi!
Quoted 12 lines
From: Jiasheng Jiang <[email protected]>
[ Upstream commit
eec91694f927d1026974444eb6a3adccd4f1cbc2]The return value of
dma_set_coherent_mask()is not always 0. To catch the exception in case that dma is not support the mask.Fixes 0a0c3b5a24bd ("Add new uio device for dynamic memory allocation")+++
b/drivers/uio/uio_dmem_genirq.cReview static int uio_dmem_genirq_probe(struct platform_device *pdev) · line 190
Quoted 9 lines
(quoted diff) +5
-1@@ -183,7 +183,11 @@ static int uio_dmem_genirq_probe(struct platform_device *pdev) goto bad0; } - dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); + ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); + if (ret) { + dev_err(&pdev->dev, "DMA enable failed\n"); + return ret; + }Handing errors is good, but you may not directly return here as it would leak the resources. Something like this?
Signed-off-by Pavel Machek <[email protected]>Best regards,
Paveldrivers/uio/uio_dmem_genirq.c +1
-1@@ -186,7 +186,7 @@ static int uio_dmem_genirq_probe(struct platform_device *pdev) ret =dma_set_coherent_mask (&pdev->dev,DMA_BIT_MASK (32 ));if (ret) {dev_err (&pdev->dev,"DMA enable failed\n" ); -return ret; + goto bad0; } priv->uioinfo = uioinfo;Signature · 3 lines
-- DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Yeah, this commit should not be backported, I'll go drop it from everywhere. But the original commit in Linus's tree is fine as the error handling is not like this anymore.
thanks,
greg k-h
Greg Kroah-Hartman
maintainerPATCH 263/563 iommu/io-pgtable-arm: Fix table descriptor paddr formatting
In reply to Greg Kroah-HartmanFrom: Hector Martin <[email protected]>
[ Upstream commit 9abe2ac834851a7d0b0756e295cf7a292c45ca53 ]
Table descriptors were being installed without properly formatting the address using paddr_to_iopte, which does not match up with the iopte_deref in __arm_lpae_map. This is incorrect for the LPAE pte format, as it does not handle the high bits properly.
This was found on Apple T6000 DARTs, which require a new pte format (different shift); adding support for that to paddr_to_iopte/iopte_to_paddr caused it to break badly, as even <48-bit addresses would end up incorrect in that case.
--- drivers/iommu/io-pgtable-arm.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
drivers/iommu/io-pgtable-arm.c +5 -4
@@ -302,11 +302,12 @@ static int arm_lpae_init_pte(struct arm_lpae_io_pgtable *data,static arm_lpae_iopte arm_lpae_install_table (arm_lpae_iopte *table,arm_lpae_iopte *ptep,arm_lpae_iopte curr, -struct io_pgtable_cfg *cfg) +struct arm_lpae_io_pgtable *data) {arm_lpae_iopte old, new; +struct io_pgtable_cfg *cfg = &data->iop.cfg; - new =__pa (table) |ARM_LPAE_PTE_TYPE_TABLE ; + new =paddr_to_iopte (__pa (table), data) |ARM_LPAE_PTE_TYPE_TABLE ;if (cfg->quirks &IO_PGTABLE_QUIRK_ARM_NS ) new |=ARM_LPAE_PTE_NSTABLE ;
@@ -357,7 +358,7 @@ static int __arm_lpae_map(struct arm_lpae_io_pgtable *data, unsigned long iova,if (!cptep)return -ENOMEM ; - pte =arm_lpae_install_table (cptep, ptep,0 , cfg); + pte =arm_lpae_install_table (cptep, ptep,0 , data);if (pte)__arm_lpae_free_pages (cptep, tblsz, cfg); }else if (!cfg->coherent_walk && !(pte &ARM_LPAE_PTE_SW_SYNC )) {
@@ -546,7 +547,7 @@ static size_t arm_lpae_split_blk_unmap(struct arm_lpae_io_pgtable *data,__arm_lpae_init_pte (data, blk_paddr, pte, lvl, &tablep[i]); } - pte =arm_lpae_install_table (tablep, ptep, blk_pte, cfg); + pte =arm_lpae_install_table (tablep, ptep, blk_pte, data);if (pte != blk_pte) {__arm_lpae_free_pages (tablep, tablesz, cfg);/*
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 264/563 scsi: ufs: Fix race conditions related to driver data
In reply to Greg Kroah-HartmanFrom: Bart Van Assche <[email protected]>
[ Upstream commit 21ad0e49085deb22c094f91f9da57319a97188e4 ]
The driver data pointer must be set before any callbacks are registered that use that pointer. Hence move the initialization of that pointer from after the ufshcd_init() call to inside ufshcd_init().
--- drivers/scsi/ufs/tc-dwc-g210-pci.c | 1 - drivers/scsi/ufs/ufshcd-pci.c | 2 -- drivers/scsi/ufs/ufshcd-pltfrm.c | 2 -- drivers/scsi/ufs/ufshcd.c | 7 +++++++ 4 files changed, 7 insertions(+), 5 deletions(-)
drivers/scsi/ufs/tc-dwc-g210-pci.c +0 -1
@@ -135,7 +135,6 @@ tc_dwc_g210_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)return err; } -pci_set_drvdata (pdev, hba);pm_runtime_put_noidle (&pdev->dev);pm_runtime_allow (&pdev->dev);
drivers/scsi/ufs/ufshcd-pci.c +0 -2
@@ -347,8 +347,6 @@ ufshcd_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)return err; } -pci_set_drvdata (pdev, hba); - hba->vops = (struct ufs_hba_variant_ops *)id->driver_data; err =ufshcd_init (hba, mmio_base, pdev->irq);
drivers/scsi/ufs/ufshcd-pltfrm.c +0 -2
@@ -412,8 +412,6 @@ int ufshcd_pltfrm_init(struct platform_device *pdev, goto dealloc_host; } -platform_set_drvdata (pdev, hba); -pm_runtime_set_active (&pdev->dev);pm_runtime_enable (&pdev->dev);
drivers/scsi/ufs/ufshcd.c +7 -0
@@ -9085,6 +9085,13 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)struct device *dev = hba->dev;char eh_wq_name[sizeof ("ufs_eh_wq_00" )]; +/* +* dev_set_drvdata() must be called before any callbacks are registered +* that use dev_get_drvdata() (frequency scaling, clock scaling, hwmon, +* sysfs). +*/ +dev_set_drvdata (dev, hba); +if (!mmio_base) {dev_err (hba->dev,"Invalid memory reference for mmio_base is NULL\n" );
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 265/563 RDMA/qedr: Fix reporting max_{send/recv}_wr attrs
In reply to Greg Kroah-HartmanFrom: Kamal Heib <[email protected]>
[ Upstream commit b1a4da64bfc189510e08df1ccb1c589e667dc7a3 ]
Fix the wrongly reported max_send_wr and max_recv_wr attributes for user QP by making sure to save their valuse on QP creation, so when query QP is called the attributes will be reported correctly.
--- drivers/infiniband/hw/qedr/verbs.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/infiniband/hw/qedr/verbs.c +2 -0
@@ -1918,6 +1918,7 @@ static int qedr_create_user_qp(struct qedr_dev *dev,/* db offset was calculated in copy_qp_uresp, now set in the user q */ if (qedr_qp_has_sq (qp)) { qp->usq.db_addr = ctx->dpi_addr + uresp.sq_db_offset; + qp->sq.max_wr = attrs->cap.max_send_wr; rc = qedr_db_recovery_add(dev, qp->usq.db_addr, &qp->usq.db_rec_data->db_data, DB_REC_WIDTH_32B,
@@ -1928,6 +1929,7 @@ static int qedr_create_user_qp(struct qedr_dev *dev,if (qedr_qp_has_rq (qp)) { qp->urq.db_addr = ctx->dpi_addr + uresp.rq_db_offset; + qp->rq.max_wr = attrs->cap.max_recv_wr; rc = qedr_db_recovery_add(dev, qp->urq.db_addr, &qp->urq.db_rec_data->db_data, DB_REC_WIDTH_32B,
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 266/563 PCI/MSI: Fix pci_irq_vector()/pci_irq_get_affinity()
In reply to Greg Kroah-HartmanFrom: Thomas Gleixner <[email protected]>
[ Upstream commit 29bbc35e29d9b6347780dcacde2deb4b39344167 ]
pci_irq_vector() and pci_irq_get_affinity() use the list position to find the MSI-X descriptor at a given index. That's correct for the normal case where the entry number is the same as the list position.
But it's wrong for cases where MSI-X was allocated with an entries array describing sparse entry numbers into the hardware message descriptor table. That's inconsistent at best.
Make it always check the entry number because that's what the zero base index really means. This change won't break existing users which use a sparse entries array for allocation because these users retrieve the Linux interrupt number from the entries array after allocation and none of them uses pci_irq_vector() or pci_irq_get_affinity().
--- drivers/pci/msi.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-)
drivers/pci/msi.c +18 -8
@@ -1291,19 +1291,24 @@ EXPORT_SYMBOL(pci_free_irq_vectors);/** * pci_irq_vector - return Linux IRQ number of a device vector -* @dev: PCI device to operate on -* @nr: device-relative interrupt vector index (0-based). +* @dev: PCI device to operate on +* @nr: Interrupt vector index (0-based) +* +* @nr has the following meanings depending on the interrupt mode: +* MSI-X: The index in the MSI-X vector table +* MSI: The index of the enabled MSI vectors +* INTx: Must be 0 +* +* Return: The Linux interrupt number or -EINVAl if @nr is out of range. */ int pci_irq_vector (struct pci_dev *dev,unsigned int nr) {if (dev->msix_enabled) {struct msi_desc *entry; -int i =0 ;for_each_pci_msi_entry (entry, dev) { -if (i == nr) +if (entry->msi_attrib.entry_nr == nr)return entry->irq; - i++; }WARN_ON_ONCE (1 );return -EINVAL ;
@@ -1327,17 +1332,22 @@ EXPORT_SYMBOL(pci_irq_vector);* pci_irq_get_affinity - return the affinity of a particular MSI vector * @dev: PCI device to operate on * @nr: device-relative interrupt vector index (0-based). +* +* @nr has the following meanings depending on the interrupt mode: +* MSI-X: The index in the MSI-X vector table +* MSI: The index of the enabled MSI vectors +* INTx: Must be 0 +* +* Return: A cpumask pointer or NULL if @nr is out of range */ const struct cpumask *pci_irq_get_affinity (struct pci_dev *dev,int nr) {if (dev->msix_enabled) {struct msi_desc *entry; -int i =0 ;for_each_pci_msi_entry (entry, dev) { -if (i == nr) +if (entry->msi_attrib.entry_nr == nr)return &entry->affinity->mask; - i++; }WARN_ON_ONCE (1 );return NULL ;
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 267/563 powerpc/powermac: Add additional missing lockdep_register_key()
In reply to Greg Kroah-HartmanFrom: Christophe Leroy <[email protected]>
[ Upstream commit b149d5d45ac9171ed699a256f026c8ebef901112 ]
Commit df1f679d19ed ("powerpc/powermac: Add missing lockdep_register_key()") fixed a problem that was causing a WARNING.
There are two other places in the same file with the same problem originating from commit 9e607f72748d ("i2c_powermac: shut up lockdep warning").
Add missing lockdep_register_key()
Depends-on: df1f679d19ed ("powerpc/powermac: Add missing lockdep_register_key()")
--- arch/powerpc/platforms/powermac/low_i2c.c | 2 ++ 1 file changed, 2 insertions(+)
arch/powerpc/platforms/powermac/low_i2c.c +2 -0
@@ -810,6 +810,7 @@ static void __init pmu_i2c_probe(void) bus->hostdata = bus +1 ; bus->xfer = pmu_i2c_xfer;mutex_init (&bus->mutex); +lockdep_register_key (&bus->lock_key);lockdep_set_class (&bus->mutex, &bus->lock_key); bus->flags = pmac_i2c_multibus;list_add (&bus->link, &pmac_i2c_busses);
@@ -933,6 +934,7 @@ static void __init smu_i2c_probe(void) bus->hostdata = bus +1 ; bus->xfer = smu_i2c_xfer;mutex_init (&bus->mutex); +lockdep_register_key (&bus->lock_key);lockdep_set_class (&bus->mutex, &bus->lock_key); bus->flags =0 ;list_add (&bus->link, &pmac_i2c_busses);
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 268/563 RDMA/core: Let ib_find_gid() continue search even after empty entry
In reply to Greg Kroah-HartmanFrom: Avihai Horon <[email protected]>
[ Upstream commit 483d805191a23191f8294bbf9b4e94836f5d92e4 ]
Currently, ib_find_gid() will stop searching after encountering the first empty GID table entry. This behavior is wrong since neither IB nor RoCE spec enforce tightly packed GID tables.
For example, when a valid GID entry exists at index N, and if a GID entry is empty at index N-1, ib_find_gid() will fail to find the valid entry.
Fix it by making ib_find_gid() continue searching even after encountering missing entries.
--- drivers/infiniband/core/device.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/infiniband/core/device.c +2 -1
@@ -2411,7 +2411,8 @@ int ib_find_gid(struct ib_device *device, union ib_gid *gid, ++i) { ret =rdma_query_gid (device, port, i, &tmp_gid);if (ret) -return ret; +continue ; +if (!memcmp (&tmp_gid, gid,sizeof *gid)) { *port_num = port;if (index)
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 269/563 RDMA/cma: Let cma_resolve_ib_dev() continue search even after empty entry
In reply to Greg Kroah-HartmanFrom: Avihai Horon <[email protected]>
[ Upstream commit 20679094a0161c94faf77e373fa3f7428a8e14bd ]
Currently, when cma_resolve_ib_dev() searches for a matching GID it will stop searching after encountering the first empty GID table entry. This behavior is wrong since neither IB nor RoCE spec enforce tightly packed GID tables.
For example, when the matching valid GID entry exists at index N, and if a GID entry is empty at index N-1, cma_resolve_ib_dev() will fail to find the matching valid entry.
Fix it by making cma_resolve_ib_dev() continue searching even after encountering missing entries.
--- drivers/infiniband/core/cma.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
drivers/infiniband/core/cma.c +9 -3
@@ -775,6 +775,7 @@ static int cma_resolve_ib_dev(struct rdma_id_private *id_priv)unsigned int p;u16 pkey, index;enum ib_port_state port_state; +int ret;int i; cma_dev =NULL ;
@@ -793,9 +794,14 @@ static int cma_resolve_ib_dev(struct rdma_id_private *id_priv)if (ib_get_cached_port_state (cur_dev->device, p, &port_state))continue ; -for (i =0 ; !rdma_query_gid (cur_dev->device, - p, i, &gid); - i++) { + +for (i =0 ; i < cur_dev->device->port_data[p].immutable.gid_tbl_len; + ++i) { + ret =rdma_query_gid (cur_dev->device, p, i, + &gid); +if (ret) +continue ; +if (!memcmp (&gid, dgid,sizeof (gid))) { cma_dev = cur_dev; sgid = gid;
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 270/563 ASoC: rt5663: Handle device_property_read_u32_array error codes
In reply to Greg Kroah-HartmanFrom: Jiasheng Jiang <[email protected]>
[ Upstream commit 2167c0b205960607fb136b4bb3c556a62be1569a ]
The return value of device_property_read_u32_array() is not always 0. To catch the exception in case that devm_kzalloc failed and the rt5663->imp_table was NULL, which caused the failure of device_property_read_u32_array.
--- sound/soc/codecs/rt5663.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
sound/soc/codecs/rt5663.c +9 -3
@@ -3461,6 +3461,7 @@ static void rt5663_calibrate(struct rt5663_priv *rt5663)static int rt5663_parse_dp (struct rt5663_priv *rt5663,struct device *dev) {int table_size; +int ret;device_property_read_u32 (dev,"realtek,dc_offset_l_manual" , &rt5663->pdata.dc_offset_l_manual);
@@ -3477,9 +3478,11 @@ static int rt5663_parse_dp(struct rt5663_priv *rt5663, struct device *dev) table_size =sizeof (struct impedance_mapping_table ) * rt5663->pdata.impedance_sensing_num; rt5663->imp_table =devm_kzalloc (dev, table_size,GFP_KERNEL ); -device_property_read_u32_array (dev, + ret =device_property_read_u32_array (dev,"realtek,impedance_sensing_table" , (u32 *)rt5663->imp_table, table_size); +if (ret) +return ret; }return 0 ;
@@ -3504,8 +3507,11 @@ static int rt5663_i2c_probe(struct i2c_client *i2c,if (pdata) rt5663->pdata = *pdata; -else -rt5663_parse_dp (rt5663, &i2c->dev); +else { + ret =rt5663_parse_dp (rt5663, &i2c->dev); +if (ret) +return ret; + }for (i =0 ; i <ARRAY_SIZE (rt5663->supplies); i++) rt5663->supplies[i].supply = rt5663_supply_names[i];
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 271/563 of: unittest: fix warning on PowerPC frame size warning
In reply to Greg Kroah-HartmanFrom: Jim Quinlan <[email protected]>
[ Upstream commit a8d61a9112ad0c9216ab45d050991e07bc4f3408 ]
The struct device variable "dev_bogus" was triggering this warning on a PowerPC build:
drivers/of/unittest.c: In function 'of_unittest_dma_ranges_one.constprop':
[...] >> The frame size of 1424 bytes is larger than 1024 bytes
[-Wframe-larger-than=]
This variable is now dynamically allocated.
--- drivers/of/unittest.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-)
drivers/of/unittest.c +12 -4
@@ -910,11 +910,18 @@ static void __init of_unittest_dma_ranges_one(const char *path,if (!rc) {phys_addr_t paddr;dma_addr_t dma_addr; -struct device dev_bogus; +struct device *dev_bogus; - dev_bogus.dma_range_map = map; - paddr =dma_to_phys (&dev_bogus, expect_dma_addr); - dma_addr =phys_to_dma (&dev_bogus, expect_paddr); + dev_bogus =kzalloc (sizeof (struct device ),GFP_KERNEL ); +if (!dev_bogus) { +unittest (0 ,"kzalloc() failed\n" ); +kfree (map); +return ; + } + + dev_bogus->dma_range_map = map; + paddr =dma_to_phys (dev_bogus, expect_dma_addr); + dma_addr =phys_to_dma (dev_bogus, expect_paddr); unittest(paddr == expect_paddr, "of_dma_get_range: wrong phys addr %pap (expecting %llx) on node %pOF\n",
@@ -924,6 +931,7 @@ static void __init of_unittest_dma_ranges_one(const char *path, &dma_addr, expect_dma_addr, np);kfree (map); + kfree(dev_bogus); }of_node_put (np);#endif
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 272/563 of: unittest: 64 bit dma address test requires arch support
In reply to Greg Kroah-HartmanFrom: Frank Rowand <[email protected]>
[ Upstream commit 9fd4cf5d3571b27d746b8ead494a3f051485b679 ]
If an architecture does not support 64 bit dma addresses then testing for an expected dma address >= 0x100000000 will fail.
--- drivers/of/unittest.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/of/unittest.c +3 -2
@@ -941,8 +941,9 @@ static void __init of_unittest_parse_dma_ranges(void) {of_unittest_dma_ranges_one ("/testcase-data/address-tests/device@70000000" ,0x0 ,0x20000000 ); -of_unittest_dma_ranges_one ("/testcase-data/address-tests/bus@80000000/device@1000" , -0x100000000 ,0x20000000 ); +if (IS_ENABLED (CONFIG_ARCH_DMA_ADDR_T_64BIT )) +of_unittest_dma_ranges_one ("/testcase-data/address-tests/bus@80000000/device@1000" , +0x100000000 ,0x20000000 );of_unittest_dma_ranges_one ("/testcase-data/address-tests/pci@90000000" ,0x80000000 ,0x20000000 ); }
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 273/563 clk: stm32: Fix ltdcs clock turn off by clk_disable_unused() after system enter shell
In reply to Greg Kroah-HartmanFrom: Dillon Min <[email protected]>
[ Upstream commit 6fc058a72f3b7b07fc4de6d66ad1f68951b00f6e ]
stm32's clk driver register two ltdc gate clk to clk core by clk_hw_register_gate() and clk_hw_register_composite()
first: 'stm32f429_gates[]', clk name is 'ltdc', which no user to use.
second: 'stm32f429_aux_clk[]', clk name is 'lcd-tft', used by ltdc driver
both of them point to the same offset of stm32's RCC register. after kernel enter console, clk core turn off ltdc's clk as 'stm32f429_gates[]' is no one to use. but, actually 'stm32f429_aux_clk[]' is in use.
stm32f469/746/769 have the same issue, fix it.
--- drivers/clk/clk-stm32f4.c | 4 ---- 1 file changed, 4 deletions(-)
drivers/clk/clk-stm32f4.c +0 -4
@@ -129,7 +129,6 @@ static const struct stm32f4_gate_data stm32f429_gates[] __initconst = { { STM32F4_RCC_APB2ENR, 20, "spi5", "apb2_div" }, { STM32F4_RCC_APB2ENR, 21, "spi6", "apb2_div" }, { STM32F4_RCC_APB2ENR, 22, "sai1", "apb2_div" }, - { STM32F4_RCC_APB2ENR, 26, "ltdc", "apb2_div" }, }; static const struct stm32f4_gate_data stm32f469_gates[] __initconst = {
@@ -211,7 +210,6 @@ static const struct stm32f4_gate_data stm32f469_gates[] __initconst = { { STM32F4_RCC_APB2ENR, 20, "spi5", "apb2_div" }, { STM32F4_RCC_APB2ENR, 21, "spi6", "apb2_div" }, { STM32F4_RCC_APB2ENR, 22, "sai1", "apb2_div" }, - { STM32F4_RCC_APB2ENR, 26, "ltdc", "apb2_div" }, }; static const struct stm32f4_gate_data stm32f746_gates[] __initconst = {
@@ -286,7 +284,6 @@ static const struct stm32f4_gate_data stm32f746_gates[] __initconst = { { STM32F4_RCC_APB2ENR, 21, "spi6", "apb2_div" }, { STM32F4_RCC_APB2ENR, 22, "sai1", "apb2_div" }, { STM32F4_RCC_APB2ENR, 23, "sai2", "apb2_div" }, - { STM32F4_RCC_APB2ENR, 26, "ltdc", "apb2_div" }, }; static const struct stm32f4_gate_data stm32f769_gates[] __initconst = {
@@ -364,7 +361,6 @@ static const struct stm32f4_gate_data stm32f769_gates[] __initconst = { { STM32F4_RCC_APB2ENR, 21, "spi6", "apb2_div" }, { STM32F4_RCC_APB2ENR, 22, "sai1", "apb2_div" }, { STM32F4_RCC_APB2ENR, 23, "sai2", "apb2_div" }, - { STM32F4_RCC_APB2ENR, 26, "ltdc", "apb2_div" }, { STM32F4_RCC_APB2ENR, 30, "mdio", "apb2_div" }, };
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 274/563 mips: add SYS_HAS_CPU_MIPS64_R5 config for MIPS Release 5 support
In reply to Greg Kroah-HartmanFrom: Lukas Bulwahn <[email protected]>
[ Upstream commit fd4eb90b164442cb1e9909f7845e12a0835ac699 ]
Commit ab7c01fdc3cf ("mips: Add MIPS Release 5 support") adds the two configs CPU_MIPS32_R5 and CPU_MIPS64_R5, which depend on the corresponding SYS_HAS_CPU_MIPS32_R5 and SYS_HAS_CPU_MIPS64_R5, respectively.
The config SYS_HAS_CPU_MIPS32_R5 was already introduced with commit c5b367835cfc ("MIPS: Add support for XPA."); the config SYS_HAS_CPU_MIPS64_R5, however, was never introduced.
Hence, ./scripts/checkkconfigsymbols.py warns:
SYS_HAS_CPU_MIPS64_R5
Referencing files: arch/mips/Kconfig, arch/mips/include/asm/cpu-type.h
Add the definition for config SYS_HAS_CPU_MIPS64_R5 under the assumption that SYS_HAS_CPU_MIPS64_R5 follows the same pattern as the existing SYS_HAS_CPU_MIPS32_R5 and SYS_HAS_CPU_MIPS64_R6.
--- arch/mips/Kconfig | 4 ++++ 1 file changed, 4 insertions(+)
arch/mips/Kconfig +4 -0
@@ -1985,6 +1985,10 @@ config SYS_HAS_CPU_MIPS64_R1 config SYS_HAS_CPU_MIPS64_R2 bool +config SYS_HAS_CPU_MIPS64_R5 + bool + select ARCH_HAS_SYNC_DMA_FOR_CPU if DMA_NONCOHERENT + config SYS_HAS_CPU_MIPS64_R6 bool select ARCH_HAS_SYNC_DMA_FOR_CPU if DMA_NONCOHERENT
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 275/563 mips: fix Kconfig reference to PHYS_ADDR_T_64BIT
In reply to Greg Kroah-HartmanFrom: Lukas Bulwahn <[email protected]>
[ Upstream commit a670c82d9ca4f1e7385d9d6f26ff41a50fbdd944 ]
Commit d4a451d5fc84 ("arch: remove the ARCH_PHYS_ADDR_T_64BIT config symbol") removes config ARCH_PHYS_ADDR_T_64BIT with all instances of that config refactored appropriately. Since then, it is recommended to use the config PHYS_ADDR_T_64BIT instead.
Commit 171543e75272 ("MIPS: Disallow CPU_SUPPORTS_HUGEPAGES for XPA,EVA") introduces the expression "!(32BIT && (ARCH_PHYS_ADDR_T_64BIT || EVA))" for config CPU_SUPPORTS_HUGEPAGES, which unintentionally refers to the non-existing symbol ARCH_PHYS_ADDR_T_64BIT instead of the intended PHYS_ADDR_T_64BIT.
Fix this Kconfig reference to the intended PHYS_ADDR_T_64BIT.
This issue was identified with the script ./scripts/checkkconfigsymbols.py. I then reported it on the mailing list and Paul confirmed the mistake in the linked email thread.
--- arch/mips/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/mips/Kconfig +1 -1
@@ -2150,7 +2150,7 @@ config CPU_SUPPORTS_ADDRWINCFG bool config CPU_SUPPORTS_HUGEPAGES bool - depends on !(32BIT && (ARCH_PHYS_ADDR_T_64BIT || EVA)) + depends on !(32BIT && (PHYS_ADDR_T_64BIT || EVA)) config MIPS_PGD_C0_CONTEXT bool default y if 64BIT && (CPU_MIPSR2 || CPU_MIPSR6) && !CPU_XLP
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 276/563 dmaengine: pxa/mmp: stop referencing config->slave_id
In reply to Greg Kroah-HartmanFrom: Arnd Bergmann <[email protected]>
[ Upstream commit 134c37fa250a87a7e77c80a7c59ae16c462e46e0 ]
The last driver referencing the slave_id on Marvell PXA and MMP platforms was the SPI driver, but this stopped doing so a long time ago, so the TODO from the earlier patch can no be removed.
--- drivers/dma/mmp_pdma.c | 6 ------ drivers/dma/pxa_dma.c | 7 ------- 2 files changed, 13 deletions(-)
drivers/dma/mmp_pdma.c +0 -6
@@ -728,12 +728,6 @@ static int mmp_pdma_config_write(struct dma_chan *dchan, chan->dir = direction; chan->dev_addr = addr; -/* FIXME: drivers should be ported over to use the filter -* function. Once that's done, the following two lines can -* be removed. -*/ -if (cfg->slave_id) - chan->drcmr = cfg->slave_id;return 0 ; }
drivers/dma/pxa_dma.c +0 -7
@@ -911,13 +911,6 @@ static void pxad_get_config(struct pxad_chan *chan, *dcmd |=PXA_DCMD_BURST16 ; else if (maxburst == 32) *dcmd |= PXA_DCMD_BURST32; - - /* FIXME: drivers should be ported over to use the filter - * function. Once that's done, the following two lines can - * be removed. - */ - if (chan->cfg.slave_id) - chan->drcmr = chan->cfg.slave_id; } static struct dma_async_tx_descriptor *
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 277/563 iommu/amd: Remove iommu_init_ga()
In reply to Greg Kroah-HartmanFrom: Suravee Suthikulpanit <[email protected]>
[ Upstream commit eb03f2d2f6a4da25d286613717d10add9ce9f175 ]
Since the function has been simplified and only call iommu_init_ga_log(), remove the function and replace with iommu_init_ga_log() instead.
--- drivers/iommu/amd/init.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-)
drivers/iommu/amd/init.c +4 -13
@@ -830,9 +830,9 @@ static int iommu_ga_log_enable(struct amd_iommu *iommu)return 0 ; } -#ifdef CONFIG_IRQ_REMAP static int iommu_init_ga_log (struct amd_iommu *iommu) { +#ifdef CONFIG_IRQ_REMAP u64 entry;if (!AMD_IOMMU_GUEST_IR_VAPIC (amd_iommu_guest_ir))
@@ -862,18 +862,9 @@ static int iommu_init_ga_log(struct amd_iommu *iommu) err_out:free_ga_log (iommu);return -EINVAL ; -} -#endif /* CONFIG_IRQ_REMAP */ - -static int iommu_init_ga (struct amd_iommu *iommu) -{ -int ret =0 ; - -#ifdef CONFIG_IRQ_REMAP - ret =iommu_init_ga_log (iommu); +#else +return 0 ;#endif /* CONFIG_IRQ_REMAP */ - -return ret; }static int __init alloc_cwwb_sem (struct amd_iommu *iommu)
@@ -1860,7 +1851,7 @@ static int __init iommu_init_pci(struct amd_iommu *iommu)if (iommu_feature (iommu,FEATURE_PPR ) &&alloc_ppr_log (iommu))return -ENOMEM ; - ret =iommu_init_ga (iommu); + ret =iommu_init_ga_log (iommu);if (ret)return ret;
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 278/563 iommu/amd: Restore GA log/tail pointer on host resume
In reply to Greg Kroah-HartmanFrom: Maxim Levitsky <[email protected]>
[ Upstream commit a8d4a37d1bb93608501d0d0545f902061152669a ]
This will give IOMMU GA log a chance to work after resume from s3/s4.
--- drivers/iommu/amd/init.c | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-)
drivers/iommu/amd/init.c +15 -16
@@ -805,16 +805,27 @@ static int iommu_ga_log_enable(struct amd_iommu *iommu) {#ifdef CONFIG_IRQ_REMAP u32 status, i; +u64 entry;if (!iommu->ga_log)return -EINVAL ; - status =readl (iommu->mmio_base +MMIO_STATUS_OFFSET ); -/* Check if already running */ -if (status & (MMIO_STATUS_GALOG_RUN_MASK )) + status =readl (iommu->mmio_base +MMIO_STATUS_OFFSET ); +if (WARN_ON (status & (MMIO_STATUS_GALOG_RUN_MASK )))return 0 ; + entry =iommu_virt_to_phys (iommu->ga_log) |GA_LOG_SIZE_512 ; +memcpy_toio (iommu->mmio_base +MMIO_GA_LOG_BASE_OFFSET , + &entry,sizeof (entry)); + entry = (iommu_virt_to_phys (iommu->ga_log_tail) & + (BIT_ULL (52 )-1 )) & ~7ULL ; +memcpy_toio (iommu->mmio_base +MMIO_GA_LOG_TAIL_OFFSET , + &entry,sizeof (entry)); +writel (0x00 , iommu->mmio_base +MMIO_GA_HEAD_OFFSET ); +writel (0x00 , iommu->mmio_base +MMIO_GA_TAIL_OFFSET ); + +iommu_feature_enable (iommu,CONTROL_GAINT_EN );iommu_feature_enable (iommu,CONTROL_GALOG_EN );
@@ -824,7 +835,7 @@ static int iommu_ga_log_enable(struct amd_iommu *iommu) break; } -if (i >=LOOP_TIMEOUT ) +if (WARN_ON (i >=LOOP_TIMEOUT ))return -EINVAL ;#endif /* CONFIG_IRQ_REMAP */ return 0 ;
@@ -833,8 +844,6 @@ static int iommu_ga_log_enable(struct amd_iommu *iommu)static int iommu_init_ga_log (struct amd_iommu *iommu) {#ifdef CONFIG_IRQ_REMAP -u64 entry; -if (!AMD_IOMMU_GUEST_IR_VAPIC (amd_iommu_guest_ir))return 0 ;
@@ -848,16 +857,6 @@ static int iommu_init_ga_log(struct amd_iommu *iommu)if (!iommu->ga_log_tail) goto err_out; - entry =iommu_virt_to_phys (iommu->ga_log) |GA_LOG_SIZE_512 ; -memcpy_toio (iommu->mmio_base +MMIO_GA_LOG_BASE_OFFSET , - &entry,sizeof (entry)); - entry = (iommu_virt_to_phys (iommu->ga_log_tail) & - (BIT_ULL (52 )-1 )) & ~7ULL ; -memcpy_toio (iommu->mmio_base +MMIO_GA_LOG_TAIL_OFFSET , - &entry,sizeof (entry)); -writel (0x00 , iommu->mmio_base +MMIO_GA_HEAD_OFFSET ); -writel (0x00 , iommu->mmio_base +MMIO_GA_TAIL_OFFSET ); -return 0 ; err_out:free_ga_log (iommu);
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 279/563 ASoC: Intel: catpt: Test dmaengine_submit() result before moving on
In reply to Greg Kroah-HartmanFrom: Cezary Rojewski <[email protected]>
[ Upstream commit 2a9a72e290d4a4741e673f86b9fba9bfb319786d ]
After calling dmaengine_submit(), the submitted transfer descriptor belongs to the DMA engine. Pointer to that descriptor may no longer be valid after the call and should be tested before awaiting transfer completion.
--- sound/soc/intel/catpt/dsp.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
sound/soc/intel/catpt/dsp.c +12 -2
@@ -65,6 +65,7 @@ static int catpt_dma_memcpy(struct catpt_dev *cdev, struct dma_chan *chan, {struct dma_async_tx_descriptor *desc;enum dma_status status; +int ret; desc =dmaengine_prep_dma_memcpy (chan, dst_addr, src_addr, size,DMA_CTRL_ACK );
@@ -77,13 +78,22 @@ static int catpt_dma_memcpy(struct catpt_dev *cdev, struct dma_chan *chan,catpt_updatel_shim (cdev,HMDC ,CATPT_HMDC_HDDA (CATPT_DMA_DEVID , chan->chan_id),CATPT_HMDC_HDDA (CATPT_DMA_DEVID , chan->chan_id)); -dmaengine_submit (desc); + + ret =dma_submit_error (dmaengine_submit (desc)); +if (ret) { +dev_err (cdev->dev,"submit tx failed: %d\n" , ret); + goto clear_hdda; + } + status =dma_wait_for_async_tx (desc); + ret = (status ==DMA_COMPLETE ) ?0 : -EPROTO ; + +clear_hdda:/* regardless of status, disable access to HOST memory in demand mode */ catpt_updatel_shim (cdev,HMDC ,CATPT_HMDC_HDDA (CATPT_DMA_DEVID , chan->chan_id),0 ); -return (status ==DMA_COMPLETE ) ?0 : -EPROTO ; +return ret; } int catpt_dma_memcpy_todsp(struct catpt_dev *cdev, struct dma_chan *chan,
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 280/563 iommu/iova: Fix race between FQ timeout and teardown
In reply to Greg Kroah-HartmanFrom: Xiongfeng Wang <[email protected]>
[ Upstream commit d7061627d701c90e1cac1e1e60c45292f64f3470 ]
It turns out to be possible for hotplugging out a device to reach the stage of tearing down the device's group and default domain before the domain's flush queue has drained naturally. At this point, it is then possible for the timeout to expire just before the del_timer() call in free_iova_flush_queue(), such that we then proceed to free the FQ resources while fq_flush_timeout() is still accessing them on another CPU. Crashes due to this have been observed in the wild while removing NVMe devices.
Close the race window by using del_timer_sync() to safely wait for any active timeout handler to finish before we start to free things. We already avoid any locking in free_iova_flush_queue() since the FQ is supposed to be inactive anyway, so the potential deadlock scenario does not apply.
--- drivers/iommu/iova.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/iommu/iova.c +1 -2
@@ -64,8 +64,7 @@ static void free_iova_flush_queue(struct iova_domain *iovad)if (!has_iova_flush_queue (iovad))return ; -if (timer_pending (&iovad->fq_timer)) -del_timer (&iovad->fq_timer); +del_timer_sync (&iovad->fq_timer);fq_destroy_all_entries (iovad);
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 281/563 scsi: block: pm: Always set request queue runtime active in blk_post_runtime_resume()
In reply to Greg Kroah-HartmanFrom: Alan Stern <[email protected]>
[ Upstream commit 6e1fcab00a23f7fe9f4fe9704905a790efa1eeab ]
John Garry reported a deadlock that occurs when trying to access a runtime-suspended SATA device. For obscure reasons, the rescan procedure causes the link to be hard-reset, which disconnects the device.
The rescan tries to carry out a runtime resume when accessing the device. scsi_rescan_device() holds the SCSI device lock and won't release it until it can put commands onto the device's block queue. This can't happen until the queue is successfully runtime-resumed or the device is unregistered. But the runtime resume fails because the device is disconnected, and __scsi_remove_device() can't do the unregistration because it can't get the device lock.
The best way to resolve this deadlock appears to be to allow the block queue to start running again even after an unsuccessful runtime resume. The idea is that the driver or the SCSI error handler will need to be able to use the queue to resolve the runtime resume failure.
This patch removes the err argument to blk_post_runtime_resume() and makes the routine act as though the resume was successful always. This fixes the deadlock.
--- block/blk-pm.c | 22 +++++++--------------- drivers/scsi/scsi_pm.c | 2 +- include/linux/blk-pm.h | 2 +- 3 files changed, 9 insertions(+), 17 deletions(-)
block/blk-pm.c +7 -15
@@ -163,27 +163,19 @@ EXPORT_SYMBOL(blk_pre_runtime_resume);/** * blk_post_runtime_resume - Post runtime resume processing * @q: the queue of the device -* @err: return value of the device's runtime_resume function * * Description: -* Update the queue's runtime status according to the return value of the -* device's runtime_resume function. If the resume was successful, call -* blk_set_runtime_active() to do the real work of restarting the queue. +* For historical reasons, this routine merely calls blk_set_runtime_active() +* to do the real work of restarting the queue. It does this regardless of +* whether the device's runtime-resume succeeded; even if it failed the +* driver or error handler will need to communicate with the device. * * This function should be called near the end of the device's * runtime_resume callback. */ -void blk_post_runtime_resume (struct request_queue *q,int err) +void blk_post_runtime_resume (struct request_queue *q) { -if (!q->dev) -return ; -if (!err) { -blk_set_runtime_active (q); - }else { -spin_lock_irq (&q->queue_lock); - q->rpm_status =RPM_SUSPENDED ; -spin_unlock_irq (&q->queue_lock); - } +blk_set_runtime_active (q); }EXPORT_SYMBOL (blk_post_runtime_resume);
@@ -201,7 +193,7 @@ EXPORT_SYMBOL(blk_post_runtime_resume);* runtime PM status and re-enable peeking requests from the queue. It * should be called before first request is added to the queue. * -* This function is also called by blk_post_runtime_resume() for successful +* This function is also called by blk_post_runtime_resume() for * runtime resumes. It does everything necessary to restart the queue. */ void blk_set_runtime_active (struct request_queue *q)
drivers/scsi/scsi_pm.c +1 -1
@@ -262,7 +262,7 @@ static int sdev_runtime_resume(struct device *dev)blk_pre_runtime_resume (sdev->request_queue);if (pm && pm->runtime_resume) err = pm->runtime_resume (dev); -blk_post_runtime_resume (sdev->request_queue, err); +blk_post_runtime_resume (sdev->request_queue);return err; }
include/linux/blk-pm.h +1 -1
@@ -14,7 +14,7 @@ extern void blk_pm_runtime_init(struct request_queue *q, struct device *dev);extern int blk_pre_runtime_suspend (struct request_queue *q);extern void blk_post_runtime_suspend (struct request_queue *q,int err);extern void blk_pre_runtime_resume (struct request_queue *q); -extern void blk_post_runtime_resume (struct request_queue *q,int err); +extern void blk_post_runtime_resume (struct request_queue *q);extern void blk_set_runtime_active (struct request_queue *q);#else static inline void blk_pm_runtime_init(struct request_queue *q,
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 282/563 phy: uniphier-usb3ss: fix unintended writing zeros to PHY register
In reply to Greg Kroah-HartmanFrom: Ryuta NAKANISHI <[email protected]>
[ Upstream commit 898c7a9ec81620125f2463714a0f4dea18ad6e54 ]
Similar to commit 4a90bbb478db ("phy: uniphier-pcie: Fix updating phy parameters"), in function uniphier_u3ssphy_set_param(), unintentionally write zeros to other fields when writing PHY registers.
--- drivers/phy/socionext/phy-uniphier-usb3ss.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
drivers/phy/socionext/phy-uniphier-usb3ss.c +6 -4
@@ -22,11 +22,13 @@#include <linux/reset.h> #define SSPHY_TESTI 0x0 -#define SSPHY_TESTO 0x4#define TESTI_DAT_MASK GENMASK(13, 6)#define TESTI_ADR_MASK GENMASK(5, 1)#define TESTI_WR_EN BIT(0) +#define SSPHY_TESTO 0x4 +#define TESTO_DAT_MASK GENMASK(7, 0) +#define PHY_F (regno, msb, lsb) { (regno), (msb), (lsb) }#define CDR_CPD_TRIM PHY_F(7, 3, 0)/* RxPLL charge pump current */
@@ -84,12 +86,12 @@ static void uniphier_u3ssphy_set_param(struct uniphier_u3ssphy_priv *priv, val =FIELD_PREP (TESTI_DAT_MASK ,1 ); val |=FIELD_PREP (TESTI_ADR_MASK , p->field.reg_no);uniphier_u3ssphy_testio_write (priv, val); - val =readl (priv->base +SSPHY_TESTO ); + val =readl (priv->base +SSPHY_TESTO ) &TESTO_DAT_MASK ;/* update value */ - val &= ~FIELD_PREP (TESTI_DAT_MASK , field_mask); + val &= ~field_mask; data = field_mask & (p->value << p->field.lsb); - val =FIELD_PREP (TESTI_DAT_MASK , data); + val =FIELD_PREP (TESTI_DAT_MASK , data | val); val |=FIELD_PREP (TESTI_ADR_MASK , p->field.reg_no);uniphier_u3ssphy_testio_write (priv, val);uniphier_u3ssphy_testio_write (priv, val |TESTI_WR_EN );
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 283/563 ASoC: mediatek: Check for error clk pointer
In reply to Greg Kroah-HartmanFrom: Jiasheng Jiang <[email protected]>
[ Upstream commit 9de2b9286a6dd16966959b3cb34fc2ddfd39213e ]
Yes, you are right and now the return code depending on the init_clks().
--- drivers/soc/mediatek/mtk-scpsys.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-)
drivers/soc/mediatek/mtk-scpsys.c +11 -4
@@ -411,12 +411,17 @@ out:return ret; } -static void init_clks (struct platform_device *pdev,struct clk **clk) +static int init_clks (struct platform_device *pdev,struct clk **clk) {int i; -for (i =CLK_NONE +1 ; i <CLK_MAX ; i++) +for (i =CLK_NONE +1 ; i <CLK_MAX ; i++) { clk[i] =devm_clk_get (&pdev->dev, clk_names[i]); +if (IS_ERR (clk[i])) +return PTR_ERR (clk[i]); + } + +return 0 ; } static struct scp *init_scp(struct platform_device *pdev,
@@ -426,7 +431,7 @@ static struct scp *init_scp(struct platform_device *pdev, {struct genpd_onecell_data *pd_data;struct resource *res; -int i, j; +int i, j, ret;struct scp *scp;struct clk *clk[CLK_MAX ];
@@ -481,7 +486,9 @@ static struct scp *init_scp(struct platform_device *pdev, pd_data->num_domains = num; -init_clks (pdev, clk); + ret =init_clks (pdev, clk); +if (ret) +return ERR_PTR (ret);for (i =0 ; i < num; i++) {struct scp_domain *scpd = &scp->domains[i];
Signature · 1 line
2.34.1
Greg Kroah-Hartman
maintainerPATCH 284/563 ASoC: samsung: idma: Check of ioremap return value
In reply to Greg Kroah-HartmanFrom: Jiasheng Jiang <[email protected]>
[ Upstream commit 3ecb46755eb85456b459a1a9f952c52986bce8ec ]
Because of the potential failure of the ioremap(), the buf->area could be NULL.
Therefore, we need to check it and return -ENOMEM in order to transfer the error.
--- sound/soc/samsung/idma.c | 2 ++ 1 file changed, 2 insertions(+)
sound/soc/samsung/idma.c +2 -0
@@ -360,6 +360,8 @@ static int preallocate_idma_buffer(struct snd_pcm *pcm, int stream) buf->addr = idma.lp_tx_addr; buf->bytes = idma_hardware.buffer_bytes_max; buf->area = (unsigned char *__force )ioremap (buf->addr, buf->bytes); +if (!buf->area) +return -ENOMEM ;return 0 ; }
Signature · 1 line
2.34.1