6.1.43-rc1 review
Subsystems (4)
Greg Kroah-Hartman
maintainerPATCH 118/228 RDMA/irdma: Add missing read barriers
In reply to Greg Kroah-HartmanFrom: Shiraz Saleem <[email protected]>
[ Upstream commit 4984eb51453ff7eddee9e5ce816145be39c0ec5c ]
On code inspection, there are many instances in the driver where CEQE and AEQE fields written to by HW are read without guaranteeing that the polarity bit has been read and checked first.
Add a read barrier to avoid reordering of loads on the CEQE/AEQE fields prior to checking the polarity bit.
--- drivers/infiniband/hw/irdma/ctrl.c | 9 ++++++++- drivers/infiniband/hw/irdma/puda.c | 6 ++++++ drivers/infiniband/hw/irdma/uk.c | 3 +++ 3 files changed, 17 insertions(+), 1 deletion(-)
drivers/infiniband/hw/irdma/ctrl.c +8 -1
@@ -3344,6 +3344,9 @@ int irdma_sc_ccq_get_cqe_info(struct irdma_sc_cq *ccq,if (polarity != ccq->cq_uk.polarity)return -ENOENT ; +/* Ensure CEQE contents are read after valid bit is checked */ +dma_rmb (); +get_64bit_val (cqe,8 , &qp_ctx); cqp = (struct irdma_sc_cqp *)(unsigned long )qp_ctx; info->error = (bool )FIELD_GET (IRDMA_CQ_ERROR , temp);
@@ -3990,13 +3993,17 @@ int irdma_sc_get_next_aeqe(struct irdma_sc_aeq *aeq,u8 polarity; aeqe =IRDMA_GET_CURRENT_AEQ_ELEM (aeq); -get_64bit_val (aeqe,0 , &compl_ctx);get_64bit_val (aeqe,8 , &temp); polarity = (u8 )FIELD_GET (IRDMA_AEQE_VALID , temp);if (aeq->polarity != polarity)return -ENOENT ; +/* Ensure AEQE contents are read after valid bit is checked */ +dma_rmb (); + +get_64bit_val (aeqe,0 , &compl_ctx); +print_hex_dump_debug ("WQE: AEQ_ENTRY WQE" ,DUMP_PREFIX_OFFSET ,16 ,8 , aeqe,16 , false);
drivers/infiniband/hw/irdma/puda.c +6 -0
@@ -230,6 +230,9 @@ static int irdma_puda_poll_info(struct irdma_sc_cq *cq,if (valid_bit != cq_uk->polarity)return -ENOENT ; +/* Ensure CQE contents are read after valid bit is checked */ +dma_rmb (); +if (cq->dev->hw_attrs.uk_attrs.hw_rev >=IRDMA_GEN_2 ) ext_valid = (bool )FIELD_GET (IRDMA_CQ_EXTCQE , qword3);
@@ -243,6 +246,9 @@ static int irdma_puda_poll_info(struct irdma_sc_cq *cq,if (polarity != cq_uk->polarity)return -ENOENT ; +/* Ensure ext CQE contents are read after ext valid bit is checked */ +dma_rmb (); +IRDMA_RING_MOVE_HEAD_NOCHECK (cq_uk->cq_ring);if (!IRDMA_RING_CURRENT_HEAD (cq_uk->cq_ring)) cq_uk->polarity = !cq_uk->polarity;
drivers/infiniband/hw/irdma/uk.c +3 -0
@@ -1527,6 +1527,9 @@ void irdma_uk_clean_cq(void *q, struct irdma_cq_uk *cq)if (polarity != temp)break ; +/* Ensure CQE contents are read after valid bit is checked */ +dma_rmb (); +get_64bit_val (cqe,8 , &comp_ctx);if ((void *)(unsigned long )comp_ctx == q)set_64bit_val (cqe,8 ,0 );
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 119/228 RDMA/irdma: Fix data race on CQP completion stats
In reply to Greg Kroah-HartmanFrom: Shiraz Saleem <[email protected]>
[ Upstream commit f2c3037811381f9149243828c7eb9a1631df9f9c ]
CQP completion statistics is read lockesly in irdma_wait_event and irdma_check_cqp_progress while it can be updated in the completion thread irdma_sc_ccq_get_cqe_info on another CPU as KCSAN reports.
Make completion statistics an atomic variable to reflect coherent updates to it. This will also avoid load/store tearing logic bug potentially possible by compiler optimizations.
[77346.170861] BUG: KCSAN: data-race in irdma_handle_cqp_op [irdma] / irdma_sc_ccq_get_cqe_info [irdma]
[77346.171383] write to 0xffff8a3250b108e0 of 8 bytes by task 9544 on cpu 4: [77346.171483] irdma_sc_ccq_get_cqe_info+0x27a/0x370 [irdma] [77346.171658] irdma_cqp_ce_handler+0x164/0x270 [irdma] [77346.171835] cqp_compl_worker+0x1b/0x20 [irdma] [77346.172009] process_one_work+0x4d1/0xa40 [77346.172024] worker_thread+0x319/0x700 [77346.172037] kthread+0x180/0x1b0 [77346.172054] ret_from_fork+0x22/0x30
[77346.172136] read to 0xffff8a3250b108e0 of 8 bytes by task 9838 on cpu 2: [77346.172234] irdma_handle_cqp_op+0xf4/0x4b0 [irdma] [77346.172413] irdma_cqp_aeq_cmd+0x75/0xa0 [irdma] [77346.172592] irdma_create_aeq+0x390/0x45a [irdma] [77346.172769] irdma_rt_init_hw.cold+0x212/0x85d [irdma] [77346.172944] irdma_probe+0x54f/0x620 [irdma] [77346.173122] auxiliary_bus_probe+0x66/0xa0 [77346.173137] really_probe+0x140/0x540 [77346.173154] __driver_probe_device+0xc7/0x220 [77346.173173] driver_probe_device+0x5f/0x140 [77346.173190] __driver_attach+0xf0/0x2c0 [77346.173208] bus_for_each_dev+0xa8/0xf0 [77346.173225] driver_attach+0x29/0x30 [77346.173240] bus_add_driver+0x29c/0x2f0 [77346.173255] driver_register+0x10f/0x1a0 [77346.173272] __auxiliary_driver_register+0xbc/0x140 [77346.173287] irdma_init_module+0x55/0x1000 [irdma] [77346.173460] do_one_initcall+0x7d/0x410 [77346.173475] do_init_module+0x81/0x2c0 [77346.173491] load_module+0x1232/0x12c0 [77346.173506] __do_sys_finit_module+0x101/0x180 [77346.173522] __x64_sys_finit_module+0x3c/0x50 [77346.173538] do_syscall_64+0x39/0x90 [77346.173553] entry_SYSCALL_64_after_hwframe+0x63/0xcd
[77346.173634] value changed: 0x0000000000000094 -> 0x0000000000000095
--- drivers/infiniband/hw/irdma/ctrl.c | 22 +++++++------- drivers/infiniband/hw/irdma/defs.h | 46 ++++++++++++++--------------- drivers/infiniband/hw/irdma/type.h | 2 ++ drivers/infiniband/hw/irdma/utils.c | 2 +- 4 files changed, 36 insertions(+), 36 deletions(-)
drivers/infiniband/hw/irdma/ctrl.c +11 -11
@@ -2693,13 +2693,13 @@ static int irdma_sc_cq_modify(struct irdma_sc_cq *cq,*/ void irdma_check_cqp_progress (struct irdma_cqp_timeout *timeout,struct irdma_sc_dev *dev) { -if (timeout->compl_cqp_cmds != dev->cqp_cmd_stats[IRDMA_OP_CMPL_CMDS ]) { - timeout->compl_cqp_cmds = dev->cqp_cmd_stats[IRDMA_OP_CMPL_CMDS ]; +u64 completed_ops =atomic64_read (&dev->cqp->completed_ops); + +if (timeout->compl_cqp_cmds != completed_ops) { + timeout->compl_cqp_cmds = completed_ops; timeout->count =0 ; - }else { -if (dev->cqp_cmd_stats[IRDMA_OP_REQ_CMDS ] != - timeout->compl_cqp_cmds) - timeout->count++; + }else if (timeout->compl_cqp_cmds != dev->cqp->requested_ops) { + timeout->count++; } }
@@ -2742,7 +2742,7 @@ static int irdma_cqp_poll_registers(struct irdma_sc_cqp *cqp, u32 tail,if (newtail != tail) {/* SUCCESS */ IRDMA_RING_MOVE_TAIL (cqp->sq_ring); - cqp->dev->cqp_cmd_stats[IRDMA_OP_CMPL_CMDS ]++; +atomic64_inc (&cqp->completed_ops);return 0 ; }udelay (cqp->dev->hw_attrs.max_sleep_count);
@@ -3102,8 +3102,8 @@ int irdma_sc_cqp_init(struct irdma_sc_cqp *cqp, info->dev->cqp = cqp;IRDMA_RING_INIT (cqp->sq_ring, cqp->sq_size); - cqp->dev->cqp_cmd_stats[IRDMA_OP_REQ_CMDS ] =0 ; - cqp->dev->cqp_cmd_stats[IRDMA_OP_CMPL_CMDS ] =0 ; + cqp->requested_ops =0 ; +atomic64_set (&cqp->completed_ops,0 );/* for the cqp commands backlog. */ INIT_LIST_HEAD (&cqp->dev->cqp_cmd_head);
@@ -3255,7 +3255,7 @@ __le64 *irdma_sc_cqp_get_next_send_wqe_idx(struct irdma_sc_cqp *cqp, u64 scratchif (ret_code)return NULL ; - cqp->dev->cqp_cmd_stats[IRDMA_OP_REQ_CMDS ]++; + cqp->requested_ops++;if (!*wqe_idx) cqp->polarity = !cqp->polarity; wqe = cqp->sq_base[*wqe_idx].elem;
@@ -3381,7 +3381,7 @@ int irdma_sc_ccq_get_cqe_info(struct irdma_sc_cq *ccq,dma_wmb ();/* make sure shadow area is updated before moving tail */ IRDMA_RING_MOVE_TAIL (cqp->sq_ring); - ccq->dev->cqp_cmd_stats[IRDMA_OP_CMPL_CMDS ]++; +atomic64_inc (&cqp->completed_ops);return ret_code; }
drivers/infiniband/hw/irdma/defs.h +22 -24
54 lines not on this page · raw message
drivers/infiniband/hw/irdma/type.h +2 -0
@@ -410,6 +410,8 @@ struct irdma_sc_cqp {struct irdma_dcqcn_cc_params dcqcn_params;__le64 *host_ctx;u64 *scratch_array; +u64 requested_ops; +atomic64_t completed_ops;u32 cqp_id;u32 sq_size;u32 hw_sq_size;
drivers/infiniband/hw/irdma/utils.c +1 -1
@@ -567,7 +567,7 @@ static int irdma_wait_event(struct irdma_pci_f *rf,bool cqp_error = false;int err_code =0 ; - cqp_timeout.compl_cqp_cmds = rf->sc_dev.cqp_cmd_stats[IRDMA_OP_CMPL_CMDS ]; + cqp_timeout.compl_cqp_cmds =atomic64_read (&rf->sc_dev.cqp->completed_ops); do { irdma_cqp_ce_handler(rf, &rf->ccq.sc_cq); if (wait_event_timeout(cqp_request->waitq,
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 120/228 RDMA/irdma: Fix data race on CQP request done
In reply to Greg Kroah-HartmanFrom: Shiraz Saleem <[email protected]>
[ Upstream commit f0842bb3d38863777e3454da5653d80b5fde6321 ]
KCSAN detects a data race on cqp_request->request_done memory location which is accessed locklessly in irdma_handle_cqp_op while being updated in irdma_cqp_ce_handler.
Annotate lockless intent with READ_ONCE/WRITE_ONCE to avoid any compiler optimizations like load fusing and/or KCSAN warning.
[222808.417128] BUG: KCSAN: data-race in irdma_cqp_ce_handler [irdma] / irdma_wait_event [irdma]
[222808.417532] write to 0xffff8e44107019dc of 1 bytes by task 29658 on cpu 5: [222808.417610] irdma_cqp_ce_handler+0x21e/0x270 [irdma] [222808.417725] cqp_compl_worker+0x1b/0x20 [irdma] [222808.417827] process_one_work+0x4d1/0xa40 [222808.417835] worker_thread+0x319/0x700 [222808.417842] kthread+0x180/0x1b0 [222808.417852] ret_from_fork+0x22/0x30
[222808.417918] read to 0xffff8e44107019dc of 1 bytes by task 29688 on cpu 1: [222808.417995] irdma_wait_event+0x1e2/0x2c0 [irdma] [222808.418099] irdma_handle_cqp_op+0xae/0x170 [irdma] [222808.418202] irdma_cqp_cq_destroy_cmd+0x70/0x90 [irdma] [222808.418308] irdma_puda_dele_rsrc+0x46d/0x4d0 [irdma] [222808.418411] irdma_rt_deinit_hw+0x179/0x1d0 [irdma] [222808.418514] irdma_ib_dealloc_device+0x11/0x40 [irdma] [222808.418618] ib_dealloc_device+0x2a/0x120 [ib_core] [222808.418823] __ib_unregister_device+0xde/0x100 [ib_core] [222808.418981] ib_unregister_device+0x22/0x40 [ib_core] [222808.419142] irdma_ib_unregister_device+0x70/0x90 [irdma] [222808.419248] i40iw_close+0x6f/0xc0 [irdma] [222808.419352] i40e_client_device_unregister+0x14a/0x180 [i40e] [222808.419450] i40iw_remove+0x21/0x30 [irdma] [222808.419554] auxiliary_bus_remove+0x31/0x50 [222808.419563] device_remove+0x69/0xb0 [222808.419572] device_release_driver_internal+0x293/0x360 [222808.419582] driver_detach+0x7c/0xf0 [222808.419592] bus_remove_driver+0x8c/0x150 [222808.419600] driver_unregister+0x45/0x70 [222808.419610] auxiliary_driver_unregister+0x16/0x30 [222808.419618] irdma_exit_module+0x18/0x1e [irdma] [222808.419733] __do_sys_delete_module.constprop.0+0x1e2/0x310 [222808.419745] __x64_sys_delete_module+0x1b/0x30 [222808.419755] do_syscall_64+0x39/0x90 [222808.419763] entry_SYSCALL_64_after_hwframe+0x63/0xcd
[222808.419829] value changed: 0x01 -> 0x03
--- drivers/infiniband/hw/irdma/hw.c | 2 +- drivers/infiniband/hw/irdma/main.h | 2 +- drivers/infiniband/hw/irdma/utils.c | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-)
drivers/infiniband/hw/irdma/hw.c +1 -1
@@ -2068,7 +2068,7 @@ void irdma_cqp_ce_handler(struct irdma_pci_f *rf, struct irdma_sc_cq *cq) cqp_request->compl_info.error = info.error;if (cqp_request->waiting) { - cqp_request->request_done = true; +WRITE_ONCE (cqp_request->request_done, true);wake_up (&cqp_request->waitq);irdma_put_cqp_request (&rf->cqp, cqp_request); }else {
drivers/infiniband/hw/irdma/main.h +1 -1
@@ -159,8 +159,8 @@ struct irdma_cqp_request {void (*callback_fcn)(struct irdma_cqp_request *cqp_request);void *param;struct irdma_cqp_compl_info compl_info; +bool request_done;/* READ/WRITE_ONCE macros operate on it */ bool waiting:1; - bool request_done:1; bool dynamic:1; };
drivers/infiniband/hw/irdma/utils.c +3 -3
@@ -481,7 +481,7 @@ void irdma_free_cqp_request(struct irdma_cqp *cqp,if (cqp_request->dynamic) {kfree (cqp_request); }else { - cqp_request->request_done = false; +WRITE_ONCE (cqp_request->request_done, false); cqp_request->callback_fcn =NULL ; cqp_request->waiting = false;
@@ -515,7 +515,7 @@ irdma_free_pending_cqp_request(struct irdma_cqp *cqp, {if (cqp_request->waiting) { cqp_request->compl_info.error = true; - cqp_request->request_done = true; +WRITE_ONCE (cqp_request->request_done, true);wake_up (&cqp_request->waitq); } wait_event_timeout(cqp->remove_wq,
@@ -571,7 +571,7 @@ static int irdma_wait_event(struct irdma_pci_f *rf, do { irdma_cqp_ce_handler(rf, &rf->ccq.sc_cq); if (wait_event_timeout(cqp_request->waitq, - cqp_request->request_done, + READ_ONCE(cqp_request->request_done), msecs_to_jiffies(CQP_COMPL_WAIT_TIME_MS))) break;
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 121/228 RDMA/mthca: Fix crash when polling CQ for shared QPs
In reply to Greg Kroah-HartmanFrom: Thomas Bogendoerfer <[email protected]>
[ Upstream commit dc52aadbc1849cbe3fcf6bc54d35f6baa396e0a1 ]
Commit 21c2fe94abb2 ("RDMA/mthca: Combine special QP struct with mthca QP") introduced a new struct mthca_sqp which doesn't contain struct mthca_qp any longer. Placing a pointer of this new struct into qptable leads to crashes, because mthca_poll_one() expects a qp pointer. Fix this by putting the correct pointer into qptable.
--- drivers/infiniband/hw/mthca/mthca_qp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/infiniband/hw/mthca/mthca_qp.c +1 -1
@@ -1393,7 +1393,7 @@ int mthca_alloc_sqp(struct mthca_dev *dev,if (mthca_array_get (&dev->qp_table.qp, mqpn)) err = -EBUSY ;else -mthca_array_set (&dev->qp_table.qp, mqpn, qp->sqp); +mthca_array_set (&dev->qp_table.qp, mqpn, qp);spin_unlock_irq (&dev->qp_table.lock);if (err)
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 122/228 RDMA/bnxt_re: Prevent handling any completions after qp destroy
In reply to Greg Kroah-HartmanFrom: Kashyap Desai <[email protected]>
[ Upstream commit b5bbc6551297447d3cca55cf907079e206e9cd82 ]
HW may generate completions that indicates QP is destroyed. Driver should not be scheduling any more completion handlers for this QP, after the QP is destroyed. Since CQs are active during the QP destroy, driver may still schedule completion handlers. This can cause a race where the destroy_cq and poll_cq running simultaneously.
Snippet of kernel panic while doing bnxt_re driver load unload in loop. This indicates a poll after the CQ is freed.
[77786.481636] Call Trace: [77786.481640] <TASK> [77786.481644] bnxt_re_poll_cq+0x14a/0x620 [bnxt_re] [77786.481658] ? kvm_clock_read+0x14/0x30 [77786.481693] __ib_process_cq+0x57/0x190 [ib_core] [77786.481728] ib_cq_poll_work+0x26/0x80 [ib_core] [77786.481761] process_one_work+0x1e5/0x3f0 [77786.481768] worker_thread+0x50/0x3a0 [77786.481785] ? __pfx_worker_thread+0x10/0x10 [77786.481790] kthread+0xe2/0x110 [77786.481794] ? __pfx_kthread+0x10/0x10 [77786.481797] ret_from_fork+0x2c/0x50
To avoid this, complete all completion handlers before returning the destroy QP. If free_cq is called soon after destroy_qp, IB stack will cancel the CQ work before invoking the destroy_cq verb and this will prevent any race mentioned.
--- drivers/infiniband/hw/bnxt_re/ib_verbs.c | 12 ++++++++++++ drivers/infiniband/hw/bnxt_re/qplib_fp.c | 18 ++++++++++++++++++ drivers/infiniband/hw/bnxt_re/qplib_fp.h | 1 + 3 files changed, 31 insertions(+)
drivers/infiniband/hw/bnxt_re/ib_verbs.c +12 -0
@@ -796,7 +796,10 @@ static int bnxt_re_destroy_gsi_sqp(struct bnxt_re_qp *qp)int bnxt_re_destroy_qp (struct ib_qp *ib_qp,struct ib_udata *udata) { struct bnxt_re_qp *qp = container_of(ib_qp, struct bnxt_re_qp, ib_qp); +struct bnxt_qplib_qp *qplib_qp = &qp->qplib_qp;struct bnxt_re_dev *rdev = qp->rdev; +struct bnxt_qplib_nq *scq_nq =NULL ; +struct bnxt_qplib_nq *rcq_nq =NULL ;unsigned int flags;int rc;
@@ -830,6 +833,15 @@ int bnxt_re_destroy_qp(struct ib_qp *ib_qp, struct ib_udata *udata)ib_umem_release (qp->rumem);ib_umem_release (qp->sumem); +/* Flush all the entries of notification queue associated with +* given qp. +*/ + scq_nq = qplib_qp->scq->nq; + rcq_nq = qplib_qp->rcq->nq; +bnxt_re_synchronize_nq (scq_nq); +if (scq_nq != rcq_nq) +bnxt_re_synchronize_nq (rcq_nq); +return 0 ; }
drivers/infiniband/hw/bnxt_re/qplib_fp.c +18 -0
@@ -387,6 +387,24 @@ static void bnxt_qplib_service_nq(struct tasklet_struct *t)spin_unlock_bh (&hwq->lock); } +/* bnxt_re_synchronize_nq - self polling notification queue. +* @nq - notification queue pointer +* +* This function will start polling entries of a given notification queue +* for all pending entries. +* This function is useful to synchronize notification entries while resources +* are going away. +*/ + +void bnxt_re_synchronize_nq (struct bnxt_qplib_nq *nq) +{ +int budget = nq->budget; + + nq->budget = nq->hwq.max_elements; +bnxt_qplib_service_nq (&nq->nq_tasklet); + nq->budget = budget; +} +static irqreturn_t bnxt_qplib_nq_irq (int irq,void *dev_instance) {struct bnxt_qplib_nq *nq = dev_instance;
drivers/infiniband/hw/bnxt_re/qplib_fp.h +1 -0
@@ -548,6 +548,7 @@ int bnxt_qplib_process_flush_list(struct bnxt_qplib_cq *cq,struct bnxt_qplib_cqe *cqe, int num_cqes);void bnxt_qplib_flush_cqn_wq (struct bnxt_qplib_qp *qp); +void bnxt_re_synchronize_nq (struct bnxt_qplib_nq *nq);static inline void *bnxt_qplib_get_swqe (struct bnxt_qplib_q *que,u32 *swq_idx) {
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 123/228 drm/msm: Fix IS_ERR_OR_NULL() vs NULL check in a5xx_submit_in_rb()
In reply to Greg Kroah-HartmanFrom: Gaosheng Cui <[email protected]>
[ Upstream commit 6e8a996563ecbe68e49c49abd4aaeef69f11f2dc ]
The msm_gem_get_vaddr() returns an ERR_PTR() on failure, and a null is catastrophic here, so we should use IS_ERR_OR_NULL() to check the return value.
Patchwork: https://patchwork.freedesktop.org/patch/547712/
--- drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/msm/adreno/a5xx_gpu.c +1 -1
@@ -89,7 +89,7 @@ static void a5xx_submit_in_rb(struct msm_gpu *gpu, struct msm_gem_submit *submit* since we've already mapped it once in * submit_reloc() */ -if (WARN_ON (!ptr)) +if (WARN_ON (IS_ERR_OR_NULL (ptr)))return ;for (i =0 ; i < dwords; i++) {
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 124/228 cxl/acpi: Fix a use-after-free in cxl_parse_cfmws()
In reply to Greg Kroah-HartmanFrom: Breno Leitao <[email protected]>
[ Upstream commit 4cf67d3cc9994a59cf77bb9c0ccf9007fe916afe ]
KASAN and KFENCE detected an user-after-free in the CXL driver. This happens in the cxl_decoder_add() fail path. KASAN prints the following error:
BUG: KASAN: slab-use-after-free in cxl_parse_cfmws (drivers/cxl/acpi.c:299)
This happens in cxl_parse_cfmws(), where put_device() is called, releasing cxld, which is accessed later.
Use the local variables in the dev_err() instead of pointing to the released memory. Since the dev_err() is printing a resource, change the open coded print format to use the %pr format specifier.
--- drivers/cxl/acpi.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/cxl/acpi.c +1 -2
@@ -154,8 +154,7 @@ static int cxl_parse_cfmws(union acpi_subtable_headers *header, void *arg,else rc =cxl_decoder_autoremove (dev, cxld);if (rc) { -dev_err (dev,"Failed to add decode range [%#llx - %#llx]\n" , - cxld->hpa_range.start, cxld->hpa_range.end); +dev_err (dev,"Failed to add decode range: %pr" , res);return 0 ; } dev_dbg(dev, "add: %s node: %d range [%#llx - %#llx]\n",
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 125/228 cxl/acpi: Return rc instead of 0 in cxl_parse_cfmws()
In reply to Greg Kroah-HartmanFrom: Breno Leitao <[email protected]>
[ Upstream commit 91019b5bc7c2c5e6f676cce80ee6d12b2753d018 ]
Driver initialization returned success (return 0) even if the initialization (cxl_decoder_add() or acpi_table_parse_cedt()) failed.
Return the error instead of swallowing it.
--- drivers/cxl/acpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/cxl/acpi.c +1 -1
@@ -155,7 +155,7 @@ static int cxl_parse_cfmws(union acpi_subtable_headers *header, void *arg, rc =cxl_decoder_autoremove (dev, cxld);if (rc) {dev_err (dev,"Failed to add decode range: %pr" , res); -return 0 ; +return rc; } dev_dbg(dev, "add: %s node: %d range [%#llx - %#llx]\n", dev_name(&cxld->dev),
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 126/228 ASoC: fsl_spdif: Silence output on stop
In reply to Greg Kroah-HartmanFrom: Matus Gajdos <[email protected]>
[ Upstream commit 0e4c2b6b0c4a4b4014d9424c27e5e79d185229c5 ]
Clear TX registers on stop to prevent the SPDIF interface from sending last written word over and over again.
--- sound/soc/fsl/fsl_spdif.c | 2 ++ 1 file changed, 2 insertions(+)
sound/soc/fsl/fsl_spdif.c +2 -0
@@ -751,6 +751,8 @@ static int fsl_spdif_trigger(struct snd_pcm_substream *substream,case SNDRV_PCM_TRIGGER_PAUSE_PUSH :regmap_update_bits (regmap,REG_SPDIF_SCR , dmaen,0 );regmap_update_bits (regmap,REG_SPDIF_SIE , intr,0 ); +regmap_write (regmap,REG_SPDIF_STL ,0x0 ); +regmap_write (regmap,REG_SPDIF_STR ,0x0 );break ;default :return -EINVAL ;
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 127/228 block: Fix a source code comment in include/uapi/linux/blkzoned.h
In reply to Greg Kroah-HartmanFrom: Bart Van Assche <[email protected]>
[ Upstream commit e0933b526fbfd937c4a8f4e35fcdd49f0e22d411 ]
Fix the symbolic names for zone conditions in the blkzoned.h header file.
--- include/uapi/linux/blkzoned.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
include/uapi/linux/blkzoned.h +5 -5
@@ -51,13 +51,13 @@ enum blk_zone_type {* * The Zone Condition state machine in the ZBC/ZAC standards maps the above * deinitions as: -* - ZC1: Empty | BLK_ZONE_EMPTY +* - ZC1: Empty | BLK_ZONE_COND_EMPTY * - ZC2: Implicit Open | BLK_ZONE_COND_IMP_OPEN * - ZC3: Explicit Open | BLK_ZONE_COND_EXP_OPEN -* - ZC4: Closed | BLK_ZONE_CLOSED -* - ZC5: Full | BLK_ZONE_FULL -* - ZC6: Read Only | BLK_ZONE_READONLY -* - ZC7: Offline | BLK_ZONE_OFFLINE +* - ZC4: Closed | BLK_ZONE_COND_CLOSED +* - ZC5: Full | BLK_ZONE_COND_FULL +* - ZC6: Read Only | BLK_ZONE_COND_READONLY +* - ZC7: Offline | BLK_ZONE_COND_OFFLINE * * Conditions 0x5 to 0xC are reserved by the current ZBC/ZAC spec and should * be considered invalid.
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 128/228 smb3: do not set NTLMSSP_VERSION flag for negotiate not auth request
In reply to Greg Kroah-HartmanFrom: Steve French <[email protected]>
[ Upstream commit 19826558210b9102a7d4681c91784d137d60d71b ]
The NTLMSSP_NEGOTIATE_VERSION flag only needs to be sent during the NTLMSSP NEGOTIATE (not the AUTH) request, so filter it out for NTLMSSP AUTH requests. See MS-NLMP 2.2.1.3
This fixes a problem found by the gssntlmssp server.
--- fs/smb/client/sess.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
fs/smb/client/sess.c +3 -1
@@ -1014,6 +1014,7 @@ int build_ntlmssp_smb3_negotiate_blob(unsigned char **pbuffer, } +/* See MS-NLMP 2.2.1.3 */ int build_ntlmssp_auth_blob(unsigned char **pbuffer, u16 *buflen, struct cifs_ses *ses,
@@ -1048,7 +1049,8 @@ int build_ntlmssp_auth_blob(unsigned char **pbuffer, flags = ses->ntlmssp->server_flags |NTLMSSP_REQUEST_TARGET |NTLMSSP_NEGOTIATE_TARGET_INFO |NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED ; - +/* we only send version information in ntlmssp negotiate, so do not set this flag */ + flags = flags & ~NTLMSSP_NEGOTIATE_VERSION ; tmp = *pbuffer +sizeof (AUTHENTICATE_MESSAGE ); sec_blob->NegotiateFlags =cpu_to_le32 (flags);
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 129/228 drm/i915: Fix an error handling path in igt_write_huge()
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit e354f67733115b4453268f61e6e072e9b1ea7a2f ]
All error handling paths go to 'out', except this one. Be consistent and also branch to 'out' here.
--- drivers/gpu/drm/i915/gem/selftests/huge_pages.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/gpu/drm/i915/gem/selftests/huge_pages.c +4 -2
@@ -1185,8 +1185,10 @@ static int igt_write_huge(struct drm_i915_private *i915,* times in succession a possibility by enlarging the permutation array. */ order =i915_random_order (count * count, &prng); -if (!order) -return -ENOMEM ; +if (!order) { + err = -ENOMEM ; + goto out; + } max_page_size =rounddown_pow_of_two (obj->mm.page_sizes.sg); max =div_u64 (max - size, max_page_size);
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 130/228 xenbus: check xen_domain in xenbus_probe_initcall
In reply to Greg Kroah-HartmanFrom: Stefano Stabellini <[email protected]>
[ Upstream commit 0d8f7cc8057890db08c54fe610d8a94af59da082 ]
The same way we already do in xenbus_init.
Fixes the following warning:
[ 352.175563] Trying to free already-free IRQ 0 [ 352.177355] WARNING: CPU: 1 PID: 88 at kernel/irq/manage.c:1893 free_irq+0xbf/0x350 [...] [ 352.213951] Call Trace: [ 352.214390] <TASK> [ 352.214717] ? __warn+0x81/0x170 [ 352.215436] ? free_irq+0xbf/0x350 [ 352.215906] ? report_bug+0x10b/0x200 [ 352.216408] ? prb_read_valid+0x17/0x20 [ 352.216926] ? handle_bug+0x44/0x80 [ 352.217409] ? exc_invalid_op+0x13/0x60 [ 352.217932] ? asm_exc_invalid_op+0x16/0x20 [ 352.218497] ? free_irq+0xbf/0x350 [ 352.218979] ? __pfx_xenbus_probe_thread+0x10/0x10 [ 352.219600] xenbus_probe+0x7a/0x80 [ 352.221030] xenbus_probe_thread+0x76/0xc0
--- drivers/xen/xenbus/xenbus_probe.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/xen/xenbus/xenbus_probe.c +3 -0
@@ -811,6 +811,9 @@ static int xenbus_probe_thread(void *unused)static int __init xenbus_probe_initcall (void ) { +if (!xen_domain ()) +return -ENODEV ; +/* * Probe XenBus here in the XS_PV case, and also XS_HVM unless we * need to wait for the platform PCI device to come up or
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 131/228 dm raid: fix missing reconfig_mutex unlock in raid_ctr() error paths
In reply to Greg Kroah-HartmanFrom: Yu Kuai <[email protected]>
[ Upstream commit bae3028799dc4f1109acc4df37c8ff06f2d8f1a0 ]
In the error paths 'bad_stripe_cache' and 'bad_check_reshape', 'reconfig_mutex' is still held after raid_ctr() returns.
--- drivers/md/dm-raid.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
drivers/md/dm-raid.c +7 -2
@@ -3274,15 +3274,19 @@ static int raid_ctr(struct dm_target *ti, unsigned int argc, char **argv)/* Try to adjust the raid4/5/6 stripe cache size to the stripe size */ if (rs_is_raid456 (rs)) { r =rs_set_raid456_stripe_cache (rs); -if (r) +if (r) { +mddev_unlock (&rs->md); goto bad_stripe_cache; + } }/* Now do an early reshape check */ if (test_bit (RT_FLAG_RESHAPE_RS , &rs->runtime_flags)) { r =rs_check_reshape (rs); -if (r) +if (r) { +mddev_unlock (&rs->md); goto bad_check_reshape; + }/* Restore new, ctr requested layout to perform check */ rs_config_restore (rs, &rs_layout);
@@ -3291,6 +3295,7 @@ static int raid_ctr(struct dm_target *ti, unsigned int argc, char **argv) r = rs->md.pers->check_reshape (&rs->md);if (r) { ti->error ="Reshape check failed" ; +mddev_unlock (&rs->md); goto bad_check_reshape; } }
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 132/228 dm raid: clean up four equivalent goto tags in raid_ctr()
In reply to Greg Kroah-HartmanFrom: Yu Kuai <[email protected]>
[ Upstream commit e74c874eabe2e9173a8fbdad616cd89c70eb8ffd ]
There are four equivalent goto tags in raid_ctr(), clean them up to use just one.
There is no functional change and this is preparation to fix raid_ctr()'s unprotected md_stop().
Stable-dep-of: 7d5fff8982a2 ("dm raid: protect md_stop() with 'reconfig_mutex'")
--- drivers/md/dm-raid.c | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-)
drivers/md/dm-raid.c +9 -18
@@ -3254,8 +3254,7 @@ static int raid_ctr(struct dm_target *ti, unsigned int argc, char **argv) r =md_start (&rs->md);if (r) { ti->error ="Failed to start raid array" ; -mddev_unlock (&rs->md); - goto bad_md_start; + goto bad_unlock; }/* If raid4/5/6 journal mode explicitly requested (only possible with journal dev) -> set it */
@@ -3263,8 +3262,7 @@ static int raid_ctr(struct dm_target *ti, unsigned int argc, char **argv) r =r5c_journal_mode_set (&rs->md, rs->journal_dev.mode);if (r) { ti->error ="Failed to set raid4/5/6 journal mode" ; -mddev_unlock (&rs->md); - goto bad_journal_mode_set; + goto bad_unlock; } }
@@ -3274,19 +3272,15 @@ static int raid_ctr(struct dm_target *ti, unsigned int argc, char **argv)/* Try to adjust the raid4/5/6 stripe cache size to the stripe size */ if (rs_is_raid456 (rs)) { r =rs_set_raid456_stripe_cache (rs); -if (r) { -mddev_unlock (&rs->md); - goto bad_stripe_cache; - } +if (r) + goto bad_unlock; }/* Now do an early reshape check */ if (test_bit (RT_FLAG_RESHAPE_RS , &rs->runtime_flags)) { r =rs_check_reshape (rs); -if (r) { -mddev_unlock (&rs->md); - goto bad_check_reshape; - } +if (r) + goto bad_unlock;/* Restore new, ctr requested layout to perform check */ rs_config_restore (rs, &rs_layout);
@@ -3295,8 +3289,7 @@ static int raid_ctr(struct dm_target *ti, unsigned int argc, char **argv) r = rs->md.pers->check_reshape (&rs->md);if (r) { ti->error ="Reshape check failed" ; -mddev_unlock (&rs->md); - goto bad_check_reshape; + goto bad_unlock; } } }
@@ -3307,10 +3300,8 @@ static int raid_ctr(struct dm_target *ti, unsigned int argc, char **argv)mddev_unlock (&rs->md);return 0 ; -bad_md_start: -bad_journal_mode_set: -bad_stripe_cache: -bad_check_reshape: +bad_unlock: +mddev_unlock (&rs->md);md_stop (&rs->md); bad:raid_set_free (rs);
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 133/228 dm raid: protect md_stop() with reconfig_mutex
In reply to Greg Kroah-HartmanFrom: Yu Kuai <[email protected]>
[ Upstream commit 7d5fff8982a2199d49ec067818af7d84d4f95ca0 ]
__md_stop_writes() and __md_stop() will modify many fields that are protected by 'reconfig_mutex', and all the callers will grab 'reconfig_mutex' except for md_stop().
Also, update md_stop() to make certain 'reconfig_mutex' is held using lockdep_assert_held().
--- drivers/md/dm-raid.c | 4 +++- drivers/md/md.c | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-)
drivers/md/dm-raid.c +3 -1
@@ -3301,8 +3301,8 @@ static int raid_ctr(struct dm_target *ti, unsigned int argc, char **argv)return 0 ; bad_unlock: -mddev_unlock (&rs->md);md_stop (&rs->md); +mddev_unlock (&rs->md); bad:raid_set_free (rs);
@@ -3313,7 +3313,9 @@ static void raid_dtr(struct dm_target *ti) {struct raid_set *rs = ti->private; +mddev_lock_nointr (&rs->md);md_stop (&rs->md); +mddev_unlock (&rs->md);raid_set_free (rs); }
drivers/md/md.c +2 -0
@@ -6269,6 +6269,8 @@ static void __md_stop(struct mddev *mddev)void md_stop (struct mddev *mddev) { +lockdep_assert_held (&mddev->reconfig_mutex); +/* stop the array and free an attached data structures. * This is called from dm-raid */
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 134/228 drm/amd: Fix an error handling mistake in psp_sw_init()
In reply to Greg Kroah-HartmanFrom: Mario Limonciello <[email protected]>
[ Upstream commit c01aebeef3ce45f696ffa0a1303cea9b34babb45 ]
If the second call to amdgpu_bo_create_kernel() fails, the memory allocated from the first call should be cleared. If the third call fails, the memory from the second call should be cleared.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +3 -3
@@ -472,11 +472,11 @@ static int psp_sw_init(void *handle)return 0 ; failed2: -amdgpu_bo_free_kernel (&psp->fw_pri_bo, - &psp->fw_pri_mc_addr, &psp->fw_pri_buf); -failed1:amdgpu_bo_free_kernel (&psp->fence_buf_bo, &psp->fence_buf_mc_addr, &psp->fence_buf); +failed1: +amdgpu_bo_free_kernel (&psp->fw_pri_bo, + &psp->fw_pri_mc_addr, &psp->fw_pri_buf);return ret; }
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 135/228 drm/amd/display: Unlock on error path in dm_handle_mst_sideband_msg_ready_event()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit 38ac4e8385ffb275b1837986ca6c16f26ea028c5 ]
This error path needs to unlock the "aconnector->handle_mst_msg_ready" mutex before returning.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +1 -1
@@ -677,7 +677,7 @@ void dm_handle_mst_sideband_msg_ready_event(if (retry ==3 ) {DRM_ERROR ("Failed to ack MST event.\n" ); -return ; +break ; }drm_dp_mst_hpd_irq_send_new_request (&aconnector->mst_mgr);
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 136/228 RDMA/irdma: Fix op_type reporting in CQEs
In reply to Greg Kroah-HartmanFrom: Sindhu Devale <[email protected]>
[ Upstream commit 3bfb25fa2b5bb9c29681e6ac861808f4be1331a9 ]
The op_type field CQ poll info structure is incorrectly filled in with the queue type as opposed to the op_type received in the CQEs. The wrong opcode could be decoded and returned to the ULP.
Copy the op_type field received in the CQE in the CQ poll info structure.
--- drivers/infiniband/hw/irdma/uk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/infiniband/hw/irdma/uk.c +1 -1
@@ -1161,7 +1161,7 @@ int irdma_uk_cq_poll_cmpl(struct irdma_cq_uk *cq, } wqe_idx = (u32 )FIELD_GET (IRDMA_CQ_WQEIDX , qword3); info->qp_handle = (irdma_qp_handle )(unsigned long )qp; - info->op_type = (u8 )FIELD_GET (IRDMA_CQ_SQ , qword3); + info->op_type = (u8 )FIELD_GET (IRDMACQ_OP , qword3);if (info->q_type ==IRDMA_CQE_QTYPE_RQ ) {u32 array_idx;
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 137/228 RDMA/irdma: Report correct WC error
In reply to Greg Kroah-HartmanFrom: Sindhu Devale <[email protected]>
[ Upstream commit ae463563b7a1b7d4a3d0b065b09d37a76b693937 ]
Report the correct WC error if a MW bind is performed on an already valid/bound window.
--- drivers/infiniband/hw/irdma/hw.c | 1 + 1 file changed, 1 insertion(+)
drivers/infiniband/hw/irdma/hw.c +1 -0
@@ -191,6 +191,7 @@ static void irdma_set_flush_fields(struct irdma_sc_qp *qp,case IRDMA_AE_AMP_MWBIND_INVALID_RIGHTS :case IRDMA_AE_AMP_MWBIND_BIND_DISABLED :case IRDMA_AE_AMP_MWBIND_INVALID_BOUNDS : +case IRDMA_AE_AMP_MWBIND_VALID_STAG : qp->flush_code =FLUSH_MW_BIND_ERR ; qp->event_type =IRDMA_QP_EVENT_ACCESS_ERR ;break ;
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 138/228 drm/msm: Switch idr_lock to spinlock
In reply to Greg Kroah-HartmanFrom: Rob Clark <[email protected]>
[ Upstream commit e4f020c6a05db73eac49b7c3b3650251be374200 ]
Needed to idr_preload() which returns with preemption disabled.
Patchwork: https://patchwork.freedesktop.org/patch/527846/
Stable-dep-of: 1b5d0ddcb34a ("drm/msm: Disallow submit with fence id 0")
--- drivers/gpu/drm/msm/msm_drv.c | 6 ++---- drivers/gpu/drm/msm/msm_gem_submit.c | 10 +++++----- drivers/gpu/drm/msm/msm_gpu.h | 2 +- drivers/gpu/drm/msm/msm_submitqueue.c | 2 +- 4 files changed, 9 insertions(+), 11 deletions(-)
drivers/gpu/drm/msm/msm_drv.c +2 -4
@@ -932,13 +932,11 @@ static int wait_fence(struct msm_gpu_submitqueue *queue, uint32_t fence_id,* retired, so if the fence is not found it means there is nothing * to wait for */ - ret =mutex_lock_interruptible (&queue->idr_lock); -if (ret) -return ret; +spin_lock (&queue->idr_lock); fence =idr_find (&queue->fence_idr, fence_id);if (fence) fence =dma_fence_get_rcu (fence); -mutex_unlock (&queue->idr_lock); +spin_unlock (&queue->idr_lock);if (!fence)return 0 ;
drivers/gpu/drm/msm/msm_gem_submit.c +5 -5
@@ -72,9 +72,9 @@ void __msm_gem_submit_destroy(struct kref *kref)unsigned i;if (submit->fence_id) { -mutex_lock (&submit->queue->idr_lock); +spin_lock (&submit->queue->idr_lock);idr_remove (&submit->queue->fence_idr, submit->fence_id); -mutex_unlock (&submit->queue->idr_lock); +spin_unlock (&submit->queue->idr_lock); }dma_fence_put (submit->user_fence);
@@ -866,7 +866,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, submit->nr_cmds = i; -mutex_lock (&queue->idr_lock); +spin_lock (&queue->idr_lock);/* * If using userspace provided seqno fence, validate that the id
@@ -876,7 +876,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,*/ if ((args->flags &MSM_SUBMIT_FENCE_SN_IN ) &&idr_find (&queue->fence_idr, args->fence)) { -mutex_unlock (&queue->idr_lock); +spin_unlock (&queue->idr_lock); ret = -EINVAL ; goto out; }
@@ -910,7 +910,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, INT_MAX, GFP_KERNEL); } -mutex_unlock (&queue->idr_lock); +spin_unlock (&queue->idr_lock);if (submit->fence_id <0 ) { ret = submit->fence_id;
drivers/gpu/drm/msm/msm_gpu.h +1 -1
@@ -500,7 +500,7 @@ struct msm_gpu_submitqueue {struct msm_file_private *ctx;struct list_head node;struct idr fence_idr; -struct mutex idr_lock; +struct spinlock idr_lock;struct mutex lock;struct kref ref;struct drm_sched_entity *entity;
drivers/gpu/drm/msm/msm_submitqueue.c +1 -1
@@ -200,7 +200,7 @@ int msm_submitqueue_create(struct drm_device *drm, struct msm_file_private *ctx, *id = queue->id;idr_init (&queue->fence_idr); -mutex_init (&queue->idr_lock); +spin_lock_init (&queue->idr_lock);mutex_init (&queue->lock);list_add_tail (&queue->node, &ctx->submitqueues);
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 139/228 drm/msm: Disallow submit with fence id 0
In reply to Greg Kroah-HartmanFrom: Rob Clark <[email protected]>
[ Upstream commit 1b5d0ddcb34a605835051ae2950d5cfed0373dd8 ]
A fence id of zero is expected to be invalid, and is not removed from the fence_idr table. If userspace is requesting to specify the fence id with the FENCE_SN_IN flag, we need to reject a zero fence id value.
Patchwork: https://patchwork.freedesktop.org/patch/549180/
--- drivers/gpu/drm/msm/msm_gem_submit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/msm/msm_gem_submit.c +1 -1
@@ -875,7 +875,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,* after the job is armed */ if ((args->flags &MSM_SUBMIT_FENCE_SN_IN ) && -idr_find (&queue->fence_idr, args->fence)) { + (!args->fence ||idr_find (&queue->fence_idr, args->fence))) {spin_unlock (&queue->idr_lock); ret = -EINVAL ; goto out;
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 140/228 ublk_drv: move ublk_get_device_from_id into ublk_ctrl_uring_cmd
In reply to Greg Kroah-HartmanFrom: Ming Lei <[email protected]>
[ Upstream commit bfbcef036396a73fbf4b3fee385cc670159df5ad ]
It is annoying for each control command handler to get/put ublk device and deal with failure.
Control command handler is simplified a lot by moving ublk_get_device_from_id into ublk_ctrl_uring_cmd().
Stable-dep-of: 53e7d08f6d6e ("ublk: fail to start device if queue setup is interrupted")
--- drivers/block/ublk_drv.c | 138 ++++++++++++++------------------------- 1 file changed, 49 insertions(+), 89 deletions(-)
drivers/block/ublk_drv.c +49 -89
@@ -1529,21 +1529,16 @@ static struct ublk_device *ublk_get_device_from_id(int idx)return ub; } -static int ublk_ctrl_start_dev (struct io_uring_cmd *cmd) +static int ublk_ctrl_start_dev (struct ublk_device *ub,struct io_uring_cmd *cmd) {struct ublksrv_ctrl_cmd *header = (struct ublksrv_ctrl_cmd *)cmd->cmd;int ublksrv_pid = (int )header->data[0 ]; -struct ublk_device *ub;struct gendisk *disk;int ret = -EINVAL ;if (ublksrv_pid <=0 )return -EINVAL ; - ub =ublk_get_device_from_id (header->dev_id); -if (!ub) -return -EINVAL ; -wait_for_completion_interruptible (&ub->completion);schedule_delayed_work (&ub->monitor_work,UBLK_DAEMON_MONITOR_PERIOD );
@@ -1593,21 +1588,20 @@ static int ublk_ctrl_start_dev(struct io_uring_cmd *cmd)put_disk (disk); out_unlock:mutex_unlock (&ub->mutex); -ublk_put_device (ub);return ret; } -static int ublk_ctrl_get_queue_affinity (struct io_uring_cmd *cmd) +static int ublk_ctrl_get_queue_affinity (struct ublk_device *ub, +struct io_uring_cmd *cmd) {struct ublksrv_ctrl_cmd *header = (struct ublksrv_ctrl_cmd *)cmd->cmd;void __user *argp = (void __user *)(unsigned long )header->addr; -struct ublk_device *ub;cpumask_var_t cpumask;unsigned long queue;unsigned int retlen;unsigned int i; -int ret = -EINVAL ; - +int ret; +if (header->len *BITS_PER_BYTE < nr_cpu_ids)return -EINVAL ;if (header->len & (sizeof (unsigned long )-1 ))
@@ -1615,17 +1609,12 @@ static int ublk_ctrl_get_queue_affinity(struct io_uring_cmd *cmd)if (!header->addr)return -EINVAL ; - ub =ublk_get_device_from_id (header->dev_id); -if (!ub) -return -EINVAL ; - queue = header->data[0 ];if (queue >= ub->dev_info.nr_hw_queues) - goto out_put_device; +return -EINVAL ; - ret = -ENOMEM ;if (!zalloc_cpumask_var (&cpumask,GFP_KERNEL )) - goto out_put_device; +return -ENOMEM ;for_each_possible_cpu (i) {if (ub->tag_set.map[HCTX_TYPE_DEFAULT ].mq_map[i] == queue)
@@ -1643,8 +1632,6 @@ static int ublk_ctrl_get_queue_affinity(struct io_uring_cmd *cmd) ret =0 ; out_free_cpumask:free_cpumask_var (cpumask); -out_put_device: -ublk_put_device (ub);return ret; }
@@ -1765,30 +1752,27 @@ static inline bool ublk_idr_freed(int id)return ptr ==NULL ; } -static int ublk_ctrl_del_dev (int idx) +static int ublk_ctrl_del_dev (struct ublk_device **p_ub) { -struct ublk_device *ub; +struct ublk_device *ub = *p_ub; +int idx = ub->ub_number;int ret; ret =mutex_lock_killable (&ublk_ctl_mutex);if (ret)return ret; - ub =ublk_get_device_from_id (idx); -if (ub) { -ublk_remove (ub); -ublk_put_device (ub); - ret =0 ; - }else { - ret = -ENODEV ; - } +ublk_remove (ub); + +/* Mark the reference as consumed */ + *p_ub =NULL ; +ublk_put_device (ub);/* * Wait until the idr is removed, then it can be reused after * DEL_DEV command is returned. */ -if (!ret) -wait_event (ublk_idr_wq,ublk_idr_freed (idx)); +wait_event (ublk_idr_wq,ublk_idr_freed (idx));mutex_unlock (&ublk_ctl_mutex);return ret;
@@ -1803,50 +1787,36 @@ static inline void ublk_ctrl_cmd_dump(struct io_uring_cmd *cmd) header->data[0], header->addr, header->len); } -static int ublk_ctrl_stop_dev (struct io_uring_cmd *cmd) +static int ublk_ctrl_stop_dev (struct ublk_device *ub) { -struct ublksrv_ctrl_cmd *header = (struct ublksrv_ctrl_cmd *)cmd->cmd; -struct ublk_device *ub; - - ub =ublk_get_device_from_id (header->dev_id); -if (!ub) -return -EINVAL ; -ublk_stop_dev (ub);cancel_work_sync (&ub->stop_work);cancel_work_sync (&ub->quiesce_work); -ublk_put_device (ub);return 0 ; } -static int ublk_ctrl_get_dev_info (struct io_uring_cmd *cmd) +static int ublk_ctrl_get_dev_info (struct ublk_device *ub, +struct io_uring_cmd *cmd) {struct ublksrv_ctrl_cmd *header = (struct ublksrv_ctrl_cmd *)cmd->cmd;void __user *argp = (void __user *)(unsigned long )header->addr; -struct ublk_device *ub; -int ret =0 ;if (header->len <sizeof (struct ublksrv_ctrl_dev_info ) || !header->addr)return -EINVAL ; - ub =ublk_get_device_from_id (header->dev_id); -if (!ub) -return -EINVAL ; -if (copy_to_user (argp, &ub->dev_info,sizeof (ub->dev_info))) - ret = -EFAULT ; -ublk_put_device (ub); +return -EFAULT ; -return ret; +return 0 ; } -static int ublk_ctrl_get_params (struct io_uring_cmd *cmd) +static int ublk_ctrl_get_params (struct ublk_device *ub, +struct io_uring_cmd *cmd) {struct ublksrv_ctrl_cmd *header = (struct ublksrv_ctrl_cmd *)cmd->cmd;void __user *argp = (void __user *)(unsigned long )header->addr;struct ublk_params_header ph; -struct ublk_device *ub;int ret;if (header->len <=sizeof (ph) || !header->addr)
@@ -1861,10 +1831,6 @@ static int ublk_ctrl_get_params(struct io_uring_cmd *cmd)if (ph.len >sizeof (struct ublk_params )) ph.len =sizeof (struct ublk_params ); - ub =ublk_get_device_from_id (header->dev_id); -if (!ub) -return -EINVAL ; -mutex_lock (&ub->mutex);if (copy_to_user (argp, &ub->params, ph.len)) ret = -EFAULT ;
@@ -1872,16 +1838,15 @@ static int ublk_ctrl_get_params(struct io_uring_cmd *cmd) ret =0 ;mutex_unlock (&ub->mutex); -ublk_put_device (ub);return ret; } -static int ublk_ctrl_set_params (struct io_uring_cmd *cmd) +static int ublk_ctrl_set_params (struct ublk_device *ub, +struct io_uring_cmd *cmd) {struct ublksrv_ctrl_cmd *header = (struct ublksrv_ctrl_cmd *)cmd->cmd;void __user *argp = (void __user *)(unsigned long )header->addr;struct ublk_params_header ph; -struct ublk_device *ub;int ret = -EFAULT ;if (header->len <=sizeof (ph) || !header->addr)
@@ -1896,10 +1861,6 @@ static int ublk_ctrl_set_params(struct io_uring_cmd *cmd)if (ph.len >sizeof (struct ublk_params )) ph.len =sizeof (struct ublk_params ); - ub =ublk_get_device_from_id (header->dev_id); -if (!ub) -return -EINVAL ; -/* parameters can only be changed when device isn't live */ mutex_lock (&ub->mutex);if (ub->dev_info.state ==UBLK_S_DEV_LIVE ) {
@@ -1914,7 +1875,6 @@ static int ublk_ctrl_set_params(struct io_uring_cmd *cmd) ub->params.types =0 ; }mutex_unlock (&ub->mutex); -ublk_put_device (ub);return ret; }
@@ -1941,17 +1901,13 @@ static void ublk_queue_reinit(struct ublk_device *ub, struct ublk_queue *ubq) } } -static int ublk_ctrl_start_recovery (struct io_uring_cmd *cmd) +static int ublk_ctrl_start_recovery (struct ublk_device *ub, +struct io_uring_cmd *cmd) {struct ublksrv_ctrl_cmd *header = (struct ublksrv_ctrl_cmd *)cmd->cmd; -struct ublk_device *ub;int ret = -EINVAL ;int i; - ub =ublk_get_device_from_id (header->dev_id); -if (!ub) -return ret; -mutex_lock (&ub->mutex);if (!ublk_can_use_recovery (ub)) goto out_unlock;
@@ -1984,21 +1940,16 @@ static int ublk_ctrl_start_recovery(struct io_uring_cmd *cmd) ret =0 ; out_unlock:mutex_unlock (&ub->mutex); -ublk_put_device (ub);return ret; } -static int ublk_ctrl_end_recovery (struct io_uring_cmd *cmd) +static int ublk_ctrl_end_recovery (struct ublk_device *ub, +struct io_uring_cmd *cmd) {struct ublksrv_ctrl_cmd *header = (struct ublksrv_ctrl_cmd *)cmd->cmd;int ublksrv_pid = (int )header->data[0 ]; -struct ublk_device *ub;int ret = -EINVAL ; - ub =ublk_get_device_from_id (header->dev_id); -if (!ub) -return ret; -pr_devel ("%s: Waiting for new ubq_daemons(nr: %d) are ready, dev id %d...\n" , __func__, ub->dev_info.nr_hw_queues, header->dev_id);/* wait until new ubq_daemon sending all FETCH_REQ */
@@ -2026,7 +1977,6 @@ static int ublk_ctrl_end_recovery(struct io_uring_cmd *cmd) ret =0 ; out_unlock:mutex_unlock (&ub->mutex); -ublk_put_device (ub);return ret; }
@@ -2034,6 +1984,7 @@ static int ublk_ctrl_uring_cmd(struct io_uring_cmd *cmd, unsigned int issue_flags) {struct ublksrv_ctrl_cmd *header = (struct ublksrv_ctrl_cmd *)cmd->cmd; +struct ublk_device *ub =NULL ;int ret = -EINVAL ;if (issue_flags &IO_URING_F_NONBLOCK )
@@ -2048,41 +1999,50 @@ static int ublk_ctrl_uring_cmd(struct io_uring_cmd *cmd,if (!capable (CAP_SYS_ADMIN )) goto out; - ret = -ENODEV ; +if (cmd->cmd_op !=UBLK_CMD_ADD_DEV ) { + ret = -ENODEV ; + ub =ublk_get_device_from_id (header->dev_id); +if (!ub) + goto out; + } +switch (cmd->cmd_op) {case UBLK_CMD_START_DEV : - ret =ublk_ctrl_start_dev (cmd); + ret =ublk_ctrl_start_dev (ub, cmd);break ;case UBLK_CMD_STOP_DEV : - ret =ublk_ctrl_stop_dev (cmd); + ret =ublk_ctrl_stop_dev (ub);break ;case UBLK_CMD_GET_DEV_INFO : - ret =ublk_ctrl_get_dev_info (cmd); + ret =ublk_ctrl_get_dev_info (ub, cmd);break ;case UBLK_CMD_ADD_DEV : ret =ublk_ctrl_add_dev (cmd);break ;case UBLK_CMD_DEL_DEV : - ret =ublk_ctrl_del_dev (header->dev_id); + ret =ublk_ctrl_del_dev (&ub);break ;case UBLK_CMD_GET_QUEUE_AFFINITY : - ret =ublk_ctrl_get_queue_affinity (cmd); + ret =ublk_ctrl_get_queue_affinity (ub, cmd);break ;case UBLK_CMD_GET_PARAMS : - ret =ublk_ctrl_get_params (cmd); + ret =ublk_ctrl_get_params (ub, cmd);break ;case UBLK_CMD_SET_PARAMS : - ret =ublk_ctrl_set_params (cmd); + ret =ublk_ctrl_set_params (ub, cmd);break ;case UBLK_CMD_START_USER_RECOVERY : - ret =ublk_ctrl_start_recovery (cmd); + ret =ublk_ctrl_start_recovery (ub, cmd);break ;case UBLK_CMD_END_USER_RECOVERY : - ret =ublk_ctrl_end_recovery (cmd); + ret =ublk_ctrl_end_recovery (ub, cmd);break ;default : + ret = -ENOTSUPP ;break ; } +if (ub) +ublk_put_device (ub); out:io_uring_cmd_done (cmd, ret,0 , issue_flags); pr_devel("%s: cmd done ret %d cmd_op %x, dev id %d qid %d\n",
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 141/228 ublk: fail to start device if queue setup is interrupted
In reply to Greg Kroah-HartmanFrom: Ming Lei <[email protected]>
[ Upstream commit 53e7d08f6d6e214c40db1f51291bb2975c789dc2 ]
In ublk_ctrl_start_dev(), if wait_for_completion_interruptible() is interrupted by signal, queues aren't setup successfully yet, so we have to fail UBLK_CMD_START_DEV, otherwise kernel oops can be triggered.
Reported by German when working on qemu-storage-deamon which requires single thread ublk daemon.
--- drivers/block/ublk_drv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/block/ublk_drv.c +2 -1
@@ -1539,7 +1539,8 @@ static int ublk_ctrl_start_dev(struct ublk_device *ub, struct io_uring_cmd *cmd)if (ublksrv_pid <=0 )return -EINVAL ; -wait_for_completion_interruptible (&ub->completion); +if (wait_for_completion_interruptible (&ub->completion) !=0 ) +return -EINTR ;schedule_delayed_work (&ub->monitor_work,UBLK_DAEMON_MONITOR_PERIOD );
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 142/228 ublk: fail to recover device if queue setup is interrupted
In reply to Greg Kroah-HartmanFrom: Ming Lei <[email protected]>
[ Upstream commit 0c0cbd4ebc375ceebc75c89df04b74f215fab23a ]
In ublk_ctrl_end_recovery(), if wait_for_completion_interruptible() is interrupted by signal, queues aren't setup successfully yet, so we have to fail UBLK_CMD_END_USER_RECOVERY, otherwise kernel oops can be triggered.
--- drivers/block/ublk_drv.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/block/ublk_drv.c +3 -1
@@ -1954,7 +1954,9 @@ static int ublk_ctrl_end_recovery(struct ublk_device *ub,pr_devel ("%s: Waiting for new ubq_daemons(nr: %d) are ready, dev id %d...\n" , __func__, ub->dev_info.nr_hw_queues, header->dev_id);/* wait until new ubq_daemon sending all FETCH_REQ */ -wait_for_completion_interruptible (&ub->completion); +if (wait_for_completion_interruptible (&ub->completion)) +return -EINTR ; +pr_devel ("%s: All new ubq_daemons(nr: %d) are ready, dev id %d\n" , __func__, ub->dev_info.nr_hw_queues, header->dev_id);
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 143/228 ata: pata_ns87415: mark ns87560_tf_read static
In reply to Greg Kroah-HartmanFrom: Arnd Bergmann <[email protected]>
[ Upstream commit 3fc2febb0f8ffae354820c1772ec008733237cfa ]
The global function triggers a warning because of the missing prototype
drivers/ata/pata_ns87415.c:263:6: warning: no previous prototype for 'ns87560_tf_read' [-Wmissing-prototypes]
263 | void ns87560_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
There are no other references to this, so just make it static.
--- drivers/ata/pata_ns87415.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/ata/pata_ns87415.c +1 -1
@@ -260,7 +260,7 @@ static u8 ns87560_check_status(struct ata_port *ap)* LOCKING: * Inherited from caller. */ -void ns87560_tf_read (struct ata_port *ap,struct ata_taskfile *tf) +static void ns87560_tf_read (struct ata_port *ap,struct ata_taskfile *tf) {struct ata_ioports *ioaddr = &ap->ioaddr;
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 144/228 ring-buffer: Fix wrong stat of cpu_buffer->read
In reply to Greg Kroah-HartmanFrom: Zheng Yejian <[email protected]>
[ Upstream commit 2d093282b0d4357373497f65db6a05eb0c28b7c8 ]
When pages are removed in rb_remove_pages(), 'cpu_buffer->read' is set to 0 in order to make sure any read iterators reset themselves. However, this will mess 'entries' stating, see following steps:
# cd /sys/kernel/tracing/
# 1. Enlarge ring buffer prepare for later reducing:
# echo 20 > per_cpu/cpu0/buffer_size_kb
# 2. Write a log into ring buffer of cpu0:
# taskset -c 0 echo "hello1" > trace_marker
# 3. Read the log:
# cat per_cpu/cpu0/trace_pipe
<...>-332 [000] ..... 62.406844: tracing_mark_write: hello1
# 4. Stop reading and see the stats, now 0 entries, and 1 event readed:
# cat per_cpu/cpu0/stats
entries: 0
[...]
read events: 1
# 5. Reduce the ring buffer
# echo 7 > per_cpu/cpu0/buffer_size_kb
# 6. Now entries became unexpected 1 because actually no entries!!!
# cat per_cpu/cpu0/stats
entries: 1
[...]
read events: 0To fix it, introduce 'page_removed' field to count total removed pages since last reset, then use it to let read iterators reset themselves instead of changing the 'read' pointer.
--- kernel/trace/ring_buffer.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-)
kernel/trace/ring_buffer.c +12 -10
@@ -529,6 +529,8 @@ struct ring_buffer_per_cpu {rb_time_t before_stamp;u64 event_stamp[MAX_NEST ];u64 read_stamp; +/* pages removed since last reset */ +unsigned long pages_removed;/* ring buffer pages to update, > 0 to add, < 0 to remove */ long nr_pages_to_update;struct list_head new_pages;/* new pages to add */
@@ -564,6 +566,7 @@ struct ring_buffer_iter {struct buffer_page *head_page;struct buffer_page *cache_reader_page;unsigned long cache_read; +unsigned long cache_pages_removed;u64 read_stamp;u64 page_stamp;struct ring_buffer_event *event;
@@ -1967,6 +1970,8 @@ rb_remove_pages(struct ring_buffer_per_cpu *cpu_buffer, unsigned long nr_pages) to_remove =rb_list_head (to_remove)->next; head_bit |= (unsigned long )to_remove &RB_PAGE_HEAD ; } +/* Read iterators need to reset themselves when some pages removed */ + cpu_buffer->pages_removed += nr_removed; next_page =rb_list_head (to_remove)->next;
@@ -1988,12 +1993,6 @@ rb_remove_pages(struct ring_buffer_per_cpu *cpu_buffer, unsigned long nr_pages) cpu_buffer->head_page =list_entry (next_page, struct buffer_page, list); -/* -* change read pointer to make sure any read iterators reset -* themselves -*/ - cpu_buffer->read =0 ; -/* pages are removed, resume tracing and then free the pages */ atomic_dec (&cpu_buffer->record_disabled);raw_spin_unlock_irq (&cpu_buffer->reader_lock);
@@ -4385,6 +4384,7 @@ static void rb_iter_reset(struct ring_buffer_iter *iter) iter->cache_reader_page = iter->head_page; iter->cache_read = cpu_buffer->read; + iter->cache_pages_removed = cpu_buffer->pages_removed;if (iter->head) { iter->read_stamp = cpu_buffer->read_stamp;
@@ -4841,12 +4841,13 @@ rb_iter_peek(struct ring_buffer_iter *iter, u64 *ts) buffer = cpu_buffer->buffer;/* -* Check if someone performed a consuming read to -* the buffer. A consuming read invalidates the iterator -* and we need to reset the iterator in this case. +* Check if someone performed a consuming read to the buffer +* or removed some pages from the buffer. In these cases, +* iterator was invalidated and we need to reset it. */ if (unlikely (iter->cache_read != cpu_buffer->read || - iter->cache_reader_page != cpu_buffer->reader_page)) + iter->cache_reader_page != cpu_buffer->reader_page || + iter->cache_pages_removed != cpu_buffer->pages_removed))rb_iter_reset (iter); again:
@@ -5291,6 +5292,7 @@ rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer) cpu_buffer->last_overrun =0 ;rb_head_page_activate (cpu_buffer); + cpu_buffer->pages_removed =0 ; }/* Must have disabled the cpu buffer then done a synchronize_rcu */
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 145/228 tracing: Fix warning in trace_buffered_event_disable()
In reply to Greg Kroah-HartmanFrom: Zheng Yejian <[email protected]>
[ Upstream commit dea499781a1150d285c62b26659f62fb00824fce ]
Warning happened in trace_buffered_event_disable() at
WARN_ON_ONCE(!trace_buffered_event_ref)
Call Trace: ? __warn+0xa5/0x1b0 ? trace_buffered_event_disable+0x189/0x1b0 __ftrace_event_enable_disable+0x19e/0x3e0 free_probe_data+0x3b/0xa0 unregister_ftrace_function_probe_func+0x6b8/0x800 event_enable_func+0x2f0/0x3d0 ftrace_process_regex.isra.0+0x12d/0x1b0 ftrace_filter_write+0xe6/0x140 vfs_write+0x1c9/0x6f0 [...]
The cause of the warning is in __ftrace_event_enable_disable(), trace_buffered_event_enable() was called once while trace_buffered_event_disable() was called twice. Reproduction script show as below, for analysis, see the comments:
```
#!/bin/bash
cd /sys/kernel/tracing/
# 1. Register a 'disable_event' command, then:
# 1) SOFT_DISABLED_BIT was set;
# 2) trace_buffered_event_enable() was called first time;
echo 'cmdline_proc_show:disable_event:initcall:initcall_finish' > \
set_ftrace_filter
# 2. Enable the event registered, then:
# 1) SOFT_DISABLED_BIT was cleared;
# 2) trace_buffered_event_disable() was called first time;
echo 1 > events/initcall/initcall_finish/enable
# 3. Try to call into cmdline_proc_show(), then SOFT_DISABLED_BIT was
# set again!!!
cat /proc/cmdline
# 4. Unregister the 'disable_event' command, then:
# 1) SOFT_DISABLED_BIT was cleared again;
# 2) trace_buffered_event_disable() was called second time!!!
echo '!cmdline_proc_show:disable_event:initcall:initcall_finish' > \
set_ftrace_filter
```To fix it, IIUC, we can change to call trace_buffered_event_enable() at fist time soft-mode enabled, and call trace_buffered_event_disable() at last time soft-mode disabled.
--- kernel/trace/trace_events.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-)
kernel/trace/trace_events.c +4 -10
@@ -609,7 +609,6 @@ static int __ftrace_event_enable_disable(struct trace_event_file *file, {struct trace_event_call *call = file->event_call;struct trace_array *tr = file->tr; -unsigned long file_flags = file->flags;int ret =0 ;int disable;
@@ -633,6 +632,8 @@ static int __ftrace_event_enable_disable(struct trace_event_file *file,break ; disable = file->flags &EVENT_FILE_FL_SOFT_DISABLED ;clear_bit (EVENT_FILE_FL_SOFT_MODE_BIT , &file->flags); +/* Disable use of trace_buffered_event */ +trace_buffered_event_disable (); }else disable = !(file->flags &EVENT_FILE_FL_SOFT_MODE );
@@ -671,6 +672,8 @@ static int __ftrace_event_enable_disable(struct trace_event_file *file,if (atomic_inc_return (&file->sm_ref) >1 )break ;set_bit (EVENT_FILE_FL_SOFT_MODE_BIT , &file->flags); +/* Enable use of trace_buffered_event */ +trace_buffered_event_enable (); }if (!(file->flags &EVENT_FILE_FL_ENABLED )) {
@@ -710,15 +713,6 @@ static int __ftrace_event_enable_disable(struct trace_event_file *file,break ; } -/* Enable or disable use of trace_buffered_event */ -if ((file_flags &EVENT_FILE_FL_SOFT_DISABLED ) != - (file->flags &EVENT_FILE_FL_SOFT_DISABLED )) { -if (file->flags &EVENT_FILE_FL_SOFT_DISABLED ) -trace_buffered_event_enable (); -else -trace_buffered_event_disable (); - } -return ret; }
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 146/228 Revert "usb: gadget: tegra-xudc: Fix error check in tegra_xudc_powerdomain_init()"
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
commit a8291be6b5dd465c22af229483dbac543a91e24e upstream.
This reverts commit f08aa7c80dac27ee00fa6827f447597d2fba5465.
The reverted commit was based on static analysis and a misunderstanding of how PTR_ERR() and NULLs are supposed to work. When a function returns both pointer errors and NULL then normally the NULL means "continue operating without a feature because it was deliberately turned off". The NULL should not be treated as a failure. If a driver cannot work when that feature is disabled then the KConfig should enforce that the function cannot return NULL. We should not need to test for it.
In this driver, the bug means that probe cannot succeed when CONFIG_PM is disabled.
--- drivers/usb/gadget/udc/tegra-xudc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/usb/gadget/udc/tegra-xudc.c +4 -4
@@ -3695,15 +3695,15 @@ static int tegra_xudc_powerdomain_init(sint err; xudc->genpd_dev_device =dev_pm_domain_attach_by_name (dev,"dev" ); -if (IS_ERR_OR_NULL (xudc->genpd_dev_device)) { - err =PTR_ERR (xudc->genpd_dev_device) ? : -ENODATA ; +if (IS_ERR (xudc->genpd_dev_device)) { + err =PTR_ERR (xudc->genpd_dev_device);dev_err (dev,"failed to get device power domain: %d\n" , err);return err; } xudc->genpd_dev_ss =dev_pm_domain_attach_by_name (dev,"ss" ); -if (IS_ERR_OR_NULL (xudc->genpd_dev_ss)) { - err =PTR_ERR (xudc->genpd_dev_ss) ? : -ENODATA ; +if (IS_ERR (xudc->genpd_dev_ss)) { + err =PTR_ERR (xudc->genpd_dev_ss);dev_err (dev,"failed to get SuperSpeed power domain: %d\n" , err);return err; }
Greg Kroah-Hartman
maintainerPATCH 147/228 usb: gadget: call usb_gadget_check_config() to verify UDC capability
In reply to Greg Kroah-HartmanFrom: Frank Li <[email protected]>
commit f4fc01af5b640bc39bd9403b5fd855345a2ad5f8 upstream.
The legacy gadget driver omitted calling usb_gadget_check_config() to ensure that the USB device controller (UDC) has adequate resources, including sufficient endpoint numbers and types, to support the given configuration.
Previously, usb_add_config() was solely invoked by the legacy gadget driver. Adds the necessary usb_gadget_check_config() after the bind() operation to fix the issue.
--- drivers/usb/gadget/composite.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/usb/gadget/composite.c +4 -0
@@ -1029,6 +1029,10 @@ int usb_add_config(struct usb_composite_ goto done; status =bind (config); + +if (status ==0 ) + status =usb_gadget_check_config (cdev->gadget); +if (status <0 ) {while (!list_empty (&config->functions)) {struct usb_function *f;
Greg Kroah-Hartman
maintainerPATCH 148/228 USB: gadget: Fix the memory leak in raw_gadget driver
In reply to Greg Kroah-HartmanFrom: Zqiang <[email protected]>
commit 83e30f2bf86ef7c38fbd476ed81a88522b620628 upstream.
Currently, increasing raw_dev->count happens before invoke the raw_queue_event(), if the raw_queue_event() return error, invoke raw_release() will not trigger the dev_free() to be called.
[ 268.905865][ T5067] raw-gadget.0 gadget.0: failed to queue event [ 268.912053][ T5067] udc dummy_udc.0: failed to start USB Raw Gadget: -12 [ 268.918885][ T5067] raw-gadget.0: probe of gadget.0 failed with error -12 [ 268.925956][ T5067] UDC core: USB Raw Gadget: couldn't find an available UDC or it's busy [ 268.934657][ T5067] misc raw-gadget: fail, usb_gadget_register_driver returned -16
BUG: memory leak [<ffffffff8154bf94>] kmalloc_trace+0x24/0x90 mm/slab_common.c:1076 [<ffffffff8347eb55>] kmalloc include/linux/slab.h:582 [inline] [<ffffffff8347eb55>] kzalloc include/linux/slab.h:703 [inline] [<ffffffff8347eb55>] dev_new drivers/usb/gadget/legacy/raw_gadget.c:191 [inline] [<ffffffff8347eb55>] raw_open+0x45/0x110 drivers/usb/gadget/legacy/raw_gadget.c:385 [<ffffffff827d1d09>] misc_open+0x1a9/0x1f0 drivers/char/misc.c:165 [<ffffffff8154bf94>] kmalloc_trace+0x24/0x90 mm/slab_common.c:1076 [<ffffffff8347cd2f>] kmalloc include/linux/slab.h:582 [inline] [<ffffffff8347cd2f>] raw_ioctl_init+0xdf/0x410 drivers/usb/gadget/legacy/raw_gadget.c:460 [<ffffffff8347dfe9>] raw_ioctl+0x5f9/0x1120 drivers/usb/gadget/legacy/raw_gadget.c:1250 [<ffffffff81685173>] vfs_ioctl fs/ioctl.c:51 [inline] [<ffffffff8154bf94>] kmalloc_trace+0x24/0x90 mm/slab_common.c:1076 [<ffffffff833ecc6a>] kmalloc include/linux/slab.h:582 [inline] [<ffffffff833ecc6a>] kzalloc include/linux/slab.h:703 [inline] [<ffffffff833ecc6a>] dummy_alloc_request+0x5a/0xe0 drivers/usb/gadget/udc/dummy_hcd.c:665 [<ffffffff833e9132>] usb_ep_alloc_request+0x22/0xd0 drivers/usb/gadget/udc/core.c:196 [<ffffffff8347f13d>] gadget_bind+0x6d/0x370 drivers/usb/gadget/legacy/raw_gadget.c:292
This commit therefore invoke kref_get() under the condition that raw_queue_event() return success.
--- drivers/usb/gadget/legacy/raw_gadget.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
drivers/usb/gadget/legacy/raw_gadget.c +6 -4
@@ -310,13 +310,15 @@ static int gadget_bind(struct usb_gadget dev->eps_num = i;spin_unlock_irqrestore (&dev->lock, flags); -/* Matches kref_put() in gadget_unbind(). */ -kref_get (&dev->count); - ret =raw_queue_event (dev,USB_RAW_EVENT_CONNECT ,0 ,NULL ); -if (ret <0 ) +if (ret <0 ) {dev_err (&gadget->dev,"failed to queue event\n" ); +set_gadget_data (gadget,NULL ); +return ret; + } +/* Matches kref_put() in gadget_unbind(). */ +kref_get (&dev->count);return ret; }
Greg Kroah-Hartman
maintainerPATCH 149/228 usb: gadget: core: remove unbalanced mutex_unlock in usb_gadget_activate
In reply to Greg Kroah-HartmanFrom: Michael Grzeschik <[email protected]>
commit 6237390644fb92b81f5262877fe545d0d2c7b5d7 upstream.
Commit 286d9975a838 ("usb: gadget: udc: core: Prevent soft_connect_store() race") introduced one extra mutex_unlock of connect_lock in the usb_gadget_active function.
--- drivers/usb/gadget/udc/core.c | 1 - 1 file changed, 1 deletion(-)
drivers/usb/gadget/udc/core.c +0 -1
@@ -851,7 +851,6 @@ int usb_gadget_activate(struct usb_gadge*/ if (gadget->connected) ret =usb_gadget_connect_locked (gadget); -mutex_unlock (&gadget->udc->connect_lock); unlock:mutex_unlock (&gadget->udc->connect_lock);
Greg Kroah-Hartman
maintainerPATCH 150/228 KVM: Grab a reference to KVM for VM and vCPU stats file descriptors
In reply to Greg Kroah-HartmanFrom: Sean Christopherson <[email protected]>
commit eed3013faa401aae662398709410a59bb0646e32 upstream.
Grab a reference to KVM prior to installing VM and vCPU stats file descriptors to ensure the underlying VM and vCPU objects are not freed until the last reference to any and all stats fds are dropped.
Note, the stats paths manually invoke fd_install() and so don't need to grab a reference before creating the file.
Message-Id: <[email protected]>
--- virt/kvm/kvm_main.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+)
virt/kvm/kvm_main.c +24 -0
@@ -4032,8 +4032,17 @@ static ssize_t kvm_vcpu_stats_read(struc sizeof(vcpu->stat), user_buffer, size, offset); } +static int kvm_vcpu_stats_release (struct inode *inode,struct file *file) +{ +struct kvm_vcpu *vcpu = file->private_data; + +kvm_put_kvm (vcpu->kvm); +return 0 ; +} +static const struct file_operations kvm_vcpu_stats_fops = { .read = kvm_vcpu_stats_read, + .release = kvm_vcpu_stats_release, .llseek = noop_llseek, };
@@ -4054,6 +4063,9 @@ static int kvm_vcpu_ioctl_get_stats_fd(sput_unused_fd (fd);return PTR_ERR (file); } + +kvm_get_kvm (vcpu->kvm); + file->f_mode |=FMODE_PREAD ;fd_install (fd, file);
@@ -4658,8 +4670,17 @@ static ssize_t kvm_vm_stats_read(struct sizeof(kvm->stat), user_buffer, size, offset); } +static int kvm_vm_stats_release (struct inode *inode,struct file *file) +{ +struct kvm *kvm = file->private_data; + +kvm_put_kvm (kvm); +return 0 ; +} +static const struct file_operations kvm_vm_stats_fops = { .read = kvm_vm_stats_read, + .release = kvm_vm_stats_release, .llseek = noop_llseek, };
@@ -4678,6 +4699,9 @@ static int kvm_vm_ioctl_get_stats_fd(strput_unused_fd (fd);return PTR_ERR (file); } + +kvm_get_kvm (kvm); + file->f_mode |=FMODE_PREAD ;fd_install (fd, file);
Greg Kroah-Hartman
maintainerPATCH 151/228 KVM: VMX: Dont fudge CR0 and CR4 for restricted L2 guest
In reply to Greg Kroah-HartmanFrom: Sean Christopherson <[email protected]>
commit c4abd7352023aa96114915a0bb2b88016a425cda upstream.
Stuff CR0 and/or CR4 to be compliant with a restricted guest if and only if KVM itself is not configured to utilize unrestricted guests, i.e. don't stuff CR0/CR4 for a restricted L2 that is running as the guest of an unrestricted L1. Any attempt to VM-Enter a restricted guest with invalid CR0/CR4 values should fail, i.e. in a nested scenario, KVM (as L0) should never observe a restricted L2 with incompatible CR0/CR4, since nested VM-Enter from L1 should have failed.
And if KVM does observe an active, restricted L2 with incompatible state, e.g. due to a KVM bug, fudging CR0/CR4 instead of letting VM-Enter fail does more harm than good, as KVM will often neglect to undo the side effects, e.g. won't clear rmode.vm86_active on nested VM-Exit, and thus the damage can easily spill over to L1. On the other hand, letting VM-Enter fail due to bad guest state is more likely to contain the damage to L2 as KVM relies on hardware to perform most guest state consistency checks, i.e. KVM needs to be able to reflect a failed nested VM-Enter into L1 irrespective of (un)restricted guest behavior.
Message-Id: <[email protected]>
--- arch/x86/kvm/vmx/vmx.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
arch/x86/kvm/vmx/vmx.c +9 -4
@@ -1461,6 +1461,11 @@ void vmx_set_rflags(struct kvm_vcpu *vcpstruct vcpu_vmx *vmx =to_vmx (vcpu);unsigned long old_rflags; +/* +* Unlike CR0 and CR4, RFLAGS handling requires checking if the vCPU +* is an unrestricted guest in order to mark L2 as needing emulation +* if L1 runs L2 as a restricted guest. +*/ if (is_unrestricted_guest (vcpu)) {kvm_register_mark_available (vcpu,VCPU_EXREG_RFLAGS ); vmx->rflags = rflags;
@@ -3169,7 +3174,7 @@ void vmx_set_cr0(struct kvm_vcpu *vcpu, old_cr0_pg =kvm_read_cr0_bits (vcpu,X86_CR0_PG ); hw_cr0 = (cr0 & ~KVM_VM_CR0_ALWAYS_OFF ); -if (is_unrestricted_guest (vcpu)) +if (enable_unrestricted_guest) hw_cr0 |=KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST ;else { hw_cr0 |=KVM_VM_CR0_ALWAYS_ON ;
@@ -3197,7 +3202,7 @@ void vmx_set_cr0(struct kvm_vcpu *vcpu, }#endif -if (enable_ept && !is_unrestricted_guest (vcpu)) { +if (enable_ept && !enable_unrestricted_guest) {/* * Ensure KVM has an up-to-date snapshot of the guest's CR3. If * the below code _enables_ CR3 exiting, vmx_cache_reg() will
@@ -3328,7 +3333,7 @@ void vmx_set_cr4(struct kvm_vcpu *vcpu,unsigned long hw_cr4; hw_cr4 = (cr4_read_shadow () &X86_CR4_MCE ) | (cr4 & ~X86_CR4_MCE ); -if (is_unrestricted_guest (vcpu)) +if (enable_unrestricted_guest) hw_cr4 |=KVM_VM_CR4_ALWAYS_ON_UNRESTRICTED_GUEST ;else if (vmx->rmode.vm86_active) hw_cr4 |=KVM_RMODE_VM_CR4_ALWAYS_ON ;
@@ -3348,7 +3353,7 @@ void vmx_set_cr4(struct kvm_vcpu *vcpu, vcpu->arch.cr4 = cr4;kvm_register_mark_available (vcpu,VCPU_EXREG_CR4 ); -if (!is_unrestricted_guest (vcpu)) { +if (!enable_unrestricted_guest) {if (enable_ept) {if (!is_paging (vcpu)) { hw_cr4 &= ~X86_CR4_PAE ;
Greg Kroah-Hartman
maintainerPATCH 152/228 KVM: x86: Disallow KVM_SET_SREGS{2} if incoming CR0 is invalid
In reply to Greg Kroah-HartmanFrom: Sean Christopherson <[email protected]>
commit 26a0652cb453c72f6aab0974bc4939e9b14f886b upstream.
Reject KVM_SET_SREGS{2} with -EINVAL if the incoming CR0 is invalid, e.g. due to setting bits 63:32, illegal combinations, or to a value that isn't allowed in VMX (non-)root mode. The VMX checks in particular are "fun" as failure to disallow Real Mode for an L2 that is configured with unrestricted guest disabled, when KVM itself has unrestricted guest enabled, will result in KVM forcing VM86 mode to virtual Real Mode for L2, but then fail to unwind the related metadata when synthesizing a nested VM-Exit back to L1 (which has unrestricted guest enabled).
Opportunistically fix a benign typo in the prototype for is_valid_cr4().
Message-Id: <[email protected]>
--- arch/x86/include/asm/kvm-x86-ops.h | 1 + arch/x86/include/asm/kvm_host.h | 3 ++- arch/x86/kvm/svm/svm.c | 6 ++++++ arch/x86/kvm/vmx/vmx.c | 28 +++++++++++++++++++++------- arch/x86/kvm/x86.c | 34 ++++++++++++++++++++++------------ 5 files changed, 52 insertions(+), 20 deletions(-)
arch/x86/include/asm/kvm-x86-ops.h +1 -0
@@ -36,6 +36,7 @@ KVM_X86_OP(get_segment) KVM_X86_OP(get_cpl) KVM_X86_OP(set_segment) KVM_X86_OP(get_cs_db_l_bits) +KVM_X86_OP(is_valid_cr0) KVM_X86_OP(set_cr0) KVM_X86_OP_OPTIONAL(post_set_cr3) KVM_X86_OP(is_valid_cr4)
arch/x86/include/asm/kvm_host.h +2 -1
@@ -1488,9 +1488,10 @@ struct kvm_x86_ops {void (*set_segment)(struct kvm_vcpu *vcpu,struct kvm_segment *var,int seg);void (*get_cs_db_l_bits)(struct kvm_vcpu *vcpu,int *db,int *l); +bool (*is_valid_cr0)(struct kvm_vcpu *vcpu,unsigned long cr0);void (*set_cr0)(struct kvm_vcpu *vcpu,unsigned long cr0);void (*post_set_cr3)(struct kvm_vcpu *vcpu,unsigned long cr3); -bool (*is_valid_cr4)(struct kvm_vcpu *vcpu,unsigned long cr0); +bool (*is_valid_cr4)(struct kvm_vcpu *vcpu,unsigned long cr4);void (*set_cr4)(struct kvm_vcpu *vcpu,unsigned long cr4);int (*set_efer)(struct kvm_vcpu *vcpu,u64 efer);void (*get_idt)(struct kvm_vcpu *vcpu,struct desc_ptr *dt);
arch/x86/kvm/svm/svm.c +6 -0
@@ -1763,6 +1763,11 @@ static void sev_post_set_cr3(struct kvm_ } } +static bool svm_is_valid_cr0 (struct kvm_vcpu *vcpu,unsigned long cr0) +{ +return true; +} +void svm_set_cr0 (struct kvm_vcpu *vcpu,unsigned long cr0) {struct vcpu_svm *svm =to_svm (vcpu);
@@ -4749,6 +4754,7 @@ static struct kvm_x86_ops svm_x86_ops __ .set_segment = svm_set_segment, .get_cpl = svm_get_cpl, .get_cs_db_l_bits = svm_get_cs_db_l_bits, + .is_valid_cr0 = svm_is_valid_cr0, .set_cr0 = svm_set_cr0, .post_set_cr3 = sev_post_set_cr3, .is_valid_cr4 = svm_is_valid_cr4,
arch/x86/kvm/vmx/vmx.c +21 -7
@@ -2975,6 +2975,15 @@ static void enter_rmode(struct kvm_vcpustruct vcpu_vmx *vmx =to_vmx (vcpu);struct kvm_vmx *kvm_vmx =to_kvm_vmx (vcpu->kvm); +/* +* KVM should never use VM86 to virtualize Real Mode when L2 is active, +* as using VM86 is unnecessary if unrestricted guest is enabled, and +* if unrestricted guest is disabled, VM-Enter (from L1) with CR0.PG=0 +* should VM-Fail and KVM should reject userspace attempts to stuff +* CR0.PG=0 when L2 is active. +*/ +WARN_ON_ONCE (is_guest_mode (vcpu)); +vmx_get_segment (vcpu, &vmx->rmode.segs[VCPU_SREG_TR ],VCPU_SREG_TR );vmx_get_segment (vcpu, &vmx->rmode.segs[VCPU_SREG_ES ],VCPU_SREG_ES );vmx_get_segment (vcpu, &vmx->rmode.segs[VCPU_SREG_DS ],VCPU_SREG_DS );
@@ -3165,6 +3174,17 @@ void ept_save_pdptrs(struct kvm_vcpu *vc#define CR3_EXITING_BITS (CPU_BASED_CR3_LOAD_EXITING | \ CPU_BASED_CR3_STORE_EXITING) +static bool vmx_is_valid_cr0 (struct kvm_vcpu *vcpu,unsigned long cr0) +{ +if (is_guest_mode (vcpu)) +return nested_guest_cr0_valid (vcpu, cr0); + +if (to_vmx (vcpu)->nested.vmxon) +return nested_host_cr0_valid (vcpu, cr0); + +return true; +} +void vmx_set_cr0 (struct kvm_vcpu *vcpu,unsigned long cr0) {struct vcpu_vmx *vmx =to_vmx (vcpu);
@@ -5316,18 +5336,11 @@ static int handle_set_cr0(struct kvm_vcp val = (val & ~vmcs12->cr0_guest_host_mask) | (vmcs12->guest_cr0 & vmcs12->cr0_guest_host_mask); -if (!nested_guest_cr0_valid (vcpu, val)) -return 1 ; -if (kvm_set_cr0 (vcpu, val))return 1 ;vmcs_writel (CR0_READ_SHADOW , orig_val);return 0 ; }else { -if (to_vmx (vcpu)->nested.vmxon && - !nested_host_cr0_valid (vcpu, val)) -return 1 ; -return kvm_set_cr0 (vcpu, val); } }
@@ -8117,6 +8130,7 @@ static struct kvm_x86_ops vmx_x86_ops __ .set_segment = vmx_set_segment, .get_cpl = vmx_get_cpl, .get_cs_db_l_bits = vmx_get_cs_db_l_bits, + .is_valid_cr0 = vmx_is_valid_cr0, .set_cr0 = vmx_set_cr0, .is_valid_cr4 = vmx_is_valid_cr4, .set_cr4 = vmx_set_cr4,
arch/x86/kvm/x86.c +22 -12
@@ -908,6 +908,22 @@ int load_pdptrs(struct kvm_vcpu *vcpu, u }EXPORT_SYMBOL_GPL (load_pdptrs); +static bool kvm_is_valid_cr0 (struct kvm_vcpu *vcpu,unsigned long cr0) +{ +#ifdef CONFIG_X86_64 +if (cr0 &0xffffffff00000000UL ) +return false; +#endif + +if ((cr0 &X86_CR0_NW ) && !(cr0 &X86_CR0_CD )) +return false; + +if ((cr0 &X86_CR0_PG ) && !(cr0 &X86_CR0_PE )) +return false; + +return static_call (kvm_x86_is_valid_cr0)(vcpu, cr0); +} +void kvm_post_set_cr0 (struct kvm_vcpu *vcpu,unsigned long old_cr0,unsigned long cr0) {/*
@@ -948,20 +964,13 @@ int kvm_set_cr0(struct kvm_vcpu *vcpu, u {unsigned long old_cr0 =kvm_read_cr0 (vcpu); - cr0 |=X86_CR0_ET ; - -#ifdef CONFIG_X86_64 -if (cr0 &0xffffffff00000000UL ) +if (!kvm_is_valid_cr0 (vcpu, cr0))return 1 ; -#endif - - cr0 &= ~CR0_RESERVED_BITS ; -if ((cr0 &X86_CR0_NW ) && !(cr0 &X86_CR0_CD )) -return 1 ; + cr0 |=X86_CR0_ET ; -if ((cr0 &X86_CR0_PG ) && !(cr0 &X86_CR0_PE )) -return 1 ; +/* Write to CR0 reserved bits are ignored, even on Intel. */ + cr0 &= ~CR0_RESERVED_BITS ;#ifdef CONFIG_X86_64 if ((vcpu->arch.efer & EFER_LME) && !is_paging(vcpu) &&
@@ -11532,7 +11541,8 @@ static bool kvm_is_valid_sregs(struct kvreturn false; } -return kvm_is_valid_cr4 (vcpu, sregs->cr4); +return kvm_is_valid_cr4 (vcpu, sregs->cr4) && +kvm_is_valid_cr0 (vcpu, sregs->cr0); } static int __set_sregs_common(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs,
Greg Kroah-Hartman
maintainerPATCH 153/228 serial: qcom-geni: drop bogus runtime pm state update
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 4dd8752a14ca0303fbdf0a6c68ff65f0a50bd2fa upstream.
The runtime PM state should not be changed by drivers that do not implement runtime PM even if it happens to work around a bug in PM core.
With the wake irq arming now fixed, drop the bogus runtime PM state update which left the device in active state (and could potentially prevent a parent device from suspending).
--- drivers/tty/serial/qcom_geni_serial.c | 7 ------- 1 file changed, 7 deletions(-)
drivers/tty/serial/qcom_geni_serial.c +0 -7
@@ -1495,13 +1495,6 @@ static int qcom_geni_serial_probe(structif (ret)return ret; -/* -* Set pm_runtime status as ACTIVE so that wakeup_irq gets -* enabled/disabled from dev_pm_arm_wake_irq during system -* suspend/resume respectively. -*/ -pm_runtime_set_active (&pdev->dev); -if (port->wakeup_irq >0 ) {device_init_wakeup (&pdev->dev, true); ret = dev_pm_set_dedicated_wake_irq(&pdev->dev,
Greg Kroah-Hartman
maintainerPATCH 154/228 serial: 8250_dw: Preserve original value of DLF register
In reply to Greg Kroah-HartmanFrom: Ruihong Luo <[email protected]>
commit 748c5ea8b8796ae8ee80b8d3a3d940570b588d59 upstream.
Preserve the original value of the Divisor Latch Fraction (DLF) register. When the DLF register is modified without preservation, it can disrupt the baudrate settings established by firmware or bootloader, leading to data corruption and the generation of unreadable or distorted characters.
--- drivers/tty/serial/8250/8250_dwlib.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/tty/serial/8250/8250_dwlib.c +4 -2
@@ -244,7 +244,7 @@ void dw8250_setup_port(struct uart_portstruct dw8250_port_data *pd = p->private_data;struct dw8250_data *data =to_dw8250_data (pd);struct uart_8250_port *up =up_to_u8250p (p); -u32 reg; +u32 reg, old_dlf; pd->hw_rs485_support =dw8250_detect_rs485_hw (p);if (pd->hw_rs485_support) {
@@ -270,9 +270,11 @@ void dw8250_setup_port(struct uart_portdev_dbg (p->dev,"Designware UART version %c.%c%c\n" , (reg >>24 ) &0xff , (reg >>16 ) &0xff , (reg >>8 ) &0xff ); +/* Preserve value written by firmware or bootloader */ + old_dlf =dw8250_readl_ext (p,DW_UART_DLF );dw8250_writel_ext (p,DW_UART_DLF , ~0U ); reg =dw8250_readl_ext (p,DW_UART_DLF ); -dw8250_writel_ext (p,DW_UART_DLF ,0 ); +dw8250_writel_ext (p,DW_UART_DLF , old_dlf);if (reg) { pd->dlf_size =fls (reg);
Greg Kroah-Hartman
maintainerPATCH 155/228 serial: sifive: Fix sifive_serial_console_setup() section
In reply to Greg Kroah-HartmanFrom: Samuel Holland <[email protected]>
commit 9b8fef6345d5487137d4193bb0a0eae2203c284e upstream.
This function is called indirectly from the platform driver probe function. Even if the driver is built in, it may be probed after free_initmem() due to deferral or unbinding/binding via sysfs. Thus the function cannot be marked as __init.
--- drivers/tty/serial/sifive.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/tty/serial/sifive.c +1 -1
@@ -832,7 +832,7 @@ static void sifive_serial_console_write(local_irq_restore (flags); } -static int __init sifive_serial_console_setup (struct console *co,char *options) +static int sifive_serial_console_setup (struct console *co,char *options) {struct sifive_serial_port *ssp;int baud =SIFIVE_DEFAULT_BAUD_RATE ;
Greg Kroah-Hartman
maintainerPATCH 156/228 USB: serial: option: support Quectel EM060K_128
In reply to Greg Kroah-HartmanFrom: Jerry Meng <[email protected]>
commit 4f7cab49cecee16120d27c1734cfdf3d6c0e5329 upstream.
EM060K_128 is EM060K's sub-model, having the same name "Quectel EM060K-GL"
MBIM + GNSS + DIAG + NMEA + AT + QDSS + DPL
T: Bus=03 Lev=01 Prnt=01 Port=01 Cnt=02 Dev#= 8 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=2c7c ProdID=0128 Rev= 5.04 S: Manufacturer=Quectel S: Product=Quectel EM060K-GL S: SerialNumber=f6fa08b6 C:* #Ifs= 8 Cfg#= 1 Atr=a0 MxPwr=500mA A: FirstIf#= 0 IfCount= 2 Cls=02(comm.) Sub=0e Prot=00 I:* If#= 0 Alt= 0 #EPs= 1 Cls=02(comm.) Sub=0e Prot=00 Driver=cdc_mbim E: Ad=81(I) Atr=03(Int.) MxPS= 64 Ivl=32ms I: If#= 1 Alt= 0 #EPs= 0 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim I:* If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim E: Ad=8e(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=0f(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 2 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none) E: Ad=82(I) Atr=03(Int.) MxPS= 64 Ivl=32ms I:* If#= 3 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=40 Driver=option E: Ad=85(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 5 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option E: Ad=87(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 6 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=70 Driver=(none)
E: Ad=88(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 7 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=80 Driver=(none)
E: Ad=8f(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
--- drivers/usb/serial/option.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/usb/serial/option.c +4 -0
@@ -251,6 +251,7 @@ static void option_instat_callback(struc#define QUECTEL_PRODUCT_EM061K_LTA 0x0123#define QUECTEL_PRODUCT_EM061K_LMS 0x0124#define QUECTEL_PRODUCT_EC25 0x0125 +#define QUECTEL_PRODUCT_EM060K_128 0x0128#define QUECTEL_PRODUCT_EG91 0x0191#define QUECTEL_PRODUCT_EG95 0x0195#define QUECTEL_PRODUCT_BG96 0x0296
@@ -1197,6 +1198,9 @@ static const struct usb_device_id option { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K, 0xff, 0x00, 0x40) }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K, 0xff, 0xff, 0x30) }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K, 0xff, 0xff, 0x40) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K_128, 0xff, 0xff, 0x30) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K_128, 0xff, 0x00, 0x40) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K_128, 0xff, 0xff, 0x40) }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM061K_LCN, 0xff, 0xff, 0x30) }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM061K_LCN, 0xff, 0x00, 0x40) }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM061K_LCN, 0xff, 0xff, 0x40) },
Greg Kroah-Hartman
maintainerPATCH 157/228 USB: serial: option: add Quectel EC200A module support
In reply to Greg Kroah-HartmanFrom: Mohsen Tahmasebi <[email protected]>
commit 857ea9005806e2a458016880278f98715873e977 upstream.
Add Quectel EC200A "DIAG, AT, MODEM":
0x6005: ECM / RNDIS + DIAG + AT + MODEM
T: Bus=01 Lev=01 Prnt=02 Port=05 Cnt=01 Dev#= 8 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=2c7c ProdID=6005 Rev=03.18 S: Manufacturer=Android S: Product=Android S: SerialNumber=0000 C: #Ifs= 5 Cfg#= 1 Atr=e0 MxPwr=500mA I: If#= 0 Alt= 0 #EPs= 1 Cls=02(commc) Sub=06 Prot=00 Driver=cdc_ether E: Ad=87(I) Atr=03(Int.) MxPS= 64 Ivl=4096ms I: If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=cdc_ether E: Ad=0c(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=0b(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=0f(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=89(I) Atr=03(Int.) MxPS= 64 Ivl=4096ms I: If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=0a(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=88(I) Atr=03(Int.) MxPS= 64 Ivl=4096ms
--- drivers/usb/serial/option.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/usb/serial/option.c +2 -0
@@ -269,6 +269,7 @@ static void option_instat_callback(struc#define QUECTEL_PRODUCT_RM520N 0x0801#define QUECTEL_PRODUCT_EC200U 0x0901#define QUECTEL_PRODUCT_EC200S_CN 0x6002 +#define QUECTEL_PRODUCT_EC200A 0x6005#define QUECTEL_PRODUCT_EM061K_LWW 0x6008#define QUECTEL_PRODUCT_EM061K_LCN 0x6009#define QUECTEL_PRODUCT_EC200T 0x6026
@@ -1229,6 +1230,7 @@ static const struct usb_device_id option { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM520N, 0xff, 0, 0) }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, 0x0900, 0xff, 0, 0), /* RM500U-CN */ .driver_info = ZLP }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200A, 0xff, 0, 0) }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200U, 0xff, 0, 0) }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200S_CN, 0xff, 0, 0) }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200T, 0xff, 0, 0) },
Greg Kroah-Hartman
maintainerPATCH 158/228 USB: serial: simple: add Kaufmann RKS+CAN VCP
In reply to Greg Kroah-HartmanFrom: Oliver Neukum <[email protected]>
commit dd92c8a1f99bcd166204ffc219ea5a23dd65d64f upstream.
Add the device and product ID for this CAN bus interface / license dongle. The device is usable either directly from user space or can be attached to a kernel CAN interface with slcan_attach.
--- drivers/usb/serial/usb-serial-simple.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/usb/serial/usb-serial-simple.c +7 -0
@@ -63,6 +63,11 @@ DEVICE(flashloader, FLASHLOADER_IDS); 0x01) }DEVICE (google,GOOGLE_IDS ); +/* KAUFMANN RKS+CAN VCP */ +#define KAUFMANN_IDS () \ + { USB_DEVICE(0x16d0, 0x0870) } +DEVICE (kaufmann,KAUFMANN_IDS ); +/* Libtransistor USB console */ #define LIBTRANSISTOR_IDS () \ { USB_DEVICE(0x1209, 0x8b00) }
@@ -124,6 +129,7 @@ static struct usb_serial_driver * const &funsoft_device, &flashloader_device, &google_device, + &kaufmann_device, &libtransistor_device, &vivopay_device, &moto_modem_device,
@@ -142,6 +148,7 @@ static const struct usb_device_id id_tabFUNSOFT_IDS (),FLASHLOADER_IDS (),GOOGLE_IDS (), +KAUFMANN_IDS (),LIBTRANSISTOR_IDS (),VIVOPAY_IDS (), MOTO_IDS(),
Greg Kroah-Hartman
maintainerPATCH 159/228 USB: serial: simple: sort driver entries
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit d245aedc00775c4d7265a9f4522cc4e1fd34d102 upstream.
Sort the driver symbols alphabetically in order to make it more obvious where new driver entries should be added.
--- drivers/usb/serial/usb-serial-simple.c | 66 ++++++++++++++++----------------- 1 file changed, 33 insertions(+), 33 deletions(-)
drivers/usb/serial/usb-serial-simple.c +33 -33
@@ -38,16 +38,6 @@ static struct usb_serial_driver vendor## { USB_DEVICE(0x0a21, 0x8001) } /* MMT-7305WW */DEVICE (carelink,CARELINK_IDS ); -/* ZIO Motherboard USB driver */ -#define ZIO_IDS () \ - { USB_DEVICE(0x1CBE, 0x0103) } -DEVICE (zio,ZIO_IDS ); - -/* Funsoft Serial USB driver */ -#define FUNSOFT_IDS () \ - { USB_DEVICE(0x1404, 0xcddc) } -DEVICE (funsoft,FUNSOFT_IDS ); -/* Infineon Flashloader driver */ #define FLASHLOADER_IDS () \ { USB_DEVICE_INTERFACE_CLASS(0x058b, 0x0041, USB_CLASS_CDC_DATA) }, \
@@ -55,6 +45,11 @@ DEVICE(funsoft, FUNSOFT_IDS); { USB_DEVICE(0x8087, 0x0801) }DEVICE (flashloader,FLASHLOADER_IDS ); +/* Funsoft Serial USB driver */ +#define FUNSOFT_IDS () \ + { USB_DEVICE(0x1404, 0xcddc) } +DEVICE (funsoft,FUNSOFT_IDS ); +/* Google Serial USB SubClass */ #define GOOGLE_IDS () \ { USB_VENDOR_AND_INTERFACE_INFO(0x18d1, \
@@ -63,6 +58,11 @@ DEVICE(flashloader, FLASHLOADER_IDS); 0x01) }DEVICE (google,GOOGLE_IDS ); +/* HP4x (48/49) Generic Serial driver */ +#define HP4X_IDS () \ + { USB_DEVICE(0x03f0, 0x0121) } +DEVICE (hp4x,HP4X_IDS ); +/* KAUFMANN RKS+CAN VCP */ #define KAUFMANN_IDS () \ { USB_DEVICE(0x16d0, 0x0870) }
@@ -73,11 +73,6 @@ DEVICE(kaufmann, KAUFMANN_IDS); { USB_DEVICE(0x1209, 0x8b00) }DEVICE (libtransistor,LIBTRANSISTOR_IDS ); -/* ViVOpay USB Serial Driver */ -#define VIVOPAY_IDS () \ - { USB_DEVICE(0x1d5f, 0x1004) }/* ViVOpay 8800 */ -DEVICE (vivopay,VIVOPAY_IDS ); -/* Motorola USB Phone driver */ #define MOTO_IDS () \ { USB_DEVICE(0x05c6, 0x3197) },/* unknown Motorola phone */ \
@@ -106,10 +101,10 @@ DEVICE(nokia, NOKIA_IDS); { USB_DEVICE(0x09d7, 0x0100) } /* NovAtel FlexPack GPS */DEVICE_N (novatel_gps,NOVATEL_IDS ,3 ); -/* HP4x (48/49) Generic Serial driver */ -#define HP4X_IDS () \ - { USB_DEVICE(0x03f0, 0x0121) } -DEVICE (hp4x,HP4X_IDS ); +/* Siemens USB/MPI adapter */ +#define SIEMENS_IDS () \ + { USB_DEVICE(0x908, 0x0004) } +DEVICE (siemens_mpi,SIEMENS_IDS );/* Suunto ANT+ USB Driver */ #define SUUNTO_IDS () \
@@ -117,47 +112,52 @@ DEVICE(hp4x, HP4X_IDS); { USB_DEVICE(0x0fcf, 0x1009) } /* Dynastream ANT USB-m Stick */DEVICE (suunto,SUUNTO_IDS ); -/* Siemens USB/MPI adapter */ -#define SIEMENS_IDS () \ - { USB_DEVICE(0x908, 0x0004) } -DEVICE (siemens_mpi,SIEMENS_IDS ); +/* ViVOpay USB Serial Driver */ +#define VIVOPAY_IDS () \ + { USB_DEVICE(0x1d5f, 0x1004) }/* ViVOpay 8800 */ +DEVICE (vivopay,VIVOPAY_IDS ); + +/* ZIO Motherboard USB driver */ +#define ZIO_IDS () \ + { USB_DEVICE(0x1CBE, 0x0103) } +DEVICE (zio,ZIO_IDS );/* All of the above structures mushed into two lists */ static struct usb_serial_driver *const serial_drivers[] = { &carelink_device, - &zio_device, - &funsoft_device, &flashloader_device, + &funsoft_device, &google_device, + &hp4x_device, &kaufmann_device, &libtransistor_device, - &vivopay_device, &moto_modem_device, &motorola_tetra_device, &nokia_device, &novatel_gps_device, - &hp4x_device, - &suunto_device, &siemens_mpi_device, + &suunto_device, + &vivopay_device, + &zio_device,NULL };static const struct usb_device_id id_table[] = {CARELINK_IDS (), -ZIO_IDS (), -FUNSOFT_IDS (),FLASHLOADER_IDS (), +FUNSOFT_IDS (),GOOGLE_IDS (), +HP4X_IDS (),KAUFMANN_IDS (),LIBTRANSISTOR_IDS (), -VIVOPAY_IDS (),MOTO_IDS (),MOTOROLA_TETRA_IDS (),NOKIA_IDS (),NOVATEL_IDS (), -HP4X_IDS (), -SUUNTO_IDS (),SIEMENS_IDS (), +SUUNTO_IDS (), +VIVOPAY_IDS (), +ZIO_IDS (), { }, };MODULE_DEVICE_TABLE (usb, id_table);
Greg Kroah-Hartman
maintainerPATCH 160/228 can: gs_usb: gs_can_close(): add missing set of CAN state to CAN_STATE_STOPPED
In reply to Greg Kroah-HartmanFrom: Marc Kleine-Budde <[email protected]>
commit f8a2da6ec2417cca169fa85a8ab15817bccbb109 upstream.
After an initial link up the CAN device is in ERROR-ACTIVE mode. Due to a missing CAN_STATE_STOPPED in gs_can_close() it doesn't change to STOPPED after a link down:
| ip link set dev can0 up | ip link set dev can0 down | ip --details link show can0 | 13: can0: <NOARP,ECHO> mtu 16 qdisc pfifo_fast state DOWN mode DEFAULT group default qlen 10 | link/can promiscuity 0 allmulti 0 minmtu 0 maxmtu 0 | can state ERROR-ACTIVE restart-ms 1000
Add missing assignment of CAN_STATE_STOPPED in gs_can_close().
--- drivers/net/can/usb/gs_usb.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/can/usb/gs_usb.c +2 -0
@@ -989,6 +989,8 @@ static int gs_can_close(struct net_devicusb_kill_anchored_urbs (&dev->tx_submitted);atomic_set (&dev->active_tx_urbs,0 ); + dev->can.state =CAN_STATE_STOPPED ; +/* reset the device */ rc =gs_cmd_reset (dev);if (rc <0 )
Greg Kroah-Hartman
maintainerPATCH 161/228 usb: typec: Set port->pd before adding device for typec_port
In reply to Greg Kroah-HartmanFrom: Kyle Tso <[email protected]>
commit b33ebb2415e7e0a55ee3d049c2890d3a3e3805b6 upstream.
When calling device_add in the registration of typec_port, it will do the NULL check on usb_power_delivery handle in typec_port for the visibility of the device attributes. It is always NULL because port->pd is set in typec_port_set_usb_power_delivery which is later than the device_add call.
Set port->pd before device_add and only link the device after that.
--- drivers/usb/typec/class.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/usb/typec/class.c +3 -1
@@ -2259,6 +2259,8 @@ struct typec_port *typec_register_port(sreturn ERR_PTR (ret); } + port->pd = cap->pd; + ret =device_add (&port->dev);if (ret) {dev_err (parent,"failed to register port (%d)\n" , ret);
@@ -2266,7 +2268,7 @@ struct typec_port *typec_register_port(sreturn ERR_PTR (ret); } - ret =typec_port_set_usb_power_delivery (port, cap->pd); + ret =usb_power_delivery_link_device (port->pd, &port->dev);if (ret) {dev_err (&port->dev,"failed to link pd\n" );device_unregister (&port->dev);
Greg Kroah-Hartman
maintainerPATCH 162/228 usb: typec: Iterate pds array when showing the pd list
In reply to Greg Kroah-HartmanFrom: Kyle Tso <[email protected]>
commit 4b642dc9829507e4afabc03d32a18abbdb192c5e upstream.
The pointers of each usb_power_delivery handles are stored in "pds" array returned from the pd_get ops but not in the adjacent memory calculated from "pd". Get the handles from "pds" array directly instead of deriving them from "pd".
--- drivers/usb/typec/class.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-)
drivers/usb/typec/class.c +5 -6
@@ -1258,8 +1258,7 @@ static ssize_t select_usb_power_delivery {struct typec_port *port =to_typec_port (dev);struct usb_power_delivery **pds; -struct usb_power_delivery *pd; -int ret =0 ; +int i, ret =0 ;if (!port->ops || !port->ops->pd_get)return -EOPNOTSUPP ;
@@ -1268,11 +1267,11 @@ static ssize_t select_usb_power_deliveryif (!pds)return 0 ; -for (pd = pds[0 ]; pd; pd++) { -if (pd == port->pd) - ret +=sysfs_emit (buf + ret,"[%s] " ,dev_name (&pd->dev)); +for (i =0 ; pds[i]; i++) { +if (pds[i] == port->pd) + ret +=sysfs_emit (buf + ret,"[%s] " ,dev_name (&pds[i]->dev));else - ret +=sysfs_emit (buf + ret,"%s " ,dev_name (&pd->dev)); + ret +=sysfs_emit (buf + ret,"%s " ,dev_name (&pds[i]->dev)); } buf[ret -1 ] ='\n' ;
Greg Kroah-Hartman
maintainerPATCH 163/228 usb: typec: Use sysfs_emit_at when concatenating the string
In reply to Greg Kroah-HartmanFrom: Kyle Tso <[email protected]>
commit 609fded3f91972ada551c141c5d04a71704f8967 upstream.
The buffer address used in sysfs_emit should be aligned to PAGE_SIZE. Use sysfs_emit_at instead to offset the buffer.
--- drivers/usb/typec/class.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/usb/typec/class.c +2 -2
@@ -1269,9 +1269,9 @@ static ssize_t select_usb_power_deliveryfor (i =0 ; pds[i]; i++) {if (pds[i] == port->pd) - ret +=sysfs_emit (buf + ret,"[%s] " ,dev_name (&pds[i]->dev)); + ret +=sysfs_emit_at (buf, ret,"[%s] " ,dev_name (&pds[i]->dev));else - ret +=sysfs_emit (buf + ret,"%s " ,dev_name (&pds[i]->dev)); + ret +=sysfs_emit_at (buf, ret,"%s " ,dev_name (&pds[i]->dev)); } buf[ret -1 ] ='\n' ;
Greg Kroah-Hartman
maintainerPATCH 164/228 Revert "usb: dwc3: core: Enable AutoRetry feature in the controller"
In reply to Greg Kroah-HartmanFrom: Jakub Vanek <[email protected]>
commit 734ae15ab95a18d3d425fc9cb38b7a627d786f08 upstream.
This reverts commit b138e23d3dff90c0494925b4c1874227b81bddf7.
AutoRetry has been found to sometimes cause controller freezes when communicating with buggy USB devices.
This controller feature allows the controller in host mode to send non-terminating/burst retry ACKs instead of terminating retry ACKs to devices when a transaction error (CRC error or overflow) occurs.
Unfortunately, if the USB device continues to respond with a CRC error, the controller will not complete endpoint-related commands while it keeps trying to auto-retry. [3] The xHCI driver will notice this once it tries to abort the transfer using a Stop Endpoint command and does not receive a completion in time. [1]
This situation is reported to dmesg:
[sda] tag#29 uas_eh_abort_handler 0 uas-tag 1 inflight: CMD IN [sda] tag#29 CDB: opcode=0x28 28 00 00 69 42 80 00 00 48 00
xhci-hcd: xHCI host not responding to stop endpoint command
xhci-hcd: xHCI host controller not responding, assume dead
xhci-hcd: HC died; cleaning up
Some users observed this problem on an Odroid HC2 with the JMS578 USB3-to-SATA bridge. The issue can be triggered by starting a read-heavy workload on an attached SSD. After a while, the host controller would die and the SSD would disappear from the system. [1]
Further analysis by Synopsys determined that controller revisions other than the one in Odroid HC2 are also affected by this. The recommended solution was to disable AutoRetry altogether. This change does not have a noticeable performance impact. [2]
Revert the enablement commit. This will keep the AutoRetry bit in the default state configured during SoC design [2].
--- drivers/usb/dwc3/core.c | 16 ---------------- drivers/usb/dwc3/core.h | 3 --- 2 files changed, 19 deletions(-)
drivers/usb/dwc3/core.c +0 -16
@@ -1241,22 +1241,6 @@ static int dwc3_core_init(struct dwc3 *ddwc3_writel (dwc->regs,DWC3_GUCTL1 , reg); } -if (dwc->dr_mode ==USB_DR_MODE_HOST || - dwc->dr_mode ==USB_DR_MODE_OTG ) { - reg =dwc3_readl (dwc->regs,DWC3_GUCTL ); - -/* -* Enable Auto retry Feature to make the controller operating in -* Host mode on seeing transaction errors(CRC errors or internal -* overrun scenerios) on IN transfers to reply to the device -* with a non-terminating retry ACK (i.e, an ACK transcation -* packet with Retry=1 & Nump != 0) -*/ - reg |=DWC3_GUCTL_HSTINAUTORETRY ; - -dwc3_writel (dwc->regs,DWC3_GUCTL , reg); - } -/* * Must config both number of packets and max burst settings to enable * RX and/or TX threshold.
drivers/usb/dwc3/core.h +0 -3
@@ -254,9 +254,6 @@#define DWC3_GCTL_GBLHIBERNATIONEN BIT(1)#define DWC3_GCTL_DSBLCLKGTNG BIT(0) -/* Global User Control Register */ -#define DWC3_GUCTL_HSTINAUTORETRY BIT(14) -/* Global User Control 1 Register */ #define DWC3_GUCTL1_DEV_DECOUPLE_L1L2_EVT BIT(31)#define DWC3_GUCTL1_TX_IPGAP_LINECHECK_DIS BIT(28)
Greg Kroah-Hartman
maintainerPATCH 165/228 usb: dwc3: pci: skip BYT GPIO lookup table for hardwired phy
In reply to Greg Kroah-HartmanFrom: Gratian Crisan <[email protected]>
commit b32b8f2b9542d8039f5468303a6ca78c1b5611a5 upstream.
Hardware based on the Bay Trail / BYT SoCs require an external ULPI phy for USB device-mode. The phy chip usually has its 'reset' and 'chip select' lines connected to GPIOs described by ACPI fwnodes in the DSDT table.
Because of hardware with missing ACPI resources for the 'reset' and 'chip select' GPIOs commit 5741022cbdf3 ("usb: dwc3: pci: Add GPIO lookup table on platforms without ACPI GPIO resources") introduced a fallback gpiod_lookup_table with hard-coded mappings for Bay Trail devices.
However there are existing Bay Trail based devices, like the National Instruments cRIO-903x series, where the phy chip has its 'reset' and 'chip-select' lines always asserted in hardware via resistor pull-ups. On this hardware the phy chip is always enabled and the ACPI dsdt table is missing information not only for the 'chip-select' and 'reset' lines but also for the BYT GPIO controller itself "INT33FC".
With the introduction of the gpiod_lookup_table initializing the USB device-mode on these hardware now errors out. The error comes from the gpiod_get_optional() calls in dwc3_pci_quirks() which will now return an -ENOENT error due to the missing ACPI entry for the INT33FC gpio controller used in the aforementioned table.
This hardware used to work before because gpiod_get_optional() will return NULL instead of -ENOENT if no GPIO has been assigned to the requested function. The dwc3_pci_quirks() code for setting the 'cs' and 'reset' GPIOs was then skipped (due to the NULL return). This is the correct behavior in cases where the phy chip is hardwired and there are no GPIOs to control.
Since the gpiod_lookup_table relies on the presence of INT33FC fwnode in ACPI tables only add the table if we know the entry for the INT33FC gpio controller is present. This allows Bay Trail based devices with hardwired dwc3 ULPI phys to continue working.
--- drivers/usb/dwc3/dwc3-pci.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/usb/dwc3/dwc3-pci.c +4 -2
@@ -233,10 +233,12 @@ static int dwc3_pci_quirks(struct dwc3_p/* * A lot of BYT devices lack ACPI resource entries for -* the GPIOs, add a fallback mapping to the reference +* the GPIOs. If the ACPI entry for the GPIO controller +* is present add a fallback mapping to the reference * design GPIOs which all boards seem to use. */ -gpiod_add_lookup_table (&platform_bytcr_gpios); +if (acpi_dev_present ("INT33FC" ,NULL ,-1 )) +gpiod_add_lookup_table (&platform_bytcr_gpios);/* * These GPIOs will turn on the USB2 PHY. Note that we have to
Greg Kroah-Hartman
maintainerPATCH 166/228 usb: dwc3: dont reset device side if dwc3 was configured as host-only
In reply to Greg Kroah-HartmanFrom: Jisheng Zhang <[email protected]>
commit e835c0a4e23c38531dcee5ef77e8d1cf462658c7 upstream.
Commit c4a5153e87fd ("usb: dwc3: core: Power-off core/PHYs on system_suspend in host mode") replaces check for HOST only dr_mode with current_dr_role. But during booting, the current_dr_role isn't initialized, thus the device side reset is always issued even if dwc3 was configured as host-only. What's more, on some platforms with host only dwc3, aways issuing device side reset by accessing device register block can cause kernel panic.
--- drivers/usb/dwc3/core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/usb/dwc3/core.c +2 -2
@@ -277,9 +277,9 @@ int dwc3_core_soft_reset(struct dwc3 *dw/* * We're resetting only the device side because, if we're in host mode, * XHCI driver will reset the host block. If dwc3 was configured for -* host-only mode, then we can return early. +* host-only mode or current role is host, then we can return early. */ -if (dwc->current_dr_role ==DWC3_GCTL_PRTCAP_HOST ) +if (dwc->dr_mode ==USB_DR_MODE_HOST || dwc->current_dr_role ==DWC3_GCTL_PRTCAP_HOST )return 0 ; reg =dwc3_readl (dwc->regs,DWC3_DCTL );
Greg Kroah-Hartman
maintainerPATCH 167/228 usb: misc: ehset: fix wrong if condition
In reply to Greg Kroah-HartmanFrom: Xu Yang <[email protected]>
commit 7f2327666a9080e428166964e37548b0168cd5e9 upstream.
A negative number from ret means the host controller had failed to send usb message and 0 means succeed. Therefore, the if logic is wrong here and this patch will fix it.
--- drivers/usb/misc/ehset.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/usb/misc/ehset.c +4 -4
@@ -77,7 +77,7 @@ static int ehset_probe(struct usb_interfswitch (test_pid) {case TEST_SE0_NAK_PID : ret =ehset_prepare_port_for_testing (hub_udev, portnum); -if (!ret) +if (ret <0 )break ; ret = usb_control_msg_send(hub_udev, 0, USB_REQ_SET_FEATURE, USB_RT_PORT, USB_PORT_FEAT_TEST,
@@ -86,7 +86,7 @@ static int ehset_probe(struct usb_interfbreak ;case TEST_J_PID : ret =ehset_prepare_port_for_testing (hub_udev, portnum); -if (!ret) +if (ret <0 )break ; ret = usb_control_msg_send(hub_udev, 0, USB_REQ_SET_FEATURE, USB_RT_PORT, USB_PORT_FEAT_TEST,
@@ -95,7 +95,7 @@ static int ehset_probe(struct usb_interfbreak ;case TEST_K_PID : ret =ehset_prepare_port_for_testing (hub_udev, portnum); -if (!ret) +if (ret <0 )break ; ret = usb_control_msg_send(hub_udev, 0, USB_REQ_SET_FEATURE, USB_RT_PORT, USB_PORT_FEAT_TEST,
@@ -104,7 +104,7 @@ static int ehset_probe(struct usb_interfbreak ;case TEST_PACKET_PID : ret =ehset_prepare_port_for_testing (hub_udev, portnum); -if (!ret) +if (ret <0 )break ; ret = usb_control_msg_send(hub_udev, 0, USB_REQ_SET_FEATURE, USB_RT_PORT, USB_PORT_FEAT_TEST,
Greg Kroah-Hartman
maintainerPATCH 168/228 usb: ohci-at91: Fix the unhandle interrupt when resume
In reply to Greg Kroah-HartmanFrom: Guiting Shen <[email protected]>
commit c55afcbeaa7a6f4fffdbc999a9bf3f0b29a5186f upstream.
The ohci_hcd_at91_drv_suspend() sets ohci->rh_state to OHCI_RH_HALTED when suspend which will let the ohci_irq() skip the interrupt after resume. And nobody to handle this interrupt.
According to the comment in ohci_hcd_at91_drv_suspend(), it need to reset when resume from suspend(MEM) to fix by setting "hibernated" argument of ohci_resume().
--- drivers/usb/host/ohci-at91.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/usb/host/ohci-at91.c +7 -1
@@ -673,7 +673,13 @@ ohci_hcd_at91_drv_resume(struct device *else at91_start_clock (ohci_at91); -ohci_resume (hcd, false); +/* +* According to the comment in ohci_hcd_at91_drv_suspend() +* we need to do a reset if the 48Mhz clock was stopped, +* that is, if ohci_at91->wakeup is clear. Tell ohci_resume() +* to reset in this case by setting its "hibernated" flag. +*/ +ohci_resume (hcd, !ohci_at91->wakeup);return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 169/228 USB: quirks: add quirk for Focusrite Scarlett
In reply to Greg Kroah-HartmanFrom: Łukasz Bartosik <[email protected]>
commit 9dc162e22387080e2d06de708b89920c0e158c9a upstream.
The Focusrite Scarlett audio device does not behave correctly during resumes. Below is what happens during every resume (captured with Beagle 5000):
<Suspend>
<Resume>
<Reset>/<Chirp J>/<Tiny J>
<Reset/Target disconnected>
<High Speed>
The Scarlett disconnects and is enumerated again.
However from time to time it drops completely off the USB bus during resume. Below is captured occurrence of such an event:
<Suspend>
<Resume>
<Reset>/<Chirp J>/<Tiny J>
<Reset>/<Chirp K>/<Tiny K>
<High Speed>
<Corrupted packet>
<Reset/Target disconnected>
To fix the condition a user has to unplug and plug the device again.
With USB_QUIRK_RESET_RESUME applied ("usbcore.quirks=1235:8211:b") for the Scarlett audio device the issue still reproduces.
Applying USB_QUIRK_DISCONNECT_SUSPEND ("usbcore.quirks=1235:8211:m") fixed the issue and the Scarlett audio device didn't drop off the USB bus for ~5000 suspend/resume cycles where originally issue reproduced in ~100 or less suspend/resume cycles.
--- drivers/usb/core/quirks.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/usb/core/quirks.c +4 -0
@@ -436,6 +436,10 @@ static const struct usb_device_id usb_qu/* novation SoundControl XL */ { USB_DEVICE(0x1235, 0x0061), .driver_info = USB_QUIRK_RESET_RESUME }, + /* Focusrite Scarlett Solo USB */ + { USB_DEVICE(0x1235, 0x8211), .driver_info = + USB_QUIRK_DISCONNECT_SUSPEND }, + /* Huawei 4G LTE module */ { USB_DEVICE(0x12d1, 0x15bb), .driver_info = USB_QUIRK_DISCONNECT_SUSPEND },
Greg Kroah-Hartman
maintainerPATCH 170/228 usb: cdns3: fix incorrect calculation of ep_buf_size when more than one config
In reply to Greg Kroah-HartmanFrom: Frank Li <[email protected]>
commit 2627335a1329a0d39d8d277994678571c4f21800 upstream.
Previously, the cdns3_gadget_check_config() function in the cdns3 driver mistakenly calculated the ep_buf_size by considering only one configuration's endpoint information because "claimed" will be clear after call usb_gadget_check_config().
The fix involves checking the private flags EP_CLAIMED instead of relying on the "claimed" flag.
--- drivers/usb/cdns3/cdns3-gadget.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/usb/cdns3/cdns3-gadget.c +3 -1
@@ -3012,12 +3012,14 @@ static int cdns3_gadget_udc_stop(structstatic int cdns3_gadget_check_config (struct usb_gadget *gadget) {struct cdns3_device *priv_dev =gadget_to_cdns3_device (gadget); +struct cdns3_endpoint *priv_ep;struct usb_ep *ep;int n_in =0 ;int total;list_for_each_entry (ep, &gadget->ep_list, ep_list) { -if (ep->claimed && (ep->address &USB_DIR_IN )) + priv_ep =ep_to_cdns3_ep (ep); +if ((priv_ep->flags &EP_CLAIMED ) && (ep->address &USB_DIR_IN )) n_in++; }
Greg Kroah-Hartman
maintainerPATCH 171/228 usb: xhci-mtk: set the dma max_seg_size
In reply to Greg Kroah-HartmanFrom: Ricardo Ribalda <[email protected]>
commit 9fd10829a9eb482e192a845675ecc5480e0bfa10 upstream.
Allow devices to have dma operations beyond 64K, and avoid warnings such as:
DMA-API: xhci-mtk 11200000.usb: mapping sg segment longer than device claims to support [len=98304] [max=65536]
--- drivers/usb/host/xhci-mtk.c | 1 + 1 file changed, 1 insertion(+)
drivers/usb/host/xhci-mtk.c +1 -0
@@ -590,6 +590,7 @@ static int xhci_mtk_probe(struct platfor }device_init_wakeup (dev, true); +dma_set_max_seg_size (dev,UINT_MAX ); xhci =hcd_to_xhci (hcd); xhci->main_hcd = hcd;
Greg Kroah-Hartman
maintainerPATCH 172/228 Revert "usb: xhci: tegra: Fix error check"
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
commit 288b4fa1798e3637a9304c6e90a93d900e02369c upstream.
This reverts commit 18fc7c435be3f17ea26a21b2e2312fcb9088e01f.
The reverted commit was based on static analysis and a misunderstanding of how PTR_ERR() and NULLs are supposed to work. When a function returns both pointer errors and NULL then normally the NULL means "continue operating without a feature because it was deliberately turned off". The NULL should not be treated as a failure. If a driver cannot work when that feature is disabled then the KConfig should enforce that the function cannot return NULL. We should not need to test for it.
In this code, the patch means that certain tegra_xusb_probe() will fail if the firmware supports power-domains but CONFIG_PM is disabled.
--- drivers/usb/host/xhci-tegra.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/usb/host/xhci-tegra.c +4 -4
@@ -1010,15 +1010,15 @@ static int tegra_xusb_powerdomain_init(sint err; tegra->genpd_dev_host =dev_pm_domain_attach_by_name (dev,"xusb_host" ); -if (IS_ERR_OR_NULL (tegra->genpd_dev_host)) { - err =PTR_ERR (tegra->genpd_dev_host) ? : -ENODATA ; +if (IS_ERR (tegra->genpd_dev_host)) { + err =PTR_ERR (tegra->genpd_dev_host);dev_err (dev,"failed to get host pm-domain: %d\n" , err);return err; } tegra->genpd_dev_ss =dev_pm_domain_attach_by_name (dev,"xusb_ss" ); -if (IS_ERR_OR_NULL (tegra->genpd_dev_ss)) { - err =PTR_ERR (tegra->genpd_dev_ss) ? : -ENODATA ; +if (IS_ERR (tegra->genpd_dev_ss)) { + err =PTR_ERR (tegra->genpd_dev_ss);dev_err (dev,"failed to get superspeed pm-domain: %d\n" , err);return err; }
Greg Kroah-Hartman
maintainerPATCH 173/228 Documentation: security-bugs.rst: update preferences when dealing with the linux-distros group
In reply to Greg Kroah-HartmanFrom: Greg Kroah-Hartman <[email protected]>
commit 4fee0915e649bd0cea56dece6d96f8f4643df33c upstream.
Because the linux-distros group forces reporters to release information about reported bugs, and they impose arbitrary deadlines in having those bugs fixed despite not actually being kernel developers, the kernel security team recommends not interacting with them at all as this just causes confusion and the early-release of reported security problems.
--- Documentation/admin-guide/security-bugs.rst | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-)
Documentation/admin-guide/security-bugs.rst +11 -13
@@ -63,20 +63,18 @@ information submitted to the security li of the report are treated confidentially even after the embargo has been lifted, in perpetuity. -Coordination ------------- +Coordination with other groups +------------------------------ -Fixes for sensitive bugs, such as those that might lead to privilege -escalations, may need to be coordinated with the private -<[email protected]> mailing list so that distribution vendors -are well prepared to issue a fixed kernel upon public disclosure of the -upstream fix. Distros will need some time to test the proposed patch and -will generally request at least a few days of embargo, and vendor update -publication prefers to happen Tuesday through Thursday. When appropriate, -the security team can assist with this coordination, or the reporter can -include linux-distros from the start. In this case, remember to prefix -the email Subject line with "[vs]" as described in the linux-distros wiki: -<http://oss-security.openwall.org/wiki/mailing-lists/distros#how-to-use-the-lists> +The kernel security team strongly recommends that reporters of potential +security issues NEVER contact the "linux-distros" mailing list until +AFTER discussing it with the kernel security team. Do not Cc: both +lists at once. You may contact the linux-distros mailing list after a +fix has been agreed on and you fully understand the requirements that +doing so will impose on you and the kernel community. + +The different lists have different goals and the linux-distros rules do +not contribute to actually fixing any potential security problems. CVE assignment --------------
Greg Kroah-Hartman
maintainerPATCH 174/228 Documentation: security-bugs.rst: clarify CVE handling
In reply to Greg Kroah-HartmanFrom: Greg Kroah-Hartman <[email protected]>
commit 3c1897ae4b6bc7cc586eda2feaa2cd68325ec29c upstream.
The kernel security team does NOT assign CVEs, so document that properly and provide the "if you want one, ask MITRE for it" response that we give on a weekly basis in the document, so we don't have to constantly say it to everyone who asks.
--- Documentation/admin-guide/security-bugs.rst | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-)
Documentation/admin-guide/security-bugs.rst +6 -7
@@ -79,13 +79,12 @@ not contribute to actually fixing any po CVE assignment -------------- -The security team does not normally assign CVEs, nor do we require them -for reports or fixes, as this can needlessly complicate the process and -may delay the bug handling. If a reporter wishes to have a CVE identifier -assigned ahead of public disclosure, they will need to contact the private -linux-distros list, described above. When such a CVE identifier is known -before a patch is provided, it is desirable to mention it in the commit -message if the reporter agrees. +The security team does not assign CVEs, nor do we require them for +reports or fixes, as this can needlessly complicate the process and may +delay the bug handling. If a reporter wishes to have a CVE identifier +assigned, they should find one by themselves, for example by contacting +MITRE directly. However under no circumstances will a patch inclusion +be delayed to wait for a CVE identifier to arrive. Non-disclosure agreements -------------------------
Greg Kroah-Hartman
maintainerPATCH 175/228 staging: r8712: Fix memory leak in _r8712_init_xmit_priv()
In reply to Greg Kroah-HartmanFrom: Larry Finger <[email protected]>
commit ac83631230f77dda94154ed0ebfd368fc81c70a3 upstream.
In the above mentioned routine, memory is allocated in several places. If the first succeeds and a later one fails, the routine will leak memory. This patch fixes commit 2865d42c78a9 ("staging: r8712u: Add the new driver to the mainline kernel"). A potential memory leak in r8712_xmit_resource_alloc() is also addressed.
--- drivers/staging/rtl8712/rtl871x_xmit.c | 43 ++++++++++++++++++++++++++------- drivers/staging/rtl8712/xmit_linux.c | 6 ++++ 2 files changed, 40 insertions(+), 9 deletions(-)
drivers/staging/rtl8712/rtl871x_xmit.c +34 -9
@@ -21,6 +21,7 @@#include "osdep_intf.h" #include "usb_ops.h" +#include <linux/usb.h> #include <linux/ieee80211.h> static const u8 P802_1H_OUI [P80211_OUI_LEN ] = {0x00 ,0x00 ,0xf8 };
@@ -55,6 +56,7 @@ int _r8712_init_xmit_priv(struct xmit_prsint i;struct xmit_buf *pxmitbuf;struct xmit_frame *pxframe; +int j;memset ((unsigned char *)pxmitpriv,0 ,sizeof (struct xmit_priv ));spin_lock_init (&pxmitpriv->lock);
@@ -117,11 +119,8 @@ int _r8712_init_xmit_priv(struct xmit_pr_init_queue (&pxmitpriv->pending_xmitbuf_queue); pxmitpriv->pallocated_xmitbuf =kmalloc (NR_XMITBUFF *sizeof (struct xmit_buf ) +4 ,GFP_ATOMIC ); -if (!pxmitpriv->pallocated_xmitbuf) { -kfree (pxmitpriv->pallocated_frame_buf); - pxmitpriv->pallocated_frame_buf =NULL ; -return -ENOMEM ; - } +if (!pxmitpriv->pallocated_xmitbuf) + goto clean_up_frame_buf; pxmitpriv->pxmitbuf = pxmitpriv->pallocated_xmitbuf +4 - ((addr_t)(pxmitpriv->pallocated_xmitbuf) &3 ); pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf;
@@ -129,13 +128,17 @@ int _r8712_init_xmit_priv(struct xmit_prINIT_LIST_HEAD (&pxmitbuf->list); pxmitbuf->pallocated_buf =kmalloc (MAX_XMITBUF_SZ +XMITBUF_ALIGN_SZ ,GFP_ATOMIC ); -if (!pxmitbuf->pallocated_buf) -return -ENOMEM ; +if (!pxmitbuf->pallocated_buf) { + j =0 ; + goto clean_up_alloc_buf; + } pxmitbuf->pbuf = pxmitbuf->pallocated_buf +XMITBUF_ALIGN_SZ - ((addr_t) (pxmitbuf->pallocated_buf) & (XMITBUF_ALIGN_SZ -1 )); -if (r8712_xmit_resource_alloc (padapter, pxmitbuf)) -return -ENOMEM ; +if (r8712_xmit_resource_alloc (padapter, pxmitbuf)) { + j =1 ; + goto clean_up_alloc_buf; + }list_add_tail (&pxmitbuf->list, &(pxmitpriv->free_xmitbuf_queue.queue)); pxmitbuf++;
@@ -146,6 +149,28 @@ int _r8712_init_xmit_priv(struct xmit_prinit_hwxmits (pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry);tasklet_setup (&pxmitpriv->xmit_tasklet, r8712_xmit_bh);return 0 ; + +clean_up_alloc_buf: +if (j) { +/* failure happened in r8712_xmit_resource_alloc() +* delete extra pxmitbuf->pallocated_buf +*/ +kfree (pxmitbuf->pallocated_buf); + } +for (j =0 ; j < i; j++) { +int k; + + pxmitbuf--;/* reset pointer */ +kfree (pxmitbuf->pallocated_buf); +for (k =0 ; k <8 ; k++)/* delete xmit urb's */ +usb_free_urb (pxmitbuf->pxmit_urb[k]); + } +kfree (pxmitpriv->pallocated_xmitbuf); + pxmitpriv->pallocated_xmitbuf =NULL ; +clean_up_frame_buf: +kfree (pxmitpriv->pallocated_frame_buf); + pxmitpriv->pallocated_frame_buf =NULL ; +return -ENOMEM ; }void _free_xmit_priv (struct xmit_priv *pxmitpriv)
drivers/staging/rtl8712/xmit_linux.c +6 -0
@@ -112,6 +112,12 @@ int r8712_xmit_resource_alloc(struct _adfor (i =0 ; i <8 ; i++) { pxmitbuf->pxmit_urb[i] =usb_alloc_urb (0 ,GFP_KERNEL );if (!pxmitbuf->pxmit_urb[i]) { +int k; + +for (k = i -1 ; k >=0 ; k--) { +/* handle allocation errors part way through loop */ +usb_free_urb (pxmitbuf->pxmit_urb[k]); + }netdev_err (padapter->pnetdev,"pxmitbuf->pxmit_urb[i] == NULL\n" );return -ENOMEM ; }
Greg Kroah-Hartman
maintainerPATCH 176/228 staging: ks7010: potential buffer overflow in ks_wlan_set_encode_ext()
In reply to Greg Kroah-HartmanFrom: Zhang Shurong <[email protected]>
commit 5f1c7031e044cb2fba82836d55cc235e2ad619dc upstream.
The "exc->key_len" is a u16 that comes from the user. If it's over IW_ENCODING_TOKEN_MAX (64) that could lead to memory corruption.
--- drivers/staging/ks7010/ks_wlan_net.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/staging/ks7010/ks_wlan_net.c +4 -2
@@ -1584,8 +1584,10 @@ static int ks_wlan_set_encode_ext(struct commit |=SME_WEP_FLAG ; }if (enc->key_len) { -memcpy (&key->key_val[0 ], &enc->key[0 ], enc->key_len); - key->key_len = enc->key_len; +int key_len =clamp_val (enc->key_len,0 ,IW_ENCODING_TOKEN_MAX ); + +memcpy (&key->key_val[0 ], &enc->key[0 ], key_len); + key->key_len = key_len; commit |= (SME_WEP_VAL1 << index); }break ;
Greg Kroah-Hartman
maintainerPATCH 177/228 tty: n_gsm: fix UAF in gsm_cleanup_mux
In reply to Greg Kroah-HartmanFrom: Chaoyuan Peng <[email protected]>
commit 9b9c8195f3f0d74a826077fc1c01b9ee74907239 upstream.
In gsm_cleanup_mux() the 'gsm->dlci' pointer was not cleaned properly, leaving it a dangling pointer after gsm_dlci_release.
This leads to use-after-free where 'gsm->dlci[0]' are freed and accessed by the subsequent gsm_cleanup_mux().
Such is the case in the following call trace:
<TASK> __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0x1e3/0x2cb lib/dump_stack.c:106 print_address_description+0x63/0x3b0 mm/kasan/report.c:248 __kasan_report mm/kasan/report.c:434 [inline] kasan_report+0x16b/0x1c0 mm/kasan/report.c:451 gsm_cleanup_mux+0x76a/0x850 drivers/tty/n_gsm.c:2397 gsm_config drivers/tty/n_gsm.c:2653 [inline] gsmld_ioctl+0xaae/0x15b0 drivers/tty/n_gsm.c:2986 tty_ioctl+0x8ff/0xc50 drivers/tty/tty_io.c:2816 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:874 [inline] __se_sys_ioctl+0xf1/0x160 fs/ioctl.c:860 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x3d/0xb0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x61/0xcb </TASK> Allocated by task 3501: kasan_save_stack mm/kasan/common.c:38 [inline] kasan_set_track mm/kasan/common.c:46 [inline] set_alloc_info mm/kasan/common.c:434 [inline] ____kasan_kmalloc+0xba/0xf0 mm/kasan/common.c:513 kasan_kmalloc include/linux/kasan.h:264 [inline] kmem_cache_alloc_trace+0x143/0x290 mm/slub.c:3247 kmalloc include/linux/slab.h:591 [inline] kzalloc include/linux/slab.h:721 [inline] gsm_dlci_alloc+0x53/0x3a0 drivers/tty/n_gsm.c:1932 gsm_activate_mux+0x1c/0x330 drivers/tty/n_gsm.c:2438 gsm_config drivers/tty/n_gsm.c:2677 [inline] gsmld_ioctl+0xd46/0x15b0 drivers/tty/n_gsm.c:2986 tty_ioctl+0x8ff/0xc50 drivers/tty/tty_io.c:2816 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:874 [inline] __se_sys_ioctl+0xf1/0x160 fs/ioctl.c:860 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x3d/0xb0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x61/0xcb Freed by task 3501: kasan_save_stack mm/kasan/common.c:38 [inline] kasan_set_track+0x4b/0x80 mm/kasan/common.c:46 kasan_set_free_info+0x1f/0x40 mm/kasan/generic.c:360 ____kasan_slab_free+0xd8/0x120 mm/kasan/common.c:366 kasan_slab_free include/linux/kasan.h:230 [inline] slab_free_hook mm/slub.c:1705 [inline] slab_free_freelist_hook+0xdd/0x160 mm/slub.c:1731 slab_free mm/slub.c:3499 [inline] kfree+0xf1/0x270 mm/slub.c:4559 dlci_put drivers/tty/n_gsm.c:1988 [inline] gsm_dlci_release drivers/tty/n_gsm.c:2021 [inline] gsm_cleanup_mux+0x574/0x850 drivers/tty/n_gsm.c:2415 gsm_config drivers/tty/n_gsm.c:2653 [inline] gsmld_ioctl+0xaae/0x15b0 drivers/tty/n_gsm.c:2986 tty_ioctl+0x8ff/0xc50 drivers/tty/tty_io.c:2816 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:874 [inline] __se_sys_ioctl+0xf1/0x160 fs/ioctl.c:860 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x3d/0xb0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x61/0xcb
--- drivers/tty/n_gsm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/tty/n_gsm.c +3 -1
@@ -2508,8 +2508,10 @@ static void gsm_cleanup_mux(struct gsm_m gsm->has_devices = false; }for (i =NUM_DLCI -1 ; i >=0 ; i--) -if (gsm->dlci[i]) +if (gsm->dlci[i]) {gsm_dlci_release (gsm->dlci[i]); + gsm->dlci[i] =NULL ; + }mutex_unlock (&gsm->mutex);/* Now wipe the queues */ tty_ldisc_flush (gsm->tty);
Greg Kroah-Hartman
maintainerPATCH 178/228 Revert "xhci: add quirk for host controllers that dont update endpoint DCS"
In reply to Greg Kroah-HartmanFrom: Oliver Neukum <[email protected]>
commit 5bef4b3cb95a5b883dfec8b3ffc0d671323d55bb upstream.
This reverts commit 5255660b208aebfdb71d574f3952cf48392f4306.
This quirk breaks at least the following hardware:
0b:00.0 0c03: 1106:3483 (rev 01) (prog-if 30 [XHCI])
Subsystem: 1106:3483
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx+
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0, Cache Line Size: 64 bytes
Interrupt: pin A routed to IRQ 66
Region 0: Memory at fb400000 (64-bit, non-prefetchable) [size=4K]
Capabilities: [80] Power Management version 3
Flags: PMEClk- DSI- D1- D2- AuxCurrent=375mA PME(D0+,D1+,D2+,D3hot+,D3cold+)
Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [90] MSI: Enable+ Count=1/4 Maskable- 64bit+
Address: 00000000fee007b8 Data: 0000
Capabilities: [c4] Express (v2) Endpoint, MSI 00
DevCap: MaxPayload 256 bytes, PhantFunc 0, Latency L0s <64ns, L1 <1us
ExtTag- AttnBtn- AttnInd- PwrInd- RBE+ FLReset- SlotPowerLimit 89W
DevCtl: CorrErr- NonFatalErr- FatalErr- UnsupReq-
RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop+
MaxPayload 128 bytes, MaxReadReq 512 bytes
DevSta: CorrErr- NonFatalErr- FatalErr- UnsupReq- AuxPwr+ TransPend-
LnkCap: Port #0, Speed 5GT/s, Width x1, ASPM L0s L1, Exit Latency L0s <2us, L1 <16us
ClockPM+ Surprise- LLActRep- BwNot- ASPMOptComp-
LnkCtl: ASPM Disabled; RCB 64 bytes, Disabled- CommClk+
ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
LnkSta: Speed 5GT/s, Width x1
TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt-
DevCap2: Completion Timeout: Range B, TimeoutDis+ NROPrPrP- LTR-
10BitTagComp- 10BitTagReq- OBFF Not Supported, ExtFmt- EETLPPrefix- EmergencyPowerReduction Not Supported, EmergencyPowerReductionInit- FRS- TPHComp- ExtTPHComp-
AtomicOpsCap: 32bit- 64bit- 128bitCAS-
DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis- LTR- 10BitTagReq- OBFF Disabled,
AtomicOpsCtl: ReqEn-
LnkCtl2: Target Link Speed: 5GT/s, EnterCompliance- SpeedDis-
Transmit Margin: Normal Operating Range, EnterModifiedCompliance- ComplianceSOS- Compliance Preset/De-emphasis: -6dB de-emphasis, 0dB preshoot
LnkSta2: Current De-emphasis Level: -6dB, EqualizationComplete- EqualizationPhase1-
EqualizationPhase2- EqualizationPhase3- LinkEqualizationRequest- Retimer- 2Retimers- CrosslinkRes: unsupported
Capabilities: [100 v1] Advanced Error Reporting
UESta: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
UEMsk: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
UESvrt: DLP+ SDES+ TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+ ECRC- UnsupReq- ACSViol-
CESta: RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr-
CEMsk: RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr+
AERCap: First Error Pointer: 00, ECRCGenCap- ECRCGenEn- ECRCChkCap- ECRCChkEn-
MultHdrRecCap- MultHdrRecEn- TLPPfxPres- HdrLogCap-
HeaderLog: 00000000 00000000 00000000 00000000
Kernel driver in use: xhci_hcd
Kernel modules: xhci_pci
with the quirk enabled it fails early with
[ 0.754373] pci 0000:0b:00.0: xHCI HW did not halt within 32000 usec status = 0x1000 [ 0.754419] pci 0000:0b:00.0: quirk_usb_early_handoff+0x0/0x7a0 took 31459 usecs [ 2.228048] xhci_hcd 0000:0b:00.0: xHCI Host Controller [ 2.228053] xhci_hcd 0000:0b:00.0: new USB bus registered, assigned bus number 7 [ 2.260073] xhci_hcd 0000:0b:00.0: Host halt failed, -110 [ 2.260079] xhci_hcd 0000:0b:00.0: can't setup: -110 [ 2.260551] xhci_hcd 0000:0b:00.0: USB bus 7 deregistered [ 2.260624] xhci_hcd 0000:0b:00.0: init 0000:0b:00.0 fail, -110 [ 2.260639] xhci_hcd: probe of 0000:0b:00.0 failed with error -110
The hardware in question is an external PCIe card. It looks to me like the quirk needs to be narrowed down. But this needs information about the hardware showing the issue this quirk is to fix. So for now a clean revert.
--- drivers/usb/host/xhci-pci.c | 4 +--- drivers/usb/host/xhci-ring.c | 25 +------------------------ 2 files changed, 2 insertions(+), 27 deletions(-)
drivers/usb/host/xhci-pci.c +1 -3
@@ -293,10 +293,8 @@ static void xhci_pci_quirks(struct devic pdev->device == 0x3432) xhci->quirks |=XHCI_BROKEN_STREAMS ; -if (pdev->vendor ==PCI_VENDOR_ID_VIA && pdev->device ==0x3483 ) { +if (pdev->vendor ==PCI_VENDOR_ID_VIA && pdev->device ==0x3483 ) xhci->quirks |=XHCI_LPM_SUPPORT ; - xhci->quirks |=XHCI_EP_CTX_BROKEN_DCS ; - }if (pdev->vendor ==PCI_VENDOR_ID_ASMEDIA && pdev->device ==PCI_DEVICE_ID_ASMEDIA_1042_XHCI ) {
drivers/usb/host/xhci-ring.c +1 -24
@@ -592,11 +592,8 @@ static int xhci_move_dequeue_past_td(strstruct xhci_ring *ep_ring;struct xhci_command *cmd;struct xhci_segment *new_seg; -struct xhci_segment *halted_seg =NULL ;union xhci_trb *new_deq;int new_cycle; -union xhci_trb *halted_trb; -int index =0 ;dma_addr_t addr;u64 hw_dequeue;bool cycle_found = false;
@@ -634,27 +631,7 @@ static int xhci_move_dequeue_past_td(str hw_dequeue =xhci_get_hw_deq (xhci, dev, ep_index, stream_id); new_seg = ep_ring->deq_seg; new_deq = ep_ring->dequeue; - -/* -* Quirk: xHC write-back of the DCS field in the hardware dequeue -* pointer is wrong - use the cycle state of the TRB pointed to by -* the dequeue pointer. -*/ -if (xhci->quirks &XHCI_EP_CTX_BROKEN_DCS && - !(ep->ep_state &EP_HAS_STREAMS )) - halted_seg =trb_in_td (xhci, td->start_seg, - td->first_trb, td->last_trb, - hw_dequeue & ~0xf , false); -if (halted_seg) { - index = ((dma_addr_t)(hw_dequeue & ~0xf ) - halted_seg->dma) / -sizeof (*halted_trb); - halted_trb = &halted_seg->trbs[index]; - new_cycle = halted_trb->generic.field[3 ] &0x1 ; -xhci_dbg (xhci,"Endpoint DCS = %d TRB index = %d cycle = %d\n" , - (u8)(hw_dequeue &0x1 ), index, new_cycle); - }else { - new_cycle = hw_dequeue &0x1 ; - } + new_cycle = hw_dequeue &0x1 ;/* * We want to find the pointer, segment and cycle state of the new trb
Greg Kroah-Hartman
maintainerPATCH 179/228 ALSA: hda/realtek: Support ASUS G713PV laptop
In reply to Greg Kroah-HartmanFrom: Pavel Asyutchenko <[email protected]>
commit 8019a4ab3d80c7af391a646cccff953753fc025f upstream.
This laptop has CS35L41 amp connected via I2C.
With this patch speakers begin to work if the
missing _DSD properties are added to ACPI tables.
--- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+)
sound/pci/hda/patch_realtek.c +1 -0
@@ -9580,6 +9580,7 @@ static const struct snd_pci_quirk alc269SND_PCI_QUIRK (0x1043 ,0x1c62 ,"ASUS GU603" ,ALC289_FIXUP_ASUS_GA401 ),SND_PCI_QUIRK (0x1043 ,0x1c92 ,"ASUS ROG Strix G15" ,ALC285_FIXUP_ASUS_G533Z_PINS ),SND_PCI_QUIRK (0x1043 ,0x1ccd ,"ASUS X555UB" ,ALC256_FIXUP_ASUS_MIC ), +SND_PCI_QUIRK (0x1043 ,0x1d1f ,"ASUS ROG Strix G17 2023 (G713PV)" ,ALC287_FIXUP_CS35L41_I2C_2 ),SND_PCI_QUIRK (0x1043 ,0x1d42 ,"ASUS Zephyrus G14 2022" ,ALC289_FIXUP_ASUS_GA401 ),SND_PCI_QUIRK (0x1043 ,0x1d4e ,"ASUS TM420" ,ALC256_FIXUP_ASUS_HPE ), SND_PCI_QUIRK(0x1043, 0x1e02, "ASUS UX3402", ALC245_FIXUP_CS35L41_SPI_2),
Greg Kroah-Hartman
maintainerPATCH 180/228 ALSA: hda/relatek: Enable Mute LED on HP 250 G8
In reply to Greg Kroah-HartmanFrom: Luka Guzenko <[email protected]>
commit d510acb610e6aa07a04b688236868b2a5fd60deb upstream.
This HP Notebook used ALC236 codec with COEF 0x07 idx 1 controlling the mute LED. Enable already existing quirk for this device.
--- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+)
sound/pci/hda/patch_realtek.c +1 -0
@@ -9457,6 +9457,7 @@ static const struct snd_pci_quirk alc269SND_PCI_QUIRK (0x103c ,0x880d ,"HP EliteBook 830 G8 Notebook PC" ,ALC285_FIXUP_HP_GPIO_LED ),SND_PCI_QUIRK (0x103c ,0x8811 ,"HP Spectre x360 15-eb1xxx" ,ALC285_FIXUP_HP_SPECTRE_X360_EB1 ),SND_PCI_QUIRK (0x103c ,0x8812 ,"HP Spectre x360 15-eb1xxx" ,ALC285_FIXUP_HP_SPECTRE_X360_EB1 ), +SND_PCI_QUIRK (0x103c ,0x881d ,"HP 250 G8 Notebook PC" ,ALC236_FIXUP_HP_MUTE_LED_COEFBIT2 ),SND_PCI_QUIRK (0x103c ,0x8846 ,"HP EliteBook 850 G8 Notebook PC" ,ALC285_FIXUP_HP_GPIO_LED ),SND_PCI_QUIRK (0x103c ,0x8847 ,"HP EliteBook x360 830 G8 Notebook PC" ,ALC285_FIXUP_HP_GPIO_LED ), SND_PCI_QUIRK(0x103c, 0x884b, "HP EliteBook 840 Aero G8 Notebook PC", ALC285_FIXUP_HP_GPIO_LED),
Greg Kroah-Hartman
maintainerPATCH 181/228 hwmon: (k10temp) Enable AMD3255 Proc to show negative temperature
In reply to Greg Kroah-HartmanFrom: Baskaran Kannan <[email protected]>
commit e146503ac68418859fb063a3a0cd9ec93bc52238 upstream.
Industrial processor i3255 supports temperatures -40 deg celcius to 105 deg Celcius. The current implementation of k10temp_read_temp rounds off any negative temperatures to '0'. To fix this, the following changes have been made.
A flag 'disp_negative' is added to struct k10temp_data to support AMD i3255 processors. Flag 'disp_negative' is set if 3255 processor is found during k10temp_probe. Flag 'disp_negative' is used to determine whether to round off negative temperatures to '0' in k10temp_read_temp.
--- drivers/hwmon/k10temp.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-)
drivers/hwmon/k10temp.c +15 -2
@@ -77,6 +77,13 @@ static DEFINE_MUTEX(nb_smu_ind_mutex);#define ZEN_CUR_TEMP_RANGE_SEL_MASK BIT(19)#define ZEN_CUR_TEMP_TJ_SEL_MASK GENMASK(17, 16) +/* +* AMD's Industrial processor 3255 supports temperature from -40 deg to 105 deg Celsius. +* Use the model name to identify 3255 CPUs and set a flag to display negative temperature. +* Do not round off to zero for negative Tctl or Tdie values if the flag is set +*/ +#define AMD_I3255_STR "3255" +struct k10temp_data {struct pci_dev *pdev;void (*read_htcreg)(struct pci_dev *pdev,u32 *regval);
@@ -86,6 +93,7 @@ struct k10temp_data {u32 show_temp;bool is_zen;u32 ccd_offset; +bool disp_negative; };#define TCTL_BIT 0
@@ -204,12 +212,12 @@ static int k10temp_read_temp(struct deviswitch (channel) {case 0 :/* Tctl */ *val =get_raw_temp (data); -if (*val <0 ) +if (*val <0 && !data->disp_negative) *val =0 ;break ;case 1 :/* Tdie */ *val =get_raw_temp (data) - data->temp_offset; -if (*val <0 ) +if (*val <0 && !data->disp_negative) *val =0 ;break ; case 2 ... 13: /* Tccd{1-12} */
@@ -405,6 +413,11 @@ static int k10temp_probe(struct pci_dev data->pdev = pdev; data->show_temp |=BIT (TCTL_BIT );/* Always show Tctl */ +if (boot_cpu_data.x86 ==0x17 && +strstr (boot_cpu_data.x86_model_id,AMD_I3255_STR )) { + data->disp_negative = true; + } +if (boot_cpu_data.x86 ==0x15 && ((boot_cpu_data.x86_model &0xf0 ) ==0x60 || (boot_cpu_data.x86_model &0xf0 ) ==0x70 )) {
Greg Kroah-Hartman
maintainerPATCH 182/228 hwmon: (nct7802) Fix for temp6 (PECI1) processed even if PECI1 disabled
In reply to Greg Kroah-HartmanFrom: Gilles Buloz <[email protected]>
commit 54685abe660a59402344d5045ce08c43c6a5ac42 upstream.
Because of hex value 0x46 used instead of decimal 46, the temp6 (PECI1) temperature is always declared visible and then displayed even if disabled in the chip
--- drivers/hwmon/nct7802.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/hwmon/nct7802.c +1 -1
@@ -725,7 +725,7 @@ static umode_t nct7802_temp_is_visible(sif (index >=38 && index <46 && !(reg &0x01 ))/* PECI 0 */ return 0 ; -if (index >=0x46 && (!(reg &0x02 )))/* PECI 1 */ +if (index >=46 && !(reg &0x02 ))/* PECI 1 */ return 0 ;return attr->mode;
Greg Kroah-Hartman
maintainerPATCH 183/228 btrfs: account block group tree when calculating global reserve size
In reply to Greg Kroah-HartmanFrom: Filipe Manana <[email protected]>
commit 8dbfc14fc736eb701089aff09645c3d4ad3decb1 upstream.
When using the block group tree feature, this tree is a critical tree just like the extent, csum and free space trees, and just like them it uses the delayed refs block reserve.
So take into account the block group tree, and its current size, when calculating the size for the global reserve.
--- fs/btrfs/block-rsv.c | 5 +++++ 1 file changed, 5 insertions(+)
fs/btrfs/block-rsv.c +5 -0
@@ -377,6 +377,11 @@ void btrfs_update_global_block_rsv(struc }read_unlock (&fs_info->global_root_lock); +if (btrfs_fs_compat_ro (fs_info,BLOCK_GROUP_TREE )) { + num_bytes +=btrfs_root_used (&fs_info->block_group_root->root_item); + min_items++; + } +/* * But we also want to reserve enough space so we can do the fallback * global reserve for an unlink, which is an additional 5 items (see the
Greg Kroah-Hartman
maintainerPATCH 184/228 btrfs: check if the transaction was aborted at btrfs_wait_for_commit()
In reply to Greg Kroah-HartmanFrom: Filipe Manana <[email protected]>
commit bf7ecbe9875061bf3fce1883e3b26b77f847d1e8 upstream.
At btrfs_wait_for_commit() we wait for a transaction to finish and then always return 0 (success) without checking if it was aborted, in which case the transaction didn't happen due to some critical error. Fix this by checking if the transaction was aborted.
--- fs/btrfs/transaction.c | 1 + 1 file changed, 1 insertion(+)
fs/btrfs/transaction.c +1 -0
@@ -919,6 +919,7 @@ int btrfs_wait_for_commit(struct btrfs_f }wait_for_commit (cur_trans,TRANS_STATE_COMPLETED ); + ret = cur_trans->aborted;btrfs_put_transaction (cur_trans); out:return ret;
Greg Kroah-Hartman
maintainerPATCH 185/228 btrfs: check for commit error at btrfs_attach_transaction_barrier()
In reply to Greg Kroah-HartmanFrom: Filipe Manana <[email protected]>
commit b28ff3a7d7e97456fd86b68d24caa32e1cfa7064 upstream.
btrfs_attach_transaction_barrier() is used to get a handle pointing to the current running transaction if the transaction has not started its commit yet (its state is < TRANS_STATE_COMMIT_START). If the transaction commit has started, then we wait for the transaction to commit and finish before returning - however we completely ignore if the transaction was aborted due to some error during its commit, we simply return ERR_PT(-ENOENT), which makes the caller assume everything is fine and no errors happened.
This could make an fsync return success (0) to user space when in fact we had a transaction abort and the target inode changes were therefore not persisted.
Fix this by checking for the return value from btrfs_wait_for_commit(), and if it returned an error, return it back to the caller.
--- fs/btrfs/transaction.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
fs/btrfs/transaction.c +7 -2
@@ -814,8 +814,13 @@ btrfs_attach_transaction_barrier(struct trans =start_transaction (root,0 ,TRANS_ATTACH ,BTRFS_RESERVE_NO_FLUSH , true); -if (trans ==ERR_PTR (-ENOENT )) -btrfs_wait_for_commit (root->fs_info,0 ); +if (trans ==ERR_PTR (-ENOENT )) { +int ret; + + ret =btrfs_wait_for_commit (root->fs_info,0 ); +if (ret) +return ERR_PTR (ret); + }return trans; }
Greg Kroah-Hartman
maintainerPATCH 186/228 x86/MCE/AMD: Decrement threshold_bank refcount when removing threshold blocks
In reply to Greg Kroah-HartmanFrom: Yazen Ghannam <[email protected]>
commit 3ba2e83334bed2b1980b59734e6e84dfaf96026c upstream.
AMD systems from Family 10h to 16h share MCA bank 4 across multiple CPUs. Therefore, the threshold_bank structure for bank 4, and its threshold_block structures, will be initialized once at boot time. And the kobject for the shared bank will be added to each of the CPUs that share it. Furthermore, the threshold_blocks for the shared bank will be added again to the bank's kobject. These additions will increase the refcount for the bank's kobject.
For example, a shared bank with two blocks and shared across two CPUs will be set up like this:
CPU0 init
bank create and add; bank refcount = 1; threshold_create_bank()
block 0 init and add; bank refcount = 2; allocate_threshold_blocks() block 1 init and add; bank refcount = 3; allocate_threshold_blocks()
CPU1 init
bank add; bank refcount = 3; threshold_create_bank()
block 0 add; bank refcount = 4; __threshold_add_blocks() block 1 add; bank refcount = 5; __threshold_add_blocks()
Currently in threshold_remove_bank(), if the bank is shared then __threshold_remove_blocks() is called. Here the shared bank's kobject and the bank's blocks' kobjects are deleted. This is done on the first call even while the structures are still shared. Subsequent calls from other CPUs that share the structures will attempt to delete the kobjects.
During kobject_del(), kobject->sd is removed. If the kobject is not part of a kset with default_groups, then subsequent kobject_del() calls seem safe even with kobject->sd == NULL.
Originally, the AMD MCA thresholding structures did not use default_groups. And so the above behavior was not apparent.
However, a recent change implemented default_groups for the thresholding structures. Therefore, kobject_del() will go down the sysfs_remove_groups() code path. In this case, the first kobject_del() may succeed and remove kobject->sd. But subsequent kobject_del() calls will give a WARNing in kernfs_remove_by_name_ns() since kobject->sd == NULL.
Use kobject_put() on the shared bank's kobject when "removing" blocks. This decrements the bank's refcount while keeping kobjects enabled until the bank is no longer shared. At that point, kobject_put() will be called on the blocks which drives their refcount to 0 and deletes them and also decrementing the bank's refcount. And finally kobject_put() will be called on the bank driving its refcount to 0 and deleting it.
The same example above:
CPU1 shutdown
bank is shared; bank refcount = 5; threshold_remove_bank()
block 0 put parent bank; bank refcount = 4; __threshold_remove_blocks() block 1 put parent bank; bank refcount = 3; __threshold_remove_blocks()
CPU0 shutdown
bank is no longer shared; bank refcount = 3; threshold_remove_bank()
block 0 put block; bank refcount = 2; deallocate_threshold_blocks() block 1 put block; bank refcount = 1; deallocate_threshold_blocks()
put bank; bank refcount = 0; threshold_remove_bank()
--- arch/x86/kernel/cpu/mce/amd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/x86/kernel/cpu/mce/amd.c +2 -2
@@ -1265,10 +1265,10 @@ static void __threshold_remove_blocks(ststruct threshold_block *pos =NULL ;struct threshold_block *tmp =NULL ; -kobject_del (b->kobj); +kobject_put (b->kobj);list_for_each_entry_safe (pos, tmp, &b->blocks->miscj, miscj) -kobject_del (&pos->kobj); +kobject_put (b->kobj); }static void threshold_remove_bank (struct threshold_bank *bank)
Greg Kroah-Hartman
maintainerPATCH 187/228 file: always lock position for FMODE_ATOMIC_POS
In reply to Greg Kroah-HartmanFrom: Christian Brauner <[email protected]>
commit 20ea1e7d13c1b544fe67c4a8dc3943bb1ab33e6f upstream.
The pidfd_getfd() system call allows a caller with ptrace_may_access() abilities on another process to steal a file descriptor from this process. This system call is used by debuggers, container runtimes, system call supervisors, networking proxies etc. So while it is a special interest system call it is used in common tools.
That ability ends up breaking our long-time optimization in fdget_pos(), which "knew" that if we had exclusive access to the file descriptor nobody else could access it, and we didn't need the lock for the file position.
That check for file_count(file) was always fairly subtle - it depended on __fdget() not incrementing the file count for single-threaded processes and thus included that as part of the rule - but it did mean that we didn't need to take the lock in all those traditional unix process contexts.
So it's sad to see this go, and I'd love to have some way to re-instate the optimization. At the same time, the lock obviously isn't ever contended in the case we optimized, so all we were optimizing away is the atomics and the cacheline dirtying. Let's see if anybody even notices that the optimization is gone.
--- fs/file.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
fs/file.c +2 -4
@@ -1042,10 +1042,8 @@ unsigned long __fdget_pos(unsigned int fstruct file *file = (struct file *)(v & ~3 );if (file && (file->f_mode &FMODE_ATOMIC_POS )) { -if (file_count (file) >1 ) { - v |=FDPUT_POS_UNLOCK ; -mutex_lock (&file->f_pos_lock); - } + v |=FDPUT_POS_UNLOCK ; +mutex_lock (&file->f_pos_lock); }return v; }
Greg Kroah-Hartman
maintainerPATCH 188/228 nfsd: Remove incorrect check in nfsd4_validate_stateid
In reply to Greg Kroah-HartmanFrom: Trond Myklebust <[email protected]>
commit f75546f58a70da5cfdcec5a45ffc377885ccbee8 upstream.
If the client is calling TEST_STATEID, then it is because some event occurred that requires it to check all the stateids for validity and call FREE_STATEID on the ones that have been revoked. In this case, either the stateid exists in the list of stateids associated with that nfs4_client, in which case it should be tested, or it does not. There are no additional conditions to be considered.
--- fs/nfsd/nfs4state.c | 2 -- 1 file changed, 2 deletions(-)
fs/nfsd/nfs4state.c +0 -2
@@ -6269,8 +6269,6 @@ static __be32 nfsd4_validate_stateid(strif (ZERO_STATEID (stateid) ||ONE_STATEID (stateid) ||CLOSE_STATEID (stateid))return status; -if (!same_clid (&stateid->si_opaque.so_clid, &cl->cl_clientid)) -return status;spin_lock (&cl->cl_lock); s =find_stateid_locked (cl, stateid);if (!s)
Greg Kroah-Hartman
maintainerPATCH 189/228 ACPI/IORT: Remove erroneous id_count check in iort_node_get_rmr_info()
In reply to Greg Kroah-HartmanFrom: Guanghui Feng <[email protected]>
commit 003e6b56d780095a9adc23efc9cb4b4b4717169b upstream.
According to the ARM IORT specifications DEN 0049 issue E, the "Number of IDs" field in the ID mapping format reports the number of IDs in the mapping range minus one.
In iort_node_get_rmr_info(), we erroneously skip ID mappings whose "Number of IDs" equal to 0, resulting in valid mapping nodes with a single ID to map being skipped, which is wrong.
Fix iort_node_get_rmr_info() by removing the bogus id_count check.
--- drivers/acpi/arm64/iort.c | 3 --- 1 file changed, 3 deletions(-)
drivers/acpi/arm64/iort.c +0 -3
@@ -998,9 +998,6 @@ static void iort_node_get_rmr_info(strucfor (i =0 ; i < node->mapping_count; i++, map++) {struct acpi_iort_node *parent; -if (!map->id_count) -continue ; - parent = ACPI_ADD_PTR(struct acpi_iort_node, iort_table, map->output_reference);if (parent != iommu)
Greg Kroah-Hartman
maintainerPATCH 190/228 tpm_tis: Explicitly check for error code
In reply to Greg Kroah-HartmanFrom: Alexander Steffen <[email protected]>
commit 513253f8c293c0c8bd46d09d337fc892bf8f9f48 upstream.
recv_data either returns the number of received bytes, or a negative value representing an error code. Adding the return value directly to the total number of received bytes therefore looks a little weird, since it might add a negative error code to a sum of bytes.
The following check for size < expected usually makes the function return ETIME in that case, so it does not cause too many problems in practice. But to make the code look cleaner and because the caller might still be interested in the original error code, explicitly check for the presence of an error code and pass that through.
--- drivers/char/tpm/tpm_tis_core.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
drivers/char/tpm/tpm_tis_core.c +7 -2
@@ -356,8 +356,13 @@ static int tpm_tis_recv(struct tpm_chip goto out; } - size +=recv_data (chip, &buf[TPM_HEADER_SIZE ], - expected -TPM_HEADER_SIZE ); + rc =recv_data (chip, &buf[TPM_HEADER_SIZE ], + expected -TPM_HEADER_SIZE ); +if (rc <0 ) { + size = rc; + goto out; + } + size += rc;if (size < expected) {dev_err (&chip->dev,"Unable to read remainder of result\n" ); size = -ETIME ;
Greg Kroah-Hartman
maintainerPATCH 191/228 irq-bcm6345-l1: Do not assume a fixed block to cpu mapping
In reply to Greg Kroah-HartmanFrom: Jonas Gorski <[email protected]>
[ Upstream commit 55ad24857341c36616ecc1d9580af5626c226cf1 ]
The irq to block mapping is fixed, and interrupts from the first block will always be routed to the first parent IRQ. But the parent interrupts themselves can be routed to any available CPU.
This is used by the bootloader to map the first parent interrupt to the boot CPU, regardless wether the boot CPU is the first one or the second one.
When booting from the second CPU, the assumption that the first block's IRQ is mapped to the first CPU breaks, and the system hangs because interrupts do not get routed correctly.
Fix this by passing the appropriate bcm6434_l1_cpu to the interrupt handler instead of the chip itself, so the handler always has the right block.
--- drivers/irqchip/irq-bcm6345-l1.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-)
drivers/irqchip/irq-bcm6345-l1.c +5 -9
@@ -82,6 +82,7 @@ struct bcm6345_l1_chip { };struct bcm6345_l1_cpu { +struct bcm6345_l1_chip *intc;void __iomem *map_base;unsigned int parent_irq;u32 enable_cache[];
@@ -115,17 +116,11 @@ static inline unsigned int cpu_for_irq(struct bcm6345_l1_chip *intc,static void bcm6345_l1_irq_handle (struct irq_desc *desc) { -struct bcm6345_l1_chip *intc =irq_desc_get_handler_data (desc); -struct bcm6345_l1_cpu *cpu; +struct bcm6345_l1_cpu *cpu =irq_desc_get_handler_data (desc); +struct bcm6345_l1_chip *intc = cpu->intc;struct irq_chip *chip =irq_desc_get_chip (desc);unsigned int idx; -#ifdef CONFIG_SMP - cpu = intc->cpus[cpu_logical_map (smp_processor_id ())]; -#else - cpu = intc->cpus[0 ]; -#endif -chained_irq_enter (chip, desc);for (idx =0 ; idx < intc->n_words; idx++) {
@@ -253,6 +248,7 @@ static int __init bcm6345_l1_init_one(struct device_node *dn,if (!cpu)return -ENOMEM ; + cpu->intc = intc; cpu->map_base =ioremap (res.start, sz);if (!cpu->map_base)return -ENOMEM ;
@@ -268,7 +264,7 @@ static int __init bcm6345_l1_init_one(struct device_node *dn,return -EINVAL ; }irq_set_chained_handler_and_data (cpu->parent_irq, - bcm6345_l1_irq_handle, intc); + bcm6345_l1_irq_handle, cpu);return 0 ; }
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 192/228 irqchip/gic-v4.1: Properly lock VPEs when doing a directLPI invalidation
In reply to Greg Kroah-HartmanFrom: Marc Zyngier <[email protected]>
[ Upstream commit 926846a703cbf5d0635cc06e67d34b228746554b ]
We normally rely on the irq_to_cpuid_[un]lock() primitives to make sure nothing will change col->idx while performing a LPI invalidation.
However, these primitives do not cover VPE doorbells, and we have some open-coded locking for that. Unfortunately, this locking is pretty bogus.
Instead, extend the above primitives to cover VPE doorbells and convert the whole thing to it.
--- drivers/irqchip/irq-gic-v3-its.c | 75 ++++++++++++++++++++------------ 1 file changed, 46 insertions(+), 29 deletions(-)
drivers/irqchip/irq-gic-v3-its.c +46 -29
@@ -271,13 +271,23 @@ static void vpe_to_cpuid_unlock(struct its_vpe *vpe, unsigned long flags)raw_spin_unlock_irqrestore (&vpe->vpe_lock, flags); } +static struct irq_chip its_vpe_irq_chip; +static int irq_to_cpuid_lock (struct irq_data *d,unsigned long *flags) { -struct its_vlpi_map *map =get_vlpi_map (d); +struct its_vpe *vpe =NULL ;int cpu; -if (map) { - cpu =vpe_to_cpuid_lock (map->vpe, flags); +if (d->chip == &its_vpe_irq_chip) { + vpe =irq_data_get_irq_chip_data (d); + }else { +struct its_vlpi_map *map =get_vlpi_map (d); +if (map) + vpe = map->vpe; + } + +if (vpe) { + cpu =vpe_to_cpuid_lock (vpe, flags); }else {/* Physical LPIs are already locked via the irq_desc lock */ struct its_device *its_dev =irq_data_get_irq_chip_data (d);
@@ -291,10 +301,18 @@ static int irq_to_cpuid_lock(struct irq_data *d, unsigned long *flags)static void irq_to_cpuid_unlock (struct irq_data *d,unsigned long flags) { -struct its_vlpi_map *map =get_vlpi_map (d); +struct its_vpe *vpe =NULL ; + +if (d->chip == &its_vpe_irq_chip) { + vpe =irq_data_get_irq_chip_data (d); + }else { +struct its_vlpi_map *map =get_vlpi_map (d); +if (map) + vpe = map->vpe; + } -if (map) -vpe_to_cpuid_unlock (map->vpe, flags); +if (vpe) +vpe_to_cpuid_unlock (vpe, flags); }static struct its_collection *valid_col (struct its_collection *col)
@@ -1431,14 +1449,29 @@ static void wait_for_syncr(void __iomem *rdbase)cpu_relax (); } -static void direct_lpi_inv (struct irq_data *d) +static void __direct_lpi_inv (struct irq_data *d,u64 val) { -struct its_vlpi_map *map =get_vlpi_map (d);void __iomem *rdbase;unsigned long flags; -u64 val;int cpu; +/* Target the redistributor this LPI is currently routed to */ + cpu =irq_to_cpuid_lock (d, &flags); +raw_spin_lock (&gic_data_rdist_cpu (cpu)->rd_lock); + + rdbase =per_cpu_ptr (gic_rdists->rdist, cpu)->rd_base; +gic_write_lpir (val, rdbase +GICR_INVLPIR ); +wait_for_syncr (rdbase); + +raw_spin_unlock (&gic_data_rdist_cpu (cpu)->rd_lock); +irq_to_cpuid_unlock (d, flags); +} + +static void direct_lpi_inv (struct irq_data *d) +{ +struct its_vlpi_map *map =get_vlpi_map (d); +u64 val; +if (map) {struct its_device *its_dev =irq_data_get_irq_chip_data (d);
@@ -1451,15 +1484,7 @@ static void direct_lpi_inv(struct irq_data *d) val = d->hwirq; } -/* Target the redistributor this LPI is currently routed to */ - cpu =irq_to_cpuid_lock (d, &flags); -raw_spin_lock (&gic_data_rdist_cpu (cpu)->rd_lock); - rdbase =per_cpu_ptr (gic_rdists->rdist, cpu)->rd_base; -gic_write_lpir (val, rdbase +GICR_INVLPIR ); - -wait_for_syncr (rdbase); -raw_spin_unlock (&gic_data_rdist_cpu (cpu)->rd_lock); -irq_to_cpuid_unlock (d, flags); +__direct_lpi_inv (d, val); }static void lpi_update_config (struct irq_data *d,u8 clr,u8 set)
@@ -3941,18 +3966,10 @@ static void its_vpe_send_inv(struct irq_data *d) {struct its_vpe *vpe =irq_data_get_irq_chip_data (d); -if (gic_rdists->has_direct_lpi) { -void __iomem *rdbase; - -/* Target the redistributor this VPE is currently known on */ -raw_spin_lock (&gic_data_rdist_cpu (vpe->col_idx)->rd_lock); - rdbase =per_cpu_ptr (gic_rdists->rdist, vpe->col_idx)->rd_base; -gic_write_lpir (d->parent_data->hwirq, rdbase +GICR_INVLPIR ); -wait_for_syncr (rdbase); -raw_spin_unlock (&gic_data_rdist_cpu (vpe->col_idx)->rd_lock); - }else { +if (gic_rdists->has_direct_lpi) +__direct_lpi_inv (d, d->parent_data->hwirq); +else its_vpe_send_cmd (vpe, its_send_inv); - } }static void its_vpe_mask_irq (struct irq_data *d)
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 193/228 locking/rtmutex: Fix task->pi_waiters integrity
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
[ Upstream commit f7853c34241807bb97673a5e97719123be39a09e ]
Henry reported that rt_mutex_adjust_prio_check() has an ordering problem and puts the lie to the comment in [7]. Sharing the sort key between lock->waiters and owner->pi_waiters *does* create problems, since unlike what the comment claims, holding [L] is insufficient.
Notably, consider:
A
/ \
M1 M2
| |
B CThat is, task A owns both M1 and M2, B and C block on them. In this case a concurrent chain walk (B & C) will modify their resp. sort keys in [7] while holding M1->wait_lock and M2->wait_lock. So holding [L] is meaningless, they're different Ls.
This then gives rise to a race condition between [7] and [11], where the requeue of pi_waiters will observe an inconsistent tree order.
B C
(holds M1->wait_lock, (holds M2->wait_lock,
holds B->pi_lock) holds A->pi_lock)
[7] waiter_update_prio(); ... [8] raw_spin_unlock(B->pi_lock); ... [10] raw_spin_lock(A->pi_lock);
[11] rt_mutex_enqueue_pi(); // observes inconsistent A->pi_waiters // tree order
Fixing this means either extending the range of the owner lock from [10-13] to [6-13], with the immediate problem that this means [6-8] hold both blocked and owner locks, or duplicating the sort key.
Since the locking in chain walk is horrible enough without having to consider pi_lock nesting rules, duplicate the sort key instead.
By giving each tree their own sort key, the above race becomes harmless, if C sees B at the old location, then B will correct things (if they need correcting) when it walks up the chain and reaches A.
--- kernel/locking/rtmutex.c | 170 +++++++++++++++++++++----------- kernel/locking/rtmutex_api.c | 2 +- kernel/locking/rtmutex_common.h | 47 ++++++--- kernel/locking/ww_mutex.h | 12 +-- 4 files changed, 155 insertions(+), 76 deletions(-)
kernel/locking/rtmutex.c +114 -56
@@ -333,21 +333,43 @@ static __always_inline int __waiter_prio(struct task_struct *task)return prio; } +/* +* Update the waiter->tree copy of the sort keys. +*/ static __always_inline voidwaiter_update_prio (struct rt_mutex_waiter *waiter,struct task_struct *task) { - waiter->prio =__waiter_prio (task); - waiter->deadline = task->dl.deadline; +lockdep_assert_held (&waiter->lock->wait_lock); +lockdep_assert (RB_EMPTY_NODE (&waiter->tree.entry)); + + waiter->tree.prio =__waiter_prio (task); + waiter->tree.deadline = task->dl.deadline; +} + +/* +* Update the waiter->pi_tree copy of the sort keys (from the tree copy). +*/ +static __always_inline void +waiter_clone_prio (struct rt_mutex_waiter *waiter,struct task_struct *task) +{ +lockdep_assert_held (&waiter->lock->wait_lock); +lockdep_assert_held (&task->pi_lock); +lockdep_assert (RB_EMPTY_NODE (&waiter->pi_tree.entry)); + + waiter->pi_tree.prio = waiter->tree.prio; + waiter->pi_tree.deadline = waiter->tree.deadline; }/* -* Only use with rt_mutex_waiter_{less,equal}() +* Only use with rt_waiter_node_{less,equal}() */ +#define task_to_waiter_node (p) \ + &(struct rt_waiter_node){ .prio = __waiter_prio(p), .deadline = (p)->dl.deadline }#define task_to_waiter (p) \ - &(struct rt_mutex_waiter){ .prio = __waiter_prio(p), .deadline = (p)->dl.deadline } + &(struct rt_mutex_waiter){ .tree = *task_to_waiter_node(p) } -static __always_inline int rt_mutex_waiter_less(struct rt_mutex_waiter *left, -struct rt_mutex_waiter *right) +static __always_inline int rt_waiter_node_less(struct rt_waiter_node *left, +struct rt_waiter_node *right) {if (left->prio < right->prio)return 1 ;
@@ -364,8 +386,8 @@ static __always_inline int rt_mutex_waiter_less(struct rt_mutex_waiter *left,return 0 ; } -static __always_inline int rt_mutex_waiter_equal(struct rt_mutex_waiter *left, -struct rt_mutex_waiter *right) +static __always_inline int rt_waiter_node_equal(struct rt_waiter_node *left, +struct rt_waiter_node *right) {if (left->prio != right->prio)return 0 ;
@@ -385,7 +407,7 @@ static __always_inline int rt_mutex_waiter_equal(struct rt_mutex_waiter *left,static inline bool rt_mutex_steal (struct rt_mutex_waiter *waiter,struct rt_mutex_waiter *top_waiter) { -if (rt_mutex_waiter_less (waiter, top_waiter)) +if (rt_waiter_node_less (&waiter->tree, &top_waiter->tree))return true;#ifdef RT_MUTEX_BUILD_SPINLOCKS
@@ -393,30 +415,30 @@ static inline bool rt_mutex_steal(struct rt_mutex_waiter *waiter,* Note that RT tasks are excluded from same priority (lateral) * steals to prevent the introduction of an unbounded latency. */ -if (rt_prio (waiter->prio) ||dl_prio (waiter->prio)) +if (rt_prio (waiter->tree.prio) ||dl_prio (waiter->tree.prio))return false; -return rt_mutex_waiter_equal (waiter, top_waiter); +return rt_waiter_node_equal (&waiter->tree, &top_waiter->tree);#else return false;#endif }#define __node_2_waiter (node) \ - rb_entry((node), struct rt_mutex_waiter, tree_entry) + rb_entry((node), struct rt_mutex_waiter, tree.entry) static __always_inline bool __waiter_less(struct rb_node *a, const struct rb_node *b) {struct rt_mutex_waiter *aw =__node_2_waiter (a);struct rt_mutex_waiter *bw =__node_2_waiter (b); -if (rt_mutex_waiter_less (aw, bw)) +if (rt_waiter_node_less (&aw->tree, &bw->tree))return 1 ;if (!build_ww_mutex ())return 0 ; -if (rt_mutex_waiter_less (bw, aw)) +if (rt_waiter_node_less (&bw->tree, &aw->tree))return 0 ;/* NOTE: relies on waiter->ww_ctx being set before insertion */
@@ -434,48 +456,58 @@ static __always_inline bool __waiter_less(struct rb_node *a, const struct rb_nod static __always_inline voidrt_mutex_enqueue (struct rt_mutex_base *lock,struct rt_mutex_waiter *waiter) { -rb_add_cached (&waiter->tree_entry, &lock->waiters, __waiter_less); +lockdep_assert_held (&lock->wait_lock); + +rb_add_cached (&waiter->tree.entry, &lock->waiters, __waiter_less); } static __always_inline voidrt_mutex_dequeue (struct rt_mutex_base *lock,struct rt_mutex_waiter *waiter) { -if (RB_EMPTY_NODE (&waiter->tree_entry)) +lockdep_assert_held (&lock->wait_lock); + +if (RB_EMPTY_NODE (&waiter->tree.entry))return ; -rb_erase_cached (&waiter->tree_entry, &lock->waiters); -RB_CLEAR_NODE (&waiter->tree_entry); +rb_erase_cached (&waiter->tree.entry, &lock->waiters); +RB_CLEAR_NODE (&waiter->tree.entry); } -#define __node_2_pi_waiter (node) \ - rb_entry((node), struct rt_mutex_waiter, pi_tree_entry) +#define __node_2_rt_node (node) \ + rb_entry((node), struct rt_waiter_node, entry) -static __always_inline bool -__pi_waiter_less (struct rb_node *a,const struct rb_node *b) +static __always_inline bool __pi_waiter_less(struct rb_node *a, const struct rb_node *b) { -return rt_mutex_waiter_less (__node_2_pi_waiter (a),__node_2_pi_waiter (b)); +return rt_waiter_node_less (__node_2_rt_node (a),__node_2_rt_node (b)); } static __always_inline voidrt_mutex_enqueue_pi (struct task_struct *task,struct rt_mutex_waiter *waiter) { -rb_add_cached (&waiter->pi_tree_entry, &task->pi_waiters, __pi_waiter_less); +lockdep_assert_held (&task->pi_lock); + +rb_add_cached (&waiter->pi_tree.entry, &task->pi_waiters, __pi_waiter_less); } static __always_inline voidrt_mutex_dequeue_pi (struct task_struct *task,struct rt_mutex_waiter *waiter) { -if (RB_EMPTY_NODE (&waiter->pi_tree_entry)) +lockdep_assert_held (&task->pi_lock); + +if (RB_EMPTY_NODE (&waiter->pi_tree.entry))return ; -rb_erase_cached (&waiter->pi_tree_entry, &task->pi_waiters); -RB_CLEAR_NODE (&waiter->pi_tree_entry); +rb_erase_cached (&waiter->pi_tree.entry, &task->pi_waiters); +RB_CLEAR_NODE (&waiter->pi_tree.entry); } -static __always_inline void rt_mutex_adjust_prio(struct task_struct *p) +static __always_inline void rt_mutex_adjust_prio(struct rt_mutex_base *lock, +struct task_struct *p) {struct task_struct *pi_task =NULL ; +lockdep_assert_held (&lock->wait_lock); +lockdep_assert (rt_mutex_owner (lock) == p);lockdep_assert_held (&p->pi_lock);if (task_has_pi_waiters (p))
@@ -571,9 +603,14 @@ static __always_inline struct rt_mutex_base *task_blocked_on_lock(struct task_st* Chain walk basics and protection scope * * [R] refcount on task -* [P] task->pi_lock held +* [Pn] task->pi_lock held * [L] rtmutex->wait_lock held * +* Normal locking order: +* +* rtmutex->wait_lock +* task->pi_lock +* * Step Description Protected by * function arguments: * @task [R]
@@ -588,27 +625,32 @@ static __always_inline struct rt_mutex_base *task_blocked_on_lock(struct task_st* again: * loop_sanity_check(); * retry: -* [1] lock(task->pi_lock); [R] acquire [P] -* [2] waiter = task->pi_blocked_on; [P] -* [3] check_exit_conditions_1(); [P] -* [4] lock = waiter->lock; [P] -* [5] if (!try_lock(lock->wait_lock)) { [P] try to acquire [L] -* unlock(task->pi_lock); release [P] +* [1] lock(task->pi_lock); [R] acquire [P1] +* [2] waiter = task->pi_blocked_on; [P1] +* [3] check_exit_conditions_1(); [P1] +* [4] lock = waiter->lock; [P1] +* [5] if (!try_lock(lock->wait_lock)) { [P1] try to acquire [L] +* unlock(task->pi_lock); release [P1] * goto retry; * } -* [6] check_exit_conditions_2(); [P] + [L] -* [7] requeue_lock_waiter(lock, waiter); [P] + [L] -* [8] unlock(task->pi_lock); release [P] +* [6] check_exit_conditions_2(); [P1] + [L] +* [7] requeue_lock_waiter(lock, waiter); [P1] + [L] +* [8] unlock(task->pi_lock); release [P1] * put_task_struct(task); release [R] * [9] check_exit_conditions_3(); [L] * [10] task = owner(lock); [L] * get_task_struct(task); [L] acquire [R] -* lock(task->pi_lock); [L] acquire [P] -* [11] requeue_pi_waiter(tsk, waiters(lock));[P] + [L] -* [12] check_exit_conditions_4(); [P] + [L] -* [13] unlock(task->pi_lock); release [P] +* lock(task->pi_lock); [L] acquire [P2] +* [11] requeue_pi_waiter(tsk, waiters(lock));[P2] + [L] +* [12] check_exit_conditions_4(); [P2] + [L] +* [13] unlock(task->pi_lock); release [P2] * unlock(lock->wait_lock); release [L] * goto again; +* +* Where P1 is the blocking task and P2 is the lock owner; going up one step +* the owner becomes the next blocked task etc.. +* +* */ static int __sched rt_mutex_adjust_prio_chain(struct task_struct *task, enum rtmutex_chainwalk chwalk,
@@ -756,7 +798,7 @@ static int __sched rt_mutex_adjust_prio_chain(struct task_struct *task,* enabled we continue, but stop the requeueing in the chain * walk. */ -if (rt_mutex_waiter_equal (waiter,task_to_waiter (task))) { +if (rt_waiter_node_equal (&waiter->tree,task_to_waiter_node (task))) {if (!detect_deadlock) goto out_unlock_pi;else
@@ -764,13 +806,18 @@ static int __sched rt_mutex_adjust_prio_chain(struct task_struct *task, }/* -* [4] Get the next lock +* [4] Get the next lock; per holding task->pi_lock we can't unblock +* and guarantee @lock's existence. */ lock = waiter->lock;/* * [5] We need to trylock here as we are holding task->pi_lock, * which is the reverse lock order versus the other rtmutex * operations. +* +* Per the above, holding task->pi_lock guarantees lock exists, so +* inverting this lock order is infeasible from a life-time +* perspective. */ if (!raw_spin_trylock (&lock->wait_lock)) {raw_spin_unlock_irq (&task->pi_lock);
@@ -874,17 +921,18 @@ static int __sched rt_mutex_adjust_prio_chain(struct task_struct *task,* or * * DL CBS enforcement advancing the effective deadline. -* -* Even though pi_waiters also uses these fields, and that tree is only -* updated in [11], we can do this here, since we hold [L], which -* serializes all pi_waiters access and rb_erase() does not care about -* the values of the node being removed. */ waiter_update_prio (waiter, task);rt_mutex_enqueue (lock, waiter); -/* [8] Release the task */ +/* +* [8] Release the (blocking) task in preparation for +* taking the owner task in [10]. +* +* Since we hold lock->waiter_lock, task cannot unblock, even if we +* release task->pi_lock. +*/ raw_spin_unlock (&task->pi_lock);put_task_struct (task);
@@ -908,7 +956,12 @@ static int __sched rt_mutex_adjust_prio_chain(struct task_struct *task,return 0 ; } -/* [10] Grab the next task, i.e. the owner of @lock */ +/* +* [10] Grab the next task, i.e. the owner of @lock +* +* Per holding lock->wait_lock and checking for !owner above, there +* must be an owner and it cannot go away. +*/ task =get_task_struct (rt_mutex_owner (lock));raw_spin_lock (&task->pi_lock);
@@ -921,8 +974,9 @@ static int __sched rt_mutex_adjust_prio_chain(struct task_struct *task,* and adjust the priority of the owner. */ rt_mutex_dequeue_pi (task, prerequeue_top_waiter); +waiter_clone_prio (waiter, task);rt_mutex_enqueue_pi (task, waiter); -rt_mutex_adjust_prio (task); +rt_mutex_adjust_prio (lock, task); }else if (prerequeue_top_waiter == waiter) {/*
@@ -937,8 +991,9 @@ static int __sched rt_mutex_adjust_prio_chain(struct task_struct *task,*/ rt_mutex_dequeue_pi (task, waiter); waiter =rt_mutex_top_waiter (lock); +waiter_clone_prio (waiter, task);rt_mutex_enqueue_pi (task, waiter); -rt_mutex_adjust_prio (task); +rt_mutex_adjust_prio (lock, task); }else {/* * Nothing changed. No need to do any priority
@@ -1154,6 +1209,7 @@ static int __sched task_blocks_on_rt_mutex(struct rt_mutex_base *lock, waiter->task = task; waiter->lock = lock;waiter_update_prio (waiter, task); +waiter_clone_prio (waiter, task);/* Get the top priority waiter on the lock */ if (rt_mutex_has_waiters (lock))
@@ -1187,7 +1243,7 @@ static int __sched task_blocks_on_rt_mutex(struct rt_mutex_base *lock,rt_mutex_dequeue_pi (owner, top_waiter);rt_mutex_enqueue_pi (owner, waiter); -rt_mutex_adjust_prio (owner); +rt_mutex_adjust_prio (lock, owner);if (owner->pi_blocked_on) chain_walk =1 ; }else if (rt_mutex_cond_detect_deadlock (waiter, chwalk)) {
@@ -1234,6 +1290,8 @@ static void __sched mark_wakeup_next_waiter(struct rt_wake_q_head *wqh, {struct rt_mutex_waiter *waiter; +lockdep_assert_held (&lock->wait_lock); +raw_spin_lock (¤t->pi_lock); waiter =rt_mutex_top_waiter (lock);
@@ -1246,7 +1304,7 @@ static void __sched mark_wakeup_next_waiter(struct rt_wake_q_head *wqh,* task unblocks. */ rt_mutex_dequeue_pi (current, waiter); -rt_mutex_adjust_prio (current); +rt_mutex_adjust_prio (lock, current);/* * As we are waking up the top waiter, and the waiter stays
@@ -1482,7 +1540,7 @@ static void __sched remove_waiter(struct rt_mutex_base *lock,if (rt_mutex_has_waiters (lock))rt_mutex_enqueue_pi (owner,rt_mutex_top_waiter (lock)); -rt_mutex_adjust_prio (owner); +rt_mutex_adjust_prio (lock, owner);/* Store the lock on which owner is blocked or NULL */ next_lock =task_blocked_on_lock (owner);
kernel/locking/rtmutex_api.c +1 -1
@@ -459,7 +459,7 @@ void __sched rt_mutex_adjust_pi(struct task_struct *task)raw_spin_lock_irqsave (&task->pi_lock, flags); waiter = task->pi_blocked_on; -if (!waiter ||rt_mutex_waiter_equal (waiter,task_to_waiter (task))) { +if (!waiter ||rt_waiter_node_equal (&waiter->tree,task_to_waiter_node (task))) {raw_spin_unlock_irqrestore (&task->pi_lock, flags);return ; }
kernel/locking/rtmutex_common.h +34 -13
92 lines not on this page · raw message
kernel/locking/ww_mutex.h +6 -6
@@ -96,25 +96,25 @@ __ww_waiter_first(struct rt_mutex *lock)struct rb_node *n =rb_first (&lock->rtmutex.waiters.rb_root);if (!n)return NULL ; - return rb_entry(n, struct rt_mutex_waiter, tree_entry); + return rb_entry(n, struct rt_mutex_waiter, tree.entry); }static inline struct rt_mutex_waiter *__ww_waiter_next (struct rt_mutex *lock,struct rt_mutex_waiter *w) { -struct rb_node *n =rb_next (&w->tree_entry); +struct rb_node *n =rb_next (&w->tree.entry);if (!n)return NULL ; - return rb_entry(n, struct rt_mutex_waiter, tree_entry); + return rb_entry(n, struct rt_mutex_waiter, tree.entry); }static inline struct rt_mutex_waiter *__ww_waiter_prev (struct rt_mutex *lock,struct rt_mutex_waiter *w) { -struct rb_node *n =rb_prev (&w->tree_entry); +struct rb_node *n =rb_prev (&w->tree.entry);if (!n)return NULL ; - return rb_entry(n, struct rt_mutex_waiter, tree_entry); + return rb_entry(n, struct rt_mutex_waiter, tree.entry); } static inline struct rt_mutex_waiter *
@@ -123,7 +123,7 @@ __ww_waiter_last(struct rt_mutex *lock)struct rb_node *n =rb_last (&lock->rtmutex.waiters.rb_root);if (!n)return NULL ; - return rb_entry(n, struct rt_mutex_waiter, tree_entry); + return rb_entry(n, struct rt_mutex_waiter, tree.entry); } static inline void
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 194/228 proc/vmcore: fix signedness bug in read_from_oldmem()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
commit 641db40f3afe7998011bfabc726dba3e698f8196 upstream.
The bug is the error handling:
if (tmp < nr_bytes) {"tmp" can hold negative error codes but because "nr_bytes" is type size_t the negative error codes are treated as very high positive values (success). Fix this by changing "nr_bytes" to type ssize_t. The "nr_bytes" variable is used to store values between 1 and PAGE_SIZE and they can fit in ssize_t without any issue.
--- fs/proc/vmcore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/proc/vmcore.c +1 -1
@@ -132,7 +132,7 @@ ssize_t read_from_oldmem(struct iov_iter u64 *ppos, bool encrypted) {unsigned long pfn, offset; -size_t nr_bytes; +ssize_t nr_bytes;ssize_t read =0 , tmp;int idx;
Greg Kroah-Hartman
maintainerPATCH 195/228 xen: speed up grant-table reclaim
In reply to Greg Kroah-HartmanFrom: Demi Marie Obenour <[email protected]>
commit c04e9894846c663f3278a414f34416e6e45bbe68 upstream.
When a grant entry is still in use by the remote domain, Linux must put it on a deferred list. Normally, this list is very short, because the PV network and block protocols expect the backend to unmap the grant first. However, Qubes OS's GUI protocol is subject to the constraints of the X Window System, and as such winds up with the frontend unmapping the window first. As a result, the list can grow very large, resulting in a massive memory leak and eventual VM freeze.
To partially solve this problem, make the number of entries that the VM will attempt to free at each iteration tunable. The default is still 10, but it can be overridden via a module parameter.
This is Cc: stable because (when combined with appropriate userspace changes) it fixes a severe performance and stability problem for Qubes OS users.
--- Documentation/ABI/testing/sysfs-module | 11 +++++++++ drivers/xen/grant-table.c | 40 +++++++++++++++++++++++---------- 2 files changed, 40 insertions(+), 11 deletions(-)
Documentation/ABI/testing/sysfs-module +11 -0
@@ -60,3 +60,14 @@ Description: Module taint flags: C staging driver module E unsigned module == ===================== + +What: /sys/module/grant_table/parameters/free_per_iteration +Date: July 2023 +KernelVersion: 6.5 but backported to all supported stable branches +Contact: Xen developer discussion <[email protected]> +Description: Read and write number of grant entries to attempt to free per iteration. + + Note: Future versions of Xen and Linux may provide a better + interface for controlling the rate of deferred grant reclaim + or may not need it at all. +Users: Qubes OS (https://www.qubes-os.org)
drivers/xen/grant-table.c +29 -11
@@ -498,14 +498,21 @@ static LIST_HEAD(deferred_list);static void gnttab_handle_deferred (struct timer_list *); static DEFINE_TIMER(deferred_timer, gnttab_handle_deferred); +static atomic64_t deferred_count; +static atomic64_t leaked_count; +static unsigned int free_per_iteration =10 ; +module_param (free_per_iteration, uint,0600 ); +static void gnttab_handle_deferred (struct timer_list *unused) { -unsigned int nr =10 ; +unsigned int nr =READ_ONCE (free_per_iteration); +const bool ignore_limit = nr ==0 ;struct deferred_entry *first =NULL ;unsigned long flags; +size_t freed =0 ;spin_lock_irqsave (&gnttab_list_lock, flags); -while (nr--) { +while ((ignore_limit || nr--) && !list_empty (&deferred_list)) {struct deferred_entry *entry =list_first_entry (&deferred_list, struct deferred_entry, list);
@@ -515,10 +522,14 @@ static void gnttab_handle_deferred(struclist_del (&entry->list);spin_unlock_irqrestore (&gnttab_list_lock, flags);if (_gnttab_end_foreign_access_ref (entry->ref)) { +uint64_t ret =atomic64_dec_return (&deferred_count); +put_free_entry (entry->ref); -pr_debug ("freeing g.e. %#x (pfn %#lx)\n" , - entry->ref,page_to_pfn (entry->page)); +pr_debug ("freeing g.e. %#x (pfn %#lx), %llu remaining\n" , + entry->ref,page_to_pfn (entry->page), + (unsigned long long )ret);put_page (entry->page); + freed++;kfree (entry); entry =NULL ; }else {
@@ -530,21 +541,22 @@ static void gnttab_handle_deferred(strucspin_lock_irqsave (&gnttab_list_lock, flags);if (entry)list_add_tail (&entry->list, &deferred_list); -else if (list_empty (&deferred_list)) -break ; } -if (!list_empty (&deferred_list) && !timer_pending (&deferred_timer)) { +if (list_empty (&deferred_list)) +WARN_ON (atomic64_read (&deferred_count)); +else if (!timer_pending (&deferred_timer)) { deferred_timer.expires = jiffies +HZ ;add_timer (&deferred_timer); }spin_unlock_irqrestore (&gnttab_list_lock, flags); +pr_debug ("Freed %zu references" , freed); }static void gnttab_add_deferred (grant_ref_t ref,struct page *page) {struct deferred_entry *entry;gfp_t gfp = (in_atomic () ||irqs_disabled ()) ?GFP_ATOMIC :GFP_KERNEL ; -const char *what =KERN_WARNING "leaking" ; +uint64_t leaked, deferred; entry =kmalloc (sizeof (*entry), gfp);if (!page) {
@@ -567,10 +579,16 @@ static void gnttab_add_deferred(grant_readd_timer (&deferred_timer); }spin_unlock_irqrestore (&gnttab_list_lock, flags); - what =KERN_DEBUG "deferring" ; + deferred =atomic64_inc_return (&deferred_count); + leaked =atomic64_read (&leaked_count); +pr_debug ("deferring g.e. %#x (pfn %#lx) (total deferred %llu, total leaked %llu)\n" , + ref, page ?page_to_pfn (page) :-1 , deferred, leaked); + }else { + deferred =atomic64_read (&deferred_count); + leaked =atomic64_inc_return (&leaked_count); +pr_warn ("leaking g.e. %#x (pfn %#lx) (total deferred %llu, total leaked %llu)\n" , + ref, page ?page_to_pfn (page) :-1 , deferred, leaked); } -printk ("%s g.e. %#x (pfn %#lx)\n" , - what, ref, page ?page_to_pfn (page) :-1 ); }int gnttab_try_end_foreign_access (grant_ref_t ref)
Greg Kroah-Hartman
maintainerPATCH 196/228 virtio-net: fix race between set queues and probe
In reply to Greg Kroah-HartmanFrom: Jason Wang <[email protected]>
commit 25266128fe16d5632d43ada34c847d7b8daba539 upstream.
A race were found where set_channels could be called after registering but before virtnet_set_queues() in virtnet_probe(). Fixing this by moving the virtnet_set_queues() before netdevice registering. While at it, use _virtnet_set_queues() to avoid holding rtnl as the device is not even registered at that time.
--- drivers/net/virtio_net.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/virtio_net.c +2 -2
@@ -3940,6 +3940,8 @@ static int virtnet_probe(struct virtio_dif (vi->has_rss || vi->has_rss_hash_report)virtnet_init_default_rss (vi); +_virtnet_set_queues (vi, vi->curr_queue_pairs); +/* serialize netdev register + virtio_device_ready() with ndo_open() */ rtnl_lock ();
@@ -3960,8 +3962,6 @@ static int virtnet_probe(struct virtio_d goto free_unregister_netdev; } -virtnet_set_queues (vi, vi->curr_queue_pairs); -/* Assume link up if device can't report link status, otherwise get link status from config. */ netif_carrier_off (dev);
Greg Kroah-Hartman
maintainerPATCH 197/228 net: dsa: qca8k: fix search_and_insert wrong handling of new rule
In reply to Greg Kroah-HartmanFrom: Christian Marangi <[email protected]>
commit 80248d4160894d7e40b04111bdbaa4ff93fc4bd7 upstream.
On inserting a mdb entry, fdb_search_and_insert is used to add a port to the qca8k target entry in the FDB db.
A FDB entry can't be modified so it needs to be removed and insert again with the new values.
To detect if an entry already exist, the SEARCH operation is used and we check the aging of the entry. If the entry is not 0, the entry exist and we proceed to delete it.
Current code have 2 main problem:
- The condition to check if the FDB entry exist is wrong and should be the opposite.
- When a FDB entry doesn't exist, aging was never actually set to the STATIC value resulting in allocating an invalid entry.
Fix both problem by adding aging support to the function, calling the function with STATIC as aging by default and finally by correct the condition to check if the entry actually exist.
--- drivers/net/dsa/qca/qca8k-common.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
drivers/net/dsa/qca/qca8k-common.c +6 -3
@@ -281,7 +281,7 @@ void qca8k_fdb_flush(struct qca8k_priv * }static int qca8k_fdb_search_and_insert (struct qca8k_priv *priv,u8 port_mask, -const u8 *mac,u16 vid) +const u8 *mac,u16 vid,u8 aging) {struct qca8k_fdb fdb = {0 };int ret;
@@ -298,10 +298,12 @@ static int qca8k_fdb_search_and_insert(s goto exit;/* Rule exist. Delete first */ -if (!fdb.aging) { +if (fdb.aging) { ret =qca8k_fdb_access (priv,QCA8K_FDB_PURGE ,-1 );if (ret) goto exit; + }else { + fdb.aging = aging; }/* Add port to fdb portmask */
@@ -847,7 +849,8 @@ int qca8k_port_mdb_add(struct dsa_switchconst u8 *addr = mdb->addr;u16 vid = mdb->vid; -return qca8k_fdb_search_and_insert (priv,BIT (port), addr, vid); +return qca8k_fdb_search_and_insert (priv,BIT (port), addr, vid, +QCA8K_ATU_STATUS_STATIC ); } int qca8k_port_mdb_del(struct dsa_switch *ds, int port,
Greg Kroah-Hartman
maintainerPATCH 198/228 net: dsa: qca8k: fix broken search_and_del
In reply to Greg Kroah-HartmanFrom: Christian Marangi <[email protected]>
commit ae70dcb9d9ecaf7d9836d3e1b5bef654d7ef5680 upstream.
On deleting an MDB entry for a port, fdb_search_and_del is used. An FDB entry can't be modified so it needs to be deleted and readded again with the new portmap (and the port deleted as requested)
We use the SEARCH operator to search the entry to edit by vid and mac address and then we check the aging if we actually found an entry.
Currently the code suffer from a bug where the searched fdb entry is never read again with the found values (if found) resulting in the code always returning -EINVAL as aging was always 0.
Fix this by correctly read the fdb entry after it was searched.
--- drivers/net/dsa/qca/qca8k-common.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/net/dsa/qca/qca8k-common.c +4 -0
@@ -330,6 +330,10 @@ static int qca8k_fdb_search_and_del(struif (ret <0 ) goto exit; + ret =qca8k_fdb_read (priv, &fdb); +if (ret <0 ) + goto exit; +/* Rule doesn't exist. Why delete? */ if (!fdb.aging) { ret = -EINVAL ;
Greg Kroah-Hartman
maintainerPATCH 199/228 net: dsa: qca8k: fix mdb add/del case with 0 VID
In reply to Greg Kroah-HartmanFrom: Christian Marangi <[email protected]>
commit dfd739f182b00b02bd7470ed94d112684cc04fa2 upstream.
The qca8k switch doesn't support using 0 as VID and require a default VID to be always set. MDB add/del function doesn't currently handle this and are currently setting the default VID.
Fix this by correctly handling this corner case and internally use the default VID for VID 0 case.
--- drivers/net/dsa/qca/qca8k-common.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/net/dsa/qca/qca8k-common.c +6 -0
@@ -853,6 +853,9 @@ int qca8k_port_mdb_add(struct dsa_switchconst u8 *addr = mdb->addr;u16 vid = mdb->vid; +if (!vid) + vid =QCA8K_PORT_VID_DEF ; +return qca8k_fdb_search_and_insert (priv,BIT (port), addr, vid,QCA8K_ATU_STATUS_STATIC ); }
@@ -865,6 +868,9 @@ int qca8k_port_mdb_del(struct dsa_switchconst u8 *addr = mdb->addr;u16 vid = mdb->vid; +if (!vid) + vid =QCA8K_PORT_VID_DEF ; +return qca8k_fdb_search_and_del (priv,BIT (port), addr, vid); }
Greg Kroah-Hartman
maintainerPATCH 200/228 selftests/rseq: Play nice with binaries statically linked against glibc 2.35+
In reply to Greg Kroah-HartmanFrom: Sean Christopherson <[email protected]>
commit 3bcbc20942db5d738221cca31a928efc09827069 upstream.
To allow running rseq and KVM's rseq selftests as statically linked binaries, initialize the various "trampoline" pointers to point directly at the expect glibc symbols, and skip the dlysm() lookups if the rseq size is non-zero, i.e. the binary is statically linked *and* the libc registered its own rseq.
Define weak versions of the symbols so as not to break linking against libc versions that don't support rseq in any capacity.
The KVM selftests in particular are often statically linked so that they can be run on targets with very limited runtime environments, i.e. test machines.
Message-Id: <[email protected]>
--- tools/testing/selftests/rseq/rseq.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-)
tools/testing/selftests/rseq/rseq.c +22 -6
@@ -32,9 +32,17 @@#include "../kselftest.h" #include "rseq.h" -static const ptrdiff_t *libc_rseq_offset_p; -static const unsigned int *libc_rseq_size_p; -static const unsigned int *libc_rseq_flags_p; +/* +* Define weak versions to play nice with binaries that are statically linked +* against a libc that doesn't support registering its own rseq. +*/ +__weak ptrdiff_t __rseq_offset; +__weak unsigned int __rseq_size; +__weak unsigned int __rseq_flags; + +static const ptrdiff_t *libc_rseq_offset_p = &__rseq_offset; +static const unsigned int *libc_rseq_size_p = &__rseq_size; +static const unsigned int *libc_rseq_flags_p = &__rseq_flags;/* Offset from the thread pointer to the rseq area. */ ptrdiff_t rseq_offset;
@@ -108,9 +116,17 @@ int rseq_unregister_current_thread(void)static __attribute__((constructor))void rseq_init (void ) { - libc_rseq_offset_p =dlsym (RTLD_NEXT ,"__rseq_offset" ); - libc_rseq_size_p =dlsym (RTLD_NEXT ,"__rseq_size" ); - libc_rseq_flags_p =dlsym (RTLD_NEXT ,"__rseq_flags" ); +/* +* If the libc's registered rseq size isn't already valid, it may be +* because the binary is dynamically linked and not necessarily due to +* libc not having registered a restartable sequence. Try to find the +* symbols if that's the case. +*/ +if (!*libc_rseq_size_p) { + libc_rseq_offset_p =dlsym (RTLD_NEXT ,"__rseq_offset" ); + libc_rseq_size_p =dlsym (RTLD_NEXT ,"__rseq_size" ); + libc_rseq_flags_p =dlsym (RTLD_NEXT ,"__rseq_flags" ); + }if (libc_rseq_size_p && libc_rseq_offset_p && libc_rseq_flags_p && *libc_rseq_size_p !=0 ) {/* rseq registration owned by glibc */
Greg Kroah-Hartman
maintainerPATCH 201/228 selftests: mptcp: join: only check for ip6tables if needed
In reply to Greg Kroah-HartmanFrom: Matthieu Baerts <[email protected]>
commit 016e7ba47f33064fbef8c4307a2485d2669dfd03 upstream.
If 'iptables-legacy' is available, 'ip6tables-legacy' command will be used instead of 'ip6tables'. So no need to look if 'ip6tables' is available in this case.
--- tools/testing/selftests/net/mptcp/mptcp_join.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
tools/testing/selftests/net/mptcp/mptcp_join.sh +1 -3
@@ -151,9 +151,7 @@ check_tools() elif ! iptables -V &> /dev/null; then echo "SKIP: Could not run all tests without iptables tool" exit $ksft_skip - fi - - if ! ip6tables -V &> /dev/null; then + elif ! ip6tables -V &> /dev/null; then echo "SKIP: Could not run all tests without ip6tables tool" exit $ksft_skip fi
Greg Kroah-Hartman
maintainerPATCH 202/228 soundwire: fix enumeration completion
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit c40d6b3249b11d60e09d81530588f56233d9aa44 upstream.
The soundwire subsystem uses two completion structures that allow drivers to wait for soundwire device to become enumerated on the bus and initialised by their drivers, respectively.
The code implementing the signalling is currently broken as it does not signal all current and future waiters and also uses the wrong reinitialisation function, which can potentially lead to memory corruption if there are still waiters on the queue.
Not signalling future waiters specifically breaks sound card probe deferrals as codec drivers can not tell that the soundwire device is already attached when being reprobed. Some codec runtime PM implementations suffer from similar problems as waiting for enumeration during resume can also timeout despite the device already having been enumerated.
--- drivers/soundwire/bus.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/soundwire/bus.c +4 -4
@@ -884,8 +884,8 @@ static void sdw_modify_slave_status(stru"initializing enumeration and init completion for Slave %d\n" , slave->dev_num); -init_completion (&slave->enumeration_complete); -init_completion (&slave->initialization_complete); +reinit_completion (&slave->enumeration_complete); +reinit_completion (&slave->initialization_complete); }else if ((status ==SDW_SLAVE_ATTACHED ) && (slave->status ==SDW_SLAVE_UNATTACHED )) {
@@ -893,7 +893,7 @@ static void sdw_modify_slave_status(stru"signaling enumeration completion for Slave %d\n" , slave->dev_num); -complete (&slave->enumeration_complete); +complete_all (&slave->enumeration_complete); } slave->status = status;mutex_unlock (&bus->bus_lock);
@@ -1916,7 +1916,7 @@ int sdw_handle_slave_status(struct sdw_b"signaling initialization completion for Slave %d\n" , slave->dev_num); -complete (&slave->initialization_complete); +complete_all (&slave->initialization_complete);/* * If the manager became pm_runtime active, the peripherals will be
Greg Kroah-Hartman
maintainerPATCH 203/228 Revert "um: Use swap() to make code cleaner"
In reply to Greg Kroah-HartmanFrom: Andy Shevchenko <[email protected]>
commit dddfa05eb58076ad60f9a66e7155a5b3502b2dd5 upstream.
This reverts commit 9b0da3f22307af693be80f5d3a89dc4c7f360a85.
The sigio.c is clearly user space code which is handled by arch/um/scripts/Makefile.rules (see USER_OBJS rule).
The above mentioned commit simply broke this agreement, we may not use Linux kernel internal headers in them without thorough thinking.
Hence, revert the wrong commit.
--- arch/um/os-Linux/sigio.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
arch/um/os-Linux/sigio.c +4 -3
@@ -3,7 +3,6 @@* Copyright (C) 2002 - 2008 Jeff Dike (jdike@{addtoit,linux.intel}.com) */ -#include <linux/minmax.h> #include <unistd.h> #include <errno.h> #include <fcntl.h>
@@ -51,7 +50,7 @@ static struct pollfds all_sigio_fds;static int write_sigio_thread (void *unused) { -struct pollfds *fds; +struct pollfds *fds, tmp;struct pollfd *p;int i, n, respond_fd;char c;
@@ -78,7 +77,9 @@ static int write_sigio_thread(void *unus"write_sigio_thread : " "read on socket failed, " "err = %d\n", errno); -swap (current_poll, next_poll); + tmp = current_poll; + current_poll = next_poll; + next_poll = tmp; respond_fd = sigio_private[1 ]; }else {
Greg Kroah-Hartman
maintainerPATCH 204/228 LoongArch: BPF: Fix check condition to call lu32id in move_imm()
In reply to Greg Kroah-HartmanFrom: Tiezhu Yang <[email protected]>
commit 4eece7e6de94d833c8aeed2f438faf487cbf94ff upstream.
As the code comment says, the initial aim is to reduce one instruction in some corner cases, if bit[51:31] is all 0 or all 1, no need to call lu32id. That is to say, it should call lu32id only if bit[51:31] is not all 0 and not all 1. The current code always call lu32id, the result is right but the logic is unexpected and wrong, fix it.
--- arch/loongarch/net/bpf_jit.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/loongarch/net/bpf_jit.h +1 -1
@@ -148,7 +148,7 @@ static inline void move_imm(struct jit_c* no need to call lu32id to do a new filled operation. */ imm_51_31 = (imm >>31 ) &0x1fffff ; -if (imm_51_31 !=0 || imm_51_31 !=0x1fffff ) { +if (imm_51_31 !=0 && imm_51_31 !=0x1fffff ) {/* lu32id rd, imm_51_32 */ imm_51_32 = (imm >>32 ) &0xfffff ;emit_insn (ctx, lu32id, rd, imm_51_32);
Greg Kroah-Hartman
maintainerPATCH 205/228 LoongArch: BPF: Enable bpf_probe_read{, str}() on LoongArch
In reply to Greg Kroah-HartmanFrom: Chenguang Zhao <[email protected]>
commit de0e30bee86d0f99c696a1fea34474e556a946ec upstream.
Currently nettrace does not work on LoongArch due to missing bpf_probe_read{,str}() support, with the error message:
ERROR: failed to load kprobe-based eBPF
ERROR: failed to load kprobe-based bpf
According to commit 0ebeea8ca8a4d1d ("bpf: Restrict bpf_probe_read{, str}() only to archs where they work"), we only need to select CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE to add said support, because LoongArch does have non-overlapping address ranges for kernel and userspace.
--- arch/loongarch/Kconfig | 1 + 1 file changed, 1 insertion(+)
arch/loongarch/Kconfig +1 -0
@@ -10,6 +10,7 @@ config LOONGARCH select ARCH_ENABLE_MEMORY_HOTPLUG select ARCH_ENABLE_MEMORY_HOTREMOVE select ARCH_HAS_ACPI_TABLE_UPGRADE if ACPI + select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE select ARCH_HAS_PTE_SPECIAL select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST select ARCH_INLINE_READ_LOCK if !PREEMPTION
Greg Kroah-Hartman
maintainerPATCH 206/228 s390/dasd: fix hanging device after quiesce/resume
In reply to Greg Kroah-HartmanFrom: Stefan Haberland <[email protected]>
commit 05f1d8ed03f547054efbc4d29bb7991c958ede95 upstream.
Quiesce and resume are functions that tell the DASD driver to stop/resume issuing I/Os to a specific DASD.
On resume dasd_schedule_block_bh() is called to kick handling of IO requests again. This does unfortunately not cover internal requests which are used for path verification for example.
This could lead to a hanging device when a path event or anything else that triggers internal requests occurs on a quiesced device.
Fix by also calling dasd_schedule_device_bh() which triggers handling of internal requests on resume.
--- drivers/s390/block/dasd_ioctl.c | 1 + 1 file changed, 1 insertion(+)
drivers/s390/block/dasd_ioctl.c +1 -0
@@ -131,6 +131,7 @@ static int dasd_ioctl_resume(struct dasdspin_unlock_irqrestore (get_ccwdev_lock (base->cdev), flags);dasd_schedule_block_bh (block); +dasd_schedule_device_bh (base);return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 207/228 s390/dasd: print copy pair message only for the correct error
In reply to Greg Kroah-HartmanFrom: Stefan Haberland <[email protected]>
commit 856d8e3c633b183df23549ce760ae84478a7098d upstream.
The DASD driver has certain types of requests that might be rejected by the storage server or z/VM because they are not supported. Since the missing support of the command is not a real issue there is no user visible kernel error message for this.
For copy pair setups there is a specific error that IO is not allowed on secondary devices. This error case is explicitly handled and an error message is printed.
The code checking for the error did use a bitwise 'and' that is used to check for specific bits. But in this case the whole sense byte has to match.
This leads to the problem that the copy pair related error message is erroneously printed for other error cases that are usually not reported. This might heavily confuse users and lead to follow on actions that might disrupt application processing.
Fix by checking the sense byte for the exact value and not single bits.
--- drivers/s390/block/dasd_3990_erp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/s390/block/dasd_3990_erp.c +1 -1
@@ -1050,7 +1050,7 @@ dasd_3990_erp_com_rej(struct dasd_ccw_req * erp, char *sense)dev_err (&device->cdev->dev,"An I/O request was rejected" " because writing is inhibited\n" ); erp =dasd_3990_erp_cleanup (erp,DASD_CQR_FAILED ); - }else if (sense[7 ] &SNS7_INVALID_ON_SEC ) { + }else if (sense[7 ] ==SNS7_INVALID_ON_SEC ) {dev_err (&device->cdev->dev,"An I/O request was rejected on a copy pair secondary device\n" );/* suppress dump of sense data for this error */ set_bit (DASD_CQR_SUPPRESS_CR , &erp->refers->flags);
Signature · 1 line
2.41.0
Greg Kroah-Hartman
maintainerPATCH 208/228 ASoC: wm8904: Fill the cache for WM8904_ADC_TEST_0 register
In reply to Greg Kroah-HartmanFrom: Mark Brown <[email protected]>
commit f061e2be8689057cb4ec0dbffa9f03e1a23cdcb2 upstream.
The WM8904_ADC_TEST_0 register is modified as part of updating the OSR controls but does not have a cache default, leading to errors when we try to modify these controls in cache only mode with no prior read:
wm8904 3-001a: ASoC: error at snd_soc_component_update_bits on wm8904.3-001a for register: [0x000000c6] -16
Add a read of the register to probe() to fill the cache and avoid both the error messages and the misconfiguration of the chip which will result.
--- sound/soc/codecs/wm8904.c | 3 +++ 1 file changed, 3 insertions(+)
sound/soc/codecs/wm8904.c +3 -0
@@ -2308,6 +2308,9 @@ static int wm8904_i2c_probe(struct i2c_cregmap_update_bits (wm8904->regmap,WM8904_BIAS_CONTROL_0 ,WM8904_POBCTRL ,0 ); +/* Fill the cache for the ADC test register */ +regmap_read (wm8904->regmap,WM8904_ADC_TEST_0 , &val); +/* Can leave the device powered off until we need it */ regcache_cache_only (wm8904->regmap, true);regulator_bulk_disable (ARRAY_SIZE (wm8904->supplies), wm8904->supplies);
Greg Kroah-Hartman
maintainerPATCH 209/228 arm64/sme: Set new vector length before reallocating
In reply to Greg Kroah-HartmanFrom: Mark Brown <[email protected]>
commit 05d881b85b48c7ac6a7c92ce00aa916c4a84d052 upstream.
As part of fixing the allocation of the buffer for SVE state when changing SME vector length we introduced an immediate reallocation of the SVE state, this is also done when changing the SVE vector length for consistency. Unfortunately this reallocation is done prior to writing the new vector length to the task struct, meaning the allocation is done with the old vector length and can lead to memory corruption due to an undersized buffer being used.
Move the update of the vector length before the allocation to ensure that the new vector length is taken into account.
For some reason this isn't triggering any problems when running tests on the arm64 fixes branch (even after repeated tries) but is triggering issues very often after merge into mainline.
--- arch/arm64/kernel/fpsimd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm64/kernel/fpsimd.c +2 -2
@@ -871,6 +871,8 @@ int vec_set_vector_length(struct task_stif (task == current)put_cpu_fpsimd_context (); +task_set_vl (task, type, vl); +/* * Free the changed states if they are not in use, SME will be * reallocated to the correct size on next use and we just
@@ -885,8 +887,6 @@ int vec_set_vector_length(struct task_stif (free_sme)sme_free (task); -task_set_vl (task, type, vl); - out:update_tsk_thread_flag (task,vec_vl_inherit_flag (type), flags &PR_SVE_VL_INHERIT );
Greg Kroah-Hartman
maintainerPATCH 210/228 PM: sleep: wakeirq: fix wake irq arming
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 8527beb12087238d4387607597b4020bc393c4b4 upstream.
The decision whether to enable a wake irq during suspend can not be done based on the runtime PM state directly as a driver may use wake irqs without implementing runtime PM. Such drivers specifically leave the state set to the default 'suspended' and the wake irq is thus never enabled at suspend.
Add a new wake irq flag to track whether a dedicated wake irq has been enabled at runtime suspend and therefore must not be enabled at system suspend.
Note that pm_runtime_enabled() can not be used as runtime PM is always disabled during late suspend.
--- drivers/base/power/power.h | 1 + drivers/base/power/wakeirq.c | 12 ++++++++---- 2 files changed, 9 insertions(+), 4 deletions(-)
drivers/base/power/power.h +1 -0
@@ -29,6 +29,7 @@ extern u64 pm_runtime_active_time(struct#define WAKE_IRQ_DEDICATED_MASK (WAKE_IRQ_DEDICATED_ALLOCATED | \ WAKE_IRQ_DEDICATED_MANAGED | \ WAKE_IRQ_DEDICATED_REVERSE) +#define WAKE_IRQ_DEDICATED_ENABLED BIT(3)struct wake_irq {struct device *dev;
drivers/base/power/wakeirq.c +8 -4
@@ -314,8 +314,10 @@ void dev_pm_enable_wake_irq_check(structreturn ; enable: -if (!can_change_status || !(wirq->status &WAKE_IRQ_DEDICATED_REVERSE )) +if (!can_change_status || !(wirq->status &WAKE_IRQ_DEDICATED_REVERSE )) {enable_irq (wirq->irq); + wirq->status |=WAKE_IRQ_DEDICATED_ENABLED ; + } }/**
@@ -336,8 +338,10 @@ void dev_pm_disable_wake_irq_check(strucif (cond_disable && (wirq->status &WAKE_IRQ_DEDICATED_REVERSE ))return ; -if (wirq->status &WAKE_IRQ_DEDICATED_MANAGED ) +if (wirq->status &WAKE_IRQ_DEDICATED_MANAGED ) { + wirq->status &= ~WAKE_IRQ_DEDICATED_ENABLED ;disable_irq_nosync (wirq->irq); + } }/**
@@ -376,7 +380,7 @@ void dev_pm_arm_wake_irq(struct wake_irqif (device_may_wakeup (wirq->dev)) {if (wirq->status &WAKE_IRQ_DEDICATED_ALLOCATED && - !pm_runtime_status_suspended (wirq->dev)) + !(wirq->status &WAKE_IRQ_DEDICATED_ENABLED ))enable_irq (wirq->irq);enable_irq_wake (wirq->irq);
@@ -399,7 +403,7 @@ void dev_pm_disarm_wake_irq(struct wake_disable_irq_wake (wirq->irq);if (wirq->status &WAKE_IRQ_DEDICATED_ALLOCATED && - !pm_runtime_status_suspended (wirq->dev)) + !(wirq->status &WAKE_IRQ_DEDICATED_ENABLED ))disable_irq_nosync (wirq->irq); } }
Greg Kroah-Hartman
maintainerPATCH 211/228 ceph: never send metrics if disable_send_metrics is set
In reply to Greg Kroah-HartmanFrom: Xiubo Li <[email protected]>
commit 50164507f6b7b7ed85d8c3ac0266849fbd908db7 upstream.
Even the 'disable_send_metrics' is true so when the session is being opened it will always trigger to send the metric for the first time.
--- fs/ceph/metric.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/ceph/metric.c +1 -1
@@ -208,7 +208,7 @@ static void metric_delayed_work(struct wstruct ceph_mds_client *mdsc = container_of(m, struct ceph_mds_client, metric); -if (mdsc->stopping) +if (mdsc->stopping || disable_send_metrics)return ;if (!m->session || !check_session_state (m->session)) {
Greg Kroah-Hartman
maintainerPATCH 212/228 drm/i915/dpt: Use shmem for dpt objects
In reply to Greg Kroah-HartmanFrom: Radhakrishna Sripada <[email protected]>
commit 3844ed5e78823eebb5f0f1edefc403310693d402 upstream.
Dpt objects that are created from internal get evicted when there is memory pressure and do not get restored when pinned during scanout. The pinned page table entries look corrupted and programming the display engine with the incorrect pte's result in DE throwing pipe faults.
Create DPT objects from shmem and mark the object as dirty when pinning so that the object is restored when shrinker evicts an unpinned buffer object.
v2: Unconditionally mark the dpt objects dirty during pinning(Chris).
--- drivers/gpu/drm/i915/display/intel_dpt.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/gpu/drm/i915/display/intel_dpt.c +3 -1
@@ -163,6 +163,8 @@ struct i915_vma *intel_dpt_pin(struct i9i915_vma_get (vma); } + dpt->obj->mm.dirty = true; +atomic_dec (&i915->gpu_error.pending_fb_pin);intel_runtime_pm_put (&i915->runtime_pm, wakeref);
@@ -258,7 +260,7 @@ intel_dpt_create(struct intel_framebuffe dpt_obj =i915_gem_object_create_stolen (i915, size);if (IS_ERR (dpt_obj) && !HAS_LMEM (i915)) {drm_dbg_kms (&i915->drm,"Allocating dpt from smem\n" ); - dpt_obj =i915_gem_object_create_internal (i915, size); + dpt_obj =i915_gem_object_create_shmem (i915, size); }if (IS_ERR (dpt_obj))return ERR_CAST (dpt_obj);
Greg Kroah-Hartman
maintainerPATCH 213/228 dm cache policy smq: ensure IO doesnt prevent cleaner policy progress
In reply to Greg Kroah-HartmanFrom: Joe Thornber <[email protected]>
commit 1e4ab7b4c881cf26c1c72b3f56519e03475486fb upstream.
When using the cleaner policy to decommission the cache, there is never any writeback started from the cache as it is constantly delayed due to normal I/O keeping the device busy. Meaning @idle=false was always being passed to clean_target_met()
Fix this by adding a specific 'cleaner' flag that is set when the cleaner policy is configured. This flag serves to always allow the cleaner's writeback work to be queued until the cache is decommissioned (even if the cache isn't idle).
--- drivers/md/dm-cache-policy-smq.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-)
drivers/md/dm-cache-policy-smq.c +18 -10
@@ -855,7 +855,13 @@ struct smq_policy {struct background_tracker *bg_work; -bool migrations_allowed; + bool migrations_allowed:1; + +/* +* If this is set the policy will try and clean the whole cache +* even if the device is not idle. +*/ + bool cleaner:1; };/*----------------------------------------------------------------*/
@@ -1136,7 +1142,7 @@ static bool clean_target_met(struct smq_* Cache entries may not be populated. So we cannot rely on the * size of the clean queue. */ -if (idle) { +if (idle || mq->cleaner) {/* * We'd like to clean everything. */
@@ -1719,11 +1725,9 @@ static void calc_hotspot_params(sector_t *hotspot_block_size /=2u ; } -static struct dm_cache_policy *__smq_create (dm_cblock_t cache_size, -sector_t origin_size, -sector_t cache_block_size, -bool mimic_mq, -bool migrations_allowed) +static struct dm_cache_policy * +__smq_create (dm_cblock_t cache_size,sector_t origin_size,sector_t cache_block_size, +bool mimic_mq,bool migrations_allowed,bool cleaner) {unsigned int i;unsigned int nr_sentinels_per_queue =2u *NR_CACHE_LEVELS ;
@@ -1810,6 +1814,7 @@ static struct dm_cache_policy *__smq_cre goto bad_btracker; mq->migrations_allowed = migrations_allowed; + mq->cleaner = cleaner;return &mq->policy;
@@ -1833,21 +1838,24 @@ static struct dm_cache_policy *smq_creatsector_t origin_size, sector_t cache_block_size) { - return __smq_create(cache_size, origin_size, cache_block_size, false, true); + return __smq_create(cache_size, origin_size, cache_block_size, +false ,true ,false ); }static struct dm_cache_policy *mq_create (dm_cblock_t cache_size,sector_t origin_size,sector_t cache_block_size) { -return __smq_create (cache_size, origin_size, cache_block_size, true, true); +return __smq_create (cache_size, origin_size, cache_block_size, + true, true, false); }static struct dm_cache_policy *cleaner_create (dm_cblock_t cache_size,sector_t origin_size,sector_t cache_block_size) { -return __smq_create (cache_size, origin_size, cache_block_size, false, false); +return __smq_create (cache_size, origin_size, cache_block_size, + false, false, true); }/*----------------------------------------------------------------*/
Greg Kroah-Hartman
maintainerPATCH 214/228 rbd: make get_lock_owner_info() return a single locker or NULL
In reply to Greg Kroah-HartmanFrom: Ilya Dryomov <[email protected]>
commit f38cb9d9c2045dad16eead4a2e1aedfddd94603b upstream.
Make the "num_lockers can be only 0 or 1" assumption explicit and simplify the API by getting rid of output parameters in preparation for calling get_lock_owner_info() twice before blocklisting.
--- drivers/block/rbd.c | 84 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 51 insertions(+), 33 deletions(-)
drivers/block/rbd.c +51 -33
@@ -3850,10 +3850,17 @@ static void wake_lock_waiters(struct rbdlist_splice_tail_init (&rbd_dev->acquiring_list, &rbd_dev->running_list); } -static int get_lock_owner_info (struct rbd_device *rbd_dev, -struct ceph_locker **lockers,u32 *num_lockers) +static void free_locker (struct ceph_locker *locker) +{ +if (locker) +ceph_free_lockers (locker,1 ); +} + +static struct ceph_locker *get_lock_owner_info (struct rbd_device *rbd_dev) {struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; +struct ceph_locker *lockers; +u32 num_lockers;u8 lock_type;char *lock_tag;int ret;
@@ -3862,39 +3869,45 @@ static int get_lock_owner_info(struct rb ret =ceph_cls_lock_info (osdc, &rbd_dev->header_oid, &rbd_dev->header_oloc,RBD_LOCK_NAME , - &lock_type, &lock_tag, lockers, num_lockers); -if (ret) -return ret; + &lock_type, &lock_tag, &lockers, &num_lockers); +if (ret) { +rbd_warn (rbd_dev,"failed to retrieve lockers: %d" , ret); +return ERR_PTR (ret); + } -if (*num_lockers ==0 ) { +if (num_lockers ==0 ) {dout ("%s rbd_dev %p no lockers detected\n" , __func__, rbd_dev); + lockers =NULL ; goto out; }if (strcmp (lock_tag,RBD_LOCK_TAG )) {rbd_warn (rbd_dev,"locked by external mechanism, tag %s" , lock_tag); - ret = -EBUSY ; - goto out; + goto err_busy; }if (lock_type ==CEPH_CLS_LOCK_SHARED ) {rbd_warn (rbd_dev,"shared lock type detected" ); - ret = -EBUSY ; - goto out; + goto err_busy; } -if (strncmp ((*lockers)[0 ].id.cookie,RBD_LOCK_COOKIE_PREFIX , +WARN_ON (num_lockers !=1 ); +if (strncmp (lockers[0 ].id.cookie,RBD_LOCK_COOKIE_PREFIX ,strlen (RBD_LOCK_COOKIE_PREFIX ))) {rbd_warn (rbd_dev,"locked by external mechanism, cookie %s" , - (*lockers)[0 ].id.cookie); - ret = -EBUSY ; - goto out; + lockers[0 ].id.cookie); + goto err_busy; } out:kfree (lock_tag); -return ret; +return lockers; + +err_busy: +kfree (lock_tag); +ceph_free_lockers (lockers, num_lockers); +return ERR_PTR (-EBUSY ); } static int find_watcher(struct rbd_device *rbd_dev,
@@ -3948,51 +3961,56 @@ out:static int rbd_try_lock (struct rbd_device *rbd_dev) {struct ceph_client *client = rbd_dev->rbd_client->client; -struct ceph_locker *lockers; -u32 num_lockers; +struct ceph_locker *locker;int ret;for (;;) { + locker =NULL ; + ret =rbd_lock (rbd_dev);if (ret != -EBUSY ) -return ret; + goto out;/* determine if the current lock holder is still alive */ - ret =get_lock_owner_info (rbd_dev, &lockers, &num_lockers); -if (ret) -return ret; - -if (num_lockers ==0 ) + locker =get_lock_owner_info (rbd_dev); +if (IS_ERR (locker)) { + ret =PTR_ERR (locker); + locker =NULL ; + goto out; + } +if (!locker) goto again; - ret =find_watcher (rbd_dev, lockers); + ret =find_watcher (rbd_dev, locker);if (ret) goto out;/* request lock or error */ rbd_warn (rbd_dev,"breaking header lock owned by %s%llu" , -ENTITY_NAME (lockers[0 ].id.name)); +ENTITY_NAME (locker->id.name)); ret =ceph_monc_blocklist_add (&client->monc, - &lockers[0 ].info.addr); + &locker->info.addr);if (ret) { -rbd_warn (rbd_dev,"blocklist of %s%llu failed: %d" , -ENTITY_NAME (lockers[0 ].id.name), ret); +rbd_warn (rbd_dev,"failed to blocklist %s%llu: %d" , +ENTITY_NAME (locker->id.name), ret); goto out; } ret =ceph_cls_break_lock (&client->osdc, &rbd_dev->header_oid, &rbd_dev->header_oloc,RBD_LOCK_NAME , - lockers[0 ].id.cookie, - &lockers[0 ].id.name); -if (ret && ret != -ENOENT ) + locker->id.cookie, &locker->id.name); +if (ret && ret != -ENOENT ) { +rbd_warn (rbd_dev,"failed to break header lock: %d" , + ret); goto out; + } again: -ceph_free_lockers (lockers, num_lockers); +free_locker (locker); } out: -ceph_free_lockers (lockers, num_lockers); +free_locker (locker);return ret; }
Greg Kroah-Hartman
maintainerPATCH 215/228 rbd: harden get_lock_owner_info() a bit
In reply to Greg Kroah-HartmanFrom: Ilya Dryomov <[email protected]>
commit 8ff2c64c9765446c3cef804fb99da04916603e27 upstream.
- we want the exclusive lock type, so test for it directly
- use sscanf() to actually parse the lock cookie and avoid admitting invalid handles
- bail if locker has a blank address
--- drivers/block/rbd.c | 21 +++++++++++++++------ net/ceph/messenger.c | 1 + 2 files changed, 16 insertions(+), 6 deletions(-)
drivers/block/rbd.c +15 -6
@@ -3863,10 +3863,9 @@ static struct ceph_locker *get_lock_owneu32 num_lockers;u8 lock_type;char *lock_tag; +u64 handle;int ret; -dout ("%s rbd_dev %p\n" , __func__, rbd_dev); - ret =ceph_cls_lock_info (osdc, &rbd_dev->header_oid, &rbd_dev->header_oloc,RBD_LOCK_NAME , &lock_type, &lock_tag, &lockers, &num_lockers);
@@ -3887,18 +3886,28 @@ static struct ceph_locker *get_lock_owne goto err_busy; } -if (lock_type ==CEPH_CLS_LOCK_SHARED ) { -rbd_warn (rbd_dev,"shared lock type detected" ); +if (lock_type !=CEPH_CLS_LOCK_EXCLUSIVE ) { +rbd_warn (rbd_dev,"incompatible lock type detected" ); goto err_busy; }WARN_ON (num_lockers !=1 ); -if (strncmp (lockers[0 ].id.cookie,RBD_LOCK_COOKIE_PREFIX , -strlen (RBD_LOCK_COOKIE_PREFIX ))) { + ret =sscanf (lockers[0 ].id.cookie,RBD_LOCK_COOKIE_PREFIX " %llu" , + &handle); +if (ret !=1 ) {rbd_warn (rbd_dev,"locked by external mechanism, cookie %s" , lockers[0 ].id.cookie); goto err_busy; } +if (ceph_addr_is_blank (&lockers[0 ].info.addr)) { +rbd_warn (rbd_dev,"locker has a blank address" ); + goto err_busy; + } + +dout ("%s rbd_dev %p got locker %s%llu@%pISpc/%u handle %llu\n" , + __func__, rbd_dev,ENTITY_NAME (lockers[0 ].id.name), + &lockers[0 ].info.addr.in_addr, +le32_to_cpu (lockers[0 ].info.addr.nonce), handle); out:kfree (lock_tag);
net/ceph/messenger.c +1 -0
@@ -1118,6 +1118,7 @@ bool ceph_addr_is_blank(const struct cepreturn true; } } +EXPORT_SYMBOL (ceph_addr_is_blank);int ceph_addr_port (const struct ceph_entity_addr *addr) {
Greg Kroah-Hartman
maintainerPATCH 216/228 rbd: retrieve and check lock owner twice before blocklisting
In reply to Greg Kroah-HartmanFrom: Ilya Dryomov <[email protected]>
commit 588159009d5b7a09c3e5904cffddbe4a4e170301 upstream.
An attempt to acquire exclusive lock can race with the current lock owner closing the image:
1. lock is held by client123, rbd_lock() returns -EBUSY
2. get_lock_owner_info() returns client123 instance details
3. client123 closes the image, lock is released
4. find_watcher() returns 0 as there is no matching watcher anymore
5. client123 instance gets erroneously blocklisted
Particularly impacted is mirror snapshot scheduler in snapshot-based mirroring since it happens to open and close images a lot (images are opened only for as long as it takes to take the next mirror snapshot, the same client instance is used for all images).
To reduce the potential for erroneous blocklisting, retrieve the lock owner again after find_watcher() returns 0. If it's still there, make sure it matches the previously detected lock owner.
--- drivers/block/rbd.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-)
drivers/block/rbd.c +23 -2
@@ -3850,6 +3850,15 @@ static void wake_lock_waiters(struct rbdlist_splice_tail_init (&rbd_dev->acquiring_list, &rbd_dev->running_list); } +static bool locker_equal (const struct ceph_locker *lhs, +const struct ceph_locker *rhs) +{ +return lhs->id.name.type == rhs->id.name.type && + lhs->id.name.num == rhs->id.name.num && + !strcmp (lhs->id.cookie, rhs->id.cookie) && +ceph_addr_equal_no_type (&lhs->info.addr, &rhs->info.addr); +} +static void free_locker (struct ceph_locker *locker) {if (locker)
@@ -3970,11 +3979,11 @@ out:static int rbd_try_lock (struct rbd_device *rbd_dev) {struct ceph_client *client = rbd_dev->rbd_client->client; -struct ceph_locker *locker; +struct ceph_locker *locker, *refreshed_locker;int ret;for (;;) { - locker =NULL ; + locker = refreshed_locker =NULL ; ret =rbd_lock (rbd_dev);if (ret != -EBUSY )
@@ -3994,6 +4003,16 @@ static int rbd_try_lock(struct rbd_devicif (ret) goto out;/* request lock or error */ + refreshed_locker =get_lock_owner_info (rbd_dev); +if (IS_ERR (refreshed_locker)) { + ret =PTR_ERR (refreshed_locker); + refreshed_locker =NULL ; + goto out; + } +if (!refreshed_locker || + !locker_equal (locker, refreshed_locker)) + goto again; +rbd_warn (rbd_dev,"breaking header lock owned by %s%llu" ,ENTITY_NAME (locker->id.name));
@@ -4015,10 +4034,12 @@ static int rbd_try_lock(struct rbd_devic } again: +free_locker (refreshed_locker);free_locker (locker); } out: +free_locker (refreshed_locker);free_locker (locker);return ret; }
Greg Kroah-Hartman
maintainerPATCH 217/228 drm/amd/display: set per pipe dppclk to 0 when dpp is off
In reply to Greg Kroah-HartmanFrom: Dmytro Laktyushkin <[email protected]>
commit 6609141c49df1b86fbad26a8643d4b4044f28b11 upstream.
The 'commit 52e4fdf09ebc ("drm/amd/display: use low clocks for no plane configs")' introduced a change that set low clock values for DCN31 and DCN32. As a result of these changes, DC started to spam the log with the following warning:
------------[ cut here ]------------ WARNING: CPU: 8 PID: 1486 at drivers/gpu/drm/amd/amdgpu/../display/dc/dcn20/dcn20_dccg.c:58 dccg2_update_dpp_dto+0x3f/0xf0 [amdgpu] [..] CPU: 8 PID: 1486 Comm: kms_atomic Tainted: G W 5.18.0+ #1 RIP: 0010:dccg2_update_dpp_dto+0x3f/0xf0 [amdgpu] RSP: 0018:ffffbbd8025334d0 EFLAGS: 00010206 RAX: 00000000000001ee RBX: ffffa02c87dd3de0 RCX: 00000000000a7f80 RDX: 000000000007dec3 RSI: 0000000000000000 RDI: ffffa02c87dd3de0 RBP: ffffbbd8025334e8 R08: 0000000000000001 R09: 0000000000000005 R10: 00000000000331a0 R11: ffffffffc0b03d80 R12: ffffa02ca576d000 R13: ffffa02cd02c0000 R14: 00000000001453bc R15: ffffa02cdc280000 [..] dcn20_update_clocks_update_dpp_dto+0x4e/0xa0 [amdgpu] dcn32_update_clocks+0x5d9/0x650 [amdgpu] dcn20_prepare_bandwidth+0x49/0x100 [amdgpu] dcn30_prepare_bandwidth+0x63/0x80 [amdgpu] dc_commit_state_no_check+0x39d/0x13e0 [amdgpu] dc_commit_streams+0x1f9/0x3b0 [amdgpu] dc_commit_state+0x37/0x120 [amdgpu] amdgpu_dm_atomic_commit_tail+0x5e5/0x2520 [amdgpu] ? _raw_spin_unlock_irqrestore+0x1f/0x40 ? down_trylock+0x2c/0x40 ? vprintk_emit+0x186/0x2c0 ? vprintk_default+0x1d/0x20 ? vprintk+0x4e/0x60
We can easily trigger this issue by using a 4k@120 or a 2k@165 and running some of the kms_atomic tests. This warning is triggered because the per-pipe clock update is not happening; this commit fixes this issue by ensuring that DPPCLK is updated when calculating the watermark and dlg is invoked.
--- drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.c | 3 +++ drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c | 5 ++++- 2 files changed, 7 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.c +3 -0
@@ -559,6 +559,9 @@ void dcn31_calculate_wm_and_dlg_fp( context->bw_ctx.bw.dcn.clk.dramclk_khz =0 ; context->bw_ctx.bw.dcn.clk.fclk_khz =0 ; context->bw_ctx.bw.dcn.clk.p_state_change_support = true; +for (i =0 ; i < dc->res_pool->pipe_count; i++) +if (context->res_ctx.pipe_ctx[i].stream) + context->res_ctx.pipe_ctx[i].plane_res.bw.dppclk_khz =0 ; }for (i =0 , pipe_idx =0 ; i < dc->res_pool->pipe_count; i++) {if (!context->res_ctx.pipe_ctx[i].stream)
drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c +4 -1
@@ -1305,7 +1305,10 @@ static void dcn32_calculate_dlg_params(sif (context->bw_ctx.bw.dcn.clk.dppclk_khz < pipes[pipe_idx].clks_cfg.dppclk_mhz *1000 ) context->bw_ctx.bw.dcn.clk.dppclk_khz = pipes[pipe_idx].clks_cfg.dppclk_mhz *1000 ; - context->res_ctx.pipe_ctx[i].plane_res.bw.dppclk_khz = pipes[pipe_idx].clks_cfg.dppclk_mhz *1000 ; +if (context->res_ctx.pipe_ctx[i].plane_state) + context->res_ctx.pipe_ctx[i].plane_res.bw.dppclk_khz = pipes[pipe_idx].clks_cfg.dppclk_mhz *1000 ; +else + context->res_ctx.pipe_ctx[i].plane_res.bw.dppclk_khz =0 ; context->res_ctx.pipe_ctx[i].pipe_dlg_param = pipes[pipe_idx].pipe.dest; pipe_idx++; }
Greg Kroah-Hartman
maintainerPATCH 218/228 tracing: Fix trace_event_raw_event_synth() if else statement
In reply to Greg Kroah-HartmanFrom: Steven Rostedt (Google) <[email protected]>
commit 9971c3f944489ff7aacb9d25e0cde841a5f6018a upstream.
The test to check if the field is a stack is to be done if it is not a string. But the code had:
} if (event->fields[i]->is_stack) {and not
} else if (event->fields[i]->is_stack) {which would cause it to always be tested. Worse yet, this also included an "else" statement that was only to be called if the field was not a string and a stack, but this code allows it to be called if it was a string (and not a stack).
Also fixed some whitespace issues.
--- kernel/trace/trace_events_synth.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/trace/trace_events_synth.c +2 -2
@@ -576,8 +576,8 @@ static notrace void trace_event_raw_even event->fields[i]->is_dynamic, data_size, &n_u64); data_size += len;/* only dynamic string increments */ - }if (event->fields[i]->is_stack) { -long *stack = (long *)(long )var_ref_vals[val_idx]; + }else if (event->fields[i]->is_stack) { +long *stack = (long *)(long )var_ref_vals[val_idx]; len =trace_stack (entry, event, stack, data_size, &n_u64);
Greg Kroah-Hartman
maintainerPATCH 219/228 drm/amd/display: perform a bounds check before filling dirty rectangles
In reply to Greg Kroah-HartmanFrom: Hamza Mahfooz <[email protected]>
commit af22d6a869cc26b519bfdcd54293c53f2e491870 upstream.
Currently, it is possible for us to access memory that we shouldn't. Since, we acquire (possibly dangling) pointers to dirty rectangles before doing a bounds check to make sure we can actually accommodate the number of dirty rectangles userspace has requested to fill. This issue is especially evident if a compositor requests both MPO and damage clips at the same time, in which case I have observed a soft-hang. So, to avoid this issue, perform the bounds check before filling a single dirty rectangle and WARN() about it, if it is ever attempted in fill_dc_dirty_rect().
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +4 -9
@@ -4953,11 +4953,7 @@ static inline void fill_dc_dirty_rect(st int32_t y, int32_t width, int32_t height, int *i, bool ffu) { - if (*i > DC_MAX_DIRTY_RECTS) - return; - -if (*i ==DC_MAX_DIRTY_RECTS ) - goto out; + WARN_ON(*i >= DC_MAX_DIRTY_RECTS); dirty_rect->x = x; dirty_rect->y = y;
@@ -4973,7 +4969,6 @@ static inline void fill_dc_dirty_rect(st"[PLANE:%d] PSR SU dirty rect at (%d, %d) size (%d, %d)" , plane->base.id, x, y, width, height); -out: (*i)++; }
@@ -5055,6 +5050,9 @@ static void fill_dc_dirty_rects(struct d new_plane_state->plane->base.id, bb_changed, fb_changed, num_clips); +if ((num_clips + (bb_changed ?2 :0 )) >DC_MAX_DIRTY_RECTS ) + goto ffu; +if (bb_changed) { fill_dc_dirty_rect(new_plane_state->plane, &dirty_rects[i], new_plane_state->crtc_x,
@@ -5084,9 +5082,6 @@ static void fill_dc_dirty_rects(struct d new_plane_state->crtc_h, &i, false); } -if (i >DC_MAX_DIRTY_RECTS ) - goto ffu; - flip_addrs->dirty_rect_count = i;return ;
Greg Kroah-Hartman
maintainerPATCH 220/228 drm/amd/display: Write to correct dirty_rect
In reply to Greg Kroah-HartmanFrom: Benjamin Cheng <[email protected]>
commit 751281c55579f0cb0e56c9797d4663f689909681 upstream.
When FB_DAMAGE_CLIPS are provided in a non-MPO scenario, the loop does not use the counter i. This causes the fill_dc_dity_rect() to always fill dirty_rects[0], causing graphical artifacts when a damage clip aware DRM client sends more than 1 damage clip.
Instead, use the flip_addrs->dirty_rect_count which is incremented by fill_dc_dirty_rect() on a successful fill.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +3 -3
@@ -5023,9 +5023,9 @@ static void fill_dc_dirty_rects(struct dfor (; flip_addrs->dirty_rect_count < num_clips; clips++)fill_dc_dirty_rect (new_plane_state->plane, - &dirty_rects[i], clips->x1, - clips->y1, clips->x2 - clips->x1, - clips->y2 - clips->y1, + &dirty_rects[flip_addrs->dirty_rect_count], + clips->x1, clips->y1, + clips->x2 - clips->x1, clips->y2 - clips->y1, &flip_addrs->dirty_rect_count, false);return ;
Greg Kroah-Hartman
maintainerPATCH 221/228 ACPI: processor: perflib: Use the "no limit" frequency QoS
In reply to Greg Kroah-HartmanFrom: Rafael J. Wysocki <[email protected]>
commit c02d5feb6e2f60affc6ba8606d8d614c071e2ba6 upstream.
When _PPC returns 0, it means that the CPU frequency is not limited by the platform firmware, so make acpi_processor_get_platform_limit() update the frequency QoS request used by it to "no limit" in that case.
This addresses a problem with limiting CPU frequency artificially on some systems after CPU offline/online to the frequency that corresponds to the first entry in the _PSS return package.
--- drivers/acpi/processor_perflib.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-)
drivers/acpi/processor_perflib.c +16 -4
@@ -53,6 +53,8 @@ static int acpi_processor_get_platform_l {acpi_status status =0 ;unsigned long long ppc =0 ; +s32 qos_value; +int index;int ret;if (!pr)
@@ -72,17 +74,27 @@ static int acpi_processor_get_platform_l } } + index = ppc; +pr_debug ("CPU %d: _PPC is %d - frequency %s limited\n" , pr->id, - (int )ppc, ppc ?"" :"not" ); + index, index ?"is" :"is not" ); - pr->performance_platform_limit = (int )ppc; + pr->performance_platform_limit = index;if (ppc >= pr->performance->state_count ||unlikely (!freq_qos_request_active (&pr->perflib_req)))return 0 ; - ret =freq_qos_update_request (&pr->perflib_req, - pr->performance->states[ppc].core_frequency *1000 ); +/* +* If _PPC returns 0, it means that all of the available states can be +* used ("no limit"). +*/ +if (index ==0 ) + qos_value =FREQ_QOS_MAX_DEFAULT_VALUE ; +else + qos_value = pr->performance->states[index].core_frequency *1000 ; + + ret =freq_qos_update_request (&pr->perflib_req, qos_value);if (ret <0 ) {pr_warn ("Failed to update perflib freq constraint: CPU%d (%d)\n" , pr->id, ret);
Greg Kroah-Hartman
maintainerPATCH 222/228 ACPI: processor: perflib: Avoid updating frequency QoS unnecessarily
In reply to Greg Kroah-HartmanFrom: Rafael J. Wysocki <[email protected]>
commit 99387b016022c29234c4ebf9abd34358c6e56532 upstream.
Modify acpi_processor_get_platform_limit() to avoid updating its frequency QoS request when the _PPC return value has not changed by comparing that value to the previous _PPC return value stored in the performance_platform_limit field of the struct acpi_processor corresponding to the given CPU.
While at it, do the _PPC return value check against the state count earlier, to avoid setting performance_platform_limit to an invalid value, and make acpi_processor_ppc_init() use FREQ_QOS_MAX_DEFAULT_VALUE as the "no limit" frequency QoS for consistency.
--- drivers/acpi/processor_perflib.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-)
drivers/acpi/processor_perflib.c +14 -4
@@ -76,13 +76,16 @@ static int acpi_processor_get_platform_l index = ppc; +if (pr->performance_platform_limit == index || + ppc >= pr->performance->state_count) +return 0 ; +pr_debug ("CPU %d: _PPC is %d - frequency %s limited\n" , pr->id, index, index ?"is" :"is not" ); pr->performance_platform_limit = index; -if (ppc >= pr->performance->state_count || -unlikely (!freq_qos_request_active (&pr->perflib_req))) +if (unlikely (!freq_qos_request_active (&pr->perflib_req)))return 0 ;/*
@@ -177,9 +180,16 @@ void acpi_processor_ppc_init(struct cpufif (!pr)continue ; +/* +* Reset performance_platform_limit in case there is a stale +* value in it, so as to make it match the "no limit" QoS value +* below. +*/ + pr->performance_platform_limit =0 ; + ret =freq_qos_add_request (&policy->constraints, - &pr->perflib_req, -FREQ_QOS_MAX ,INT_MAX ); + &pr->perflib_req,FREQ_QOS_MAX , +FREQ_QOS_MAX_DEFAULT_VALUE );if (ret <0 )pr_err ("Failed to add freq constraint for CPU%d (%d)\n" , cpu, ret);
Greg Kroah-Hartman
maintainerPATCH 223/228 cpufreq: intel_pstate: Drop ACPI _PSS states table patching
In reply to Greg Kroah-HartmanFrom: Rafael J. Wysocki <[email protected]>
commit e8a0e30b742f76ebd0f3b196973df4bf65d8fbbb upstream.
After making acpi_processor_get_platform_limit() use the "no limit" value for its frequency QoS request when _PPC returns 0, it is not necessary to replace the frequency corresponding to the first _PSS return package entry with the maximum turbo frequency of the given CPU in intel_pstate_init_acpi_perf_limits() any more, so drop the code doing that along with the comment explaining it.
--- drivers/cpufreq/intel_pstate.c | 14 -------------- 1 file changed, 14 deletions(-)
drivers/cpufreq/intel_pstate.c +0 -14
@@ -451,20 +451,6 @@ static void intel_pstate_init_acpi_perf_ (u32) cpu->acpi_perf_data.states[i].control); } -/* -* The _PSS table doesn't contain whole turbo frequency range. -* This just contains +1 MHZ above the max non turbo frequency, -* with control value corresponding to max turbo ratio. But -* when cpufreq set policy is called, it will call with this -* max frequency, which will cause a reduced performance as -* this driver uses real max turbo frequency as the max -* frequency. So correct this frequency in _PSS table to -* correct max turbo frequency based on the turbo state. -* Also need to convert to MHz as _PSS freq is in MHz. -*/ -if (!global.turbo_disabled) - cpu->acpi_perf_data.states[0 ].core_frequency = - policy->cpuinfo.max_freq /1000 ; cpu->valid_pss_table = true;pr_debug ("_PPC limits will be enforced\n" );
Greg Kroah-Hartman
maintainerPATCH 224/228 mptcp: ensure subflow is unhashed before cleaning the backlog
In reply to Greg Kroah-HartmanFrom: Paolo Abeni <[email protected]>
commit 3fffa15bfef48b0ad6424779c03e68ae8ace5acb upstream.
While tacking care of the mptcp-level listener I unintentionally moved the subflow level unhash after the subflow listener backlog cleanup.
That could cause some nasty race and makes the code harder to read.
Address the issue restoring the proper order of operations.
--- net/mptcp/protocol.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/mptcp/protocol.c +1 -1
@@ -2945,9 +2945,9 @@ static void mptcp_check_listen_stop(strureturn ;lock_sock_nested (ssk,SINGLE_DEPTH_NESTING ); +tcp_set_state (ssk,TCP_CLOSE );mptcp_subflow_queue_clean (sk, ssk);inet_csk_listen_stop (ssk); -tcp_set_state (ssk,TCP_CLOSE );release_sock (ssk); }
Greg Kroah-Hartman
maintainerPATCH 225/228 selftests: mptcp: sockopt: use iptables-legacy if available
In reply to Greg Kroah-HartmanFrom: Matthieu Baerts <[email protected]>
commit a5a5990c099dd354e05e89ee77cd2dbf6655d4a1 upstream.
IPTables commands using 'iptables-nft' fail on old kernels, at least on v5.15 because it doesn't see the default IPTables chains:
$ iptables -L iptables/1.8.2 Failed to initialize nft: Protocol not supported
As a first step before switching to NFTables, we can use iptables-legacy if available.
--- tools/testing/selftests/net/mptcp/mptcp_sockopt.sh | 24 +++++++++++---------- 1 file changed, 13 insertions(+), 11 deletions(-)
tools/testing/selftests/net/mptcp/mptcp_sockopt.sh +13 -11
@@ -13,13 +13,15 @@ timeout_poll=30 timeout_test=$((timeout_poll * 2 + 1)) mptcp_connect="" do_all_tests=1 +iptables="iptables" +ip6tables="ip6tables" add_mark_rules() { local ns=$1 local m=$2 - for t in iptables ip6tables; do + for t in ${iptables} ${ip6tables}; do # just to debug: check we have multiple subflows connection requests ip netns exec $ns $t -A OUTPUT -p tcp --syn -m mark --mark $m -j ACCEPT
@@ -92,14 +94,14 @@ if [ $? -ne 0 ];then exit $ksft_skip fi -iptables -V > /dev/null 2>&1 -if [ $? -ne 0 ];then +# Use the legacy version if available to support old kernel versions +if iptables-legacy -V &> /dev/null; then + iptables="iptables-legacy" + ip6tables="ip6tables-legacy" +elif ! iptables -V &> /dev/null; then echo "SKIP: Could not run all tests without iptables tool" exit $ksft_skip -fi - -ip6tables -V > /dev/null 2>&1 -if [ $? -ne 0 ];then +elif ! ip6tables -V &> /dev/null; then echo "SKIP: Could not run all tests without ip6tables tool" exit $ksft_skip fi
@@ -109,10 +111,10 @@ check_mark() local ns=$1 local af=$2 - tables=iptables + tables=${iptables} if [ $af -eq 6 ];then - tables=ip6tables + tables=${ip6tables} fi counters=$(ip netns exec $ns $tables -v -L OUTPUT | grep DROP)
@@ -314,8 +316,8 @@ do_tcpinq_tests() { local lret=0 - ip netns exec "$ns1" iptables -F - ip netns exec "$ns1" ip6tables -F + ip netns exec "$ns1" ${iptables} -F + ip netns exec "$ns1" ${ip6tables} -F if ! mptcp_lib_kallsyms_has "mptcp_ioctl$"; then echo "INFO: TCP_INQ not supported: SKIP"
Greg Kroah-Hartman
maintainerPATCH 226/228 test_firmware: return ENOMEM instead of ENOSPC on failed memory allocation
In reply to Greg Kroah-HartmanFrom: Mirsad Goran Todorovac <[email protected]>
commit 7dae593cd226a0bca61201cf85ceb9335cf63682 upstream.
In a couple of situations like
name = kstrndup(buf, count, GFP_KERNEL); if (!name) return -ENOSPC;
the error is not actually "No space left on device", but "Out of memory".
It is semantically correct to return -ENOMEM in all failed kstrndup() and kzalloc() cases in this driver, as it is not a problem with disk space, but with kernel memory allocator failing allocation.
The semantically correct should be:
name = kstrndup(buf, count, GFP_KERNEL);
if (!name)
return -ENOMEM;Message-ID: <[email protected]>
--- lib/test_firmware.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
lib/test_firmware.c +6 -6
@@ -214,7 +214,7 @@ static int __kstrncpy(char **dst, const { *dst =kstrndup (name, count, gfp);if (!*dst) -return -ENOSPC ; +return -ENOMEM ;return count; }
@@ -671,7 +671,7 @@ static ssize_t trigger_request_store(str name =kstrndup (buf, count,GFP_KERNEL );if (!name) -return -ENOSPC ; +return -ENOMEM ;pr_info ("loading '%s'\n" , name);
@@ -719,7 +719,7 @@ static ssize_t trigger_request_platform_ name =kstrndup (buf, count,GFP_KERNEL );if (!name) -return -ENOSPC ; +return -ENOMEM ;pr_info ("inserting test platform fw '%s'\n" , name); efi_embedded_fw.name = name;
@@ -772,7 +772,7 @@ static ssize_t trigger_async_request_sto name =kstrndup (buf, count,GFP_KERNEL );if (!name) -return -ENOSPC ; +return -ENOMEM ;pr_info ("loading '%s'\n" , name);
@@ -817,7 +817,7 @@ static ssize_t trigger_custom_fallback_s name =kstrndup (buf, count,GFP_KERNEL );if (!name) -return -ENOSPC ; +return -ENOMEM ;pr_info ("loading '%s' using custom fallback mechanism\n" , name);
@@ -868,7 +868,7 @@ static int test_fw_run_batch_request(voi test_buf =kzalloc (TEST_FIRMWARE_BUF_SIZE ,GFP_KERNEL );if (!test_buf) -return -ENOSPC ; +return -ENOMEM ;if (test_fw_config->partial) req->rc = request_partial_firmware_into_buf
Greg Kroah-Hartman
maintainerPATCH 227/228 dma-buf: keep the signaling time of merged fences v3
In reply to Greg Kroah-HartmanFrom: Christian König <[email protected]>
commit f781f661e8c99b0cb34129f2e374234d61864e77 upstream.
Some Android CTS is testing if the signaling time keeps consistent during merges.
v2: use the current time if the fence is still in the signaling path and the timestamp not yet available.
v3: improve comment, fix one more case to use the correct timestamp
--- drivers/dma-buf/dma-fence-unwrap.c | 26 ++++++++++++++++++++++---- drivers/dma-buf/dma-fence.c | 5 +++-- drivers/gpu/drm/drm_syncobj.c | 2 +- include/linux/dma-fence.h | 2 +- 4 files changed, 27 insertions(+), 8 deletions(-)
drivers/dma-buf/dma-fence-unwrap.c +22 -4
@@ -66,18 +66,36 @@ struct dma_fence *__dma_fence_unwrap_mer {struct dma_fence_array *result;struct dma_fence *tmp, **array; +ktime_t timestamp;unsigned int i;size_t count; count =0 ; + timestamp =ns_to_ktime (0 );for (i =0 ; i < num_fences; ++i) { -dma_fence_unwrap_for_each (tmp, &iter[i], fences[i]) -if (!dma_fence_is_signaled (tmp)) +dma_fence_unwrap_for_each (tmp, &iter[i], fences[i]) { +if (!dma_fence_is_signaled (tmp)) { ++count; + }else if (test_bit (DMA_FENCE_FLAG_TIMESTAMP_BIT , + &tmp->flags)) { +if (ktime_after (tmp->timestamp, timestamp)) + timestamp = tmp->timestamp; + }else { +/* +* Use the current time if the fence is +* currently signaling. +*/ + timestamp =ktime_get (); + } + } } +/* +* If we couldn't find a pending fence just return a private signaled +* fence with the timestamp of the last signaled one. +*/ if (count ==0 ) -return dma_fence_get_stub (); +return dma_fence_allocate_private_stub (timestamp); array =kmalloc_array (count,sizeof (*array),GFP_KERNEL );if (!array)
@@ -138,7 +156,7 @@ restart: }while (tmp);if (count ==0 ) { - tmp =dma_fence_get_stub (); + tmp =dma_fence_allocate_private_stub (ktime_get ()); goto return_tmp; }
drivers/dma-buf/dma-fence.c +3 -2
@@ -150,10 +150,11 @@ EXPORT_SYMBOL(dma_fence_get_stub);/** * dma_fence_allocate_private_stub - return a private, signaled fence +* @timestamp: timestamp when the fence was signaled * * Return a newly allocated and signaled stub fence. */ -struct dma_fence *dma_fence_allocate_private_stub (void ) +struct dma_fence *dma_fence_allocate_private_stub (ktime_t timestamp) {struct dma_fence *fence;
@@ -169,7 +170,7 @@ struct dma_fence *dma_fence_allocate_priset_bit (DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT , &fence->flags); -dma_fence_signal (fence); +dma_fence_signal_timestamp (fence, timestamp);return fence; }
drivers/gpu/drm/drm_syncobj.c +1 -1
@@ -353,7 +353,7 @@ EXPORT_SYMBOL(drm_syncobj_replace_fence)*/ static int drm_syncobj_assign_null_handle (struct drm_syncobj *syncobj) { -struct dma_fence *fence =dma_fence_allocate_private_stub (); +struct dma_fence *fence =dma_fence_allocate_private_stub (ktime_get ());if (IS_ERR (fence))return PTR_ERR (fence);
include/linux/dma-fence.h +1 -1
@@ -584,7 +584,7 @@ static inline signed long dma_fence_wait }struct dma_fence *dma_fence_get_stub (void ); -struct dma_fence *dma_fence_allocate_private_stub (void ); +struct dma_fence *dma_fence_allocate_private_stub (ktime_t timestamp);u64 dma_fence_context_alloc (unsigned num);extern const struct dma_fence_ops dma_fence_array_ops;
Greg Kroah-Hartman
maintainerPATCH 228/228 dma-buf: fix an error pointer vs NULL bug
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
commit 00ae1491f970acc454be0df63f50942d94825860 upstream.
Smatch detected potential error pointer dereference.
drivers/gpu/drm/drm_syncobj.c:888 drm_syncobj_transfer_to_timeline()
error: 'fence' dereferencing possible ERR_PTR()
The error pointer comes from dma_fence_allocate_private_stub(). One caller expected error pointers and one expected NULL pointers. Change it to return NULL and update the caller which expected error pointers, drm_syncobj_assign_null_handle(), to check for NULL instead.
--- drivers/dma-buf/dma-fence.c | 2 +- drivers/gpu/drm/drm_syncobj.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-)
drivers/dma-buf/dma-fence.c +1 -1
@@ -160,7 +160,7 @@ struct dma_fence *dma_fence_allocate_pri fence =kzalloc (sizeof (*fence),GFP_KERNEL );if (fence ==NULL ) -return ERR_PTR (-ENOMEM ); +return NULL ; dma_fence_init(fence, &dma_fence_stub_ops,
drivers/gpu/drm/drm_syncobj.c +2 -2
@@ -355,8 +355,8 @@ static int drm_syncobj_assign_null_handl {struct dma_fence *fence =dma_fence_allocate_private_stub (ktime_get ()); -if (IS_ERR (fence)) -return PTR_ERR (fence); +if (!fence) +return -ENOMEM ;drm_syncobj_replace_fence (syncobj, fence);dma_fence_put (fence);
Hi Greg
Quoted 10 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.1.43 release. There are 228 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.
Responses should be made by Thu, 03 Aug 2023 09:18:38 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 9 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.1.43-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.1.y
and the diffstat can be found below.thanks,
greg k-h
6.1.43-rc1 tested.
Build successfully completed.
Boot successfully completed.
No dmesg regressions.
Video output normal.
Sound output normal.
Lenovo ThinkPad X1 Carbon Gen10(Intel i7-1260P(x86_64) arch linux)
Thanks
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.1.43 release. There are 228 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.
Responses should be made by Thu, 03 Aug 2023 09:18:38 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.1.43-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.1.y
and the diffstat can be found below.thanks,
greg k-h
All tests passing for Tegra ...
Test results for stable-v6.1:
11 builds: 11 pass, 0 fail
28 boots: 28 pass, 0 fail
130 tests: 130 pass, 0 failLinux version: 6.1.43-rc1-g9f9cafb14305
Boards tested: tegra124-jetson-tk1, tegra186-p2771-0000,
tegra194-p2972-0000, tegra194-p3509-0000+p3668-0000,
tegra20-ventana, tegra210-p2371-2180,
tegra210-p3450-0000, tegra30-cardhu-a04Jon
Quoted 4 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.1.43 release. There are 228 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.
Thanks,
Conor.
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.1.43 release. There are 228 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.
Responses should be made by Thu, 03 Aug 2023 09:18:38 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.1.43-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.1.y
and the diffstat can be found below.thanks,
greg k-h
On ARCH_BRCMSTB using 32-bit and 64-bit ARM kernels, build tested on BMIPS_GENERIC:
Signature · 1 line
Florian
Hello,
Quoted 5 lines · On Tue, 1 Aug 2023 11:17:38 +0200 Greg Kroah-Hartman…
This is the start of the stable review cycle for the 6.1.43 release. There are 228 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.
Quoted 8 lines
Responses should be made by Thu, 03 Aug 2023 09:18:38 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.1.43-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.1.y
and the diffstat can be found below.
This rc kernel passes DAMON functionality test[1] on my test machine. Attaching the test results summary below. Please note that I retrieved the kernel from linux-stable-rc tree[2].
[1] https://github.com/awslabs/damon-tests/tree/next/corr
[2] b2c388dc2443 ("Linux 5.15.124-rc1")
Thanks,
SJ
[...]
---
ok 1 selftests: damon: debugfs_attrs.sh
ok 1 selftests: damon-tests: kunit.sh
ok 2 selftests: damon-tests: huge_count_read_write.sh
ok 3 selftests: damon-tests: buffer_overflow.sh
ok 4 selftests: damon-tests: rm_contexts.sh
ok 5 selftests: damon-tests: record_null_deref.sh
ok 6 selftests: damon-tests: dbgfs_target_ids_read_before_terminate_race.sh ok 7 selftests: damon-tests: dbgfs_target_ids_pid_leak.sh
ok 8 selftests: damon-tests: damo_tests.sh
ok 9 selftests: damon-tests: masim-record.sh
ok 10 selftests: damon-tests: build_i386.sh
ok 11 selftests: damon-tests: build_m68k.sh
ok 12 selftests: damon-tests: build_arm64.sh
ok 13 selftests: damon-tests: build_i386_idle_flag.sh
ok 14 selftests: damon-tests: build_i386_highpte.sh
ok 15 selftests: damon-tests: build_nomemcg.sh
PASS
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.1.43 release. There are 228 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.
Responses should be made by Thu, 03 Aug 2023 09:18:38 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 9 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.1.43-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.1.y
and the diffstat can be found below.thanks,
greg k-h
Compiled and booted on my test system. No dmesg regressions.
thanks,
-- Shuah
Quoted 10 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.1.43 release. There are 228 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.
Responses should be made by Thu, 03 Aug 2023 09:18:38 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.1.43-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.1.y
and the diffstat can be found below.thanks,
greg k-h
Following patch caused build regression on stable-rc 6.1 and 5.15,
Regressions found on arm:
- build/gcc-12-orion5x_defconfig
- build/clang-nightly-orion5x_defconfig
- build/gcc-8-orion5x_defconfig
- build/clang-16-orion5x_defconfig
gpio: mvebu: Make use of devm_pwmchip_add
[ Upstream commit 1945063eb59e64d2919cb14d54d081476d9e53bb ]
Build log:
------drivers/gpio/gpio-mvebu.c: In function 'mvebu_pwm_probe':drivers/gpio/gpio-mvebu.c:877:16: error: implicit declaration of function 'devm_pwmchip_add'; did you mean 'pwmchip_add'? [-Werror=implicit-function-declaration]
877 | return devm_pwmchip_add(dev, &mvpwm->chip);
| ^~~~~~~~~~~~~~~~
| pwmchip_addcc1: some warnings being treated as errors
--
Linaro LKFT
https://lkft.linaro.org
Quoted 17 lines · Naresh Kamboju
Quoted 15 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.1.43 release. There are 228 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.
Responses should be made by Thu, 03 Aug 2023 09:18:38 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.1.43-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.1.y
and the diffstat can be found below.
Quoted 5 lines
Quoted 3 lines
thanks,
greg k-h
Following patch caused build regression on stable-rc 6.1 and 5.15,
Looking at 6.1.x, cherry-picking 88da4e8113110d5f4ebdd2f8cd0899e300cd1954 can be done without conflicts and fixes this regression.
Best regards
Uwe
Signature · 2 lines
Pengutronix e.K. | Uwe Kleine-König | Industrial Linux Solutions | https://www.pengutronix.de/ |
Greg Kroah-Hartman
maintainerQuoted 20 lines · Uwe Kleine-König
Quoted 19 lines · Naresh Kamboju
Quoted 17 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.1.43 release. There are 228 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.
Responses should be made by Thu, 03 Aug 2023 09:18:38 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.1.43-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.1.y
and the diffstat can be found below.thanks,
Quoted 7 lines
Quoted 3 lines
Quoted 1 line
greg k-h
Following patch caused build regression on stable-rc 6.1 and 5.15,
Looking at 6.1.x, cherry-picking
88da4e8113110d5f4ebdd2f8cd0899e300cd1954can be done without conflicts and fixes this regression.
Already done and in -rc2!
thanks,
greg k-h
Quoted 5 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.1.43 release. There are 228 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.
Successfully compiled and installed bindeb-pkgs on my computer (Acer Aspire E15, Intel Core i3 Haswell). No noticeable regressions.
Signature · 1 line
An old man doll... just what I always wanted! - Clara