6.0.3-rc1 review
Subsystems (10)
Greg Kroah-Hartman
maintainerPATCH 564/862 serial: 8250: Fix restoring termios speed after suspend
In reply to Greg Kroah-HartmanFrom: Pali Rohár <[email protected]>
[ Upstream commit 379a33786d489ab81885ff0b3935cfeb36137fea ]
Since commit edc6afc54968 ("tty: switch to ktermios and new framework") termios speed is no longer stored only in c_cflag member but also in new additional c_ispeed and c_ospeed members. If BOTHER flag is set in c_cflag then termios speed is stored only in these new members.
Since commit 027b57170bf8 ("serial: core: Fix initializing and restoring termios speed") termios speed is available also in struct console.
So properly restore also c_ispeed and c_ospeed members after suspend to fix restoring termios speed which is not represented by Bnnn constant.
--- drivers/tty/serial/8250/8250_port.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/tty/serial/8250/8250_port.c +6 -1
@@ -3319,8 +3319,13 @@ static void serial8250_console_restore(struct uart_8250_port *up)unsigned int baud, quot, frac =0 ; termios.c_cflag = port->cons->cflag; -if (port->state->port.tty && termios.c_cflag ==0 ) + termios.c_ispeed = port->cons->ispeed; + termios.c_ospeed = port->cons->ospeed; +if (port->state->port.tty && termios.c_cflag ==0 ) { termios.c_cflag = port->state->port.tty->termios.c_cflag; + termios.c_ispeed = port->state->port.tty->termios.c_ispeed; + termios.c_ospeed = port->state->port.tty->termios.c_ospeed; + } baud =serial8250_get_baud_rate (port, &termios,NULL ); quot =serial8250_get_divisor (port, baud, &frac);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 565/862 scsi: libsas: Fix use-after-free bug in smp_execute_task_sg()
In reply to Greg Kroah-HartmanFrom: Duoming Zhou <[email protected]>
[ Upstream commit 46ba53c30666717cb06c2b3c5d896301cd00d0c0 ]
When executing SMP task failed, the smp_execute_task_sg() calls del_timer() to delete "slow_task->timer". However, if the timer handler sas_task_internal_timedout() is running, the del_timer() in smp_execute_task_sg() will not stop it and a UAF will happen. The process is shown below:
(thread 1) | (thread 2)
smp_execute_task_sg() | sas_task_internal_timedout()
... |
del_timer() |
... | ...
sas_free_task(task) |
kfree(task->slow_task) //FREE|
| task->slow_task->... //USEFix by calling del_timer_sync() in smp_execute_task_sg(), which makes sure the timer handler have finished before the "task->slow_task" is deallocated.
--- drivers/scsi/libsas/sas_expander.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/scsi/libsas/sas_expander.c +1 -1
@@ -67,7 +67,7 @@ static int smp_execute_task_sg(struct domain_device *dev, res = i->dft->lldd_execute_task (task,GFP_KERNEL );if (res) { -del_timer (&task->slow_task->timer); +del_timer_sync (&task->slow_task->timer);pr_notice ("executing SMP task failed:%d\n" , res);break ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 566/862 scsi: pm8001: Fix running_req for internal abort commands
In reply to Greg Kroah-HartmanFrom: John Garry <[email protected]>
[ Upstream commit d8c22c4697c11ed28062afe3c2b377025be11a23 ]
Disabling the remote phy for a SATA disk causes a hang:
root@(none)$ more /sys/class/sas_phy/phy-0:0:8/target_port_protocols sata root@(none)$ echo 0 > sys/class/sas_phy/phy-0:0:8/enable root@(none)$ [ 67.855950] sas: ex 500e004aaaaaaa1f phy08 change count has changed [ 67.920585] sd 0:0:2:0: [sdc] Synchronizing SCSI cache [ 67.925780] sd 0:0:2:0: [sdc] Synchronize Cache(10) failed: Result: hostbyte=0x04 driverbyte=DRIVER_OK [ 67.935094] sd 0:0:2:0: [sdc] Stopping disk [ 67.939305] sd 0:0:2:0: [sdc] Start/Stop Unit failed: Result: hostbyte=0x04 driverbyte=DRIVER_OK ... [ 123.998998] INFO: task kworker/u192:1:642 blocked for more than 30 seconds. [ 124.005960] Not tainted 6.0.0-rc1-205202-gf26f8f761e83 #218 [ 124.012049] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. [ 124.019872] task:kworker/u192:1 state:D stack:0 pid: 642 ppid: 2 flags:0x00000008 [ 124.028223] Workqueue: 0000:04:00.0_event_q sas_port_event_worker [ 124.034319] Call trace: [ 124.036758] __switch_to+0x128/0x278 [ 124.040333] __schedule+0x434/0xa58 [ 124.043820] schedule+0x94/0x138 [ 124.047045] schedule_timeout+0x2fc/0x368 [ 124.051052] wait_for_completion+0xdc/0x200 [ 124.055234] __flush_workqueue+0x1a8/0x708 [ 124.059328] sas_porte_broadcast_rcvd+0xa8/0xc0 [ 124.063858] sas_port_event_worker+0x60/0x98 [ 124.068126] process_one_work+0x3f8/0x660 [ 124.072134] worker_thread+0x70/0x700 [ 124.075793] kthread+0x1a4/0x1b8 [ 124.079014] ret_from_fork+0x10/0x20
The issue is that the per-device running_req read in pm8001_dev_gone_notify() never goes to zero and we never make progress. This is caused by missing accounting for running_req for when an internal abort command completes.
In commit 2cbbf489778e ("scsi: pm8001: Use libsas internal abort support") we started to send internal abort commands as a proper sas_task. In this when we deliver a sas_task to HW the per-device running_req is incremented in pm8001_queue_command(). However it is never decremented for internal abort commnds, so decrement in pm8001_mpi_task_abort_resp().
--- drivers/scsi/pm8001/pm8001_hwi.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/scsi/pm8001/pm8001_hwi.c +4 -0
@@ -3612,6 +3612,10 @@ int pm8001_mpi_task_abort_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)pm8001_dbg (pm8001_ha,FAIL ," TASK NULL. RETURNING !!!\n" );return -1 ; } + +if (t->task_proto ==SAS_PROTOCOL_INTERNAL_ABORT ) +atomic_dec (&pm8001_dev->running_req); + ts = &t->task_status;if (status !=0 ) pm8001_dbg(pm8001_ha, FAIL, "task abort failed status 0x%x ,tag = 0x%x, scp= 0x%x\n",
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 567/862 scsi: iscsi: iscsi_tcp: Fix null-ptr-deref while calling getpeername()
In reply to Greg Kroah-HartmanFrom: Mike Christie <[email protected]>
[ Upstream commit 57569c37f0add1b6489e1a1563c71519daf732cf ]
Fix a NULL pointer crash that occurs when we are freeing the socket at the same time we access it via sysfs.
The problem is that:
1. iscsi_sw_tcp_conn_get_param() and iscsi_sw_tcp_host_get_param() take the frwd_lock and do sock_hold() then drop the frwd_lock. sock_hold() does a get on the "struct sock".
2. iscsi_sw_tcp_release_conn() does sockfd_put() which does the last put on the "struct socket" and that does __sock_release() which sets the sock->ops to NULL.
3. iscsi_sw_tcp_conn_get_param() and iscsi_sw_tcp_host_get_param() then
call kernel_getpeername() which accesses the NULL sock->ops.
Above we do a get on the "struct sock", but we needed a get on the "struct socket". Originally, we just held the frwd_lock the entire time but in commit bcf3a2953d36 ("scsi: iscsi: iscsi_tcp: Avoid holding spinlock while calling getpeername()") we switched to refcount based because the network layer changed and started taking a mutex in that path, so we could no longer hold the frwd_lock.
Instead of trying to maintain multiple refcounts, this just has us use a mutex for accessing the socket in the interface code paths.
--- drivers/scsi/iscsi_tcp.c | 73 ++++++++++++++++++++++++++++------------ drivers/scsi/iscsi_tcp.h | 3 ++ 2 files changed, 55 insertions(+), 21 deletions(-)
drivers/scsi/iscsi_tcp.c +52 -21
@@ -595,6 +595,8 @@ iscsi_sw_tcp_conn_create(struct iscsi_cls_session *cls_session,INIT_WORK (&conn->recvwork, iscsi_sw_tcp_recv_data_work); tcp_sw_conn->queue_recv = iscsi_recv_from_iscsi_q; +mutex_init (&tcp_sw_conn->sock_lock); + tfm =crypto_alloc_ahash ("crc32c" ,0 ,CRYPTO_ALG_ASYNC );if (IS_ERR (tfm)) goto free_conn;
@@ -629,11 +631,15 @@ iscsi_sw_tcp_conn_create(struct iscsi_cls_session *cls_session,static void iscsi_sw_tcp_release_conn (struct iscsi_conn *conn) { -struct iscsi_session *session = conn->session;struct iscsi_tcp_conn *tcp_conn = conn->dd_data;struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;struct socket *sock = tcp_sw_conn->sock; +/* +* The iscsi transport class will make sure we are not called in +* parallel with start, stop, bind and destroys. However, this can be +* called twice if userspace does a stop then a destroy. +*/ if (!sock)return ;
@@ -649,9 +655,9 @@ static void iscsi_sw_tcp_release_conn(struct iscsi_conn *conn)iscsi_suspend_rx (conn); -spin_lock_bh (&session->frwd_lock); +mutex_lock (&tcp_sw_conn->sock_lock); tcp_sw_conn->sock =NULL ; -spin_unlock_bh (&session->frwd_lock); +mutex_unlock (&tcp_sw_conn->sock_lock);sockfd_put (sock); }
@@ -703,7 +709,6 @@ iscsi_sw_tcp_conn_bind(struct iscsi_cls_session *cls_session, struct iscsi_cls_conn *cls_conn, uint64_t transport_eph, int is_leading) { - struct iscsi_session *session = cls_session->dd_data; struct iscsi_conn *conn = cls_conn->dd_data;struct iscsi_tcp_conn *tcp_conn = conn->dd_data;struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
@@ -723,10 +728,10 @@ iscsi_sw_tcp_conn_bind(struct iscsi_cls_session *cls_session,if (err) goto free_socket; -spin_lock_bh (&session->frwd_lock); +mutex_lock (&tcp_sw_conn->sock_lock);/* bind iSCSI connection and socket */ tcp_sw_conn->sock = sock; -spin_unlock_bh (&session->frwd_lock); +mutex_unlock (&tcp_sw_conn->sock_lock);/* setup Socket parameters */ sk = sock->sk;
@@ -763,8 +768,15 @@ static int iscsi_sw_tcp_conn_set_param(struct iscsi_cls_conn *cls_conn,break ;case ISCSI_PARAM_DATADGST_EN :iscsi_set_param (cls_conn, param, buf, buflen); + +mutex_lock (&tcp_sw_conn->sock_lock); +if (!tcp_sw_conn->sock) { +mutex_unlock (&tcp_sw_conn->sock_lock); +return -ENOTCONN ; + } tcp_sw_conn->sendpage = conn->datadgst_en ? sock_no_sendpage : tcp_sw_conn->sock->ops->sendpage; +mutex_unlock (&tcp_sw_conn->sock_lock);break ;case ISCSI_PARAM_MAX_R2T :return iscsi_tcp_set_max_r2t (conn, buf);
@@ -779,8 +791,8 @@ static int iscsi_sw_tcp_conn_get_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param, char *buf) { struct iscsi_conn *conn = cls_conn->dd_data; -struct iscsi_tcp_conn *tcp_conn = conn->dd_data; -struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data; +struct iscsi_sw_tcp_conn *tcp_sw_conn; +struct iscsi_tcp_conn *tcp_conn;struct sockaddr_in6 addr;struct socket *sock;int rc;
@@ -790,21 +802,36 @@ static int iscsi_sw_tcp_conn_get_param(struct iscsi_cls_conn *cls_conn,case ISCSI_PARAM_CONN_ADDRESS :case ISCSI_PARAM_LOCAL_PORT :spin_lock_bh (&conn->session->frwd_lock); -if (!tcp_sw_conn || !tcp_sw_conn->sock) { +if (!conn->session->leadconn) {spin_unlock_bh (&conn->session->frwd_lock);return -ENOTCONN ; } - sock = tcp_sw_conn->sock; -sock_hold (sock->sk); +/* +* The conn has been setup and bound, so just grab a ref +* incase a destroy runs while we are in the net layer. +*/ +iscsi_get_conn (conn->cls_conn);spin_unlock_bh (&conn->session->frwd_lock); + tcp_conn = conn->dd_data; + tcp_sw_conn = tcp_conn->dd_data; + +mutex_lock (&tcp_sw_conn->sock_lock); + sock = tcp_sw_conn->sock; +if (!sock) { + rc = -ENOTCONN ; + goto sock_unlock; + } +if (param ==ISCSI_PARAM_LOCAL_PORT ) rc =kernel_getsockname (sock, (struct sockaddr *)&addr);else rc =kernel_getpeername (sock, (struct sockaddr *)&addr); -sock_put (sock->sk); +sock_unlock: +mutex_unlock (&tcp_sw_conn->sock_lock); +iscsi_put_conn (conn->cls_conn);if (rc <0 )return rc;
@@ -842,17 +869,21 @@ static int iscsi_sw_tcp_host_get_param(struct Scsi_Host *shost, } tcp_conn = conn->dd_data; tcp_sw_conn = tcp_conn->dd_data; - sock = tcp_sw_conn->sock; -if (!sock) { -spin_unlock_bh (&session->frwd_lock); -return -ENOTCONN ; - } -sock_hold (sock->sk); +/* +* The conn has been setup and bound, so just grab a ref +* incase a destroy runs while we are in the net layer. +*/ +iscsi_get_conn (conn->cls_conn);spin_unlock_bh (&session->frwd_lock); - rc =kernel_getsockname (sock, - (struct sockaddr *)&addr); -sock_put (sock->sk); +mutex_lock (&tcp_sw_conn->sock_lock); + sock = tcp_sw_conn->sock; +if (!sock) + rc = -ENOTCONN ; +else + rc =kernel_getsockname (sock, (struct sockaddr *)&addr); +mutex_unlock (&tcp_sw_conn->sock_lock); +iscsi_put_conn (conn->cls_conn);if (rc <0 )return rc;
drivers/scsi/iscsi_tcp.h +3 -0
@@ -28,6 +28,9 @@ struct iscsi_sw_tcp_send {struct iscsi_sw_tcp_conn {struct socket *sock; +/* Taken when accessing the sock from the netlink/sysfs interface */ +struct mutex sock_lock; +struct work_struct recvwork;bool queue_recv;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 568/862 clk: qcom: apss-ipq6018: mark apcs_alias0_core_clk as critical
In reply to Greg Kroah-HartmanFrom: Robert Marko <[email protected]>
[ Upstream commit 86e78995c93ee182433f965babfccd48417d4dcf ]
While fixing up the driver I noticed that my IPQ8074 board was hanging after CPUFreq switched the frequency during boot, WDT would eventually reset it.
So mark apcs_alias0_core_clk as critical since its the clock feeding the CPU cluster and must never be disabled.
--- drivers/clk/qcom/apss-ipq6018.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/clk/qcom/apss-ipq6018.c +1 -1
@@ -57,7 +57,7 @@ static struct clk_branch apcs_alias0_core_clk = { .parent_hws = (const struct clk_hw *[]){ &apcs_alias0_clk_src.clkr.hw }, .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, + .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, .ops = &clk_branch2_ops, }, },
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 569/862 clk: qcom: gcc-sm6115: Override default Alpha PLL regs
In reply to Greg Kroah-HartmanFrom: Adam Skladowski <[email protected]>
[ Upstream commit 068a0605ef5a6b430e7278c169bfcd25b680b28f ]
The DEFAULT and BRAMMO PLL offsets are non-standard in downstream, but currently only BRAMMO ones are overridden. Override DEFAULT ones too.
A very similar thing is happening in gcc-qcm2290 driver.
--- drivers/clk/qcom/gcc-sm6115.c | 46 +++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 16 deletions(-)
drivers/clk/qcom/gcc-sm6115.c +30 -16
@@ -53,11 +53,25 @@ static struct pll_vco gpll10_vco[] = { { 750000000, 1500000000, 1 }, }; +static const u8 clk_alpha_pll_regs_offset[][PLL_OFF_MAX_REGS] = { + [CLK_ALPHA_PLL_TYPE_DEFAULT] = { + [PLL_OFF_L_VAL] = 0x04, + [PLL_OFF_ALPHA_VAL] = 0x08, + [PLL_OFF_ALPHA_VAL_U] = 0x0c, + [PLL_OFF_TEST_CTL] = 0x10, + [PLL_OFF_TEST_CTL_U] = 0x14, + [PLL_OFF_USER_CTL] = 0x18, + [PLL_OFF_USER_CTL_U] = 0x1c, + [PLL_OFF_CONFIG_CTL] = 0x20, + [PLL_OFF_STATUS] = 0x24, + }, +}; + static struct clk_alpha_pll gpll0 = { .offset = 0x0, .vco_table = default_vco, .num_vco = ARRAY_SIZE(default_vco), - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr = { .enable_reg = 0x79000, .enable_mask = BIT(0),
@@ -83,7 +97,7 @@ static struct clk_alpha_pll_postdiv gpll0_out_aux2 = { .post_div_table = post_div_table_gpll0_out_aux2, .num_post_div = ARRAY_SIZE(post_div_table_gpll0_out_aux2), .width = 4, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr.hw.init = &(struct clk_init_data ){ .name ="gpll0_out_aux2" , .parent_hws = (const struct clk_hw *[]){ &gpll0.clkr.hw },
@@ -115,7 +129,7 @@ static struct clk_alpha_pll_postdiv gpll0_out_main = { .post_div_table = post_div_table_gpll0_out_main, .num_post_div = ARRAY_SIZE(post_div_table_gpll0_out_main), .width = 4, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr.hw.init = &(struct clk_init_data ){ .name ="gpll0_out_main" , .parent_hws = (const struct clk_hw *[]){ &gpll0.clkr.hw },
@@ -137,7 +151,7 @@ static struct clk_alpha_pll gpll10 = { .offset = 0xa000, .vco_table = gpll10_vco, .num_vco = ARRAY_SIZE(gpll10_vco), - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr = { .enable_reg = 0x79000, .enable_mask = BIT(10),
@@ -163,7 +177,7 @@ static struct clk_alpha_pll_postdiv gpll10_out_main = { .post_div_table = post_div_table_gpll10_out_main, .num_post_div = ARRAY_SIZE(post_div_table_gpll10_out_main), .width = 4, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr.hw.init = &(struct clk_init_data ){ .name ="gpll10_out_main" , .parent_hws = (const struct clk_hw *[]){ &gpll10.clkr.hw },
@@ -189,7 +203,7 @@ static struct clk_alpha_pll gpll11 = { .vco_table = default_vco, .num_vco = ARRAY_SIZE(default_vco), .flags = SUPPORTS_DYNAMIC_UPDATE, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr = { .enable_reg = 0x79000, .enable_mask = BIT(11),
@@ -215,7 +229,7 @@ static struct clk_alpha_pll_postdiv gpll11_out_main = { .post_div_table = post_div_table_gpll11_out_main, .num_post_div = ARRAY_SIZE(post_div_table_gpll11_out_main), .width = 4, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr.hw.init = &(struct clk_init_data ){ .name ="gpll11_out_main" , .parent_hws = (const struct clk_hw *[]){ &gpll11.clkr.hw },
@@ -229,7 +243,7 @@ static struct clk_alpha_pll gpll3 = { .offset = 0x3000, .vco_table = default_vco, .num_vco = ARRAY_SIZE(default_vco), - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr = { .enable_reg = 0x79000, .enable_mask = BIT(3),
@@ -248,7 +262,7 @@ static struct clk_alpha_pll gpll4 = { .offset = 0x4000, .vco_table = default_vco, .num_vco = ARRAY_SIZE(default_vco), - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr = { .enable_reg = 0x79000, .enable_mask = BIT(4),
@@ -274,7 +288,7 @@ static struct clk_alpha_pll_postdiv gpll4_out_main = { .post_div_table = post_div_table_gpll4_out_main, .num_post_div = ARRAY_SIZE(post_div_table_gpll4_out_main), .width = 4, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr.hw.init = &(struct clk_init_data ){ .name ="gpll4_out_main" , .parent_hws = (const struct clk_hw *[]){ &gpll4.clkr.hw },
@@ -287,7 +301,7 @@ static struct clk_alpha_pll gpll6 = { .offset = 0x6000, .vco_table = default_vco, .num_vco = ARRAY_SIZE(default_vco), - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr = { .enable_reg = 0x79000, .enable_mask = BIT(6),
@@ -313,7 +327,7 @@ static struct clk_alpha_pll_postdiv gpll6_out_main = { .post_div_table = post_div_table_gpll6_out_main, .num_post_div = ARRAY_SIZE(post_div_table_gpll6_out_main), .width = 4, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr.hw.init = &(struct clk_init_data ){ .name ="gpll6_out_main" , .parent_hws = (const struct clk_hw *[]){ &gpll6.clkr.hw },
@@ -326,7 +340,7 @@ static struct clk_alpha_pll gpll7 = { .offset = 0x7000, .vco_table = default_vco, .num_vco = ARRAY_SIZE(default_vco), - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr = { .enable_reg = 0x79000, .enable_mask = BIT(7),
@@ -352,7 +366,7 @@ static struct clk_alpha_pll_postdiv gpll7_out_main = { .post_div_table = post_div_table_gpll7_out_main, .num_post_div = ARRAY_SIZE(post_div_table_gpll7_out_main), .width = 4, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr.hw.init = &(struct clk_init_data ){ .name ="gpll7_out_main" , .parent_hws = (const struct clk_hw *[]){ &gpll7.clkr.hw },
@@ -380,7 +394,7 @@ static struct clk_alpha_pll gpll8 = { .offset = 0x8000, .vco_table = default_vco, .num_vco = ARRAY_SIZE(default_vco), - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .flags = SUPPORTS_DYNAMIC_UPDATE, .clkr = { .enable_reg = 0x79000,
@@ -407,7 +421,7 @@ static struct clk_alpha_pll_postdiv gpll8_out_main = { .post_div_table = post_div_table_gpll8_out_main, .num_post_div = ARRAY_SIZE(post_div_table_gpll8_out_main), .width = 4, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr.hw.init = &(struct clk_init_data ){ .name ="gpll8_out_main" , .parent_hws = (const struct clk_hw *[]){ &gpll8.clkr.hw },
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 570/862 nvmet-auth: dont try to cancel a non-initialized work_struct
In reply to Greg Kroah-HartmanFrom: Christoph Hellwig <[email protected]>
[ Upstream commit 1befd944e05050d76950014f3dc04ed47faba2c3 ]
Currently blktests nvme/002 trips up debugobjects if CONFIG_NVME_AUTH is enabled, but authentication is not on a queue. This is because nvmet_auth_sq_free cancels sq->auth_expired_work unconditionaly, while auth_expired_work is only ever initialized if authentication is enabled for a given controller.
Fix this by calling most of what is nvmet_init_auth unconditionally when initializing the SQ, and just do the setting of the result field in the connect command handler.
--- drivers/nvme/target/core.c | 1 + drivers/nvme/target/fabrics-cmd-auth.c | 13 ++++--------- drivers/nvme/target/fabrics-cmd.c | 6 ++++-- drivers/nvme/target/nvmet.h | 7 ++++--- 4 files changed, 13 insertions(+), 14 deletions(-)
drivers/nvme/target/core.c +1 -0
@@ -832,6 +832,7 @@ int nvmet_sq_init(struct nvmet_sq *sq) }init_completion (&sq->free_done);init_completion (&sq->confirm_done); +nvmet_auth_sq_init (sq);return 0 ; }
drivers/nvme/target/fabrics-cmd-auth.c +4 -9
@@ -23,17 +23,12 @@ static void nvmet_auth_expired_work(struct work_struct *work) sq->dhchap_tid =-1 ; } -void nvmet_init_auth (struct nvmet_ctrl *ctrl,struct nvmet_req *req) +void nvmet_auth_sq_init (struct nvmet_sq *sq) { -u32 result =le32_to_cpu (req->cqe->result.u32); -/* Initialize in-band authentication */ -INIT_DELAYED_WORK (&req->sq->auth_expired_work, - nvmet_auth_expired_work); - req->sq->authenticated = false; - req->sq->dhchap_step =NVME_AUTH_DHCHAP_MESSAGE_NEGOTIATE ; - result |= (u32 )NVME_CONNECT_AUTHREQ_ATR <<16 ; - req->cqe->result.u32 =cpu_to_le32 (result); +INIT_DELAYED_WORK (&sq->auth_expired_work, nvmet_auth_expired_work); + sq->authenticated = false; + sq->dhchap_step =NVME_AUTH_DHCHAP_MESSAGE_NEGOTIATE ; }static u16 nvmet_auth_negotiate (struct nvmet_req *req,void *d)
drivers/nvme/target/fabrics-cmd.c +4 -2
@@ -272,7 +272,8 @@ static void nvmet_execute_admin_connect(struct nvmet_req *req) req->cqe->result.u16 =cpu_to_le16 (ctrl->cntlid);if (nvmet_has_auth (ctrl)) -nvmet_init_auth (ctrl, req); + req->cqe->result.u32 |= +cpu_to_le32 ((u32 )NVME_CONNECT_AUTHREQ_ATR <<16 ); out:kfree (d); complete:
@@ -334,7 +335,8 @@ static void nvmet_execute_io_connect(struct nvmet_req *req)pr_debug ("adding queue %d to ctrl %d.\n" , qid, ctrl->cntlid); req->cqe->result.u16 =cpu_to_le16 (ctrl->cntlid);if (nvmet_has_auth (ctrl)) -nvmet_init_auth (ctrl, req); + req->cqe->result.u32 |= +cpu_to_le32 ((u32 )NVME_CONNECT_AUTHREQ_ATR <<16 ); out:kfree (d);
drivers/nvme/target/nvmet.h +4 -3
@@ -704,7 +704,7 @@ int nvmet_auth_set_key(struct nvmet_host *host, const char *secret, bool set_ctrl);int nvmet_auth_set_host_hash (struct nvmet_host *host,const char *hash);int nvmet_setup_auth (struct nvmet_ctrl *ctrl); -void nvmet_init_auth (struct nvmet_ctrl *ctrl,struct nvmet_req *req); +void nvmet_auth_sq_init (struct nvmet_sq *sq);void nvmet_destroy_auth (struct nvmet_ctrl *ctrl);void nvmet_auth_sq_free (struct nvmet_sq *sq);int nvmet_setup_dhgroup (struct nvmet_ctrl *ctrl,u8 dhgroup_id);
@@ -726,8 +726,9 @@ static inline int nvmet_setup_auth(struct nvmet_ctrl *ctrl) {return 0 ; } -static inline void nvmet_init_auth (struct nvmet_ctrl *ctrl, -struct nvmet_req *req) {}; +static inline void nvmet_auth_sq_init (struct nvmet_sq *sq) +{ +}static inline void nvmet_destroy_auth (struct nvmet_ctrl *ctrl) {};static inline void nvmet_auth_sq_free (struct nvmet_sq *sq) {};static inline bool nvmet_check_auth_status (struct nvmet_req *req)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 571/862 RDMA/rxe: Set pd early in mr alloc routines
In reply to Greg Kroah-HartmanFrom: Bob Pearson <[email protected]>
[ Upstream commit 58651bbb30f87dab474eff31ab564391aa6ea1f3 ]
Move setting of pd in mr objects ahead of any possible errors so that it will always be set in rxe_mr_cleanup() to avoid seg faults when rxe_put(mr_pd(mr)) is called.
--- drivers/infiniband/sw/rxe/rxe_loc.h | 6 +++--- drivers/infiniband/sw/rxe/rxe_mr.c | 11 ++++------- drivers/infiniband/sw/rxe/rxe_verbs.c | 12 +++++++----- 3 files changed, 14 insertions(+), 15 deletions(-)
drivers/infiniband/sw/rxe/rxe_loc.h +3 -3
@@ -64,10 +64,10 @@ int rxe_mmap(struct ib_ucontext *context, struct vm_area_struct *vma);/* rxe_mr.c */ u8 rxe_get_next_key (u32 last_key); -void rxe_mr_init_dma (struct rxe_pd *pd,int access,struct rxe_mr *mr); -int rxe_mr_init_user (struct rxe_pd *pd,u64 start,u64 length,u64 iova, +void rxe_mr_init_dma (int access,struct rxe_mr *mr); +int rxe_mr_init_user (struct rxe_dev *rxe,u64 start,u64 length,u64 iova,int access,struct rxe_mr *mr); -int rxe_mr_init_fast (struct rxe_pd *pd,int max_pages,struct rxe_mr *mr); +int rxe_mr_init_fast (int max_pages,struct rxe_mr *mr);int rxe_mr_copy (struct rxe_mr *mr,u64 iova,void *addr,int length,enum rxe_mr_copy_dir dir); int copy_data(struct rxe_pd *pd, int access, struct rxe_dma_info *dma,
drivers/infiniband/sw/rxe/rxe_mr.c +4 -7
@@ -103,17 +103,16 @@ static int rxe_mr_alloc(struct rxe_mr *mr, int num_buf)return -ENOMEM ; } -void rxe_mr_init_dma (struct rxe_pd *pd,int access,struct rxe_mr *mr) +void rxe_mr_init_dma (int access,struct rxe_mr *mr) {rxe_mr_init (access, mr); - mr->ibmr.pd = &pd->ibpd; mr->access = access; mr->state =RXE_MR_STATE_VALID ; mr->type =IB_MR_TYPE_DMA ; } -int rxe_mr_init_user (struct rxe_pd *pd,u64 start,u64 length,u64 iova, +int rxe_mr_init_user (struct rxe_dev *rxe,u64 start,u64 length,u64 iova,int access,struct rxe_mr *mr) {struct rxe_map **map;
@@ -125,7 +124,7 @@ int rxe_mr_init_user(struct rxe_pd *pd, u64 start, u64 length, u64 iova,int err;int i; - umem =ib_umem_get (pd->ibpd.device, start, length, access); + umem =ib_umem_get (&rxe->ib_dev, start, length, access);if (IS_ERR (umem)) {pr_warn ("%s: Unable to pin memory region err = %d\n" , __func__, (int )PTR_ERR (umem));
@@ -175,7 +174,6 @@ int rxe_mr_init_user(struct rxe_pd *pd, u64 start, u64 length, u64 iova, } } - mr->ibmr.pd = &pd->ibpd; mr->umem = umem; mr->access = access; mr->length = length;
@@ -197,7 +195,7 @@ int rxe_mr_init_user(struct rxe_pd *pd, u64 start, u64 length, u64 iova,return err; } -int rxe_mr_init_fast (struct rxe_pd *pd,int max_pages,struct rxe_mr *mr) +int rxe_mr_init_fast (int max_pages,struct rxe_mr *mr) {int err;
@@ -208,7 +206,6 @@ int rxe_mr_init_fast(struct rxe_pd *pd, int max_pages, struct rxe_mr *mr)if (err) goto err1; - mr->ibmr.pd = &pd->ibpd; mr->max_buf = max_pages; mr->state =RXE_MR_STATE_FREE ; mr->type =IB_MR_TYPE_MEM_REG ;
drivers/infiniband/sw/rxe/rxe_verbs.c +7 -5
@@ -903,7 +903,9 @@ static struct ib_mr *rxe_get_dma_mr(struct ib_pd *ibpd, int access)return ERR_PTR (-ENOMEM );rxe_get (pd); -rxe_mr_init_dma (pd, access, mr); + mr->ibmr.pd = ibpd; + +rxe_mr_init_dma (access, mr);rxe_finalize (mr);return &mr->ibmr;
@@ -928,8 +930,9 @@ static struct ib_mr *rxe_reg_user_mr(struct ib_pd *ibpd,rxe_get (pd); + mr->ibmr.pd = ibpd; - err =rxe_mr_init_user (pd, start, length, iova, access, mr); + err =rxe_mr_init_user (rxe, start, length, iova, access, mr);if (err) goto err3;
@@ -938,7 +941,6 @@ static struct ib_mr *rxe_reg_user_mr(struct ib_pd *ibpd,return &mr->ibmr; err3: -rxe_put (pd);rxe_cleanup (mr); err2:return ERR_PTR (err);
@@ -962,8 +964,9 @@ static struct ib_mr *rxe_alloc_mr(struct ib_pd *ibpd, enum ib_mr_type mr_type, }rxe_get (pd); + mr->ibmr.pd = ibpd; - err =rxe_mr_init_fast (pd, max_num_sg, mr); + err =rxe_mr_init_fast (max_num_sg, mr);if (err) goto err2;
@@ -972,7 +975,6 @@ static struct ib_mr *rxe_alloc_mr(struct ib_pd *ibpd, enum ib_mr_type mr_type,return &mr->ibmr; err2: -rxe_put (pd);rxe_cleanup (mr); err1:return ERR_PTR (err);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 572/862 RDMA/rxe: Fix resize_finish() in rxe_queue.c
In reply to Greg Kroah-HartmanFrom: Bob Pearson <[email protected]>
[ Upstream commit fda5d0cf8aef12f0a4f714a96a4b2fce039a3e55 ]
Currently in resize_finish() in rxe_queue.c there is a loop which copies the entries in the original queue into a newly allocated queue. The termination logic for this loop is incorrect. The call to queue_next_index() updates cons but has no effect on whether the queue is empty. So if the queue starts out empty nothing is copied but if it is not then the loop will run forever. This patch changes the loop to compare the value of cons to the original producer index.
--- drivers/infiniband/sw/rxe/rxe_queue.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
drivers/infiniband/sw/rxe/rxe_queue.c +7 -5
@@ -112,23 +112,25 @@ static int resize_finish(struct rxe_queue *q, struct rxe_queue *new_q, unsigned int num_elem) {enum queue_type type = q->type; +u32 new_prod;u32 prod;u32 cons;if (!queue_empty (q, q->type) && (num_elem <queue_count (q, type)))return -EINVAL ; - prod =queue_get_producer (new_q, type); + new_prod =queue_get_producer (new_q, type); + prod =queue_get_producer (q, type); cons =queue_get_consumer (q, type); -while (!queue_empty (q, type)) { -memcpy (queue_addr_from_index (new_q, prod), +while ((prod - cons) & q->index_mask) { +memcpy (queue_addr_from_index (new_q, new_prod),queue_addr_from_index (q, cons), new_q->elem_size); - prod =queue_next_index (new_q, prod); + new_prod =queue_next_index (new_q, new_prod); cons =queue_next_index (q, cons); } - new_q->buf->producer_index = prod; + new_q->buf->producer_index = new_prod; q->buf->consumer_index = cons;/* update private index copies */
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 573/862 fsi: core: Check error number after calling ida_simple_get
In reply to Greg Kroah-HartmanFrom: Jiasheng Jiang <[email protected]>
[ Upstream commit 35af9fb49bc5c6d61ef70b501c3a56fe161cce3e ]
If allocation fails, the ida_simple_get() will return error number. So master->idx could be error number and be used in dev_set_name(). Therefore, it should be better to check it and return error if fails, like the ida_simple_get() in __fsi_get_new_minor().
--- drivers/fsi/fsi-core.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/fsi/fsi-core.c +3 -0
@@ -1314,6 +1314,9 @@ int fsi_master_register(struct fsi_master *master)mutex_init (&master->scan_lock); master->idx =ida_simple_get (&master_ida,0 ,INT_MAX ,GFP_KERNEL ); +if (master->idx <0 ) +return master->idx; +dev_set_name (&master->dev,"fsi%d" , master->idx); master->dev.class = &fsi_master_class;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 574/862 mfd: intel_soc_pmic: Fix an error handling path in intel_soc_pmic_i2c_probe()
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit 48749cabba109397b4e7dd556e85718ec0ec114d ]
The commit in Fixes: has added a pwm_add_table() call in the probe() and a pwm_remove_table() call in the remove(), but forget to update the error handling path of the probe.
Add the missing pwm_remove_table() call.
--- drivers/mfd/intel_soc_pmic_core.c | 1 + 1 file changed, 1 insertion(+)
drivers/mfd/intel_soc_pmic_core.c +1 -0
@@ -77,6 +77,7 @@ static int intel_soc_pmic_i2c_probe(struct i2c_client *i2c,return 0 ; err_del_irq_chip: +pwm_remove_table (crc_pwm_lookup,ARRAY_SIZE (crc_pwm_lookup));regmap_del_irq_chip (pmic->irq, pmic->irq_chip_data);return ret; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 575/862 mfd: fsl-imx25: Fix an error handling path in mx25_tsadc_setup_irq()
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit 3fa9e4cfb55da512ebfd57336fde468830719298 ]
If devm_of_platform_populate() fails, some resources need to be released.
Introduce a mx25_tsadc_unset_irq() function that undoes mx25_tsadc_setup_irq() and call it both from the new error handling path of the probe and in the remove function.
--- drivers/mfd/fsl-imx25-tsadc.c | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-)
drivers/mfd/fsl-imx25-tsadc.c +24 -8
@@ -84,6 +84,19 @@ static int mx25_tsadc_setup_irq(struct platform_device *pdev,return 0 ; } +static int mx25_tsadc_unset_irq (struct platform_device *pdev) +{ +struct mx25_tsadc *tsadc =platform_get_drvdata (pdev); +int irq =platform_get_irq (pdev,0 ); + +if (irq) { +irq_set_chained_handler_and_data (irq,NULL ,NULL ); +irq_domain_remove (tsadc->domain); + } + +return 0 ; +} +static void mx25_tsadc_setup_clk (struct platform_device *pdev,struct mx25_tsadc *tsadc) {
@@ -171,18 +184,21 @@ static int mx25_tsadc_probe(struct platform_device *pdev)platform_set_drvdata (pdev, tsadc); -return devm_of_platform_populate (dev); + ret =devm_of_platform_populate (dev); +if (ret) + goto err_irq; + +return 0 ; + +err_irq: +mx25_tsadc_unset_irq (pdev); + +return ret; }static int mx25_tsadc_remove (struct platform_device *pdev) { -struct mx25_tsadc *tsadc =platform_get_drvdata (pdev); -int irq =platform_get_irq (pdev,0 ); - -if (irq) { -irq_set_chained_handler_and_data (irq,NULL ,NULL ); -irq_domain_remove (tsadc->domain); - } +mx25_tsadc_unset_irq (pdev);return 0 ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 576/862 mfd: lp8788: Fix an error handling path in lp8788_probe()
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit becfdcd75126b20b8ec10066c5e85b34f8994ad5 ]
Should an error occurs in mfd_add_devices(), some resources need to be released, as already done in the .remove() function.
Add an error handling path and a lp8788_irq_exit() call to undo a previous lp8788_irq_init().
--- drivers/mfd/lp8788.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
drivers/mfd/lp8788.c +10 -2
@@ -195,8 +195,16 @@ static int lp8788_probe(struct i2c_client *cl, const struct i2c_device_id *id)if (ret)return ret; -return mfd_add_devices (lp->dev,-1 , lp8788_devs, -ARRAY_SIZE (lp8788_devs),NULL ,0 ,NULL ); + ret =mfd_add_devices (lp->dev,-1 , lp8788_devs, +ARRAY_SIZE (lp8788_devs),NULL ,0 ,NULL ); +if (ret) + goto err_exit_irq; + +return 0 ; + +err_exit_irq: +lp8788_irq_exit (lp); +return ret; }static int lp8788_remove (struct i2c_client *cl)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 577/862 mfd: lp8788: Fix an error handling path in lp8788_irq_init() and lp8788_irq_init()
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit 557244f6284f30613f2d61f14b579303165876c3 ]
In lp8788_irq_init(), if an error occurs after a successful irq_domain_add_linear() call, it must be undone by a corresponding irq_domain_remove() call.
irq_domain_remove() should also be called in lp8788_irq_exit() for the same reason.
--- drivers/mfd/lp8788-irq.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/mfd/lp8788-irq.c +3 -0
@@ -175,6 +175,7 @@ int lp8788_irq_init(struct lp8788 *lp, int irq)IRQF_TRIGGER_FALLING |IRQF_ONESHOT , "lp8788-irq", irqd);if (ret) { +irq_domain_remove (lp->irqdm);dev_err (lp->dev,"failed to create a thread for IRQ_N\n" );return ret; }
@@ -188,4 +189,6 @@ void lp8788_irq_exit(struct lp8788 *lp) {if (lp->irq)free_irq (lp->irq, lp->irqdm); +if (lp->irqdm) +irq_domain_remove (lp->irqdm); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 578/862 mfd: fsl-imx25: Fix check for platform_get_irq() errors
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit 75db7907355ca5e2ff606e9dd3e86b6c3a455fe2 ]
The mx25_tsadc_remove() function assumes all non-zero returns are success but the platform_get_irq() function returns negative on error and positive non-zero values on success. It never returns zero, but if it did then treat that as a success.
--- drivers/mfd/fsl-imx25-tsadc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/mfd/fsl-imx25-tsadc.c +2 -2
@@ -69,7 +69,7 @@ static int mx25_tsadc_setup_irq(struct platform_device *pdev,int irq; irq =platform_get_irq (pdev,0 ); -if (irq <=0 ) +if (irq <0 )return irq; tsadc->domain = irq_domain_add_simple(np, 2, 0, &mx25_tsadc_domain_ops,
@@ -89,7 +89,7 @@ static int mx25_tsadc_unset_irq(struct platform_device *pdev)struct mx25_tsadc *tsadc =platform_get_drvdata (pdev);int irq =platform_get_irq (pdev,0 ); -if (irq) { +if (irq >=0 ) {irq_set_chained_handler_and_data (irq,NULL ,NULL );irq_domain_remove (tsadc->domain); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 579/862 mfd: sm501: Add check for platform_driver_register()
In reply to Greg Kroah-HartmanFrom: Jiasheng Jiang <[email protected]>
[ Upstream commit 8325a6c24ad78b8c1acc3c42b098ee24105d68e5 ]
As platform_driver_register() can return error numbers, it should be better to check platform_driver_register() and deal with the exception.
--- drivers/mfd/sm501.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/mfd/sm501.c +6 -1
@@ -1720,7 +1720,12 @@ static struct platform_driver sm501_plat_driver = {static int __init sm501_base_init (void ) { -platform_driver_register (&sm501_plat_driver); +int ret; + + ret =platform_driver_register (&sm501_plat_driver); +if (ret <0 ) +return ret; +return pci_register_driver (&sm501_pci_driver); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 580/862 mfd: da9061: Fix Failed to set Two-Wire Bus Mode.
In reply to Greg Kroah-HartmanFrom: Jens Hillenstedt <[email protected]>
[ Upstream commit 834382ea32865a4bdeae83ec2dcb9321dc9489f2 ]
In da9062_i2c_probe() regmap_clear_bits() tries to access CONFIG_J register. As CONFIG_J is not present in da9061_aa_writeable_ranges[] probe of da9061 fails:
da9062 2-0058: Entering I2C mode!
da9062 2-0058: Failed to set Two-Wire Bus Mode.
da9062: probe of 2-0058 failed with error -5
Add CONFIG_J register to da9061_aa_writeable_ranges[].
--- drivers/mfd/da9062-core.c | 1 + 1 file changed, 1 insertion(+)
drivers/mfd/da9062-core.c +1 -0
@@ -453,6 +453,7 @@ static const struct regmap_range da9061_aa_writeable_ranges[] = {regmap_reg_range (DA9062AA_VBUCK1_B ,DA9062AA_VBUCK4_B ),regmap_reg_range (DA9062AA_VBUCK3_B ,DA9062AA_VBUCK3_B ),regmap_reg_range (DA9062AA_VLDO1_B ,DA9062AA_VLDO4_B ), +regmap_reg_range (DA9062AA_CONFIG_J ,DA9062AA_CONFIG_J ), regmap_reg_range(DA9062AA_GP_ID_0, DA9062AA_GP_ID_19), };
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 581/862 clk: mediatek: mt8183: mfgcfg: Propagate rate changes to parent
In reply to Greg Kroah-HartmanFrom: Chen-Yu Tsai <[email protected]>
[ Upstream commit 9f94f545f258b15bfa6357eb62e1e307b712851e ]
The only clock in the MT8183 MFGCFG block feeds the GPU. Propagate its rate change requests to its parent, so that DVFS for the GPU can work properly.
--- drivers/clk/mediatek/clk-mt8183-mfgcfg.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/clk/mediatek/clk-mt8183-mfgcfg.c +3 -3
@@ -18,9 +18,9 @@ static const struct mtk_gate_regs mfg_cg_regs = { .sta_ofs = 0x0, }; -#define GATE_MFG (_id, _name, _parent, _shift) \ - GATE_MTK(_id, _name, _parent, &mfg_cg_regs, _shift, \ - &mtk_clk_gate_ops_setclr) +#define GATE_MFG (_id, _name, _parent, _shift) \ + GATE_MTK_FLAGS(_id, _name, _parent, &mfg_cg_regs, _shift, \ + &mtk_clk_gate_ops_setclr, CLK_SET_RATE_PARENT)static const struct mtk_gate mfg_clks[] = {GATE_MFG (CLK_MFG_BG3D ,"mfg_bg3d" ,"mfg_sel" ,0 )
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 582/862 clk: mediatek: clk-mt8195-mfg: Reparent mfg_bg3d and propagate rate changes
In reply to Greg Kroah-HartmanFrom: AngeloGioacchino Del Regno <[email protected]>
[ Upstream commit a5f7bf5458c2cf6730106e16a6373638a0e5ed1e ]
The MFG_BG3D is a gate to enable/disable clock output to the GPU, but the actual output is decided by multiple muxes; in particular:mfg_ck_fast_ref muxes between "slow" (top_mfg_core_tmp) and "fast" (MFGPLL) clock, while top_mfg_core_tmp muxes between the 26MHz clock and various system PLLs.
The clock gate comes after all the muxes, so its parent is mfg_ck_fast_reg, not top_mfg_core_tmp.
Reparent MFG_BG3D to the latter to match the hardware and add the CLK_SET_RATE_PARENT flag to it: this way we ensure propagating rate changes that are requested on MFG_BG3D along its entire clock tree.
--- drivers/clk/mediatek/clk-mt8195-mfg.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/clk/mediatek/clk-mt8195-mfg.c +4 -2
@@ -17,10 +17,12 @@ static const struct mtk_gate_regs mfg_cg_regs = { };#define GATE_MFG (_id, _name, _parent, _shift) \ - GATE_MTK(_id, _name, _parent, &mfg_cg_regs, _shift, &mtk_clk_gate_ops_setclr) + GATE_MTK_FLAGS(_id, _name, _parent, &mfg_cg_regs, \ + _shift, &mtk_clk_gate_ops_setclr, \ + CLK_SET_RATE_PARENT)static const struct mtk_gate mfg_clks[] = { -GATE_MFG (CLK_MFG_BG3D ,"mfg_bg3d" ,"top_mfg_core_tmp" ,0 ), +GATE_MFG (CLK_MFG_BG3D ,"mfg_bg3d" ,"mfg_ck_fast_ref" ,0 ), };static const struct mtk_clk_desc mfg_desc = {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 583/862 clk: mediatek: fix unregister function in mtk_clk_register_dividers cleanup
In reply to Greg Kroah-HartmanFrom: Chen-Yu Tsai <[email protected]>
[ Upstream commit 20f7a0dba9075fb0e3d645495bc24d7025b58de1 ]
When the cleanup paths for the various clk register APIs in the MediaTek clk library were added, the one in the dividers type used the wrong type of unregister function. This would result in incorrect dereferencing of the clk pointer and freeing of invalid pointers.
Fix this by switching to the correct type of clk unregistration call.
--- drivers/clk/mediatek/clk-mtk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/clk/mediatek/clk-mtk.c +1 -1
@@ -393,7 +393,7 @@ int mtk_clk_register_dividers(const struct mtk_clk_divider *mcds, int num,if (IS_ERR_OR_NULL (clk_data->hws[mcd->id]))continue ; -mtk_clk_unregister_composite (clk_data->hws[mcd->id]); +clk_hw_unregister_divider (clk_data->hws[mcd->id]); clk_data->hws[mcd->id] =ERR_PTR (-ENOENT ); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 584/862 clk: mediatek: Migrate remaining clk_unregister_*() to clk_hw_unregister_*()
In reply to Greg Kroah-HartmanFrom: Chen-Yu Tsai <[email protected]>
[ Upstream commit fef14676fc4be40b8441745a3c96b7e7d7d8592d ]
During the previous |struct clk| to |struct clk_hw| clk provider API migration in commit 6f691a586296 ("clk: mediatek: Switch to clk_hw provider APIs"), a few clk_unregister_*() calls were missed.
Migrate the remaining ones to the |struct clk_hw| provider API, i.e. change clk_unregister_*() to clk_hw_unregister_*().
--- drivers/clk/mediatek/clk-mtk.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/clk/mediatek/clk-mtk.c +5 -5
@@ -80,7 +80,7 @@ int mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks, int num,if (IS_ERR_OR_NULL (clk_data->hws[rc->id]))continue ; -clk_unregister_fixed_rate (clk_data->hws[rc->id]->clk); +clk_hw_unregister_fixed_rate (clk_data->hws[rc->id]); clk_data->hws[rc->id] =ERR_PTR (-ENOENT ); }
@@ -102,7 +102,7 @@ void mtk_clk_unregister_fixed_clks(const struct mtk_fixed_clk *clks, int num,if (IS_ERR_OR_NULL (clk_data->hws[rc->id]))continue ; -clk_unregister_fixed_rate (clk_data->hws[rc->id]->clk); +clk_hw_unregister_fixed_rate (clk_data->hws[rc->id]); clk_data->hws[rc->id] =ERR_PTR (-ENOENT ); } }
@@ -146,7 +146,7 @@ int mtk_clk_register_factors(const struct mtk_fixed_factor *clks, int num,if (IS_ERR_OR_NULL (clk_data->hws[ff->id]))continue ; -clk_unregister_fixed_factor (clk_data->hws[ff->id]->clk); +clk_hw_unregister_fixed_factor (clk_data->hws[ff->id]); clk_data->hws[ff->id] =ERR_PTR (-ENOENT ); }
@@ -168,7 +168,7 @@ void mtk_clk_unregister_factors(const struct mtk_fixed_factor *clks, int num,if (IS_ERR_OR_NULL (clk_data->hws[ff->id]))continue ; -clk_unregister_fixed_factor (clk_data->hws[ff->id]->clk); +clk_hw_unregister_fixed_factor (clk_data->hws[ff->id]); clk_data->hws[ff->id] =ERR_PTR (-ENOENT ); } }
@@ -414,7 +414,7 @@ void mtk_clk_unregister_dividers(const struct mtk_clk_divider *mcds, int num,if (IS_ERR_OR_NULL (clk_data->hws[mcd->id]))continue ; -clk_unregister_divider (clk_data->hws[mcd->id]->clk); +clk_hw_unregister_divider (clk_data->hws[mcd->id]); clk_data->hws[mcd->id] =ERR_PTR (-ENOENT ); } }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 585/862 phy: qcom-qmp-pcie: fix resource mapping for SDM845 QHP PHY
In reply to Greg Kroah-HartmanFrom: Dmitry Baryshkov <[email protected]>
[ Upstream commit 0a40891b83f257b25a2b983758f72f6813f361cb ]
On SDM845 one of PCIe PHYs (the QHP one) has the same region for TX and RX registers. Since the commit 4be26f695ffa ("phy: qcom-qmp-pcie: fix memleak on probe deferral") added checking that resources are not allocated beforehand, this PHY can not be probed anymore. Fix this by skipping the map of ->rx resource on the QHP PHY and assign it manually.
--- drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/phy/qualcomm/phy-qcom-qmp-pcie.c +4 -1
@@ -2333,7 +2333,10 @@ int qcom_qmp_phy_pcie_create(struct device *dev, struct device_node *np, int id,if (IS_ERR (qphy->tx))return PTR_ERR (qphy->tx); - qphy->rx =devm_of_iomap (dev, np,1 ,NULL ); +if (of_device_is_compatible (dev->of_node,"qcom,sdm845-qhp-pcie-phy" )) + qphy->rx = qphy->tx; +else + qphy->rx =devm_of_iomap (dev, np,1 ,NULL );if (IS_ERR (qphy->rx))return PTR_ERR (qphy->rx);
Signature · 1 line
2.35.1
Re: [PATCH 6.0 585/862] phy: qcom-qmp-pcie: fix resource mapping for SDM845 QHP PHY
Quoted 11 lines · Greg Kroah-Hartman
From: Dmitry Baryshkov <[email protected]>
[ Upstream commit
0a40891b83f257b25a2b983758f72f6813f361cb]On SDM845 one of PCIe PHYs (the QHP one) has the same region for TX and RX registers. Since the commit
4be26f695ffa("phy: qcom-qmp-pcie: fix memleak on probe deferral") added checking that resources are not allocated beforehand, this PHY can not be probed anymore. Fix this by skipping the map of ->rx resource on the QHP PHY and assign it manually.Fixes 4be26f695ffa ("phy: qcom-qmp-pcie: fix memleak on probe deferral")
This one is not needed in 6.0 since the offending commit should not be backported.
Quoted 5 lines
Signed-off-by Dmitry Baryshkov <[email protected]>Reviewed-by Johan Hovold <[email protected]>Signed-off-by Vinod Koul <[email protected]>Signed-off-by Sasha Levin <[email protected]>
Johan
Greg Kroah-Hartman
maintainerPATCH 586/862 io_uring/rw: defer fsnotify calls to task context
In reply to Greg Kroah-HartmanFrom: Jens Axboe <[email protected]>
[ Upstream commit b000145e9907809406d8164c3b2b8861d95aecd1 ]
We can't call these off the kiocb completion as that might be off soft/hard irq context. Defer the calls to when we process the task_work for this request. That avoids valid complaints like:
stack backtrace: CPU: 1 PID: 0 Comm: swapper/1 Not tainted 6.0.0-rc6-syzkaller-00321-g105a36f3694e #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 08/26/2022 Call Trace: <IRQ> __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0xcd/0x134 lib/dump_stack.c:106 print_usage_bug kernel/locking/lockdep.c:3961 [inline] valid_state kernel/locking/lockdep.c:3973 [inline] mark_lock_irq kernel/locking/lockdep.c:4176 [inline] mark_lock.part.0.cold+0x18/0xd8 kernel/locking/lockdep.c:4632 mark_lock kernel/locking/lockdep.c:4596 [inline] mark_usage kernel/locking/lockdep.c:4527 [inline] __lock_acquire+0x11d9/0x56d0 kernel/locking/lockdep.c:5007 lock_acquire kernel/locking/lockdep.c:5666 [inline] lock_acquire+0x1ab/0x570 kernel/locking/lockdep.c:5631 __fs_reclaim_acquire mm/page_alloc.c:4674 [inline] fs_reclaim_acquire+0x115/0x160 mm/page_alloc.c:4688 might_alloc include/linux/sched/mm.h:271 [inline] slab_pre_alloc_hook mm/slab.h:700 [inline] slab_alloc mm/slab.c:3278 [inline] __kmem_cache_alloc_lru mm/slab.c:3471 [inline] kmem_cache_alloc+0x39/0x520 mm/slab.c:3491 fanotify_alloc_fid_event fs/notify/fanotify/fanotify.c:580 [inline] fanotify_alloc_event fs/notify/fanotify/fanotify.c:813 [inline] fanotify_handle_event+0x1130/0x3f40 fs/notify/fanotify/fanotify.c:948 send_to_group fs/notify/fsnotify.c:360 [inline] fsnotify+0xafb/0x1680 fs/notify/fsnotify.c:570 __fsnotify_parent+0x62f/0xa60 fs/notify/fsnotify.c:230 fsnotify_parent include/linux/fsnotify.h:77 [inline] fsnotify_file include/linux/fsnotify.h:99 [inline] fsnotify_access include/linux/fsnotify.h:309 [inline] __io_complete_rw_common+0x485/0x720 io_uring/rw.c:195 io_complete_rw+0x1a/0x1f0 io_uring/rw.c:228 iomap_dio_complete_work fs/iomap/direct-io.c:144 [inline] iomap_dio_bio_end_io+0x438/0x5e0 fs/iomap/direct-io.c:178 bio_endio+0x5f9/0x780 block/bio.c:1564 req_bio_endio block/blk-mq.c:695 [inline] blk_update_request+0x3fc/0x1300 block/blk-mq.c:825 scsi_end_request+0x7a/0x9a0 drivers/scsi/scsi_lib.c:541 scsi_io_completion+0x173/0x1f70 drivers/scsi/scsi_lib.c:971 scsi_complete+0x122/0x3b0 drivers/scsi/scsi_lib.c:1438 blk_complete_reqs+0xad/0xe0 block/blk-mq.c:1022 __do_softirq+0x1d3/0x9c6 kernel/softirq.c:571 invoke_softirq kernel/softirq.c:445 [inline] __irq_exit_rcu+0x123/0x180 kernel/softirq.c:650 irq_exit_rcu+0x5/0x20 kernel/softirq.c:662 common_interrupt+0xa9/0xc0 arch/x86/kernel/irq.c:240
--- io_uring/rw.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-)
io_uring/rw.c +15 -9
@@ -186,14 +186,6 @@ static void kiocb_end_write(struct io_kiocb *req)static bool __io_complete_rw_common (struct io_kiocb *req,long res) { - struct io_rw *rw = io_kiocb_to_cmd(req, struct io_rw); - -if (rw->kiocb.ki_flags &IOCB_WRITE ) { -kiocb_end_write (req); -fsnotify_modify (req->file); - }else { -fsnotify_access (req->file); - }if (unlikely (res != req->cqe.res)) {if ((res == -EAGAIN || res == -EOPNOTSUPP ) &&io_rw_should_reissue (req)) {
@@ -220,6 +212,20 @@ static inline int io_fixup_rw_res(struct io_kiocb *req, long res)return res; } +static void io_req_rw_complete (struct io_kiocb *req,bool *locked) +{ + struct io_rw *rw = io_kiocb_to_cmd(req, struct io_rw); + +if (rw->kiocb.ki_flags &IOCB_WRITE ) { +kiocb_end_write (req); +fsnotify_modify (req->file); + }else { +fsnotify_access (req->file); + } + +io_req_task_complete (req, locked); +} +static void io_complete_rw (struct kiocb *kiocb,long res) { struct io_rw *rw = container_of(kiocb, struct io_rw, kiocb);
@@ -228,7 +234,7 @@ static void io_complete_rw(struct kiocb *kiocb, long res)if (__io_complete_rw_common (req, res))return ;io_req_set_res (req,io_fixup_rw_res (req, res),0 ); - req->io_task_work.func = io_req_task_complete; + req->io_task_work.func = io_req_rw_complete;io_req_task_work_add (req); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 587/862 dmaengine: ioat: stop mod_timer from resurrecting deleted timer in __cleanup()
In reply to Greg Kroah-HartmanFrom: Dave Jiang <[email protected]>
[ Upstream commit 898ec89dbb55b8294695ad71694a0684e62b2a73 ]
User reports observing timer event report channel halted but no error observed in CHANERR register. The driver finished self-test and released channel resources. Debug shows that __cleanup() can call mod_timer() after the timer has been deleted and thus resurrect the timer. While harmless, it causes suprious error message to be emitted. Use mod_timer_pending() call to prevent deleted timer from being resurrected.
--- drivers/dma/ioat/dma.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/dma/ioat/dma.c +3 -3
@@ -656,7 +656,7 @@ static void __cleanup(struct ioatdma_chan *ioat_chan, dma_addr_t phys_complete)if (active - i ==0 ) {dev_dbg (to_dev (ioat_chan),"%s: cancel completion timeout\n" , __func__); -mod_timer (&ioat_chan->timer, jiffies +IDLE_TIMEOUT ); +mod_timer_pending (&ioat_chan->timer, jiffies +IDLE_TIMEOUT ); }/* microsecond delay by sysfs variable per pending descriptor */
@@ -682,7 +682,7 @@ static void ioat_cleanup(struct ioatdma_chan *ioat_chan)if (chanerr & (IOAT_CHANERR_HANDLE_MASK |IOAT_CHANERR_RECOVER_MASK )) { -mod_timer (&ioat_chan->timer, jiffies +IDLE_TIMEOUT ); +mod_timer_pending (&ioat_chan->timer, jiffies +IDLE_TIMEOUT );ioat_eh (ioat_chan); } }
@@ -879,7 +879,7 @@ static void check_active(struct ioatdma_chan *ioat_chan) }if (test_and_clear_bit (IOAT_CHAN_ACTIVE , &ioat_chan->state)) -mod_timer (&ioat_chan->timer, jiffies +IDLE_TIMEOUT ); +mod_timer_pending (&ioat_chan->timer, jiffies +IDLE_TIMEOUT ); }static void ioat_reboot_chan (struct ioatdma_chan *ioat_chan)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 588/862 HID: amd_sfh: Handle condition of "no sensors" for SFH1.1
In reply to Greg Kroah-HartmanFrom: Basavaraj Natikar <[email protected]>
[ Upstream commit 68266bdcceec10ea364e62c63732cd6fe5a256a8 ]
Based on num_hid_devices, each sensor device registers to HID. If "no sensors" then amd_sfh work initialization and scheduling doesn’t make sense and return ENODEV to stop driver probe. Hence add a check for num_hid_devices to handle special case in the situation of "no sensors" for SFH1.1.
--- drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c +2 -0
@@ -110,6 +110,8 @@ static int amd_sfh1_1_hid_client_init(stamd_sfh1_1_set_desc_ops (mp2_ops); cl_data->num_hid_devices =amd_sfh_get_sensor_num (privdata, &cl_data->sensor_idx[0 ]); +if (cl_data->num_hid_devices ==0 ) +return -ENODEV ;INIT_DELAYED_WORK (&cl_data->work, amd_sfh_work);INIT_DELAYED_WORK (&cl_data->work_buffer, amd_sfh_work_buffer);
Greg Kroah-Hartman
maintainerPATCH 589/862 usb: mtu3: fix failed runtime suspend in host only mode
In reply to Greg Kroah-HartmanFrom: Chunfeng Yun <[email protected]>
[ Upstream commit 1c703e29da5efac6180e4c189029fa34b7e48e97 ]
When the dr_mode is "host", after the host enter runtime suspend, the mtu3 can't do it, because the mtu3's device wakeup function is not enabled, instead it's enabled in gadget init function, to fix the issue, init wakeup early in mtu3's probe()
--- drivers/usb/mtu3/mtu3_core.c | 2 -- drivers/usb/mtu3/mtu3_plat.c | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-)
drivers/usb/mtu3/mtu3_core.c +0 -2
@@ -978,8 +978,6 @@ int ssusb_gadget_init(struct ssusb_mtk *ssusb) goto irq_err; } -device_init_wakeup (dev, true); -/* power down device IP for power saving by default */ mtu3_stop (mtu);
drivers/usb/mtu3/mtu3_plat.c +2 -0
@@ -356,6 +356,8 @@ static int mtu3_probe(struct platform_device *pdev)pm_runtime_enable (dev);pm_runtime_get_sync (dev); +device_init_wakeup (dev, true); + ret =ssusb_rscs_init (ssusb);if (ret) goto comm_init_err;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 590/862 spmi: pmic-arb: correct duplicate APID to PPID mapping logic
In reply to Greg Kroah-HartmanFrom: David Collins <[email protected]>
[ Upstream commit 1f1693118c2476cb1666ad357edcf3cf48bf9b16 ]
Correct the way that duplicate PPID mappings are handled for PMIC arbiter v5. The final APID mapped to a given PPID should be the one which has write owner = APPS EE, if it exists, or if not that, then the first APID mapped to the PPID, if it exists.
--- drivers/spmi/spmi-pmic-arb.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
drivers/spmi/spmi-pmic-arb.c +7 -6
@@ -992,7 +992,8 @@ static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb *pmic_arb)* version 5, there is more than one APID mapped to each PPID. * The owner field for each of these mappings specifies the EE which is * allowed to write to the APID. The owner of the last (highest) APID -* for a given PPID will receive interrupts from the PPID. +* which has the IRQ owner bit set for a given PPID will receive +* interrupts from the PPID. */ for (i =0 ; ; i++, apidd++) { offset = pmic_arb->ver_ops->apid_map_offset (i);
@@ -1015,16 +1016,16 @@ static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb *pmic_arb) apid = pmic_arb->ppid_to_apid[ppid] & ~PMIC_ARB_APID_VALID ; prev_apidd = &pmic_arb->apid_data[apid]; -if (valid && is_irq_ee && - prev_apidd->write_ee == pmic_arb->ee) { +if (!valid || apidd->write_ee == pmic_arb->ee) { +/* First PPID mapping or one for this EE */ + pmic_arb->ppid_to_apid[ppid] = i |PMIC_ARB_APID_VALID ; + }else if (valid && is_irq_ee && + prev_apidd->write_ee == pmic_arb->ee) {/* * Duplicate PPID mapping after the one for this EE; * override the irq owner */ prev_apidd->irq_ee = apidd->irq_ee; - }else if (!valid || is_irq_ee) { -/* First PPID mapping or duplicate for another EE */ - pmic_arb->ppid_to_apid[ppid] = i |PMIC_ARB_APID_VALID ; } apidd->ppid = ppid;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 591/862 clk: vc5: Fix 5P49V6901 outputs disabling when enabling FOD
In reply to Greg Kroah-HartmanFrom: Serge Semin <[email protected]>
[ Upstream commit c388cc804016cf0f65afdc2362b120aa594ff3e6 ]
We have discovered random glitches during the system boot up procedure. The problem investigation led us to the weird outcomes: when none of the Renesas 5P49V6901 ports are explicitly enabled by the kernel driver, the glitches disappeared. It was a mystery since the SoC external clock domains were fed with different 5P49V6901 outputs. The driver code didn't seem like bogus either. We almost despaired to find out a root cause when the solution has been found for a more modern revision of the chip. It turned out the 5P49V6901 clock generator stopped its output for a short period of time during the VC5_OUT_DIV_CONTROL register writing. The same problem was found for the 5P49V6965 revision of the chip and was successfully fixed in commit fc336ae622df ("clk: vc5: fix output disabling when enabling a FOD") by enabling the "bypass_sync" flag hidden inside "Unused Factory Reserved Register". Even though the 5P49V6901 registers description and programming guide doesn't provide any intel regarding that flag, setting it up anyway in the officially unused register completely eliminated the denoted glitches. Thus let's activate the functionality submitted in commit fc336ae622df ("clk: vc5: fix output disabling when enabling a FOD") for the Renesas 5P49V6901 chip too in order to remove the ports implicit inter-dependency.
--- drivers/clk/clk-versaclock5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/clk/clk-versaclock5.c +1 -1
@@ -1204,7 +1204,7 @@ static const struct vc5_chip_info idt_5p49v6901_info = { .model = IDT_VC6_5P49V6901, .clk_fod_cnt = 4, .clk_out_cnt = 5, - .flags = VC5_HAS_PFD_FREQ_DBL, + .flags = VC5_HAS_PFD_FREQ_DBL | VC5_HAS_BYPASS_SYNC_BIT, };static const struct vc5_chip_info idt_5p49v6965_info = {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 592/862 clk: baikal-t1: Fix invalid xGMAC PTP clock divider
In reply to Greg Kroah-HartmanFrom: Serge Semin <[email protected]>
[ Upstream commit 3c742088686ce922704aec5b11d09bcc5a396589 ]
Most likely due to copy-paste mistake the divider has been set to 10 while according to the SoC reference manual it's supposed to be 8 thus having PTP clock frequency of 156.25 MHz.
--- drivers/clk/baikal-t1/clk-ccu-div.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/clk/baikal-t1/clk-ccu-div.c +1 -1
@@ -207,7 +207,7 @@ static const struct ccu_div_info sys_info[] = {CCU_DIV_GATE_INFO (CCU_SYS_XGMAC_REF_CLK ,"sys_xgmac_ref_clk" ,"eth_clk" ,CCU_SYS_XGMAC_BASE ,8 ),CCU_DIV_FIXED_INFO (CCU_SYS_XGMAC_PTP_CLK ,"sys_xgmac_ptp_clk" , -"eth_clk" ,10 ), +"eth_clk" ,8 ),CCU_DIV_GATE_INFO (CCU_SYS_USB_CLK ,"sys_usb_clk" ,"eth_clk" ,CCU_SYS_USB_BASE ,10 ), CCU_DIV_VAR_INFO(CCU_SYS_PVT_CLK, "sys_pvt_clk",
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 593/862 clk: baikal-t1: Add shared xGMAC ref/ptp clocks internal parent
In reply to Greg Kroah-HartmanFrom: Serge Semin <[email protected]>
[ Upstream commit e2eef312762e0b5a5a70d29fe59a245c0a3cffa0 ]
Baikal-T1 CCU reference manual says that both xGMAC reference and xGMAC PTP clocks are generated by two different wrappers with the same constant divider thus each producing a 156.25 MHz signal. But for some reason both of these clock sources are gated by a single switch-flag in the CCU registers space - CCU_SYS_XGMAC_BASE.BIT(0). In order to make the clocks handled independently we need to define a shared parental gate so the base clock signal would be switched off only if both of the child-clocks are disabled.
Note the ID is intentionally set to -2 since we are going to add a one more internal clock identifier in the next commit.
--- drivers/clk/baikal-t1/ccu-div.c | 1 + drivers/clk/baikal-t1/ccu-div.h | 6 ++++++ drivers/clk/baikal-t1/clk-ccu-div.c | 8 +++++--- 3 files changed, 12 insertions(+), 3 deletions(-)
drivers/clk/baikal-t1/ccu-div.c +1 -0
@@ -579,6 +579,7 @@ struct ccu_div *ccu_div_hw_register(const struct ccu_div_init_data *div_init) goto err_free_div; } parent_data.fw_name = div_init->parent_name; + parent_data.name = div_init->parent_name; hw_init.parent_data = &parent_data; hw_init.num_parents =1 ;
drivers/clk/baikal-t1/ccu-div.h +6 -0
@@ -13,6 +13,12 @@#include <linux/bits.h> #include <linux/of.h> +/* +* CCU Divider private clock IDs +* @CCU_SYS_XGMAC_CLK: CCU XGMAC internal clock +*/ +#define CCU_SYS_XGMAC_CLK -2 +/* * CCU Divider private flags * @CCU_DIV_SKIP_ONE: Due to some reason divider can't be set to 1.
drivers/clk/baikal-t1/clk-ccu-div.c +5 -3
@@ -204,10 +204,12 @@ static const struct ccu_div_info sys_info[] = { "eth_clk", CCU_SYS_GMAC1_BASE, 5),CCU_DIV_FIXED_INFO (CCU_SYS_GMAC1_PTP_CLK ,"sys_gmac1_ptp_clk" ,"eth_clk" ,10 ), -CCU_DIV_GATE_INFO (CCU_SYS_XGMAC_REF_CLK ,"sys_xgmac_ref_clk" , -"eth_clk" ,CCU_SYS_XGMAC_BASE ,8 ), +CCU_DIV_GATE_INFO (CCU_SYS_XGMAC_CLK ,"sys_xgmac_clk" , +"eth_clk" ,CCU_SYS_XGMAC_BASE ,1 ), +CCU_DIV_FIXED_INFO (CCU_SYS_XGMAC_REF_CLK ,"sys_xgmac_ref_clk" , +"sys_xgmac_clk" ,8 ),CCU_DIV_FIXED_INFO (CCU_SYS_XGMAC_PTP_CLK ,"sys_xgmac_ptp_clk" , -"eth_clk" ,8 ), +"sys_xgmac_clk" ,8 ),CCU_DIV_GATE_INFO (CCU_SYS_USB_CLK ,"sys_usb_clk" ,"eth_clk" ,CCU_SYS_USB_BASE ,10 ), CCU_DIV_VAR_INFO(CCU_SYS_PVT_CLK, "sys_pvt_clk",
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 594/862 clk: baikal-t1: Add SATA internal ref clock buffer
In reply to Greg Kroah-HartmanFrom: Serge Semin <[email protected]>
[ Upstream commit 081a9b7c74eae4e12b2cb1b86720f836a8f29247 ]
It turns out the internal SATA reference clock signal will stay unavailable for the SATA interface consumer until the buffer on it's way is ungated. So aside with having the actual clock divider enabled we need to ungate a buffer placed on the signal way to the SATA controller (most likely some rudiment from the initial SoC release). Seeing the switch flag is placed in the same register as the SATA-ref clock divider at a non-standard ffset, let's implement it as a separate clock controller with the set-rate propagation to the parental clock divider wrapper. As such we'll be able to disable/enable and still change the original clock source rate.
--- drivers/clk/baikal-t1/ccu-div.c | 64 +++++++++++++++++++++++++++++ drivers/clk/baikal-t1/ccu-div.h | 4 ++ drivers/clk/baikal-t1/clk-ccu-div.c | 18 +++++++- 3 files changed, 85 insertions(+), 1 deletion(-)
drivers/clk/baikal-t1/ccu-div.c +64 -0
@@ -34,6 +34,7 @@#define CCU_DIV_CTL_CLKDIV_MASK (_width) \ GENMASK((_width) + CCU_DIV_CTL_CLKDIV_FLD - 1, CCU_DIV_CTL_CLKDIV_FLD)#define CCU_DIV_CTL_LOCK_SHIFTED BIT(27) +#define CCU_DIV_CTL_GATE_REF_BUF BIT(28)#define CCU_DIV_CTL_LOCK_NORMAL BIT(31)#define CCU_DIV_RST_DELAY_US 1
@@ -170,6 +171,40 @@ static int ccu_div_gate_is_enabled(struct clk_hw *hw)return !!(val &CCU_DIV_CTL_EN ); } +static int ccu_div_buf_enable (struct clk_hw *hw) +{ +struct ccu_div *div =to_ccu_div (hw); +unsigned long flags; + +spin_lock_irqsave (&div->lock, flags); +regmap_update_bits (div->sys_regs, div->reg_ctl, +CCU_DIV_CTL_GATE_REF_BUF ,0 ); +spin_unlock_irqrestore (&div->lock, flags); + +return 0 ; +} + +static void ccu_div_buf_disable (struct clk_hw *hw) +{ +struct ccu_div *div =to_ccu_div (hw); +unsigned long flags; + +spin_lock_irqsave (&div->lock, flags); +regmap_update_bits (div->sys_regs, div->reg_ctl, +CCU_DIV_CTL_GATE_REF_BUF ,CCU_DIV_CTL_GATE_REF_BUF ); +spin_unlock_irqrestore (&div->lock, flags); +} + +static int ccu_div_buf_is_enabled (struct clk_hw *hw) +{ +struct ccu_div *div =to_ccu_div (hw); +u32 val =0 ; + +regmap_read (div->sys_regs, div->reg_ctl, &val); + +return !(val &CCU_DIV_CTL_GATE_REF_BUF ); +} +static unsigned long ccu_div_var_recalc_rate (struct clk_hw *hw,unsigned long parent_rate) {
@@ -323,6 +358,7 @@ static const struct ccu_div_dbgfs_bit ccu_div_bits[] = {CCU_DIV_DBGFS_BIT_ATTR ("div_en" ,CCU_DIV_CTL_EN ),CCU_DIV_DBGFS_BIT_ATTR ("div_rst" ,CCU_DIV_CTL_RST ),CCU_DIV_DBGFS_BIT_ATTR ("div_bypass" ,CCU_DIV_CTL_SET_CLKDIV ), +CCU_DIV_DBGFS_BIT_ATTR ("div_buf" ,CCU_DIV_CTL_GATE_REF_BUF ), CCU_DIV_DBGFS_BIT_ATTR("div_lock", CCU_DIV_CTL_LOCK_NORMAL) };
@@ -441,6 +477,9 @@ static void ccu_div_var_debug_init(struct clk_hw *hw, struct dentry *dentry)continue ; } +if (!strcmp ("div_buf" , name)) +continue ; + bits[didx] = ccu_div_bits[bidx]; bits[didx].div = div;
@@ -477,6 +516,21 @@ static void ccu_div_gate_debug_init(struct clk_hw *hw, struct dentry *dentry) &ccu_div_dbgfs_fixed_clkdiv_fops); } +static void ccu_div_buf_debug_init (struct clk_hw *hw,struct dentry *dentry) +{ +struct ccu_div *div =to_ccu_div (hw); +struct ccu_div_dbgfs_bit *bit; + + bit =kmalloc (sizeof (*bit),GFP_KERNEL ); +if (!bit) +return ; + + *bit = ccu_div_bits[3 ]; + bit->div = div; +debugfs_create_file_unsafe (bit->name, ccu_div_dbgfs_mode, dentry, bit, + &ccu_div_dbgfs_bit_fops); +} +static void ccu_div_fixed_debug_init (struct clk_hw *hw,struct dentry *dentry) {struct ccu_div *div =to_ccu_div (hw);
@@ -489,6 +543,7 @@ static void ccu_div_fixed_debug_init(struct clk_hw *hw, struct dentry *dentry)#define ccu_div_var_debug_init NULL#define ccu_div_gate_debug_init NULL +#define ccu_div_buf_debug_init NULL#define ccu_div_fixed_debug_init NULL#endif /* !CONFIG_DEBUG_FS */
@@ -520,6 +575,13 @@ static const struct clk_ops ccu_div_gate_ops = { .debug_init = ccu_div_gate_debug_init }; +static const struct clk_ops ccu_div_buf_ops = { + .enable = ccu_div_buf_enable, + .disable = ccu_div_buf_disable, + .is_enabled = ccu_div_buf_is_enabled, + .debug_init = ccu_div_buf_debug_init +}; +static const struct clk_ops ccu_div_fixed_ops = { .recalc_rate = ccu_div_fixed_recalc_rate, .round_rate = ccu_div_fixed_round_rate,
@@ -566,6 +628,8 @@ struct ccu_div *ccu_div_hw_register(const struct ccu_div_init_data *div_init) }else if (div_init->type ==CCU_DIV_GATE ) { hw_init.ops = &ccu_div_gate_ops; div->divider = div_init->divider; + }else if (div_init->type ==CCU_DIV_BUF ) { + hw_init.ops = &ccu_div_buf_ops; }else if (div_init->type ==CCU_DIV_FIXED ) { hw_init.ops = &ccu_div_fixed_ops; div->divider = div_init->divider;
drivers/clk/baikal-t1/ccu-div.h +4 -0
@@ -15,8 +15,10 @@/* * CCU Divider private clock IDs +* @CCU_SYS_SATA_CLK: CCU SATA internal clock * @CCU_SYS_XGMAC_CLK: CCU XGMAC internal clock */ +#define CCU_SYS_SATA_CLK -1#define CCU_SYS_XGMAC_CLK -2/*
@@ -37,11 +39,13 @@* enum ccu_div_type - CCU Divider types * @CCU_DIV_VAR: Clocks gate with variable divider. * @CCU_DIV_GATE: Clocks gate with fixed divider. +* @CCU_DIV_BUF: Clock gate with no divider. * @CCU_DIV_FIXED: Ungateable clock with fixed divider. */ enum ccu_div_type {CCU_DIV_VAR ,CCU_DIV_GATE , +CCU_DIV_BUF ,CCU_DIV_FIXED };
drivers/clk/baikal-t1/clk-ccu-div.c +17 -1
@@ -76,6 +76,16 @@ .divider = _divider \ } +#define CCU_DIV_BUF_INFO (_id, _name, _pname, _base, _flags) \ + { \ + .id = _id, \ + .name = _name, \ + .parent_name = _pname, \ + .base = _base, \ + .type = CCU_DIV_BUF, \ + .flags = _flags \ + } +#define CCU_DIV_FIXED_INFO (_id, _name, _pname, _divider) \ { \ .id = _id, \
@@ -188,11 +198,14 @@ static const struct ccu_div_rst_map axi_rst_map[] = {* for the SoC devices registers IO-operations. */ static const struct ccu_div_info sys_info[] = { -CCU_DIV_VAR_INFO (CCU_SYS_SATA_REF_CLK ,"sys_sata_ref_clk" , +CCU_DIV_VAR_INFO (CCU_SYS_SATA_CLK ,"sys_sata_clk" ,"sata_clk" ,CCU_SYS_SATA_REF_BASE ,4 ,CLK_SET_RATE_GATE ,CCU_DIV_SKIP_ONE |CCU_DIV_LOCK_SHIFTED |CCU_DIV_RESET_DOMAIN ), +CCU_DIV_BUF_INFO (CCU_SYS_SATA_REF_CLK ,"sys_sata_ref_clk" , +"sys_sata_clk" ,CCU_SYS_SATA_REF_BASE , +CLK_SET_RATE_PARENT ),CCU_DIV_VAR_INFO (CCU_SYS_APB_CLK ,"sys_apb_clk" ,"pcie_clk" ,CCU_SYS_APB_BASE ,5 ,CLK_IS_CRITICAL ,CCU_DIV_RESET_DOMAIN ),
@@ -398,6 +411,9 @@ static int ccu_div_clk_register(struct ccu_div_data *data) init.base = info->base; init.sys_regs = data->sys_regs; init.divider = info->divider; + }else if (init.type ==CCU_DIV_BUF ) { + init.base = info->base; + init.sys_regs = data->sys_regs; }else { init.divider = info->divider; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 595/862 clk: bcm2835: Make peripheral PLLC critical
In reply to Greg Kroah-HartmanFrom: Maxime Ripard <[email protected]>
[ Upstream commit 6c5422851d8be8c7451e968fd2e6da41b6109e17 ]
When testing for a series affecting the VEC, it was discovered that turning off and on the VEC clock is crashing the system.
It turns out that, when disabling the VEC clock, it's the only child of the PLLC-per clock which will also get disabled. The source of the crash is PLLC-per being disabled.
It's likely that some other device might not take a clock reference that it actually needs, but it's unclear which at this point. Let's make PLLC-per critical so that we don't have that crash.
Stable-dep-of: 0b919a372869 ("clk: bcm2835: fix bcm2835_clock_rate_from_divisor declaration")
--- drivers/clk/bcm/clk-bcm2835.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/clk/bcm/clk-bcm2835.c +1 -1
@@ -1784,7 +1784,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { .load_mask = CM_PLLC_LOADPER, .hold_mask = CM_PLLC_HOLDPER, .fixed_divider = 1, - .flags = CLK_SET_RATE_PARENT), + .flags = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT),/* * PLLD is the display PLL, used to drive DSI display panels.
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 596/862 clk: bcm2835: fix bcm2835_clock_rate_from_divisor declaration
In reply to Greg Kroah-HartmanFrom: Stefan Wahren <[email protected]>
[ Upstream commit 0b919a3728691c172312dee99ba654055ccd8c84 ]
The return value of bcm2835_clock_rate_from_divisor is always unsigned and also all caller expect this. So fix the declaration accordingly.
--- drivers/clk/bcm/clk-bcm2835.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/clk/bcm/clk-bcm2835.c +3 -3
@@ -966,9 +966,9 @@ static u32 bcm2835_clock_choose_div(struct clk_hw *hw,return div; } -static long bcm2835_clock_rate_from_divisor (struct bcm2835_clock *clock, -unsigned long parent_rate, -u32 div) +static unsigned long bcm2835_clock_rate_from_divisor (struct bcm2835_clock *clock, +unsigned long parent_rate, +u32 div) {const struct bcm2835_clock_data *data = clock->data;u64 temp;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 597/862 clk: imx8mp: tune the order of enet_qos_root_clk
In reply to Greg Kroah-HartmanFrom: Peng Fan <[email protected]>
[ Upstream commit c68cd258a67730c24566b9688d7c134e67459ac6 ]
The enet_qos_root_clk takes sim_enet_root_clk as parent. When registering enet_qos_root_clk, it will be put into clk orphan list, because sim_enet_root_clk is not ready.
When sim_enet_root_clk is ready, clk_core_reparent_orphans_nolock will set enet_qos_root_clk parent to sim_enet_root_clk.
Because CLK_OPS_PARENT_ENABLE is set, sim_enet_root_clk will be enabled and disabled during the enet_qos_root_clk reparent phase.
All the above are correct. But with M7 booted early and using enet, M7 enet feature will be broken, because clk driver probe phase disable the needed clks, in case M7 firmware not configure sim_enet_root_clk.
And tune the order would also save cpu cycles.
Stable-dep-of: 855ae87a2073 ("clk: imx: scu: fix memleak on platform_device_add() fails")
--- drivers/clk/imx/clk-imx8mp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/clk/imx/clk-imx8mp.c +1 -1
@@ -665,8 +665,8 @@ static int imx8mp_clocks_probe(struct platform_device *pdev) hws[IMX8MP_CLK_CAN1_ROOT ] =imx_clk_hw_gate2 ("can1_root_clk" ,"can1" , ccm_base +0x4350 ,0 ); hws[IMX8MP_CLK_CAN2_ROOT ] =imx_clk_hw_gate2 ("can2_root_clk" ,"can2" , ccm_base +0x4360 ,0 ); hws[IMX8MP_CLK_SDMA1_ROOT ] =imx_clk_hw_gate4 ("sdma1_root_clk" ,"ipg_root" , ccm_base +0x43a0 ,0 ); - hws[IMX8MP_CLK_ENET_QOS_ROOT ] =imx_clk_hw_gate4 ("enet_qos_root_clk" ,"sim_enet_root_clk" , ccm_base +0x43b0 ,0 ); hws[IMX8MP_CLK_SIM_ENET_ROOT ] =imx_clk_hw_gate4 ("sim_enet_root_clk" ,"enet_axi" , ccm_base +0x4400 ,0 ); + hws[IMX8MP_CLK_ENET_QOS_ROOT ] =imx_clk_hw_gate4 ("enet_qos_root_clk" ,"sim_enet_root_clk" , ccm_base +0x43b0 ,0 ); hws[IMX8MP_CLK_GPU2D_ROOT ] =imx_clk_hw_gate4 ("gpu2d_root_clk" ,"gpu2d_core" , ccm_base +0x4450 ,0 ); hws[IMX8MP_CLK_GPU3D_ROOT ] =imx_clk_hw_gate4 ("gpu3d_root_clk" ,"gpu3d_core" , ccm_base +0x4460 ,0 ); hws[IMX8MP_CLK_UART1_ROOT ] =imx_clk_hw_gate4 ("uart1_root_clk" ,"uart1" , ccm_base +0x4490 ,0 );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 598/862 clk: imx: scu: fix memleak on platform_device_add() fails
In reply to Greg Kroah-HartmanFrom: Lin Yujun <[email protected]>
[ Upstream commit 855ae87a2073ebf1b395e020de54fdf9ce7d166f ]
No error handling is performed when platform_device_add() fails. Add error processing before return, and modified the return value.
--- drivers/clk/imx/clk-scu.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/clk/imx/clk-scu.c +5 -1
@@ -695,7 +695,11 @@ struct clk_hw *imx_clk_scu_alloc_dev(const char *name,pr_warn ("%s: failed to attached the power domain %d\n" , name, ret); -platform_device_add (pdev); + ret =platform_device_add (pdev); +if (ret) { +platform_device_put (pdev); +return ERR_PTR (ret); + }/* For API backwards compatiblilty, simply return NULL for success */ return NULL ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 599/862 clk: ti: Balance of_node_get() calls for of_find_node_by_name()
In reply to Greg Kroah-HartmanFrom: Liang He <[email protected]>
[ Upstream commit 058a3996b888ab60eb1857fb4fd28f1b89a9a95a ]
In ti_find_clock_provider(), of_find_node_by_name() will call of_node_put() for the 'from' argument, possibly putting the node one too many times. Let's maintain the of_node_get() from the previous search and only put when we're exiting the function early. This should avoid a misbalanced reference count on the node.
[[email protected]: Rewrite commit text, maintain reference instead of get again]
--- drivers/clk/ti/clk.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/clk/ti/clk.c +3 -2
@@ -140,11 +140,12 @@ static struct device_node *ti_find_clock_provider(struct device_node *from,break ; } } -of_node_put (from);kfree (tmp); -if (found) +if (found) { +of_node_put (from);return np; + }/* Fall back to using old node name base provider name */ return of_find_node_by_name (from, name);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 600/862 clk: ti: dra7-atl: Fix reference leak in of_dra7_atl_clk_probe
In reply to Greg Kroah-HartmanFrom: Miaoqian Lin <[email protected]>
[ Upstream commit 9c59a01caba26ec06fefd6ca1f22d5fd1de57d63 ]
pm_runtime_get_sync() will increment pm usage counter. Forgetting to putting operation will result in reference leak. Add missing pm_runtime_put_sync in some error paths.
--- drivers/clk/ti/clk-dra7-atl.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
drivers/clk/ti/clk-dra7-atl.c +6 -3
@@ -245,14 +245,16 @@ static int of_dra7_atl_clk_probe(struct platform_device *pdev)if (rc) {pr_err ("%s: failed to lookup atl clock %d\n" , __func__, i); -return -EINVAL ; + ret = -EINVAL ; + goto pm_put; } clk =of_clk_get_from_provider (&clkspec);if (IS_ERR (clk)) {pr_err ("%s: failed to get atl clock %d from provider\n" , __func__, i); -return PTR_ERR (clk); + ret =PTR_ERR (clk); + goto pm_put; } cdesc =to_atl_desc (__clk_get_hw (clk));
@@ -285,8 +287,9 @@ static int of_dra7_atl_clk_probe(struct platform_device *pdev)if (cdesc->enabled)atl_clk_enable (__clk_get_hw (clk)); } -pm_runtime_put_sync (cinfo->dev); +pm_put: +pm_runtime_put_sync (cinfo->dev);return ret; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 601/862 clk: ast2600: BCLK comes from EPLL
In reply to Greg Kroah-HartmanFrom: Joel Stanley <[email protected]>
[ Upstream commit b8c1dc9c00b252b3be853720a71b05ed451ddd9f ]
This correction was made in the u-boot SDK recently. There are no in-tree users of this clock so the impact is minimal.
--- drivers/clk/clk-ast2600.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/clk/clk-ast2600.c +1 -1
@@ -622,7 +622,7 @@ static int aspeed_g6_clk_probe(struct platform_device *pdev)regmap_write (map,0x308 ,0x12000 );/* 3x3 = 9 */ /* P-Bus (BCLK) clock divider */ - hw =clk_hw_register_divider_table (dev,"bclk" ,"hpll" ,0 , + hw =clk_hw_register_divider_table (dev,"bclk" ,"epll" ,0 , scu_g6_base +ASPEED_G6_CLK_SELECTION1 ,20 ,3 ,0 , ast2600_div_table, &aspeed_g6_clk_lock);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 602/862 mailbox: imx: fix RST channel support
In reply to Greg Kroah-HartmanFrom: Peng Fan <[email protected]>
[ Upstream commit 7e5cd064f73ccecd2ac1aadca078394bd25ea3ce ]
Because IMX_MU_xCR_MAX was increased to 5, some mu cfgs were not updated to include the CR register. Add the missed CR register to xcr array.
--- drivers/mailbox/imx-mailbox.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/mailbox/imx-mailbox.c +5 -5
@@ -904,7 +904,7 @@ static const struct imx_mu_dcfg imx_mu_cfg_imx7ulp = { .xTR = 0x20, .xRR = 0x40, .xSR = {0x60, 0x60, 0x60, 0x60}, - .xCR = {0x64, 0x64, 0x64, 0x64}, + .xCR = {0x64, 0x64, 0x64, 0x64, 0x64}, }; static const struct imx_mu_dcfg imx_mu_cfg_imx8ulp = {
@@ -927,7 +927,7 @@ static const struct imx_mu_dcfg imx_mu_cfg_imx8ulp_s4 = { .xTR = 0x200, .xRR = 0x280, .xSR = {0xC, 0x118, 0x124, 0x12C}, - .xCR = {0x110, 0x114, 0x120, 0x128}, + .xCR = {0x8, 0x110, 0x114, 0x120, 0x128}, }; static const struct imx_mu_dcfg imx_mu_cfg_imx93_s4 = {
@@ -938,7 +938,7 @@ static const struct imx_mu_dcfg imx_mu_cfg_imx93_s4 = { .xTR = 0x200, .xRR = 0x280, .xSR = {0xC, 0x118, 0x124, 0x12C}, - .xCR = {0x110, 0x114, 0x120, 0x128}, + .xCR = {0x8, 0x110, 0x114, 0x120, 0x128}, }; static const struct imx_mu_dcfg imx_mu_cfg_imx8_scu = {
@@ -949,7 +949,7 @@ static const struct imx_mu_dcfg imx_mu_cfg_imx8_scu = { .xTR = 0x0, .xRR = 0x10, .xSR = {0x20, 0x20, 0x20, 0x20}, - .xCR = {0x24, 0x24, 0x24, 0x24}, + .xCR = {0x24, 0x24, 0x24, 0x24, 0x24}, }; static const struct imx_mu_dcfg imx_mu_cfg_imx8_seco = {
@@ -960,7 +960,7 @@ static const struct imx_mu_dcfg imx_mu_cfg_imx8_seco = { .xTR = 0x0, .xRR = 0x10, .xSR = {0x20, 0x20, 0x20, 0x20}, - .xCR = {0x24, 0x24, 0x24, 0x24}, + .xCR = {0x24, 0x24, 0x24, 0x24, 0x24}, }; static const struct of_device_id imx_mu_dt_ids[] = {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 603/862 mailbox: mpfs: fix handling of the reg property
In reply to Greg Kroah-HartmanFrom: Conor Dooley <[email protected]>
[ Upstream commit 2e10289d1f304f5082a4dda55a677b72b3bdb581 ]
The "data" region of the PolarFire SoC's system controller mailbox is not one continuous register space - the system controller's QSPI sits between the control and data registers. Split the "data" reg into two
parts: "data" & "control". Optionally get the "data" register address from the 3rd reg property in the devicetree & fall back to using the old base + MAILBOX_REG_OFFSET that the current code uses.
--- drivers/mailbox/mailbox-mpfs.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-)
drivers/mailbox/mailbox-mpfs.c +14 -10
@@ -62,6 +62,7 @@ struct mpfs_mbox {struct mbox_controller controller;struct device *dev;int irq; +void __iomem *ctrl_base;void __iomem *mbox_base;void __iomem *int_reg;struct mbox_chan chans[1 ];
@@ -73,7 +74,7 @@ static bool mpfs_mbox_busy(struct mpfs_mbox *mbox) {u32 status; - status =readl_relaxed (mbox->mbox_base +SERVICES_SR_OFFSET ); + status =readl_relaxed (mbox->ctrl_base +SERVICES_SR_OFFSET );return status &SCB_STATUS_BUSY_MASK ; }
@@ -99,14 +100,13 @@ static int mpfs_mbox_send_data(struct mbox_chan *chan, void *data)for (index =0 ; index < (msg->cmd_data_size /4 ); index++)writel_relaxed (word_buf[index], - mbox->mbox_base +MAILBOX_REG_OFFSET + index *0x4 ); + mbox->mbox_base + index *0x4 );if (extra_bits) {u8 i;u8 byte_off =ALIGN_DOWN (msg->cmd_data_size,4 );u8 *byte_buf = msg->cmd_data + byte_off; - val =readl_relaxed (mbox->mbox_base + -MAILBOX_REG_OFFSET + index *0x4 ); + val =readl_relaxed (mbox->mbox_base + index *0x4 );for (i =0u ; i < extra_bits; i++) { val &= ~(0xffu << (i *8u ));
@@ -114,14 +114,14 @@ static int mpfs_mbox_send_data(struct mbox_chan *chan, void *data) }writel_relaxed (val, - mbox->mbox_base +MAILBOX_REG_OFFSET + index *0x4 ); + mbox->mbox_base + index *0x4 ); } } opt_sel = ((msg->mbox_offset <<7u ) | (msg->cmd_opcode &0x7fu )); tx_trigger = (opt_sel <<SCB_CTRL_POS ) &SCB_CTRL_MASK ; tx_trigger |=SCB_CTRL_REQ_MASK |SCB_STATUS_NOTIFY_MASK ; -writel_relaxed (tx_trigger, mbox->mbox_base +SERVICES_CR_OFFSET ); +writel_relaxed (tx_trigger, mbox->ctrl_base +SERVICES_CR_OFFSET );return 0 ; }
@@ -141,7 +141,7 @@ static void mpfs_mbox_rx_data(struct mbox_chan *chan)if (!mpfs_mbox_busy (mbox)) {for (i =0 ; i < num_words; i++) { response->resp_msg[i] = -readl_relaxed (mbox->mbox_base +MAILBOX_REG_OFFSET +readl_relaxed (mbox->mbox_base + mbox->resp_offset + i *0x4 ); } }
@@ -200,14 +200,18 @@ static int mpfs_mbox_probe(struct platform_device *pdev)if (!mbox)return -ENOMEM ; - mbox->mbox_base =devm_platform_get_and_ioremap_resource (pdev,0 , ®s); -if (IS_ERR (mbox->mbox_base)) -return PTR_ERR (mbox->mbox_base); + mbox->ctrl_base =devm_platform_get_and_ioremap_resource (pdev,0 , ®s); +if (IS_ERR (mbox->ctrl_base)) +return PTR_ERR (mbox->ctrl_base); mbox->int_reg =devm_platform_get_and_ioremap_resource (pdev,1 , ®s);if (IS_ERR (mbox->int_reg))return PTR_ERR (mbox->int_reg); + mbox->mbox_base =devm_platform_get_and_ioremap_resource (pdev,2 , ®s); +if (IS_ERR (mbox->mbox_base))// account for the old dt-binding w/ 2 regs + mbox->mbox_base = mbox->ctrl_base +MAILBOX_REG_OFFSET ; + mbox->irq =platform_get_irq (pdev,0 );if (mbox->irq <0 )return mbox->irq;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 604/862 mailbox: mpfs: account for mbox offsets while sending
In reply to Greg Kroah-HartmanFrom: Conor Dooley <[email protected]>
[ Upstream commit 0d1aadfe10ba17ebdeb96abb9638eb0f623f9b55 ]
The mailbox offset is not only used for receiving messages, but it is also used by messages sent to the system controller by Linux that have a payload, such as the "digital signature service". It is also overloaded by certain other services (reprogramming of the FPGA fabric, see Link:) to have a meaning other than the offset the system controller should read from.
When the driver was written, no such services of the latter type were in use & those of the former used an offset of zero so this has gone un-noticed.
--- drivers/mailbox/mailbox-mpfs.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
drivers/mailbox/mailbox-mpfs.c +3 -4
@@ -100,21 +100,20 @@ static int mpfs_mbox_send_data(struct mbox_chan *chan, void *data)for (index =0 ; index < (msg->cmd_data_size /4 ); index++)writel_relaxed (word_buf[index], - mbox->mbox_base + index *0x4 ); + mbox->mbox_base + msg->mbox_offset + index *0x4 );if (extra_bits) {u8 i;u8 byte_off =ALIGN_DOWN (msg->cmd_data_size,4 );u8 *byte_buf = msg->cmd_data + byte_off; - val =readl_relaxed (mbox->mbox_base + index *0x4 ); + val =readl_relaxed (mbox->mbox_base + msg->mbox_offset + index *0x4 );for (i =0u ; i < extra_bits; i++) { val &= ~(0xffu << (i *8u )); val |= (byte_buf[i] << (i *8u )); } -writel_relaxed (val, - mbox->mbox_base + index *0x4 ); +writel_relaxed (val, mbox->mbox_base + msg->mbox_offset + index *0x4 ); } }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 605/862 mailbox: bcm-ferxrm-mailbox: Fix error check for dma_map_sg
In reply to Greg Kroah-HartmanFrom: Jack Wang <[email protected]>
[ Upstream commit 6b207ce8a96a71e966831e3a13c38143ba9a73c1 ]
dma_map_sg return 0 on error, fix the error check, and return -EIO to caller.
--- drivers/mailbox/bcm-flexrm-mailbox.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/mailbox/bcm-flexrm-mailbox.c +4 -4
@@ -622,15 +622,15 @@ static int flexrm_spu_dma_map(struct device *dev, struct brcm_message *msg) rc =dma_map_sg (dev, msg->spu.src,sg_nents (msg->spu.src),DMA_TO_DEVICE ); -if (rc <0 ) -return rc; +if (!rc) +return -EIO ; rc =dma_map_sg (dev, msg->spu.dst,sg_nents (msg->spu.dst),DMA_FROM_DEVICE ); -if (rc <0 ) { +if (!rc) {dma_unmap_sg (dev, msg->spu.src,sg_nents (msg->spu.src),DMA_TO_DEVICE ); -return rc; +return -EIO ; }return 0 ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 606/862 ipc: mqueue: fix possible memory leak in init_mqueue_fs()
In reply to Greg Kroah-HartmanFrom: Hangyu Hua <[email protected]>
[ Upstream commit c579d60f0d0cd87552f64fdebe68b5d941d20309 ]
commit db7cfc380900 ("ipc: Free mq_sysctls if ipc namespace creation failed")
Here's a similar memory leak to the one fixed by the patch above. retire_mq_sysctls need to be called when init_mqueue_fs fails after setup_mq_sysctls.
--- ipc/mqueue.c | 1 + 1 file changed, 1 insertion(+)
ipc/mqueue.c +1 -0
@@ -1746,6 +1746,7 @@ static int __init init_mqueue_fs(void)unregister_filesystem (&mqueue_fs_type); out_sysctl:kmem_cache_destroy (mqueue_inode_cachep); +retire_mq_sysctls (&init_ipc_ns);return error; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 607/862 powerpc/configs: Properly enable PAPR_SCM in pseries_defconfig
In reply to Greg Kroah-HartmanFrom: Michael Ellerman <[email protected]>
[ Upstream commit aa398d88aea4ec863bd7aea35d5035a37096dc59 ]
My commit to add PAPR_SCM to pseries_defconfig failed to add the required dependencies, meaning the driver doesn't get built.
Add the required LIBNVDIMM=m.
--- arch/powerpc/configs/pseries_defconfig | 1 + 1 file changed, 1 insertion(+)
arch/powerpc/configs/pseries_defconfig +1 -0
@@ -40,6 +40,7 @@ CONFIG_PPC_SPLPAR=y CONFIG_DTL=y CONFIG_PPC_SMLPAR=y CONFIG_IBMEBUS=y +CONFIG_LIBNVDIMM=m CONFIG_PAPR_SCM=m CONFIG_PPC_SVM=y # CONFIG_PPC_PMAC is not set
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 608/862 powerpc/math_emu/efp: Include module.h
In reply to Greg Kroah-HartmanFrom: Nathan Chancellor <[email protected]>
[ Upstream commit cfe0d370e0788625ce0df3239aad07a2506c1796 ]
When building with a recent version of clang, there are a couple of errors around the call to module_init():
arch/powerpc/math-emu/math_efp.c:927:1: error: type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int [-Wimplicit-int] module_init(spe_mathemu_init);
^
int
arch/powerpc/math-emu/math_efp.c:927:13: error: a parameter list without types is only allowed in a function definition
module_init(spe_mathemu_init);
^2 errors generated.
module_init() is a macro, which is not getting expanded because module.h is not included in this file. Add the include so that the macro can expand properly, clearing up the build failure.
--- arch/powerpc/math-emu/math_efp.c | 1 + 1 file changed, 1 insertion(+)
arch/powerpc/math-emu/math_efp.c +1 -0
@@ -17,6 +17,7 @@#include <linux/types.h> #include <linux/prctl.h> +#include <linux/module.h> #include <linux/uaccess.h> #include <asm/reg.h>
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 609/862 powerpc/sysdev/fsl_msi: Add missing of_node_put()
In reply to Greg Kroah-HartmanFrom: Liang He <[email protected]>
[ Upstream commit def435c04ee984a5f9ed2711b2bfe946936c6a21 ]
In fsl_setup_msi_irqs(), use of_node_put() to drop the reference returned by of_parse_phandle().
--- arch/powerpc/sysdev/fsl_msi.c | 2 ++ 1 file changed, 2 insertions(+)
arch/powerpc/sysdev/fsl_msi.c +2 -0
@@ -209,8 +209,10 @@ static int fsl_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)dev_err (&pdev->dev,"node %pOF has an invalid fsl,msi phandle %u\n" , hose->dn, np->phandle); +of_node_put (np);return -EINVAL ; } +of_node_put (np); }msi_for_each_desc (entry, &pdev->dev,MSI_DESC_NOTASSOCIATED ) {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 610/862 powerpc/pci_dn: Add missing of_node_put()
In reply to Greg Kroah-HartmanFrom: Liang He <[email protected]>
[ Upstream commit 110a1fcb6c4d55144d8179983a475f17a1d6f832 ]
In pci_add_device_node_info(), use of_node_put() to drop the reference to 'parent' returned by of_get_parent() to keep refcount balance.
--- arch/powerpc/kernel/pci_dn.c | 1 + 1 file changed, 1 insertion(+)
arch/powerpc/kernel/pci_dn.c +1 -0
@@ -330,6 +330,7 @@ struct pci_dn *pci_add_device_node_info(struct pci_controller *hose,INIT_LIST_HEAD (&pdn->list); parent =of_get_parent (dn); pdn->parent = parent ?PCI_DN (parent) :NULL ; +of_node_put (parent);if (pdn->parent)list_add_tail (&pdn->list, &pdn->parent->child_list);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 611/862 powerpc/powernv: add missing of_node_put() in opal_export_attrs()
In reply to Greg Kroah-HartmanFrom: Zheng Yongjun <[email protected]>
[ Upstream commit 71a92e99c47900cc164620948b3863382cec4f1a ]
After using 'np' returned by of_find_node_by_path(), of_node_put() need be called to decrease the refcount.
--- arch/powerpc/platforms/powernv/opal.c | 1 + 1 file changed, 1 insertion(+)
arch/powerpc/platforms/powernv/opal.c +1 -0
@@ -892,6 +892,7 @@ static void opal_export_attrs(void) kobj =kobject_create_and_add ("exports" , opal_kobj);if (!kobj) {pr_warn ("kobject_create_and_add() of exports failed\n" ); +of_node_put (np);return ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 612/862 cpuidle: riscv-sbi: Fix CPU_PM_CPU_IDLE_ENTER_xyz() macro usage
In reply to Greg Kroah-HartmanFrom: Anup Patel <[email protected]>
[ Upstream commit cfadbb9df8c4dc917787da4458327e5ec14743d4 ]
Currently, we are using CPU_PM_CPU_IDLE_ENTER_PARAM() for all SBI HSM suspend types so retentive suspend types are also treated non-retentive and kernel will do redundant additional work for these states.
The BIT[31] of SBI HSM suspend types allows us to differentiate between retentive and non-retentive suspend types so we should use this BIT to call appropriate CPU_PM_CPU_IDLE_ENTER_xyz() macro.
--- drivers/cpuidle/cpuidle-riscv-sbi.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/cpuidle/cpuidle-riscv-sbi.c +6 -1
@@ -97,8 +97,13 @@ static int sbi_cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv, int idx) {u32 *states =__this_cpu_read (sbi_cpuidle_data.states); +u32 state = states[idx]; -return CPU_PM_CPU_IDLE_ENTER_PARAM (sbi_suspend, idx, states[idx]); +if (state &SBI_HSM_SUSP_NON_RET_BIT ) +return CPU_PM_CPU_IDLE_ENTER_PARAM (sbi_suspend, idx, state); +else +return CPU_PM_CPU_IDLE_ENTER_RETENTION_PARAM (sbi_suspend, + idx, state); } static int __sbi_enter_domain_idle_state(struct cpuidle_device *dev,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 613/862 powerpc: dts: turris1x.dts: Fix NOR partitions labels
In reply to Greg Kroah-HartmanFrom: Pali Rohár <[email protected]>
[ Upstream commit c9986f0aefd1ae22fe9cf794d49699643f1e268b ]
Partition partition@20000 contains generic kernel image and it does not have to be used only for rescue purposes. Partition partition@1c0000 contains bootable rescue system and partition partition@340000 contains factory image/data for restoring to NAND. So change partition labels to better fit their purpose by removing possible misleading substring "rootfs" from these labels.
--- arch/powerpc/boot/dts/turris1x.dts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
arch/powerpc/boot/dts/turris1x.dts +5 -5
@@ -263,21 +263,21 @@ }; partition@20000 { - /* 1.7 MB for Rescue Linux Kernel Image */ + /* 1.7 MB for Linux Kernel Image */ reg = <0x00020000 0x001a0000>; - label = "rescue-kernel"; + label = "kernel"; }; partition@1c0000 { /* 1.5 MB for Rescue JFFS2 Root File System */ reg = <0x001c0000 0x00180000>; - label = "rescue-rootfs"; + label = "rescue"; }; partition@340000 { - /* 11 MB for TAR.XZ Backup with content of NAND Root File System */ + /* 11 MB for TAR.XZ Archive with Factory content of NAND Root File System */ reg = <0x00340000 0x00b00000>; - label = "backup-rootfs"; + label = "factory"; }; partition@e40000 {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 614/862 powerpc: dts: turris1x.dts: Fix labels in DSA cpu port nodes
In reply to Greg Kroah-HartmanFrom: Pali Rohár <[email protected]>
[ Upstream commit 8bf056f57f1d16c561e43f9af37301f23990cd21 ]
DSA cpu port node has to be marked with "cpu" label. So fix it for both cpu port nodes.
--- arch/powerpc/boot/dts/turris1x.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/powerpc/boot/dts/turris1x.dts +2 -2
@@ -147,7 +147,7 @@ port@0 { reg = <0>; - label = "cpu1"; + label = "cpu"; ethernet = <&enet1>; phy-mode = "rgmii-id";
@@ -184,7 +184,7 @@ port@6 { reg = <6>; - label = "cpu0"; + label = "cpu"; ethernet = <&enet0>; phy-mode = "rgmii-id";
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 615/862 powerpc: Fix fallocate and fadvise64_64 compat parameter combination
In reply to Greg Kroah-HartmanFrom: Rohan McLure <[email protected]>
[ Upstream commit 016ff72bd2090903715c0f9422a44afbb966f4ee ]
As reported[1] by Arnd, the arch-specific fadvise64_64 and fallocate compatibility handlers assume parameters are passed with 32-bit big-endian ABI. This affects the assignment of odd-even parameter pairs to the high or low words of a 64-bit syscall parameter.
Fix fadvise64_64 fallocate compat handlers to correctly swap upper/lower 32 bits conditioned on endianness.
A future patch will replace the arch-specific compat fallocate with an asm-generic implementation. This patch is intended for ease of back-port.
[1]: https://lore.kernel.org/all/[email protected]/
--- arch/powerpc/include/asm/syscalls.h | 12 ++++++++++++ arch/powerpc/kernel/sys_ppc32.c | 14 +------------- arch/powerpc/kernel/syscalls.c | 4 ++-- 3 files changed, 15 insertions(+), 15 deletions(-)
arch/powerpc/include/asm/syscalls.h +12 -0
@@ -8,6 +8,18 @@#include <linux/types.h> #include <linux/compat.h> +/* +* long long munging: +* The 32 bit ABI passes long longs in an odd even register pair. +* High and low parts are swapped depending on endian mode, +* so define a macro (similar to mips linux32) to handle that. +*/ +#ifdef __LITTLE_ENDIAN__ +#define merge_64 (low, high) (((u64)high << 32) | low) +#else +#define merge_64 (high, low) (((u64)high << 32) | low) +#endif +struct rtas_args ; asmlinkage long sys_mmap(unsigned long addr, size_t len,
arch/powerpc/kernel/sys_ppc32.c +1 -13
@@ -56,18 +56,6 @@ unsigned long compat_sys_mmap2(unsigned long addr, size_t len,return sys_mmap (addr, len, prot, flags, fd, pgoff <<12 ); } -/* -* long long munging: -* The 32 bit ABI passes long longs in an odd even register pair. -* High and low parts are swapped depending on endian mode, -* so define a macro (similar to mips linux32) to handle that. -*/ -#ifdef __LITTLE_ENDIAN__ -#define merge_64 (low, high) ((u64)high << 32) | low -#else -#define merge_64 (high, low) ((u64)high << 32) | low -#endif -compat_ssize_t compat_sys_pread64 (unsigned int fd,char __user *ubuf,compat_size_t count,u32 reg6,u32 pos1,u32 pos2) {
@@ -94,7 +82,7 @@ asmlinkage int compat_sys_truncate64(const char __user * path, u32 reg4,asmlinkage long compat_sys_fallocate (int fd,int mode,u32 offset1,u32 offset2,u32 len1,u32 len2) { -return ksys_fallocate (fd, mode, ((loff_t )offset1 <<32 ) | offset2, +return ksys_fallocate (fd, mode,merge_64 (offset1, offset2),merge_64 (len1, len2)); }
arch/powerpc/kernel/syscalls.c +2 -2
@@ -98,8 +98,8 @@ long ppc64_personality(unsigned long personality)long ppc_fadvise64_64 (int fd,int advice,u32 offset_high,u32 offset_low,u32 len_high,u32 len_low) { -return ksys_fadvise64_64 (fd, (u64 )offset_high <<32 | offset_low, - (u64 )len_high <<32 | len_low, advice); +return ksys_fadvise64_64 (fd,merge_64 (offset_high, offset_low), +merge_64 (len_high, len_low), advice); }SYSCALL_DEFINE0 (switch_endian)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 616/862 x86/hyperv: Fix struct hv_enlightened_vmcs definition
In reply to Greg Kroah-HartmanFrom: Vitaly Kuznetsov <[email protected]>
[ Upstream commit ea9da788a61e47e7ab9cbad397453e51cd82ac0d ]
Section 1.9 of TLFS v6.0b says:
"All structures are padded in such a way that fields are aligned naturally (that is, an 8-byte field is aligned to an offset of 8 bytes and so on)".
'struct enlightened_vmcs' has a glitch:
...
struct {
u32 nested_flush_hypercall:1; /* 836: 0 4 */
u32 msr_bitmap:1; /* 836: 1 4 */
u32 reserved:30; /* 836: 2 4 */
} hv_enlightenments_control; /* 836 4 */
u32 hv_vp_id; /* 840 4 */
u64 hv_vm_id; /* 844 8 */
u64 partition_assist_page; /* 852 8 */...
And the observed values in 'partition_assist_page' make no sense at all. Fix the layout by padding the structure properly.
--- arch/x86/include/asm/hyperv-tlfs.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/x86/include/asm/hyperv-tlfs.h +2 -2
@@ -546,7 +546,7 @@ struct hv_enlightened_vmcs {u64 guest_rip;u32 hv_clean_fields; -u32 hv_padding_32; +u32 padding32_1;u32 hv_synthetic_controls;struct {u32 nested_flush_hypercall:1 ;
@@ -554,7 +554,7 @@ struct hv_enlightened_vmcs { u32 reserved:30; }__packed hv_enlightenments_control;u32 hv_vp_id; - +u32 padding32_2;u64 hv_vm_id;u64 partition_assist_page;u64 padding64_4[4 ];
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 617/862 powerpc/64s: Fix GENERIC_CPU build flags for PPC970 / G5
In reply to Greg Kroah-HartmanFrom: Nicholas Piggin <[email protected]>
[ Upstream commit 58ec7f06b74e0d6e76c4110afce367c8b5f0837d ]
Big-endian GENERIC_CPU supports 970, but builds with -mcpu=power5. POWER5 is ISA v2.02 whereas 970 is v2.01 plus Altivec. 2.02 added the popcntb instruction which a compiler might use.
Use -mcpu=power4.
--- arch/powerpc/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/powerpc/Makefile +1 -1
@@ -152,7 +152,7 @@ CFLAGS-$(CONFIG_GENERIC_CPU) += -mcpu=power8 CFLAGS-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mtune=power9,-mtune=power8) else CFLAGS-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mtune=power7,$(call cc-option,-mtune=power5)) -CFLAGS-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mcpu=power5,-mcpu=power4) +CFLAGS-$(CONFIG_GENERIC_CPU) += -mcpu=power4 endif else ifdef CONFIG_PPC_BOOK3E_64 CFLAGS-$(CONFIG_GENERIC_CPU) += -mcpu=powerpc64
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 618/862 powerpc/64/interrupt: Fix false warning in context tracking due to idle state
In reply to Greg Kroah-HartmanFrom: Nicholas Piggin <[email protected]>
[ Upstream commit 56adbb7a8b6cc7fc9b940829c38494e53c9e57d1 ]
Commit 171476775d32 ("context_tracking: Convert state to atomic_t") added a CONTEXT_IDLE state which can be encountered by interrupts from kernel mode in the idle thread, causing a false positive warning.
--- arch/powerpc/include/asm/interrupt.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
arch/powerpc/include/asm/interrupt.h +2 -1
@@ -195,7 +195,8 @@ static inline void interrupt_enter_prepare(struct pt_regs *regs)* so avoid recursion. */ if (TRAP (regs) !=INTERRUPT_PROGRAM ) { -CT_WARN_ON (ct_state () !=CONTEXT_KERNEL ); +CT_WARN_ON (ct_state () !=CONTEXT_KERNEL && +ct_state () !=CONTEXT_IDLE );if (IS_ENABLED (CONFIG_PPC_IRQ_SOFT_MASK_DEBUG ))BUG_ON (is_implicit_soft_masked (regs)); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 619/862 powerpc/64: mark irqs hard disabled in boot paca
In reply to Greg Kroah-HartmanFrom: Nicholas Piggin <[email protected]>
[ Upstream commit 799f7063c7645f9a751d17f5dfd73b952f962cd2 ]
This prevents interrupts in early boot (e.g., program check) from enabling MSR[EE], potentially causing endian mismatch or other crashes when reporting early boot traps.
--- arch/powerpc/kernel/setup_64.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
arch/powerpc/kernel/setup_64.c +3 -1
@@ -182,8 +182,10 @@ static void __init fixup_boot_paca(void)get_paca ()->cpu_start =1 ;/* Allow percpu accesses to work until we setup percpu data */ get_paca ()->data_offset =0 ; -/* Mark interrupts disabled in PACA */ +/* Mark interrupts soft and hard disabled in PACA */ irq_soft_mask_set (IRQS_DISABLED ); +get_paca ()->irq_happened =PACA_IRQ_HARD_DIS ; +WARN_ON (mfmsr () &MSR_EE ); }static void __init configure_exceptions (void )
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 620/862 powerpc/64/interrupt: Fix return to masked context after hard-mask irq becomes pending
In reply to Greg Kroah-HartmanFrom: Nicholas Piggin <[email protected]>
[ Upstream commit e485f6c751e0a969327336c635ca602feea117f0 ]
If a synchronous interrupt (e.g., hash fault) is taken inside an irqs-disabled region which has MSR[EE]=1, then an asynchronous interrupt that is PACA_IRQ_MUST_HARD_MASK (e.g., PMI) is taken inside the synchronous interrupt handler, then the synchronous interrupt will return with MSR[EE]=1 and the asynchronous interrupt fires again.
If the asynchronous interrupt is a PMI and the original context does not have PMIs disabled (only Linux IRQs), the asynchronous interrupt will fire despite having the PMI marked soft pending. This can confuse the perf code and cause warnings.
This patch changes the interrupt return so that irqs-disabled MSR[EE]=1 contexts will be returned to with MSR[EE]=0 if a PACA_IRQ_MUST_HARD_MASK interrupt has become pending in the meantime.
The longer explanation for what happens:
1. local_irq_disable()
2. Hash fault interrupt fires, do_hash_fault handler runs
3. interrupt_enter_prepare() sets IRQS_ALL_DISABLED
4. interrupt_enter_prepare() sets MSR[EE]=1
5. PMU interrupt fires, masked handler runs
6. Masked handler marks PMI pending
7. Masked handler returns with PACA_IRQ_HARD_DIS set, MSR[EE]=0
8. do_hash_fault interrupt return handler runs
9. interrupt_exit_kernel_prepare() clears PACA_IRQ_HARD_DIS
10. interrupt returns with MSR[EE]=1
11. PMU interrupt fires, perf handler runs
--- arch/powerpc/kernel/interrupt.c | 10 --------- arch/powerpc/kernel/interrupt_64.S | 34 +++++++++++++++++++++++++++--- 2 files changed, 31 insertions(+), 13 deletions(-)
arch/powerpc/kernel/interrupt.c +0 -10
@@ -431,16 +431,6 @@ notrace unsigned long interrupt_exit_kernel_prepare(struct pt_regs *regs)if (unlikely (stack_store))__hard_EE_RI_disable (); -/* -* Returning to a kernel context with local irqs disabled. -* Here, if EE was enabled in the interrupted context, enable -* it on return as well. A problem exists here where a soft -* masked interrupt may have cleared MSR[EE] and set HARD_DIS -* here, and it will still exist on return to the caller. This -* will be resolved by the masked interrupt firing again. -*/ -if (regs->msr &MSR_EE ) - local_paca->irq_happened &= ~PACA_IRQ_HARD_DIS ;#endif /* CONFIG_PPC64 */ }
arch/powerpc/kernel/interrupt_64.S +31 -3
@@ -559,15 +559,43 @@ _ASM_NOKPROBE_SYMBOL(interrupt_return_\srr\()_kernel) ld r11,SOFTE(r1) cmpwi r11,IRQS_ENABLED stb r11,PACAIRQSOFTMASK(r13) - bne 1f + beq .Linterrupt_return_\srr\()_soft_enabled + + /* + * Returning to soft-disabled context. + * Check if a MUST_HARD_MASK interrupt has become pending, in which + * case we need to disable MSR[EE] in the return context. + */ + ld r12,_MSR(r1) + andi. r10,r12,MSR_EE + beq .Lfast_kernel_interrupt_return_\srr\() // EE already disabled + lbz r11,PACAIRQHAPPENED(r13) + andi. r10,r11,PACA_IRQ_MUST_HARD_MASK + beq 1f // No HARD_MASK pending + + /* Must clear MSR_EE from _MSR */ +#ifdef CONFIG_PPC_BOOK3S + li r10,0 + /* Clear valid before changing _MSR */ + .ifc \srr,srr + stb r10,PACASRR_VALID(r13) + .else + stb r10,PACAHSRR_VALID(r13) + .endif +#endif + xori r12,r12,MSR_EE + std r12,_MSR(r1) + b .Lfast_kernel_interrupt_return_\srr\() + +.Linterrupt_return_\srr\()_soft_enabled: #ifdef CONFIG_PPC_BOOK3S lbz r11,PACAIRQHAPPENED(r13) andi. r11,r11,(~PACA_IRQ_HARD_DIS)@l bne- interrupt_return_\srr\()_kernel_restart #endif - li r11,0 - stb r11,PACAIRQHAPPENED(r13) # clear out possible HARD_DIS 1: + li r11,0 + stb r11,PACAIRQHAPPENED(r13) // clear the possible HARD_DIS .Lfast_kernel_interrupt_return_\srr\(): cmpdi cr1,r3,0
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 621/862 powerpc: Fix SPE Power ISA properties for e500v1 platforms
In reply to Greg Kroah-HartmanFrom: Pali Rohár <[email protected]>
[ Upstream commit 37b9345ce7f4ab17538ea62def6f6d430f091355 ]
Commit 2eb28006431c ("powerpc/e500v2: Add Power ISA properties to comply with ePAPR 1.1") introduced new include file e500v2_power_isa.dtsi and should have used it for all e500v2 platforms. But apparently it was used also for e500v1 platforms mpc8540, mpc8541, mpc8555 and mpc8560.
e500v1 cores compared to e500v2 do not support double precision floating point SPE instructions. Hence power-isa-sp.fd should not be set on e500v1 platforms, which is in e500v2_power_isa.dtsi include file.
Fix this issue by introducing a new e500v1_power_isa.dtsi include file and use it in all e500v1 device tree files.
--- .../boot/dts/fsl/e500v1_power_isa.dtsi | 51 +++++++++++++++++++ arch/powerpc/boot/dts/fsl/mpc8540ads.dts | 2 +- arch/powerpc/boot/dts/fsl/mpc8541cds.dts | 2 +- arch/powerpc/boot/dts/fsl/mpc8555cds.dts | 2 +- arch/powerpc/boot/dts/fsl/mpc8560ads.dts | 2 +- 5 files changed, 55 insertions(+), 4 deletions(-) create mode 100644 arch/powerpc/boot/dts/fsl/e500v1_power_isa.dtsi
arch/powerpc/boot/dts/fsl/e500v1_power_isa.dtsi new file +51 -0
@@ -0,0 +1,51 @@ +/* + * e500v1 Power ISA Device Tree Source (include) + * + * Copyright 2012 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/ { + cpus { + power-isa-version = "2.03"; + power-isa-b; // Base + power-isa-e; // Embedded + power-isa-atb; // Alternate Time Base + power-isa-cs; // Cache Specification + power-isa-e.le; // Embedded.Little-Endian + power-isa-e.pm; // Embedded.Performance Monitor + power-isa-ecl; // Embedded Cache Locking + power-isa-mmc; // Memory Coherence + power-isa-sp; // Signal Processing Engine + power-isa-sp.fs; // SPE.Embedded Float Scalar Single + power-isa-sp.fv; // SPE.Embedded Float Vector + mmu-type = "power-embedded"; + }; +};
arch/powerpc/boot/dts/fsl/mpc8540ads.dts +1 -1
@@ -7,7 +7,7 @@ /dts-v1/; -/include/ "e500v2_power_isa.dtsi" +/include/ "e500v1_power_isa.dtsi" / { model = "MPC8540ADS";
arch/powerpc/boot/dts/fsl/mpc8541cds.dts +1 -1
@@ -7,7 +7,7 @@ /dts-v1/; -/include/ "e500v2_power_isa.dtsi" +/include/ "e500v1_power_isa.dtsi" / { model = "MPC8541CDS";
arch/powerpc/boot/dts/fsl/mpc8555cds.dts +1 -1
@@ -7,7 +7,7 @@ /dts-v1/; -/include/ "e500v2_power_isa.dtsi" +/include/ "e500v1_power_isa.dtsi" / { model = "MPC8555CDS";
arch/powerpc/boot/dts/fsl/mpc8560ads.dts +1 -1
@@ -7,7 +7,7 @@ /dts-v1/; -/include/ "e500v2_power_isa.dtsi" +/include/ "e500v1_power_isa.dtsi" / { model = "MPC8560ADS";
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 622/862 powerpc/kprobes: Fix null pointer reference in arch_prepare_kprobe()
In reply to Greg Kroah-HartmanFrom: Li Huafei <[email protected]>
[ Upstream commit 97f88a3d723162781d6cbfdc7b9617eefab55b19 ]
I found a null pointer reference in arch_prepare_kprobe():
# echo 'p cmdline_proc_show' > kprobe_events
# echo 'p cmdline_proc_show+16' >> kprobe_events
Kernel attempted to read user page (0) - exploit attempt? (uid: 0)
BUG: Kernel NULL pointer dereference on read at 0x00000000
Faulting instruction address: 0xc000000000050bfc
Oops: Kernel access of bad area, sig: 11 [#1]
LE PAGE_SIZE=64K MMU=Radix SMP NR_CPUS=2048 NUMA PowerNV
Modules linked in:
CPU: 0 PID: 122 Comm: sh Not tainted 6.0.0-rc3-00007-gdcf8e5633e2e #10
NIP: c000000000050bfc LR: c000000000050bec CTR: 0000000000005bdc
REGS: c0000000348475b0 TRAP: 0300 Not tainted (6.0.0-rc3-00007-gdcf8e5633e2e)
MSR: 9000000000009033 <SF,HV,EE,ME,IR,DR,RI,LE> CR: 88002444 XER: 20040006
CFAR: c00000000022d100 DAR: 0000000000000000 DSISR: 40000000 IRQMASK: 0
...
NIP arch_prepare_kprobe+0x10c/0x2d0
LR arch_prepare_kprobe+0xfc/0x2d0
Call Trace:
0xc0000000012f77a0 (unreliable)
register_kprobe+0x3c0/0x7a0
__register_trace_kprobe+0x140/0x1a0
__trace_kprobe_create+0x794/0x1040
trace_probe_create+0xc4/0xe0
create_or_delete_trace_kprobe+0x2c/0x80
trace_parse_run_command+0xf0/0x210
probes_write+0x20/0x40
vfs_write+0xfc/0x450
ksys_write+0x84/0x140
system_call_exception+0x17c/0x3a0
system_call_vectored_common+0xe8/0x278
--- interrupt: 3000 at 0x7fffa5682de0
NIP: 00007fffa5682de0 LR: 0000000000000000 CTR: 0000000000000000
REGS: c000000034847e80 TRAP: 3000 Not tainted (6.0.0-rc3-00007-gdcf8e5633e2e)
MSR: 900000000280f033 <SF,HV,VEC,VSX,EE,PR,FP,ME,IR,DR,RI,LE> CR: 44002408 XER: 00000000The address being probed has some special:
cmdline_proc_show: Probe based on ftrace
cmdline_proc_show+16: Probe for the next instruction at the ftrace location
The ftrace-based kprobe does not generate kprobe::ainsn::insn, it gets set to NULL. In arch_prepare_kprobe() it will check for:
...
prev = get_kprobe(p->addr - 1);
preempt_enable_no_resched();
if (prev && ppc_inst_prefixed(ppc_inst_read(prev->ainsn.insn))) {
...If prev is based on ftrace, 'ppc_inst_read(prev->ainsn.insn)' will occur with a null pointer reference. At this point prev->addr will not be a prefixed instruction, so the check can be skipped.
Check if prev is ftrace-based kprobe before reading 'prev->ainsn.insn' to fix this problem.
--- arch/powerpc/kernel/kprobes.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
arch/powerpc/kernel/kprobes.c +7 -1
@@ -161,7 +161,13 @@ int arch_prepare_kprobe(struct kprobe *p)preempt_disable (); prev =get_kprobe (p->addr -1 );preempt_enable_no_resched (); -if (prev &&ppc_inst_prefixed (ppc_inst_read (prev->ainsn.insn))) { + +/* +* When prev is a ftrace-based kprobe, we don't have an insn, and it +* doesn't probe for prefixed instruction. +*/ +if (prev && !kprobe_ftrace (prev) && +ppc_inst_prefixed (ppc_inst_read (prev->ainsn.insn))) {printk ("Cannot register a kprobe on the second word of prefixed instruction\n" ); ret = -EINVAL ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 623/862 powerpc/pseries/vas: Pass hw_cpu_id to node associativity HCALL
In reply to Greg Kroah-HartmanFrom: Haren Myneni <[email protected]>
[ Upstream commit f3e5d9e53e74d77e711a2c90a91a8b0836a9e0b3 ]
Generally the hypervisor decides to allocate a window on different VAS instances. But if user space wishes to allocate on the current VAS instance where the process is executing, the kernel has to pass associativity domain IDs to allocate VAS window HCALL.
To determine the associativity domain IDs for the current CPU, smp_processor_id() is passed to node associativity HCALL which may return H_P2 (-55) error during DLPAR CPU event. This is because Linux CPU numbers (smp_processor_id()) are not the same as the hypervisor's view of CPU numbers.
Fix the issue by passing hard_smp_processor_id() with VPHN_FLAG_VCPU flag (PAPR 14.11.6.1 H_HOME_NODE_ASSOCIATIVITY).
--- arch/powerpc/platforms/pseries/vas.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/powerpc/platforms/pseries/vas.c +1 -1
@@ -333,7 +333,7 @@ static struct vas_window *vas_allocate_window(int vas_id, u64 flags,* So no unpacking needs to be done. */ rc =plpar_hcall9 (H_HOME_NODE_ASSOCIATIVITY , domain, -VPHN_FLAG_VCPU ,smp_processor_id ()); +VPHN_FLAG_VCPU ,hard_smp_processor_id ());if (rc !=H_SUCCESS ) {pr_err ("H_HOME_NODE_ASSOCIATIVITY error: %d\n" , rc); goto out;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 624/862 crypto: sahara - dont sleep when in softirq
In reply to Greg Kroah-HartmanFrom: Zhengchao Shao <[email protected]>
[ Upstream commit 108586eba094b318e6a831f977f4ddcc403a15da ]
Function of sahara_aes_crypt maybe could be called by function of crypto_skcipher_encrypt during the rx softirq, so it is not allowed to use mutex lock.
--- drivers/crypto/sahara.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-)
drivers/crypto/sahara.c +9 -9
@@ -26,10 +26,10 @@#include <linux/kernel.h> #include <linux/kthread.h> #include <linux/module.h> -#include <linux/mutex.h> #include <linux/of.h> #include <linux/of_device.h> #include <linux/platform_device.h> +#include <linux/spinlock.h> #define SHA_BUFFER_LEN PAGE_SIZE#define SAHARA_MAX_SHA_BLOCK_SIZE SHA256_BLOCK_SIZE
@@ -196,7 +196,7 @@ struct sahara_dev {void __iomem *regs_base;struct clk *clk_ipg;struct clk *clk_ahb; -struct mutex queue_mutex; +spinlock_t queue_spinlock;struct task_struct *kthread;struct completion dma_completion;
@@ -642,9 +642,9 @@ static int sahara_aes_crypt(struct skcipher_request *req, unsigned long mode) rctx->mode = mode; -mutex_lock (&dev->queue_mutex); +spin_lock_bh (&dev->queue_spinlock); err =crypto_enqueue_request (&dev->queue, &req->base); -mutex_unlock (&dev->queue_mutex); +spin_unlock_bh (&dev->queue_spinlock);wake_up_process (dev->kthread);
@@ -1043,10 +1043,10 @@ static int sahara_queue_manage(void *data) do { __set_current_state(TASK_INTERRUPTIBLE); - mutex_lock(&dev->queue_mutex); + spin_lock_bh(&dev->queue_spinlock); backlog = crypto_get_backlog(&dev->queue); async_req = crypto_dequeue_request(&dev->queue); - mutex_unlock(&dev->queue_mutex); + spin_unlock_bh(&dev->queue_spinlock); if (backlog) backlog->complete(backlog, -EINPROGRESS);
@@ -1092,9 +1092,9 @@ static int sahara_sha_enqueue(struct ahash_request *req, int last) rctx->first =1 ; } -mutex_lock (&dev->queue_mutex); +spin_lock_bh (&dev->queue_spinlock); ret =crypto_enqueue_request (&dev->queue, &req->base); -mutex_unlock (&dev->queue_mutex); +spin_unlock_bh (&dev->queue_spinlock);wake_up_process (dev->kthread);
@@ -1449,7 +1449,7 @@ static int sahara_probe(struct platform_device *pdev)crypto_init_queue (&dev->queue,SAHARA_QUEUE_LENGTH ); -mutex_init (&dev->queue_mutex); +spin_lock_init (&dev->queue_spinlock); dev_ptr = dev;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 625/862 crypto: hisilicon/zip - fix mismatch in get/set sgl_sge_nr
In reply to Greg Kroah-HartmanFrom: Ye Weihua <[email protected]>
[ Upstream commit d74f9340097a881869c4c22ca376654cc2516ecc ]
KASAN reported this Bug:
[17619.659757] BUG: KASAN: global-out-of-bounds in param_get_int+0x34/0x60 [17619.673193] Read of size 4 at addr fffff01332d7ed00 by task read_all/1507958 ... [17619.698934] The buggy address belongs to the variable: [17619.708371] sgl_sge_nr+0x0/0xffffffffffffa300 [hisi_zip]
There is a mismatch in hisi_zip when get/set the variable sgl_sge_nr. The type of sgl_sge_nr is u16, and get/set sgl_sge_nr by param_get/set_int.
Replacing param_get/set_int to param_get/set_ushort can fix this bug.
--- drivers/crypto/hisilicon/zip/zip_crypto.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/crypto/hisilicon/zip/zip_crypto.c +2 -2
@@ -123,12 +123,12 @@ static int sgl_sge_nr_set(const char *val, const struct kernel_param *kp)if (ret || n ==0 || n >HISI_ACC_SGL_SGE_NR_MAX )return -EINVAL ; -return param_set_int (val, kp); +return param_set_ushort (val, kp); }static const struct kernel_param_ops sgl_sge_nr_ops = { .set = sgl_sge_nr_set, - .get = param_get_int, + .get = param_get_ushort, };static u16 sgl_sge_nr =HZIP_SGL_SGE_NR ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 626/862 hwrng: arm-smccc-trng - fix NO_ENTROPY handling
In reply to Greg Kroah-HartmanFrom: James Cowgill <[email protected]>
[ Upstream commit 042b4b169c6fb9d4df268d66282d7302dd73d37b ]
The SMCCC_RET_TRNG_NO_ENTROPY switch arm is never used because the NO_ENTROPY return value is negative and negative values are handled above the switch by immediately returning.
Fix by handling errors using a default arm in the switch.
--- drivers/char/hw_random/arm_smccc_trng.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/char/hw_random/arm_smccc_trng.c +2 -2
@@ -71,8 +71,6 @@ static int smccc_trng_read(struct hwrng *rng, void *data, size_t max, bool wait) MAX_BITS_PER_CALL);arm_smccc_1_1_invoke (ARM_SMCCC_TRNG_RND , bits, &res); -if ((int )res.a0 <0 ) -return (int )res.a0;switch ((int )res.a0) {case SMCCC_RET_SUCCESS :
@@ -88,6 +86,8 @@ static int smccc_trng_read(struct hwrng *rng, void *data, size_t max, bool wait)return copied;cond_resched ();break ; +default : +return -EIO ; } }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 627/862 crypto: ccp - Fail the PSP initialization when writing psp data file failed
In reply to Greg Kroah-HartmanFrom: Jacky Li <[email protected]>
[ Upstream commit efb4b01c1c993d245e6608076684ff2162cf9dc6 ]
Currently the OS continues the PSP initialization when there is a write failure to the init_ex_file. Therefore, the userspace would be told that SEV is properly INIT'd even though the psp data file is not updated. This is problematic because later when asked for the SEV data, the OS won't be able to provide it.
--- drivers/crypto/ccp/sev-dev.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-)
drivers/crypto/ccp/sev-dev.c +15 -11
@@ -231,7 +231,7 @@ static int sev_read_init_ex_file(void)return 0 ; } -static void sev_write_init_ex_file (void ) +static int sev_write_init_ex_file (void ) {struct sev_device *sev = psp_master->sev_data;struct file *fp;
@@ -241,14 +241,16 @@ static void sev_write_init_ex_file(void)lockdep_assert_held (&sev_cmd_mutex);if (!sev_init_ex_buffer) -return ; +return 0 ; fp =open_file_as_root (init_ex_path,O_CREAT |O_WRONLY ,0600 );if (IS_ERR (fp)) { +int ret =PTR_ERR (fp); +dev_err (sev->dev, -"SEV: could not open file for write, error %ld\n" , -PTR_ERR (fp)); -return ; +"SEV: could not open file for write, error %d\n" , + ret); +return ret; } nwrite =kernel_write (fp, sev_init_ex_buffer,NV_LENGTH , &offset);
@@ -259,18 +261,20 @@ static void sev_write_init_ex_file(void)dev_err (sev->dev,"SEV: failed to write %u bytes to non volatile memory area, ret %ld\n" ,NV_LENGTH , nwrite); -return ; +return -EIO ; }dev_dbg (sev->dev,"SEV: write successful to NV file\n" ); + +return 0 ; } -static void sev_write_init_ex_file_if_required (int cmd_id) +static int sev_write_init_ex_file_if_required (int cmd_id) {lockdep_assert_held (&sev_cmd_mutex);if (!sev_init_ex_buffer) -return ; +return 0 ;/* * Only a few platform commands modify the SPI/NV area, but none of the
@@ -285,10 +289,10 @@ static void sev_write_init_ex_file_if_required(int cmd_id)case SEV_CMD_PEK_GEN :break ;default : -return ; +return 0 ; } -sev_write_init_ex_file (); +return sev_write_init_ex_file (); }static int __sev_do_cmd_locked (int cmd,void *data,int *psp_ret)
@@ -361,7 +365,7 @@ static int __sev_do_cmd_locked(int cmd, void *data, int *psp_ret) cmd, reg & PSP_CMDRESP_ERR_MASK); ret = -EIO ; }else { -sev_write_init_ex_file_if_required (cmd); + ret =sev_write_init_ex_file_if_required (cmd); } print_hex_dump_debug("(out): ", DUMP_PREFIX_OFFSET, 16, 2, data,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 628/862 cgroup: Honor callers cgroup NS when resolving path
In reply to Greg Kroah-HartmanFrom: Michal Koutný <[email protected]>
[ Upstream commit 74e4b956eb1cac0e4c10c240339b1bbfbc9a4c48 ]
cgroup_get_from_path() is not widely used function. Its callers presume the path is resolved under cgroup namespace. (There is one caller currently and resolving in init NS won't make harm (netfilter). However, future users may be subject to different effects when resolving globally.)
Since, there's currently no use for the global resolution, modify the existing function to take cgroup NS into account.
--- kernel/cgroup/cgroup.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
kernel/cgroup/cgroup.c +5 -1
@@ -6638,8 +6638,12 @@ struct cgroup *cgroup_get_from_path(const char *path) {struct kernfs_node *kn;struct cgroup *cgrp =ERR_PTR (-ENOENT ); +struct cgroup *root_cgrp; - kn =kernfs_walk_and_get (cgrp_dfl_root.cgrp.kn, path); +spin_lock_irq (&css_set_lock); + root_cgrp =current_cgns_cgroup_from_root (&cgrp_dfl_root); + kn =kernfs_walk_and_get (root_cgrp->kn, path); +spin_unlock_irq (&css_set_lock);if (!kn) goto out;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 629/862 hwrng: imx-rngc - use devm_clk_get_enabled
In reply to Greg Kroah-HartmanFrom: Martin Kaiser <[email protected]>
[ Upstream commit 6a2bc448423cea44e7dba0f72d7c82ae04ab201e ]
Use the new devm_clk_get_enabled function to get our clock.
We don't have to disable and unprepare the clock ourselves any more in error paths and in the remove function.
Stable-dep-of: 10a2199caf43 ("hwrng: imx-rngc - Moving IRQ handler registering after imx_rngc_irq_mask_clear()")
--- drivers/char/hw_random/imx-rngc.c | 25 ++++++------------------- 1 file changed, 6 insertions(+), 19 deletions(-)
drivers/char/hw_random/imx-rngc.c +6 -19
@@ -245,7 +245,7 @@ static int imx_rngc_probe(struct platform_device *pdev)if (IS_ERR (rngc->base))return PTR_ERR (rngc->base); - rngc->clk =devm_clk_get (&pdev->dev,NULL ); + rngc->clk =devm_clk_get_enabled (&pdev->dev,NULL );if (IS_ERR (rngc->clk)) {dev_err (&pdev->dev,"Can not get rng_clk\n" );return PTR_ERR (rngc->clk);
@@ -255,26 +255,20 @@ static int imx_rngc_probe(struct platform_device *pdev)if (irq <0 )return irq; - ret =clk_prepare_enable (rngc->clk); -if (ret) -return ret; - ver_id =readl (rngc->base +RNGC_VER_ID ); rng_type = ver_id >>RNGC_TYPE_SHIFT ;/* * This driver supports only RNGC and RNGB. (There's a different * driver for RNGA.) */ -if (rng_type !=RNGC_TYPE_RNGC && rng_type !=RNGC_TYPE_RNGB ) { - ret = -ENODEV ; - goto err; - } +if (rng_type !=RNGC_TYPE_RNGC && rng_type !=RNGC_TYPE_RNGB ) +return -ENODEV ; ret =devm_request_irq (&pdev->dev, irq, imx_rngc_irq,0 , pdev->name, (void *)rngc);if (ret) {dev_err (rngc->dev,"Can't get interrupt working.\n" ); - goto err; +return ret; }init_completion (&rngc->rng_op_done);
@@ -294,14 +288,14 @@ static int imx_rngc_probe(struct platform_device *pdev) ret =imx_rngc_self_test (rngc);if (ret) {dev_err (rngc->dev,"self test failed\n" ); - goto err; +return ret; } } ret =hwrng_register (&rngc->rng);if (ret) {dev_err (&pdev->dev,"hwrng registration failed\n" ); - goto err; +return ret; } dev_info(&pdev->dev,
@@ -309,11 +303,6 @@ static int imx_rngc_probe(struct platform_device *pdev) rng_type ==RNGC_TYPE_RNGB ?'B' :'C' , (ver_id >> RNGC_VER_MAJ_SHIFT) & 0xff, ver_id & 0xff);return 0 ; - -err: -clk_disable_unprepare (rngc->clk); - -return ret; } static int __exit imx_rngc_remove(struct platform_device *pdev)
@@ -322,8 +311,6 @@ static int __exit imx_rngc_remove(struct platform_device *pdev)hwrng_unregister (&rngc->rng); -clk_disable_unprepare (rngc->clk); -return 0 ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 630/862 hwrng: imx-rngc - Moving IRQ handler registering after imx_rngc_irq_mask_clear()
In reply to Greg Kroah-HartmanFrom: Kshitiz Varshney <[email protected]>
[ Upstream commit 10a2199caf437e893d9027d97700b3c6010048b7 ]
Issue:
While servicing interrupt, if the IRQ happens to be because of a SEED_DONE due to a previous boot stage, you end up completing the completion prematurely, hence causing kernel to crash while booting.
Fix:
Moving IRQ handler registering after imx_rngc_irq_mask_clear()
--- drivers/char/hw_random/imx-rngc.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
drivers/char/hw_random/imx-rngc.c +7 -7
@@ -264,13 +264,6 @@ static int imx_rngc_probe(struct platform_device *pdev)if (rng_type !=RNGC_TYPE_RNGC && rng_type !=RNGC_TYPE_RNGB )return -ENODEV ; - ret =devm_request_irq (&pdev->dev, - irq, imx_rngc_irq,0 , pdev->name, (void *)rngc); -if (ret) { -dev_err (rngc->dev,"Can't get interrupt working.\n" ); -return ret; - } -init_completion (&rngc->rng_op_done); rngc->rng.name = pdev->name;
@@ -284,6 +277,13 @@ static int imx_rngc_probe(struct platform_device *pdev)imx_rngc_irq_mask_clear (rngc); + ret =devm_request_irq (&pdev->dev, + irq, imx_rngc_irq,0 , pdev->name, (void *)rngc); +if (ret) { +dev_err (rngc->dev,"Can't get interrupt working.\n" ); +return ret; + } +if (self_test) { ret =imx_rngc_self_test (rngc);if (ret) {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 631/862 crypto: qat - fix default value of WDT timer
In reply to Greg Kroah-HartmanFrom: Lucas Segarra Fernandez <[email protected]>
[ Upstream commit cc40b04c08400d86d2d6ea0159e0617e717f729c ]
The QAT HW supports an hardware mechanism to detect an accelerator hang. The reporting of a hang occurs after a watchdog timer (WDT) expires.
The value of the WDT set previously was too small and was causing false positives.
Change the default value of the WDT to 0x7000000ULL to avoid this.
--- drivers/crypto/qat/qat_common/adf_gen4_hw_data.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/crypto/qat/qat_common/adf_gen4_hw_data.h +1 -1
@@ -107,7 +107,7 @@ do { \* Timeout is in cycles. Clock speed may vary across products but this * value should be a few milli-seconds. */ -#define ADF_SSM_WDT_DEFAULT_VALUE 0x200000 +#define ADF_SSM_WDT_DEFAULT_VALUE 0x7000000ULL#define ADF_SSM_WDT_PKE_DEFAULT_VALUE 0x8000000#define ADF_SSMWDTL_OFFSET 0x54#define ADF_SSMWDTH_OFFSET 0x5C
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 632/862 crypto: hisilicon/qm - fix missing put dfx access
In reply to Greg Kroah-HartmanFrom: Weili Qian <[email protected]>
[ Upstream commit 5afc904f443de2afd31c4e0686ba178beede86fe ]
In function qm_cmd_write(), if function returns from branch 'atomic_read(&qm->status.flags) == QM_STOP', the got dfx access is forgotten to put.
--- drivers/crypto/hisilicon/qm.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/crypto/hisilicon/qm.c +4 -2
@@ -2245,8 +2245,10 @@ static ssize_t qm_cmd_write(struct file *filp, const char __user *buffer,return ret;/* Judge if the instance is being reset. */ -if (unlikely (atomic_read (&qm->status.flags) ==QM_STOP )) -return 0 ; +if (unlikely (atomic_read (&qm->status.flags) ==QM_STOP )) { + ret =0 ; + goto put_dfx_access; + }if (count >QM_DBG_WRITE_LEN ) { ret = -ENOSPC ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 633/862 cgroup/cpuset: Enable update_tasks_cpumask() on top_cpuset
In reply to Greg Kroah-HartmanFrom: Waiman Long <[email protected]>
[ Upstream commit ec5fbdfb99d18482619ac42605cb80fbb56068ee ]
Previously, update_tasks_cpumask() is not supposed to be called with top cpuset. With cpuset partition that takes CPUs away from the top cpuset, adjusting the cpus_mask of the tasks in the top cpuset is necessary. Percpu kthreads, however, are ignored.
--- kernel/cgroup/cpuset.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-)
kernel/cgroup/cpuset.c +11 -7
@@ -33,6 +33,7 @@#include <linux/interrupt.h> #include <linux/kernel.h> #include <linux/kmod.h> +#include <linux/kthread.h> #include <linux/list.h> #include <linux/mempolicy.h> #include <linux/mm.h>
@@ -1127,10 +1128,18 @@ static void update_tasks_cpumask(struct cpuset *cs) {struct css_task_iter it;struct task_struct *task; +bool top_cs = cs == &top_cpuset;css_task_iter_start (&cs->css,0 , &it); -while ((task =css_task_iter_next (&it))) +while ((task =css_task_iter_next (&it))) { +/* +* Percpu kthreads in top_cpuset are ignored +*/ +if (top_cs && (task->flags &PF_KTHREAD ) && +kthread_is_per_cpu (task)) +continue ;set_cpus_allowed_ptr (task, cs->effective_cpus); + }css_task_iter_end (&it); }
@@ -2092,12 +2101,7 @@ static int update_prstate(struct cpuset *cs, int new_prs)update_flag (CS_CPU_EXCLUSIVE , cs,0 ); } -/* -* Update cpumask of parent's tasks except when it is the top -* cpuset as some system daemons cannot be mapped to other CPUs. -*/ -if (parent != &top_cpuset) -update_tasks_cpumask (parent); +update_tasks_cpumask (parent);if (parent->child_ecpus_count)update_sibling_cpumasks (parent, cs, &tmpmask);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 634/862 iommu/omap: Fix buffer overflow in debugfs
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit 184233a5202786b20220acd2d04ddf909ef18f29 ]
There are two issues here:
1) The "len" variable needs to be checked before the very first write. Otherwise if omap2_iommu_dump_ctx() with "bytes" less than 32 it is a buffer overflow.
2) The snprintf() function returns the number of bytes that *would* have been copied if there were enough space. But we want to know the number of bytes which were *actually* copied so use scnprintf() instead.
--- drivers/iommu/omap-iommu-debug.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/iommu/omap-iommu-debug.c +3 -3
@@ -32,12 +32,12 @@ static inline bool is_omap_iommu_detached(struct omap_iommu *obj)ssize_t bytes; \const char *str ="%20s: %08x\n" ; \const int maxcol =32 ; \ - bytes =snprintf (p, maxcol, str,__stringify (name), \ +if (len < maxcol) \ + goto out; \ + bytes =scnprintf (p, maxcol, str,__stringify (name), \ iommu_read_reg(obj, MMU_##name)); \ p += bytes; \ len -= bytes; \ -if (len < maxcol) \ - goto out; \ }while (0 ) static ssize_t
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 635/862 crypto: akcipher - default implementation for setting a private key
In reply to Greg Kroah-HartmanFrom: Ignat Korchagin <[email protected]>
[ Upstream commit bc155c6c188c2f0c5749993b1405673d25a80389 ]
Changes from v1:
* removed the default implementation from set_pub_key: it is assumed that an implementation must always have this callback defined as there are no use case for an algorithm, which doesn't need a public key
Many akcipher implementations (like ECDSA) support only signature verifications, so they don't have all callbacks defined.
Commit 78a0324f4a53 ("crypto: akcipher - default implementations for request callbacks") introduced default callbacks for sign/verify operations, which just return an error code.
However, these are not enough, because before calling sign the caller would likely call set_priv_key first on the instantiated transform (as the in-kernel testmgr does). This function does not have a default stub, so the kernel crashes, when trying to set a private key on an akcipher, which doesn't support signature generation.
I've noticed this, when trying to add a KAT vector for ECDSA signature to the testmgr.
With this patch the testmgr returns an error in dmesg (as it should) instead of crashing the kernel NULL ptr dereference.
--- crypto/akcipher.c | 8 ++++++++ 1 file changed, 8 insertions(+)
crypto/akcipher.c +8 -0
@@ -120,6 +120,12 @@ static int akcipher_default_op(struct akcipher_request *req)return -ENOSYS ; } +static int akcipher_default_set_key (struct crypto_akcipher *tfm, +const void *key,unsigned int keylen) +{ +return -ENOSYS ; +} +int crypto_register_akcipher (struct akcipher_alg *alg) {struct crypto_alg *base = &alg->base;
@@ -132,6 +138,8 @@ int crypto_register_akcipher(struct akcipher_alg *alg) alg->encrypt = akcipher_default_op;if (!alg->decrypt) alg->decrypt = akcipher_default_op; +if (!alg->set_priv_key) + alg->set_priv_key = akcipher_default_set_key;akcipher_prepare_alg (alg);return crypto_register_alg (base);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 636/862 crypto: ccp - Release dma channels before dmaengine unrgister
In reply to Greg Kroah-HartmanFrom: Koba Ko <[email protected]>
[ Upstream commit 68dbe80f5b510c66c800b9e8055235c5b07e37d1 ]
A warning is shown during shutdown,
__dma_async_device_channel_unregister called while 2 clients hold a reference
WARNING: CPU: 15 PID: 1 at drivers/dma/dmaengine.c:1110 __dma_async_device_channel_unregister+0xb7/0xc0
Call dma_release_channel for occupied channles before dma_async_device_unregister.
--- drivers/crypto/ccp/ccp-dmaengine.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/crypto/ccp/ccp-dmaengine.c +5 -1
@@ -641,6 +641,10 @@ static void ccp_dma_release(struct ccp_device *ccp)for (i =0 ; i < ccp->cmd_q_count; i++) { chan = ccp->ccp_dma_chan + i; dma_chan = &chan->dma_chan; + +if (dma_chan->client_count) +dma_release_channel (dma_chan); +tasklet_kill (&chan->cleanup_tasklet);list_del_rcu (&dma_chan->device_node); }
@@ -766,8 +770,8 @@ void ccp_dmaengine_unregister(struct ccp_device *ccp)if (!dmaengine)return ; -dma_async_device_unregister (dma_dev);ccp_dma_release (ccp); +dma_async_device_unregister (dma_dev);kmem_cache_destroy (ccp->dma_desc_cache);kmem_cache_destroy (ccp->dma_cmd_cache);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 637/862 crypto: inside-secure - Change swab to swab32
In reply to Greg Kroah-HartmanFrom: Peter Harliman Liem <[email protected]>
[ Upstream commit 664593407e936b6438fbfaaf98876910fd31cf9a ]
The use of swab() is causing failures in 64-bit arch, as it translates to __swab64() instead of the intended __swab32(). It eventually causes wrong results in xcbcmac & cmac algo.
--- drivers/crypto/inside-secure/safexcel_hash.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/crypto/inside-secure/safexcel_hash.c +4 -4
@@ -383,7 +383,7 @@ static int safexcel_ahash_send_req(struct crypto_async_request *async, int ring,u32 x; x = ipad[i] ^ ipad[i +4 ]; - cache[i] ^=swab (x); + cache[i] ^=swab32 (x); } } cache_len =AES_BLOCK_SIZE ;
@@ -821,7 +821,7 @@ static int safexcel_ahash_final(struct ahash_request *areq)u32 *result = (void *)areq->result;/* K3 */ - result[i] =swab (ctx->base.ipad.word[i +4 ]); + result[i] =swab32 (ctx->base.ipad.word[i +4 ]); } areq->result[0 ] ^=0x80 ;// 10- padding crypto_cipher_encrypt_one (ctx->kaes, areq->result, areq->result);
@@ -2106,7 +2106,7 @@ static int safexcel_xcbcmac_setkey(struct crypto_ahash *tfm, const u8 *key,crypto_cipher_encrypt_one (ctx->kaes, (u8 *)key_tmp +AES_BLOCK_SIZE ,"\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3" );for (i =0 ; i <3 *AES_BLOCK_SIZE /sizeof (u32); i++) - ctx->base.ipad.word[i] =swab (key_tmp[i]); + ctx->base.ipad.word[i] =swab32 (key_tmp[i]);crypto_cipher_clear_flags (ctx->kaes,CRYPTO_TFM_REQ_MASK ); crypto_cipher_set_flags(ctx->kaes, crypto_ahash_get_flags(tfm) &
@@ -2189,7 +2189,7 @@ static int safexcel_cmac_setkey(struct crypto_ahash *tfm, const u8 *key,return ret;for (i =0 ; i < len /sizeof (u32); i++) - ctx->base.ipad.word[i +8 ] =swab (aes.key_enc[i]); + ctx->base.ipad.word[i +8 ] =swab32 (aes.key_enc[i]);/* precompute the CMAC key material */ crypto_cipher_clear_flags (ctx->kaes,CRYPTO_TFM_REQ_MASK );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 638/862 crypto: qat - fix DMA transfer direction
In reply to Greg Kroah-HartmanFrom: Damian Muszynski <[email protected]>
[ Upstream commit cf5bb835b7c8a5fee7f26455099cca7feb57f5e9 ]
When CONFIG_DMA_API_DEBUG is selected, while running the crypto self test on the QAT crypto algorithms, the function add_dma_entry() reports a warning similar to the one below, saying that overlapping mappings are not supported. This occurs in tests where the input and the output scatter list point to the same buffers (i.e. two different scatter lists which point to the same chunks of memory).
The logic that implements the mapping uses the flag DMA_BIDIRECTIONAL for both the input and the output scatter lists which leads to overlapped write mappings. These are not supported by the DMA layer.
Fix by specifying the correct DMA transfer directions when mapping buffers. For in-place operations where the input scatter list matches the output scatter list, buffers are mapped once with DMA_BIDIRECTIONAL, otherwise input buffers are mapped using the flag DMA_TO_DEVICE and output buffers are mapped with DMA_FROM_DEVICE. Overlapping a read mapping with a write mapping is a valid case in dma-coherent devices like QAT.
The function that frees and unmaps the buffers, qat_alg_free_bufl() has been changed accordingly to the changes to the mapping function.
DMA-API: 4xxx 0000:06:00.0: cacheline tracking EEXIST, overlapping mappings aren't supported
WARNING: CPU: 53 PID: 4362 at kernel/dma/debug.c:570 add_dma_entry+0x1e9/0x270 ... Call Trace: dma_map_page_attrs+0x82/0x2d0 ? preempt_count_add+0x6a/0xa0 qat_alg_sgl_to_bufl+0x45b/0x990 [intel_qat] qat_alg_aead_dec+0x71/0x250 [intel_qat] crypto_aead_decrypt+0x3d/0x70 test_aead_vec_cfg+0x649/0x810 ? number+0x310/0x3a0 ? vsnprintf+0x2a3/0x550 ? scnprintf+0x42/0x70 ? valid_sg_divisions.constprop.0+0x86/0xa0 ? test_aead_vec+0xdf/0x120 test_aead_vec+0xdf/0x120 alg_test_aead+0x185/0x400 alg_test+0x3d8/0x500 ? crypto_acomp_scomp_free_ctx+0x30/0x30 ? __schedule+0x32a/0x12a0 ? ttwu_queue_wakelist+0xbf/0x110 ? _raw_spin_unlock_irqrestore+0x23/0x40 ? try_to_wake_up+0x83/0x570 ? _raw_spin_unlock_irqrestore+0x23/0x40 ? __set_cpus_allowed_ptr_locked+0xea/0x1b0 ? crypto_acomp_scomp_free_ctx+0x30/0x30 cryptomgr_test+0x27/0x50 kthread+0xe6/0x110 ? kthread_complete_and_exit+0x20/0x20 ret_from_fork+0x1f/0x30
--- drivers/crypto/qat/qat_common/qat_algs.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-)
drivers/crypto/qat/qat_common/qat_algs.c +12 -6
@@ -673,11 +673,14 @@ static void qat_alg_free_bufl(struct qat_crypto_instance *inst,dma_addr_t blpout = qat_req->buf.bloutp;size_t sz = qat_req->buf.sz;size_t sz_out = qat_req->buf.sz_out; +int bl_dma_dir;int i; + bl_dma_dir = blp != blpout ?DMA_TO_DEVICE :DMA_BIDIRECTIONAL ; +for (i =0 ; i < bl->num_bufs; i++)dma_unmap_single (dev, bl->bufers[i].addr, - bl->bufers[i].len,DMA_BIDIRECTIONAL ); + bl->bufers[i].len, bl_dma_dir);dma_unmap_single (dev, blp, sz,DMA_TO_DEVICE );
@@ -691,7 +694,7 @@ static void qat_alg_free_bufl(struct qat_crypto_instance *inst,for (i = bufless; i < blout->num_bufs; i++) {dma_unmap_single (dev, blout->bufers[i].addr, blout->bufers[i].len, -DMA_BIDIRECTIONAL ); +DMA_FROM_DEVICE ); }dma_unmap_single (dev, blpout, sz_out,DMA_TO_DEVICE );
@@ -716,6 +719,7 @@ static int qat_alg_sgl_to_bufl(struct qat_crypto_instance *inst,struct scatterlist *sg;size_t sz_out, sz =struct_size (bufl, bufers, n);int node =dev_to_node (&GET_DEV (inst->accel_dev)); +int bufl_dma_dir;if (unlikely (!n))return -EINVAL ;
@@ -733,6 +737,8 @@ static int qat_alg_sgl_to_bufl(struct qat_crypto_instance *inst, qat_req->buf.sgl_src_valid = true; } + bufl_dma_dir = sgl != sglout ?DMA_TO_DEVICE :DMA_BIDIRECTIONAL ; +for_each_sg (sgl, sg, n, i) bufl->bufers[i].addr =DMA_MAPPING_ERROR ;
@@ -744,7 +750,7 @@ static int qat_alg_sgl_to_bufl(struct qat_crypto_instance *inst, bufl->bufers[y].addr =dma_map_single (dev,sg_virt (sg), sg->length, -DMA_BIDIRECTIONAL ); + bufl_dma_dir); bufl->bufers[y].len = sg->length;if (unlikely (dma_mapping_error (dev, bufl->bufers[y].addr))) goto err_in;
@@ -787,7 +793,7 @@ static int qat_alg_sgl_to_bufl(struct qat_crypto_instance *inst, bufers[y].addr =dma_map_single (dev,sg_virt (sg), sg->length, -DMA_BIDIRECTIONAL ); +DMA_FROM_DEVICE );if (unlikely (dma_mapping_error (dev, bufers[y].addr))) goto err_out; bufers[y].len = sg->length;
@@ -817,7 +823,7 @@ static int qat_alg_sgl_to_bufl(struct qat_crypto_instance *inst,if (!dma_mapping_error (dev, buflout->bufers[i].addr))dma_unmap_single (dev, buflout->bufers[i].addr, buflout->bufers[i].len, -DMA_BIDIRECTIONAL ); +DMA_FROM_DEVICE );if (!qat_req->buf.sgl_dst_valid)kfree (buflout);
@@ -831,7 +837,7 @@ static int qat_alg_sgl_to_bufl(struct qat_crypto_instance *inst,if (!dma_mapping_error (dev, bufl->bufers[i].addr))dma_unmap_single (dev, bufl->bufers[i].addr, bufl->bufers[i].len, -DMA_BIDIRECTIONAL ); + bufl_dma_dir);if (!qat_req->buf.sgl_src_valid)kfree (bufl);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 639/862 clocksource/drivers/arm_arch_timer: Fix handling of ARM erratum 858921
In reply to Greg Kroah-HartmanFrom: Kunkun Jiang <[email protected]>
[ Upstream commit 6c3b62d93e195f78c1437c8fa7581e9b2f00886e ]
The commit a38b71b0833e ("clocksource/drivers/arm_arch_timer:
Move system register timer programming over to CVAL") moves the programming of the timers from the countdown timer (TVAL) over to the comparator (CVAL). This makes it necessary to read the counter when programming next event. However, the workaround of Cortex-A73 erratum 858921 does not set the corresponding set_next_event_phys and set_next_event_virt.
Add the appropriate hooks to apply the erratum mitigation when programming the next timer event.
--- drivers/clocksource/arm_arch_timer.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/clocksource/arm_arch_timer.c +2 -0
@@ -473,6 +473,8 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = { .desc = "ARM erratum 858921", .read_cntpct_el0 = arm64_858921_read_cntpct_el0, .read_cntvct_el0 = arm64_858921_read_cntvct_el0, + .set_next_event_phys = erratum_set_next_event_phys, + .set_next_event_virt = erratum_set_next_event_virt, },#endif #ifdef CONFIG_SUN50I_ERRATUM_UNKNOWN1
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 640/862 clocksource/drivers/timer-gxp: Add missing error handling in gxp_timer_probe
In reply to Greg Kroah-HartmanFrom: Lin Yujun <[email protected]>
[ Upstream commit 0e2c8e6d769bcdc4f6634a02c545356282275e68 ]
Add platform_device_put() to make sure to free the platform device in the event platform_device_add() fails.
--- drivers/clocksource/timer-gxp.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/clocksource/timer-gxp.c +6 -1
@@ -171,6 +171,7 @@ static int gxp_timer_probe(struct platform_device *pdev) {struct platform_device *gxp_watchdog_device;struct device *dev = &pdev->dev; +int ret;if (!gxp_timer) {pr_err ("Gxp Timer not initialized, cannot create watchdog" );
@@ -187,7 +188,11 @@ static int gxp_timer_probe(struct platform_device *pdev) gxp_watchdog_device->dev.platform_data = gxp_timer->counter; gxp_watchdog_device->dev.parent = dev; -return platform_device_add (gxp_watchdog_device); + ret =platform_device_add (gxp_watchdog_device); +if (ret) +platform_device_put (gxp_watchdog_device); + +return ret; }static const struct of_device_id gxp_timer_of_match[] = {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 641/862 cifs: return correct error in ->calc_signature()
In reply to Greg Kroah-HartmanFrom: Enzo Matsumiya <[email protected]>
[ Upstream commit 09a1f9a168ae1f69f701689429871793174417d2 ]
If an error happens while getting the key or session in the ->calc_signature implementations, 0 (success) is returned. Fix it by returning a proper error code.
Since it seems to be highly unlikely to happen wrap the rc check in unlikely() too.
--- fs/cifs/smb2transport.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
fs/cifs/smb2transport.c +6 -4
@@ -225,9 +225,9 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,struct smb_rqst drqst; ses =smb2_find_smb_ses (server,le64_to_cpu (shdr->SessionId)); -if (!ses) { +if (unlikely (!ses)) {cifs_server_dbg (VFS ,"%s: Could not find session\n" , __func__); -return 0 ; +return -ENOENT ; }memset (smb2_signature,0x0 ,SMB2_HMACSHA256_SIZE );
@@ -557,8 +557,10 @@ smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,u8 key[SMB3_SIGN_KEY_SIZE ]; rc =smb2_get_sign_key (le64_to_cpu (shdr->SessionId), server, key); -if (rc) -return 0 ; +if (unlikely (rc)) { +cifs_server_dbg (VFS ,"%s: Could not get signing key\n" , __func__); +return rc; + }if (allocate_crypto) { rc =cifs_alloc_hash ("cmac(aes)" , &hash, &sdesc);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 642/862 iommu/iova: Fix module config properly
In reply to Greg Kroah-HartmanFrom: Robin Murphy <[email protected]>
[ Upstream commit 4f58330fcc8482aa90674e1f40f601e82f18ed4a ]
IOMMU_IOVA is intended to be an optional library for users to select as and when they desire. Since it can be a module now, this means that built-in code which has chosen not to select it should not fail to link if it happens to have selected as a module by someone else. Replace IS_ENABLED() with IS_REACHABLE() to do the right thing.
--- include/linux/iova.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/iova.h +1 -1
@@ -75,7 +75,7 @@ static inline unsigned long iova_pfn(struct iova_domain *iovad, dma_addr_t iova)return iova >>iova_shift (iovad); } -#if IS_ENABLED (CONFIG_IOMMU_IOVA ) +#if IS_REACHABLE (CONFIG_IOMMU_IOVA )int iova_cache_get (void );void iova_cache_put (void );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 643/862 tracing: kprobe: Fix kprobe event gen test module on exit
In reply to Greg Kroah-HartmanFrom: Yipeng Zou <[email protected]>
[ Upstream commit ac48e189527fae87253ef2bf58892e782fb36874 ]
Correct gen_kretprobe_test clr event para on module exit. This will make it can't to delete.
--- kernel/trace/kprobe_event_gen_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/trace/kprobe_event_gen_test.c +1 -1
@@ -206,7 +206,7 @@ static void __exit kprobe_event_gen_test_exit(void)WARN_ON (kprobe_event_delete ("gen_kprobe_test" ));/* Disable the event or you can't remove it */ -WARN_ON (trace_array_set_clr_event (gen_kprobe_test->tr, +WARN_ON (trace_array_set_clr_event (gen_kretprobe_test->tr,"kprobes" ,"gen_kretprobe_test" , false));
Signature · 9 lines
2.35.1 _______________________________________________ linux-riscv mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-riscv
Greg Kroah-Hartman
maintainerPATCH 644/862 tracing: kprobe: Make gen test module work in arm and riscv
In reply to Greg Kroah-HartmanFrom: Yipeng Zou <[email protected]>
[ Upstream commit d8ef45d66c01425ff748e13ef7dd1da7a91cc93c ]
For now, this selftest module can only work in x86 because of the kprobe cmd was fixed use of x86 registers.
This patch adapted to register names under arm and riscv, So that this module can be worked on those platform.
--- kernel/trace/kprobe_event_gen_test.c | 47 +++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 4 deletions(-)
kernel/trace/kprobe_event_gen_test.c +43 -4
@@ -35,6 +35,45 @@static struct trace_event_file *gen_kprobe_test;static struct trace_event_file *gen_kretprobe_test; +#define KPROBE_GEN_TEST_FUNC "do_sys_open" + +/* X86 */ +#if defined(CONFIG_X86_64 ) || defined(CONFIG_X86_32 ) +#define KPROBE_GEN_TEST_ARG0 "dfd=%ax" +#define KPROBE_GEN_TEST_ARG1 "filename=%dx" +#define KPROBE_GEN_TEST_ARG2 "flags=%cx" +#define KPROBE_GEN_TEST_ARG3 "mode=+4($stack)" + +/* ARM64 */ +#elif defined(CONFIG_ARM64 ) +#define KPROBE_GEN_TEST_ARG0 "dfd=%x0" +#define KPROBE_GEN_TEST_ARG1 "filename=%x1" +#define KPROBE_GEN_TEST_ARG2 "flags=%x2" +#define KPROBE_GEN_TEST_ARG3 "mode=%x3" + +/* ARM */ +#elif defined(CONFIG_ARM ) +#define KPROBE_GEN_TEST_ARG0 "dfd=%r0" +#define KPROBE_GEN_TEST_ARG1 "filename=%r1" +#define KPROBE_GEN_TEST_ARG2 "flags=%r2" +#define KPROBE_GEN_TEST_ARG3 "mode=%r3" + +/* RISCV */ +#elif defined(CONFIG_RISCV ) +#define KPROBE_GEN_TEST_ARG0 "dfd=%a0" +#define KPROBE_GEN_TEST_ARG1 "filename=%a1" +#define KPROBE_GEN_TEST_ARG2 "flags=%a2" +#define KPROBE_GEN_TEST_ARG3 "mode=%a3" + +/* others */ +#else +#define KPROBE_GEN_TEST_ARG0 NULL +#define KPROBE_GEN_TEST_ARG1 NULL +#define KPROBE_GEN_TEST_ARG2 NULL +#define KPROBE_GEN_TEST_ARG3 NULL +#endif + +/* * Test to make sure we can create a kprobe event, then add more * fields.
@@ -58,14 +97,14 @@ static int __init test_gen_kprobe_cmd(void)* fields. */ ret =kprobe_event_gen_cmd_start (&cmd,"gen_kprobe_test" , -"do_sys_open" , -"dfd=%ax" ,"filename=%dx" ); +KPROBE_GEN_TEST_FUNC , +KPROBE_GEN_TEST_ARG0 ,KPROBE_GEN_TEST_ARG1 );if (ret) goto free;/* Use kprobe_event_add_fields to add the rest of the fields */ - ret =kprobe_event_add_fields (&cmd,"flags=%cx" ,"mode=+4($stack)" ); + ret =kprobe_event_add_fields (&cmd,KPROBE_GEN_TEST_ARG2 ,KPROBE_GEN_TEST_ARG3 );if (ret) goto free;
@@ -128,7 +167,7 @@ static int __init test_gen_kretprobe_cmd(void)* Define the kretprobe event. */ ret =kretprobe_event_gen_cmd_start (&cmd,"gen_kretprobe_test" , -"do_sys_open" , +KPROBE_GEN_TEST_FUNC ,"$retval" );if (ret) goto free;
Signature · 9 lines
2.35.1 _______________________________________________ linux-riscv mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-riscv
Greg Kroah-Hartman
maintainerPATCH 645/862 tracing/osnoise: Fix possible recursive locking in stop_per_cpu_kthreads
In reply to Greg Kroah-HartmanFrom: Nico Pache <[email protected]>
[ Upstream commit 99ee9317a1305cd5626736785c8cb38b0e47686c ]
There is a recursive lock on the cpu_hotplug_lock.
In kernel/trace/trace_osnoise.c:<start/stop>_per_cpu_kthreads:
- start_per_cpu_kthreads calls cpus_read_lock() and if start_kthreads returns a error it will call stop_per_cpu_kthreads.
- stop_per_cpu_kthreads then calls cpus_read_lock() again causing deadlock.
Fix this by calling cpus_read_unlock() before calling stop_per_cpu_kthreads. This behavior can also be seen in commit f46b16520a08 ("trace/hwlat: Implement the per-cpu mode").
This error was noticed during the LTP ftrace-stress-test:
WARNING: possible recursive locking detected
--------------------------------------------
sh/275006 is trying to acquire lock:ffffffffb02f5400 (cpu_hotplug_lock){++++}-{0:0}, at: stop_per_cpu_kthreads
but task is already holding lock:ffffffffb02f5400 (cpu_hotplug_lock){++++}-{0:0}, at: start_per_cpu_kthreads
other info that might help us debug this:
Possible unsafe locking scenario:
CPU0
---- lock(cpu_hotplug_lock);
lock(cpu_hotplug_lock);
*** DEADLOCK ***
May be due to missing lock nesting notation
3 locks held by sh/275006:
#0: ffff8881023f0470 (sb_writers#24){.+.+}-{0:0}, at: ksys_write #1: ffffffffb084f430 (trace_types_lock){+.+.}-{3:3}, at: rb_simple_write #2: ffffffffb02f5400 (cpu_hotplug_lock){++++}-{0:0}, at: start_per_cpu_kthreads
--- kernel/trace/trace_osnoise.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
kernel/trace/trace_osnoise.c +2 -1
@@ -1786,8 +1786,9 @@ static int start_per_cpu_kthreads(void)for_each_cpu (cpu, current_mask) { retval =start_kthread (cpu);if (retval) { +cpus_read_unlock ();stop_per_cpu_kthreads (); -break ; +return retval; } }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 646/862 ftrace: Fix recursive locking direct_mutex in ftrace_modify_direct_caller
In reply to Greg Kroah-HartmanFrom: Song Liu <[email protected]>
[ Upstream commit 9d2ce78ddcee159eb6a97449e9c68b6d60b9cec4 ]
Naveen reported recursive locking of direct_mutex with sample ftrace-direct-modify.ko:
[ 74.762406] WARNING: possible recursive locking detected
[ 74.762887] 6.0.0-rc6+ #33 Not tainted
[ 74.763216] --------------------------------------------
[ 74.763672] event-sample-fn/1084 is trying to acquire lock:
[ 74.764152] ffffffff86c9d6b0 (direct_mutex){+.+.}-{3:3}, at: \
register_ftrace_function+0x1f/0x180
[ 74.764922]
[ 74.764922] but task is already holding lock:
[ 74.765421] ffffffff86c9d6b0 (direct_mutex){+.+.}-{3:3}, at: \
modify_ftrace_direct+0x34/0x1f0
[ 74.766142]
[ 74.766142] other info that might help us debug this:
[ 74.766701] Possible unsafe locking scenario:
[ 74.766701]
[ 74.767216] CPU0
[ 74.767437] ----
[ 74.767656] lock(direct_mutex);
[ 74.767952] lock(direct_mutex);
[ 74.768245]
[ 74.768245] *** DEADLOCK ***
[ 74.768245]
[ 74.768750] May be due to missing lock nesting notation
[ 74.768750]
[ 74.769332] 1 lock held by event-sample-fn/1084:
[ 74.769731] #0: ffffffff86c9d6b0 (direct_mutex){+.+.}-{3:3}, at: \
modify_ftrace_direct+0x34/0x1f0
[ 74.770496]
[ 74.770496] stack backtrace:
[ 74.770884] CPU: 4 PID: 1084 Comm: event-sample-fn Not tainted ...
[ 74.771498] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), ...
[ 74.772474] Call Trace:
[ 74.772696] <TASK>
[ 74.772896] dump_stack_lvl+0x44/0x5b
[ 74.773223] __lock_acquire.cold.74+0xac/0x2b7
[ 74.773616] lock_acquire+0xd2/0x310
[ 74.773936] ? register_ftrace_function+0x1f/0x180
[ 74.774357] ? lock_is_held_type+0xd8/0x130
[ 74.774744] ? my_tramp2+0x11/0x11 [ftrace_direct_modify]
[ 74.775213] __mutex_lock+0x99/0x1010
[ 74.775536] ? register_ftrace_function+0x1f/0x180
[ 74.775954] ? slab_free_freelist_hook.isra.43+0x115/0x160
[ 74.776424] ? ftrace_set_hash+0x195/0x220
[ 74.776779] ? register_ftrace_function+0x1f/0x180
[ 74.777194] ? kfree+0x3e1/0x440
[ 74.777482] ? my_tramp2+0x11/0x11 [ftrace_direct_modify]
[ 74.777941] ? __schedule+0xb40/0xb40
[ 74.778258] ? register_ftrace_function+0x1f/0x180
[ 74.778672] ? my_tramp1+0xf/0xf [ftrace_direct_modify]
[ 74.779128] register_ftrace_function+0x1f/0x180
[ 74.779527] ? ftrace_set_filter_ip+0x33/0x70
[ 74.779910] ? __schedule+0xb40/0xb40
[ 74.780231] ? my_tramp1+0xf/0xf [ftrace_direct_modify]
[ 74.780678] ? my_tramp2+0x11/0x11 [ftrace_direct_modify]
[ 74.781147] ftrace_modify_direct_caller+0x5b/0x90
[ 74.781563] ? 0xffffffffa0201000
[ 74.781859] ? my_tramp1+0xf/0xf [ftrace_direct_modify]
[ 74.782309] modify_ftrace_direct+0x1b2/0x1f0
[ 74.782690] ? __schedule+0xb40/0xb40
[ 74.783014] ? simple_thread+0x2a/0xb0 [ftrace_direct_modify]
[ 74.783508] ? __schedule+0xb40/0xb40
[ 74.783832] ? my_tramp2+0x11/0x11 [ftrace_direct_modify]
[ 74.784294] simple_thread+0x76/0xb0 [ftrace_direct_modify]
[ 74.784766] kthread+0xf5/0x120
[ 74.785052] ? kthread_complete_and_exit+0x20/0x20
[ 74.785464] ret_from_fork+0x22/0x30
[ 74.785781] </TASK>Fix this by using register_ftrace_function_nolock in ftrace_modify_direct_caller.
--- kernel/trace/ftrace.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
kernel/trace/ftrace.c +5 -1
@@ -5439,6 +5439,8 @@ static struct ftrace_ops stub_ops = {* it is safe to modify the ftrace record, where it should be * currently calling @old_addr directly, to call @new_addr. * +* This is called with direct_mutex locked. +* * Safety checks should be made to make sure that the code at * @rec->ip is currently calling @old_addr. And this must * also update entry->direct to @new_addr.
@@ -5451,6 +5453,8 @@ int __weak ftrace_modify_direct_caller(struct ftrace_func_entry *entry,unsigned long ip = rec->ip;int ret; +lockdep_assert_held (&direct_mutex); +/* * The ftrace_lock was used to determine if the record * had more than one registered user to it. If it did,
@@ -5473,7 +5477,7 @@ int __weak ftrace_modify_direct_caller(struct ftrace_func_entry *entry,if (ret) goto out_lock; - ret =register_ftrace_function (&stub_ops); + ret =register_ftrace_function_nolock (&stub_ops);if (ret) {ftrace_set_filter_ip (&stub_ops, ip,1 ,0 ); goto out_lock;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 647/862 kbuild: remove the target in signal traps when interrupted
In reply to Greg Kroah-HartmanFrom: Masahiro Yamada <[email protected]>
[ Upstream commit a7f3257da8a86b96fb9bf1bba40ae0bbd7f1885a ]
When receiving some signal, GNU Make automatically deletes the target if it has already been changed by the interrupted recipe.
If the target is possibly incomplete due to interruption, it must be deleted so that it will be remade from scratch on the next run of make. Otherwise, the target would remain corrupted permanently because its timestamp had already been updated.
Thanks to this behavior of Make, you can stop the build any time by pressing Ctrl-C, and just run 'make' to resume it.
Kbuild also relies on this feature, but it is equivalently important for any build systems that make decisions based on timestamps (if you want to support Ctrl-C reliably).
However, this does not always work as claimed; Make immediately dies with Ctrl-C if its stderr goes into a pipe.
[Test Makefile]
foo:
echo hello > $@
sleep 3
echo world >> $@
[Test Result]
$ make # hit Ctrl-C
echo hello > foo
sleep 3
^Cmake: *** Deleting file 'foo'
make: *** [Makefile:3: foo] Interrupt $ make 2>&1 | cat # hit Ctrl-C
echo hello > foo
sleep 3
^C$ # 'foo' is often left-overThe reason is because SIGINT is sent to the entire process group. In this example, SIGINT kills 'cat', and 'make' writes the message to the closed pipe, then dies with SIGPIPE before cleaning the target.
A typical bad scenario (as reported by [1], [2]) is to save build log by using the 'tee' command:
$ make 2>&1 | tee log
This can be problematic for any build systems based on Make, so I hope it will be fixed in GNU Make. The maintainer of GNU Make stated this is a long-standing issue and difficult to fix [3]. It has not been fixed yet as of writing.
So, we cannot rely on Make cleaning the target. We can do it by ourselves, in signal traps.
As far as I understand, Make takes care of SIGHUP, SIGINT, SIGQUIT, and SITERM for the target removal. I added the traps for them, and also for SIGPIPE just in case cmd_* rule prints something to stdout or stderr (but I did not observe an actual case where SIGPIPE was triggered).
[Note 1]
The trap handler might be worth explaining.
rm -f $@; trap - $(sig); kill -s $(sig) $$
This lets the shell kill itself by the signal it caught, so the parent process can tell the child has exited on the signal. Generally, this is a proper manner for handling signals, in case the calling program (like Bash) may monitor WIFSIGNALED() and WTERMSIG() for WCE although this may not be a big deal here because GNU Make handles SIGHUP, SIGINT, SIGQUIT in WUE and SIGTERM in IUE.
IUE - Immediate Unconditional Exit
WUE - Wait and Unconditional Exit
WCE - Wait and Cooperative Exit
For details, see "Proper handling of SIGINT/SIGQUIT" [4].
[Note 2]
Reverting 392885ee82d3 ("kbuild: let fixdep directly write to .*.cmd files") would directly address [1], but it only saves if_changed_dep. As reported in [2], all commands that use redirection can potentially leave an empty (i.e. broken) target.
[Note 3]
Another (even safer) approach might be to always write to a temporary file, and rename it to $@ at the end of the recipe.
<command> > $(tmp-target) mv $(tmp-target) $@
It would require a lot of Makefile changes, and result in ugly code, so I did not take it.
[Note 4]
A little more thoughts about a pattern rule with multiple targets (or a grouped target).
%.x %.y: %.z
<recipe>When interrupted, GNU Make deletes both %.x and %.y, while this solution only deletes $@. Probably, this is not a big deal. The next run of make will execute the rule again to create $@ along with the other files.
[1]: https://lore.kernel.org/all/[email protected]/
[2]: https://lore.kernel.org/all/[email protected]/
[3]: https://lists.gnu.org/archive/html/help-make/2021-06/msg00001.html
[4]: https://www.cons.org/cracauer/sigint.html
--- scripts/Kbuild.include | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-)
scripts/Kbuild.include +22 -1
@@ -100,8 +100,29 @@ echo-cmd = $(if $($(quiet)cmd_$(1)),\ quiet_redirect := silent_redirect := exec >/dev/null; +# Delete the target on interruption +# +# GNU Make automatically deletes the target if it has already been changed by +# the interrupted recipe. So, you can safely stop the build by Ctrl-C (Make +# will delete incomplete targets), and resume it later. +# +# However, this does not work when the stderr is piped to another program, like +# $ make >&2 | tee log +# Make dies with SIGPIPE before cleaning the targets. +# +# To address it, we clean the target in signal traps. +# +# Make deletes the target when it catches SIGHUP, SIGINT, SIGQUIT, SIGTERM. +# So, we cover them, and also SIGPIPE just in case. +# +# Of course, this is unneeded for phony targets. +delete-on-interrupt = \ + $(if $(filter-out $(PHONY), $@), \ + $(foreach sig, HUP INT QUIT TERM PIPE, \ + trap 'rm -f $@; trap - $(sig); kill -s $(sig) $$$$' $(sig);)) + # printing commands -cmd = @set -e; $(echo-cmd) $($(quiet)redirect) $(cmd_$(1)) +cmd = @set -e; $(echo-cmd) $($(quiet)redirect) $(delete-on-interrupt) $(cmd_$(1)) ### # if_changed - execute command if any prerequisite is newer than
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 648/862 linux/export: use inline assembler to populate symbol CRCs
In reply to Greg Kroah-HartmanFrom: Masahiro Yamada <[email protected]>
[ Upstream commit f3304ecd7f060db1d4197fbdce5a503259f770d3 ]
Since commit 7b4537199a4a ("kbuild: link symbol CRCs at final link, removing CONFIG_MODULE_REL_CRCS"), the module versioning on the (non-upstreamed-yet) kvx Linux port is broken due to unexpected padding for __crc_* symbols. The kvx GCC adds padding so u32 gets 8-byte alignment instead of 4.
I do not know if this happens for upstream architectures in general, but any compiler has the freedom to insert padding for faster access.
Use the inline assembler to directly specify the wanted data layout. This is how we previously did before the breakage.
--- include/linux/export-internal.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
include/linux/export-internal.h +4 -2
@@ -10,8 +10,10 @@#include <linux/compiler.h> #include <linux/types.h> -/* __used is needed to keep __crc_* for LTO */ #define SYMBOL_CRC (sym, crc, sec) \ - u32 __section("___kcrctab" sec "+" #sym) __used __crc_##sym = crc + asm(".section \"___kcrctab" sec "+" #sym "\",\"a\"" "\n" \ + "__crc_" #sym ":" "\n" \ + ".long " #crc "\n" \ + ".previous" "\n")#endif /* __LINUX_EXPORT_INTERNAL_H__ */
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 649/862 kbuild: rpm-pkg: fix breakage when V=1 is used
In reply to Greg Kroah-HartmanFrom: Janis Schoetterl-Glausch <[email protected]>
[ Upstream commit 2e07005f4813a9ff6e895787e0c2d1fea859b033 ]
Doing make V=1 binrpm-pkg results in:
Executing(%install): /bin/sh -e /var/tmp/rpm-tmp.EgV6qJ
+ umask 022
+ cd .
+ /bin/rm -rf /home/scgl/rpmbuild/BUILDROOT/kernel-6.0.0_rc5+-1.s390x
+ /bin/mkdir -p /home/scgl/rpmbuild/BUILDROOT
+ /bin/mkdir /home/scgl/rpmbuild/BUILDROOT/kernel-6.0.0_rc5+-1.s390x
+ mkdir -p /home/scgl/rpmbuild/BUILDROOT/kernel-6.0.0_rc5+-1.s390x/boot
+ make -f ./Makefile image_name
+ cp test -e include/generated/autoconf.h -a -e include/config/auto.conf || ( \ echo >&2; \ echo >&2 " ERROR: Kernel configuration is invalid."; \ echo >&2 " include/generated/autoconf.h or include/config/auto.conf are missing.";\ echo >&2 " Run 'make oldconfig && make prepare' on kernel src to fix it."; \ echo >&2 ; \ /bin/false) arch/s390/boot/bzImage /home/scgl/rpmbuild/BUILDROOT/kernel-6.0.0_rc5+-1.s390x/boot/vmlinuz-6.0.0-rc5+
cp: invalid option -- 'e'
Try 'cp --help' for more information.
error: Bad exit status from /var/tmp/rpm-tmp.EgV6qJ (%install)
Because the make call to get the image name is verbose and prints additional information.
--- scripts/package/mkspec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
scripts/package/mkspec +2 -2
@@ -88,10 +88,10 @@ $S mkdir -p %{buildroot}/boot %ifarch ia64 mkdir -p %{buildroot}/boot/efi - cp \$($MAKE image_name) %{buildroot}/boot/efi/vmlinuz-$KERNELRELEASE + cp \$($MAKE -s image_name) %{buildroot}/boot/efi/vmlinuz-$KERNELRELEASE ln -s efi/vmlinuz-$KERNELRELEASE %{buildroot}/boot/ %else - cp \$($MAKE image_name) %{buildroot}/boot/vmlinuz-$KERNELRELEASE + cp \$($MAKE -s image_name) %{buildroot}/boot/vmlinuz-$KERNELRELEASE %endif $M $MAKE %{?_smp_mflags} INSTALL_MOD_PATH=%{buildroot} modules_install $MAKE %{?_smp_mflags} INSTALL_HDR_PATH=%{buildroot}/usr headers_install
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 650/862 crypto: marvell/octeontx - prevent integer overflows
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit caca37cf6c749ff0303f68418cfe7b757a4e0697 ]
The "code_length" value comes from the firmware file. If your firmware is untrusted realistically there is probably very little you can do to protect yourself. Still we try to limit the damage as much as possible. Also Smatch marks any data read from the filesystem as untrusted and prints warnings if it not capped correctly.
The "code_length * 2" can overflow. The round_up(ucode_size, 16) + sizeof() expression can overflow too. Prevent these overflows.
--- .../crypto/marvell/octeontx/otx_cptpf_ucode.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-)
drivers/crypto/marvell/octeontx/otx_cptpf_ucode.c +16 -2
@@ -286,6 +286,7 @@ static int process_tar_file(struct device *dev,struct tar_ucode_info_t *tar_info;struct otx_cpt_ucode_hdr *ucode_hdr;int ucode_type, ucode_size; +unsigned int code_length;/* * If size is less than microcode header size then don't report
@@ -303,7 +304,13 @@ static int process_tar_file(struct device *dev,if (get_ucode_type (ucode_hdr, &ucode_type))return 0 ; - ucode_size =ntohl (ucode_hdr->code_length) *2 ; + code_length =ntohl (ucode_hdr->code_length); +if (code_length >=INT_MAX /2 ) { +dev_err (dev,"Invalid code_length %u\n" , code_length); +return -EINVAL ; + } + + ucode_size = code_length *2 ;if (!ucode_size || (size <round_up (ucode_size,16 ) +sizeof (struct otx_cpt_ucode_hdr ) +OTX_CPT_UCODE_SIGN_LEN )) {dev_err (dev,"Ucode %s invalid size\n" , filename);
@@ -886,6 +893,7 @@ static int ucode_load(struct device *dev, struct otx_cpt_ucode *ucode, {struct otx_cpt_ucode_hdr *ucode_hdr;const struct firmware *fw; +unsigned int code_length;int ret;set_ucode_filename (ucode, ucode_filename);
@@ -896,7 +904,13 @@ static int ucode_load(struct device *dev, struct otx_cpt_ucode *ucode, ucode_hdr = (struct otx_cpt_ucode_hdr *) fw->data;memcpy (ucode->ver_str, ucode_hdr->ver_str,OTX_CPT_UCODE_VER_STR_SZ ); ucode->ver_num = ucode_hdr->ver_num; - ucode->size =ntohl (ucode_hdr->code_length) *2 ; + code_length =ntohl (ucode_hdr->code_length); +if (code_length >=INT_MAX /2 ) { +dev_err (dev,"Ucode invalid code_length %u\n" , code_length); + ret = -EINVAL ; + goto release_fw; + } + ucode->size = code_length *2 ;if (!ucode->size || (fw->size <round_up (ucode->size,16 ) +sizeof (struct otx_cpt_ucode_hdr ) +OTX_CPT_UCODE_SIGN_LEN )) {dev_err (dev,"Ucode %s invalid size\n" , ucode_filename);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 651/862 crypto: cavium - prevent integer overflow loading firmware
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit 2526d6bf27d15054bb0778b2f7bc6625fd934905 ]
The "code_length" value comes from the firmware file. If your firmware is untrusted realistically there is probably very little you can do to protect yourself. Still we try to limit the damage as much as possible. Also Smatch marks any data read from the filesystem as untrusted and prints warnings if it not capped correctly.
The "ntohl(ucode->code_length) * 2" multiplication can have an integer overflow.
--- drivers/crypto/cavium/cpt/cptpf_main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/crypto/cavium/cpt/cptpf_main.c +4 -2
@@ -253,6 +253,7 @@ static int cpt_ucode_load_fw(struct cpt_device *cpt, const u8 *fw, bool is_ae)const struct firmware *fw_entry;struct device *dev = &cpt->pdev->dev;struct ucode_header *ucode; +unsigned int code_length;struct microcode *mcode;int j, ret =0 ;
@@ -263,11 +264,12 @@ static int cpt_ucode_load_fw(struct cpt_device *cpt, const u8 *fw, bool is_ae) ucode = (struct ucode_header *)fw_entry->data; mcode = &cpt->mcode[cpt->next_mc_idx];memcpy (mcode->version, (u8 *)fw_entry->data,CPT_UCODE_VERSION_SZ ); - mcode->code_size =ntohl (ucode->code_length) *2 ; -if (!mcode->code_size) { + code_length =ntohl (ucode->code_length); +if (code_length ==0 || code_length >=INT_MAX /2 ) { ret = -EINVAL ; goto fw_release; } + mcode->code_size = code_length *2 ; mcode->is_ae = is_ae; mcode->core_mask =0ULL ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 652/862 random: schedule jitter credit for next jiffy, not in two jiffies
In reply to Greg Kroah-HartmanFrom: Jason A. Donenfeld <[email protected]>
[ Upstream commit 122733471384be8c23f019fbbd46bdf7be561dcd ]
Counterintuitively, mod_timer(..., jiffies + 1) will cause the timer to fire not in the next jiffy, but in two jiffies. The way to cause the timer to fire in the next jiffy is with mod_timer(..., jiffies). Doing so then lets us bump the upper bound back up again.
--- drivers/char/random.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/char/random.c +2 -2
@@ -1195,7 +1195,7 @@ static void __cold entropy_timer(struct timer_list *timer)*/ static void __cold try_to_generate_entropy (void ) { -enum {NUM_TRIAL_SAMPLES =8192 ,MAX_SAMPLES_PER_BIT =HZ /30 }; +enum {NUM_TRIAL_SAMPLES =8192 ,MAX_SAMPLES_PER_BIT =HZ /15 };struct entropy_timer_state stack;unsigned int i, num_different =0 ;unsigned long last =random_get_entropy ();
@@ -1214,7 +1214,7 @@ static void __cold try_to_generate_entropy(void)timer_setup_on_stack (&stack.timer, entropy_timer,0 );while (!crng_ready () && !signal_pending (current)) {if (!timer_pending (&stack.timer)) -mod_timer (&stack.timer, jiffies +1 ); +mod_timer (&stack.timer, jiffies);mix_pool_bytes (&stack.entropy,sizeof (stack.entropy));schedule (); stack.entropy =random_get_entropy ();
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 653/862 thermal/drivers/qcom/tsens-v0_1: Fix MSM8939 fourth sensor hw_id
In reply to Greg Kroah-HartmanFrom: Vincent Knecht <[email protected]>
[ Upstream commit b0c883e900702f408d62cf92b0ef01303ed69be9 ]
Reading temperature from this sensor fails with 'Invalid argument'.
Looking at old vendor dts [1], its hw_id should be 3 instead of 4. Change this hw_id accordingly.
--- drivers/thermal/qcom/tsens-v0_1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/thermal/qcom/tsens-v0_1.c +1 -1
@@ -604,7 +604,7 @@ static const struct tsens_ops ops_8939 = {struct tsens_plat_data data_8939 = { .num_sensors =10 , .ops = &ops_8939, - .hw_ids = (unsigned int []){0 ,1 ,2 ,4 ,5 ,6 ,7 ,8 ,9 ,10 }, + .hw_ids = (unsigned int []){0 ,1 ,2 ,3 ,5 ,6 ,7 ,8 ,9 ,10 }, .feat = &tsens_v0_1_feat, .fields = tsens_v0_1_regfields,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 654/862 ACPI: APEI: do not add task_work to kernel thread to avoid memory leak
In reply to Greg Kroah-HartmanFrom: Shuai Xue <[email protected]>
[ Upstream commit 415fed694fe11395df56e05022d6e7cee1d39dd3 ]
If an error is detected as a result of user-space process accessing a corrupt memory location, the CPU may take an abort. Then the platform firmware reports kernel via NMI like notifications, e.g. NOTIFY_SEA, NOTIFY_SOFTWARE_DELEGATED, etc.
For NMI like notifications, commit 7f17b4a121d0 ("ACPI: APEI: Kick the memory_failure() queue for synchronous errors") keep track of whether memory_failure() work was queued, and make task_work pending to flush out the queue so that the work is processed before return to user-space.
The code use init_mm to check whether the error occurs in user space:
if (current->mm != &init_mm)
The condition is always true, becase _nobody_ ever has "init_mm" as a real VM any more.
In addition to abort, errors can also be signaled as asynchronous exceptions, such as interrupt and SError. In such case, the interrupted current process could be any kind of thread. When a kernel thread is interrupted, the work ghes_kick_task_work deferred to task_work will never be processed because entry_handler returns to call ret_to_kernel() instead of ret_to_user(). Consequently, the estatus_node alloced from ghes_estatus_pool in ghes_in_nmi_queue_one_entry() will not be freed. After around 200 allocations in our platform, the ghes_estatus_pool will run of memory and ghes_in_nmi_queue_one_entry() returns ENOMEM. As a result, the event failed to be processed.
sdei: event 805 on CPU 113 failed with error: -2
Finally, a lot of unhandled events may cause platform firmware to exceed some threshold and reboot.
The condition should generally just do
if (current->mm)
as described in active_mm.rst documentation.
Then if an asynchronous error is detected when a kernel thread is running, (e.g. when detected by a background scrubber), do not add task_work to it as the original patch intends to do.
--- drivers/acpi/apei/ghes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/acpi/apei/ghes.c +1 -1
@@ -985,7 +985,7 @@ static void ghes_proc_in_irq(struct irq_work *irq_work)ghes_estatus_cache_add (generic, estatus); } -if (task_work_pending && current->mm != &init_mm) { +if (task_work_pending && current->mm) { estatus_node->task_work.func = ghes_kick_task_work; estatus_node->task_work_cpu =smp_processor_id (); ret = task_work_add(current, &estatus_node->task_work,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 655/862 f2fs: fix race condition on setting FI_NO_EXTENT flag
In reply to Greg Kroah-HartmanFrom: Zhang Qilong <[email protected]>
[ Upstream commit 07725adc55c0a414c10acb5c8c86cea34b95ddef ]
The following scenarios exist.
process A: process B:
->f2fs_drop_extent_tree ->f2fs_update_extent_cache_range
->f2fs_update_extent_tree_range
->write_lock
->set_inode_flag
->is_inode_flag_set
->__free_extent_tree // Shouldn't
// have been
// cleaned up
// here->write_lock
In this case, the "FI_NO_EXTENT" flag is set between f2fs_update_extent_tree_range and is_inode_flag_set by other process. it leads to clearing the whole exten tree which should not have happened. And we fix it by move the setting it to the range of write_lock.
--- fs/f2fs/extent_cache.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
fs/f2fs/extent_cache.c +1 -2
@@ -804,9 +804,8 @@ void f2fs_drop_extent_tree(struct inode *inode)if (!f2fs_may_extent_tree (inode))return ; -set_inode_flag (inode,FI_NO_EXTENT ); -write_lock (&et->lock); +set_inode_flag (inode,FI_NO_EXTENT );__free_extent_tree (sbi, et);if (et->largest.len) { et->largest.len =0 ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 656/862 f2fs: fix to account FS_CP_DATA_IO correctly
In reply to Greg Kroah-HartmanFrom: Chao Yu <[email protected]>
[ Upstream commit d80afefb17e01aa0c46a8eebc01882e0ebd8b0f6 ]
f2fs_inode_info.cp_task was introduced for FS_CP_DATA_IO accounting since commit b0af6d491a6b ("f2fs: add app/fs io stat").
However, cp_task usage coverage has been increased due to below commits:
commit 040d2bb318d1 ("f2fs: fix to avoid deadloop if data_flush is on") commit 186857c5a14a ("f2fs: fix potential recursive call when enabling data_flush")
So that, if data_flush mountoption is on, when data flush was triggered from background, the IO from data flush will be accounted as checkpoint IO type incorrectly.
In order to fix this issue, this patch splits cp_task into two:
a) cp_task: used for IO accounting
b) wb_task: used to avoid deadlock
--- fs/f2fs/checkpoint.c | 13 +++++++++---- fs/f2fs/data.c | 4 ++-- fs/f2fs/f2fs.h | 4 +++- fs/f2fs/segment.c | 2 +- 4 files changed, 15 insertions(+), 8 deletions(-)
fs/f2fs/checkpoint.c +9 -4
@@ -1061,7 +1061,8 @@ void f2fs_remove_dirty_inode(struct inode *inode)spin_unlock (&sbi->inode_lock[type]); } -int f2fs_sync_dirty_inodes (struct f2fs_sb_info *sbi,enum inode_type type) +int f2fs_sync_dirty_inodes (struct f2fs_sb_info *sbi,enum inode_type type, +bool from_cp) {struct list_head *head;struct inode *inode;
@@ -1096,11 +1097,15 @@ int f2fs_sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type)if (inode) {unsigned long cur_ino = inode->i_ino; -F2FS_I (inode)->cp_task = current; +if (from_cp) +F2FS_I (inode)->cp_task = current; +F2FS_I (inode)->wb_task = current;filemap_fdatawrite (inode->i_mapping); -F2FS_I (inode)->cp_task =NULL ; +F2FS_I (inode)->wb_task =NULL ; +if (from_cp) +F2FS_I (inode)->cp_task =NULL ;iput (inode);/* We need to give cpu to another writers. */
@@ -1229,7 +1234,7 @@ static int block_operations(struct f2fs_sb_info *sbi)/* write all the dirty dentry pages */ if (get_pages (sbi,F2FS_DIRTY_DENTS )) {f2fs_unlock_all (sbi); - err =f2fs_sync_dirty_inodes (sbi,DIR_INODE ); + err =f2fs_sync_dirty_inodes (sbi,DIR_INODE , true);if (err)return err;cond_resched ();
fs/f2fs/data.c +2 -2
@@ -2856,7 +2856,7 @@ int f2fs_write_single_data_page(struct page *page, int *submitted, }unlock_page (page);if (!S_ISDIR (inode->i_mode) && !IS_NOQUOTA (inode) && - !F2FS_I (inode)->cp_task && allow_balance) + !F2FS_I (inode)->wb_task && allow_balance)f2fs_balance_fs (sbi, need_balance_fs);if (unlikely (f2fs_cp_error (sbi))) {
@@ -3156,7 +3156,7 @@ static inline bool __should_serialize_io(struct inode *inode, struct writeback_control *wbc) {/* to avoid deadlock in path of data flush */ -if (F2FS_I (inode)->cp_task) +if (F2FS_I (inode)->wb_task)return false;if (!S_ISREG (inode->i_mode))
fs/f2fs/f2fs.h +3 -1
@@ -786,6 +786,7 @@ struct f2fs_inode_info {unsigned int clevel;/* maximum level of given file name */ struct task_struct *task;/* lookup and create consistency */ struct task_struct *cp_task;/* separate cp/wb IO stats*/ +struct task_struct *wb_task;/* indicate inode is in context of writeback */ nid_t i_xattr_nid;/* node id that contains xattrs */ loff_t last_disk_size;/* lastly written file size */ spinlock_t i_size_lock;/* protect last_disk_size */
@@ -3741,7 +3742,8 @@ int f2fs_recover_orphan_inodes(struct f2fs_sb_info *sbi);int f2fs_get_valid_checkpoint (struct f2fs_sb_info *sbi);void f2fs_update_dirty_folio (struct inode *inode,struct folio *folio);void f2fs_remove_dirty_inode (struct inode *inode); -int f2fs_sync_dirty_inodes (struct f2fs_sb_info *sbi,enum inode_type type); +int f2fs_sync_dirty_inodes (struct f2fs_sb_info *sbi,enum inode_type type, +bool from_cp);void f2fs_wait_on_all_pages (struct f2fs_sb_info *sbi,int type);u64 f2fs_get_sectors_written (struct f2fs_sb_info *sbi);int f2fs_write_checkpoint (struct f2fs_sb_info *sbi,struct cp_control *cpc);
fs/f2fs/segment.c +1 -1
@@ -476,7 +476,7 @@ void f2fs_balance_fs_bg(struct f2fs_sb_info *sbi, bool from_bg)mutex_lock (&sbi->flush_lock);blk_start_plug (&plug); -f2fs_sync_dirty_inodes (sbi,FILE_INODE ); +f2fs_sync_dirty_inodes (sbi,FILE_INODE , false);blk_finish_plug (&plug);mutex_unlock (&sbi->flush_lock);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 657/862 tools/power turbostat: Use standard Energy Unit for SPR Dram RAPL domain
In reply to Greg Kroah-HartmanFrom: Zhang Rui <[email protected]>
[ Upstream commit b2d433ae637626d44c9d4a75dd3330cf68fed9de ]
Intel Xeon servers used to use a fixed energy resolution (15.3uj) for Dram RAPL domain. But on SPR, Dram RAPL domain follows the standard energy resolution as described in MSR_RAPL_POWER_UNIT.
Remove the SPR rapl_dram_energy_units quirk.
--- tools/power/x86/turbostat/turbostat.c | 1 - 1 file changed, 1 deletion(-)
tools/power/x86/turbostat/turbostat.c +0 -1
@@ -4560,7 +4560,6 @@ static double rapl_dram_energy_units_probe(int model, double rapl_energy_units)case INTEL_FAM6_SKYLAKE_X :/* SKX */ case INTEL_FAM6_XEON_PHI_KNL :/* KNL */ case INTEL_FAM6_ICELAKE_X :/* ICX */ -case INTEL_FAM6_SAPPHIRERAPIDS_X :/* SPR */ return (rapl_dram_energy_units =15.3 /1000000 );default :return (rapl_energy_units);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 658/862 selftest: tpm2: Add Client.__del__() to close /dev/tpm* handle
In reply to Greg Kroah-HartmanFrom: Stefan Berger <[email protected]>
[ Upstream commit 2d869f0b458547386fbcd8cf3004b271b7347b7f ]
The following output can bee seen when the test is executed:
test_flush_context (tpm2_tests.SpaceTest) ... \
/usr/lib64/python3.6/unittest/case.py:605: ResourceWarning: \
unclosed file <_io.FileIO name='/dev/tpmrm0' mode='rb+' closefd=True>An instance of Client does not implicitly close /dev/tpm* handle, once it gets destroyed. Close the file handle in the class destructor Client.__del__().
--- tools/testing/selftests/tpm2/tpm2.py | 4 ++++ 1 file changed, 4 insertions(+)
tools/testing/selftests/tpm2/tpm2.py +4 -0
@@ -371,6 +371,10 @@ class Client: fcntl.fcntl(self.tpm, fcntl.F_SETFL, flags) self.tpm_poll = select.poll() + def __del__(self): + if self.tpm: + self.tpm.close() + def close(self): self.tpm.close()
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 659/862 =?UTF-8?q?ARM/dma-mapp=D1=96ng:=20dont=20override=20->dma=5Fcohe?= =?UTF-8?q?rent=20when=20set=20from=20a=20bus=20notifier?=
In reply to Greg Kroah-HartmanFrom: Christoph Hellwig <[email protected]>
[ Upstream commit 49bc8bebae79c8516cb12f91818f3a7907e3ebce ]
Commit ae626eb97376 ("ARM/dma-mapping: use dma-direct unconditionally") caused a regression on the mvebu platform, wherein devices that are dma-coherent are marked as dma-noncoherent, because although mvebu_hwcc_notifier() after that commit still marks then as coherent, the arm_coherent_dma_ops() function, which is called later, overwrites this setting, since it is being called from drivers/of/device.c with coherency parameter determined by of_dma_is_coherent(), and the device-trees do not declare the 'dma-coherent' property.
Fix this by defaulting never clearing the dma_coherent flag in arm_coherent_dma_ops().
--- arch/arm/mm/dma-mapping.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
arch/arm/mm/dma-mapping.c +10 -2
@@ -1769,8 +1769,16 @@ static void arm_teardown_iommu_dma_ops(struct device *dev) { }void arch_setup_dma_ops (struct device *dev,u64 dma_base,u64 size,const struct iommu_ops *iommu,bool coherent) { - dev->archdata.dma_coherent = coherent; - dev->dma_coherent = coherent; +/* +* Due to legacy code that sets the ->dma_coherent flag from a bus +* notifier we can't just assign coherent to the ->dma_coherent flag +* here, but instead have to make sure we only set but never clear it +* for now. +*/ +if (coherent) { + dev->archdata.dma_coherent = true; + dev->dma_coherent = true; + }/* * Don't override the dma_ops if they have already been set. Ideally
Signature · 1 line
2.35.1
Re: [PATCH 6.0 659/862] =?UTF-8?q?ARM/dma-mapp=D1=96ng:=20dont=20override=20->dma=5Fcohe?= =?UTF-8?q?rent=20when=20set=20from=20a=20bus=20notifier?=
Hi Greg,
I'm seeing:
Subject: [PATCH 6.0 659/862]
=?UTF-8?q?ARM/dma-mapp=D1=96ng:=20dont=20override=20->dma=5Fcohe?=
=?UTF-8?q?rent=20when=20set=20from=20a=20bus=20notifier?=in mutt, and mutt seems to be unable to decode that. Either a mutt bug or a bug in your scripts or git...
Russell.
Quoted 55 lines · Greg Kroah-Hartman
From: Christoph Hellwig <[email protected]>
[ Upstream commit
49bc8bebae79c8516cb12f91818f3a7907e3ebce]Commit
ae626eb97376("ARM/dma-mapping: use dma-direct unconditionally") caused a regression on the mvebu platform, wherein devices that are dma-coherent are marked as dma-noncoherent, because althoughmvebu_hwcc_notifier()after that commit still marks then as coherent, thearm_coherent_dma_ops()function, which is called later, overwrites this setting, since it is being called fromdrivers/of/device.cwith coherency parameter determined byof_dma_is_coherent(), and the device-trees do not declare the 'dma-coherent' property.Fix this by defaulting never clearing the
dma_coherentflag inarm_coherent_dma_ops().Fixes ae626eb97376 ("ARM/dma-mapping: use dma-direct unconditionally")Reported-by Marek Behún <[email protected]>Signed-off-by Christoph Hellwig <[email protected]>Reviewed-by Russell King (Oracle) <[email protected]>Tested-by Marek Behún <[email protected]>Signed-off-by Sasha Levin <[email protected]>--- arch/arm/mm/dma-mapping.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)arch/arm/mm/dma-mapping.c +10
-2@@ -1769,8 +1769,16 @@ static void arm_teardown_iommu_dma_ops(struct device *dev) { }void arch_setup_dma_ops (struct device *dev,u64 dma_base,u64 size,const struct iommu_ops *iommu,bool coherent) { - dev->archdata.dma_coherent = coherent; - dev->dma_coherent = coherent; +/* +* Due to legacy code that sets the ->dma_coherent flag from a bus +* notifier we can't just assign coherent to the ->dma_coherent flag +* here, but instead have to make sure we only set but never clear it +* for now. +*/ +if (coherent) { + dev->archdata.dma_coherent = true; + dev->dma_coherent = true; + }/* * Don't override the dma_ops if they have already been set. Ideally Signature · 1 line
2.35.1
Signature · 2 lines
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/ FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!
Re: [PATCH 6.0 659/862] =?UTF-8?q?ARM/dma-mapp=D1=96ng:=20dont=20override=20->dma=5Fcohe?= =?UTF-8?q?rent=20when=20set=20from=20a=20bus=20notifier?=
Quoted 8 lines · Russell King (Oracle)
I'm seeing:
Subject: [PATCH 6.0 659/862]
=?UTF-8?q?ARM/dma-mapp=D1=96ng:=20dont=20override=20->dma=5Fcohe?= =?UTF-8?q?rent=20when=20set=20from=20a=20bus=20notifier?=in mutt, and mutt seems to be unable to decode that. Either a mutt bug or a bug in your scripts or git...
The real problem was me fat fingering the comments and adding a non-ASCII "і" character instead of and "i" into the Subject. And then it somehow went downhill from there..
Greg Kroah-Hartman
maintainerRe: [PATCH 6.0 659/862] =?UTF-8?q?ARM/dma-mapp=D1=96ng:=20dont=20override=20->dma=5Fcohe?= =?UTF-8?q?rent=20when=20set=20from=20a=20bus=20notifier?=
In reply to Russell King (Oracle)Quoted 10 lines · Russell King (Oracle)
Hi Greg,
I'm seeing:
Subject: [PATCH 6.0 659/862]
=?UTF-8?q?ARM/dma-mapp=D1=96ng:=20dont=20override=20->dma=5Fcohe?= =?UTF-8?q?rent=20when=20set=20from=20a=20bus=20notifier?=in mutt, and mutt seems to be unable to decode that. Either a mutt bug or a bug in your scripts or git...
It's probably between git and quilt and somewhere. The issue is that the original commit's subject line is:
ARM/dma-mappіng: don't override ->dma_coherent when set from a bus notifier
Note the 'і' character in there, which then causes git to emit a subject line that looks like:
Subject: [PATCH] =?UTF-8?q?ARM/dma-mapp=D1=96ng:=20don't=20override=20->dm?= =?UTF-8?q?a=5Fcoherent=20when=20set=20from=20a=20bus=20notifier?=
which is technically correct.
Then quilt comes along and adds it's own counting of the patch and treats the whole thing as the subject and something gets confused.
Anyway, I'll go drop the funny 'і' and turn it into ascii only for the subject line.
thanks,
greg k-h
Re: [PATCH 6.0 659/862] ARM/dma-mappіng: dont override ->dma_coherent when set from a bus notifier
In reply to Greg Kroah-HartmanQuoted 13 lines · Greg Kroah-Hartman
From: Christoph Hellwig <[email protected]>
[ Upstream commit
49bc8bebae79c8516cb12f91818f3a7907e3ebce]Commit
ae626eb97376("ARM/dma-mapping: use dma-direct unconditionally") caused a regression on the mvebu platform, wherein devices that are dma-coherent are marked as dma-noncoherent, because althoughmvebu_hwcc_notifier()after that commit still marks then as coherent, thearm_coherent_dma_ops()function, which is called later, overwrites this setting, since it is being called fromdrivers/of/device.cwith coherency parameter determined byof_dma_is_coherent(), and the device-trees do not declare the 'dma-coherent' property.
Quoted 3 lines
Fix this by defaulting never clearing the
dma_coherentflag inarm_coherent_dma_ops().
The patch subject looks mangled, right?
Signature · 1 line
An old man doll... just what I always wanted! - Clara
Greg Kroah-Hartman
maintainerPATCH 660/862 module: tracking: Keep a record of tainted unloaded modules only
In reply to Greg Kroah-HartmanFrom: Aaron Tomlin <[email protected]>
[ Upstream commit 47cc75aa92837a9d3f15157d6272ff285585d75d ]
This ensures that no module record/or entry is added to the unloaded_tainted_modules list if it does not carry a taint.
--- kernel/module/tracking.c | 3 +++ 1 file changed, 3 insertions(+)
kernel/module/tracking.c +3 -0
@@ -21,6 +21,9 @@ int try_add_tainted_module(struct module *mod)module_assert_mutex_or_preempt (); +if (!mod->taints) + goto out; +list_for_each_entry_rcu (mod_taint, &unloaded_tainted_modules, list,lockdep_is_held (&module_mutex)) { if (!strcmp(mod_taint->name, mod->name) &&
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 661/862 fs: dlm: fix race in lowcomms
In reply to Greg Kroah-HartmanFrom: Alexander Aring <[email protected]>
[ Upstream commit 30ea3257e8766027c4d8d609dcbd256ff9a76073 ]
This patch fixes a race between queue_work() in _dlm_lowcomms_commit_msg() and srcu_read_unlock(). The queue_work() can take the final reference of a dlm_msg and so msg->idx can contain garbage which is signaled by the following warning:
[ 676.237050] ------------[ cut here ]------------ [ 676.237052] WARNING: CPU: 0 PID: 1060 at include/linux/srcu.h:189 dlm_lowcomms_commit_msg+0x41/0x50 [ 676.238945] Modules linked in: dlm_locktorture torture rpcsec_gss_krb5 intel_rapl_msr intel_rapl_common iTCO_wdt iTCO_vendor_support qxl kvm_intel drm_ttm_helper vmw_vsock_virtio_transport kvm vmw_vsock_virtio_transport_common ttm irqbypass crc32_pclmul joydev crc32c_intel serio_raw drm_kms_helper vsock virtio_scsi virtio_console virtio_balloon snd_pcm drm syscopyarea sysfillrect sysimgblt snd_timer fb_sys_fops i2c_i801 lpc_ich snd i2c_smbus soundcore pcspkr [ 676.244227] CPU: 0 PID: 1060 Comm: lock_torture_wr Not tainted 5.19.0-rc3+ #1546 [ 676.245216] Hardware name: Red Hat KVM/RHEL-AV, BIOS 1.16.0-2.module+el8.7.0+15506+033991b0 04/01/2014 [ 676.246460] RIP: 0010:dlm_lowcomms_commit_msg+0x41/0x50 [ 676.247132] Code: fe ff ff ff 75 24 48 c7 c6 bd 0f 49 bb 48 c7 c7 38 7c 01 bd e8 00 e7 ca ff 89 de 48 c7 c7 60 78 01 bd e8 42 3d cd ff 5b 5d c3 <0f> 0b eb d8 66 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 55 48 [ 676.249253] RSP: 0018:ffffa401c18ffc68 EFLAGS: 00010282 [ 676.249855] RAX: 0000000000000001 RBX: 00000000ffff8b76 RCX: 0000000000000006 [ 676.250713] RDX: 0000000000000000 RSI: ffffffffbccf3a10 RDI: ffffffffbcc7b62e [ 676.251610] RBP: ffffa401c18ffc70 R08: 0000000000000001 R09: 0000000000000001 [ 676.252481] R10: 0000000000000001 R11: 0000000000000001 R12: 0000000000000005 [ 676.253421] R13: ffff8b76786ec370 R14: ffff8b76786ec370 R15: ffff8b76786ec480 [ 676.254257] FS: 0000000000000000(0000) GS:ffff8b7777800000(0000) knlGS:0000000000000000 [ 676.255239] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 676.255897] CR2: 00005590205d88b8 CR3: 000000017656c003 CR4: 0000000000770ee0 [ 676.256734] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 676.257567] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 676.258397] PKRU: 55555554 [ 676.258729] Call Trace: [ 676.259063] <TASK> [ 676.259354] dlm_midcomms_commit_mhandle+0xcc/0x110 [ 676.259964] queue_bast+0x8b/0xb0 [ 676.260423] grant_pending_locks+0x166/0x1b0 [ 676.261007] _unlock_lock+0x75/0x90 [ 676.261469] unlock_lock.isra.57+0x62/0xa0 [ 676.262009] dlm_unlock+0x21e/0x330 [ 676.262457] ? lock_torture_stats+0x80/0x80 [dlm_locktorture] [ 676.263183] torture_unlock+0x5a/0x90 [dlm_locktorture] [ 676.263815] ? preempt_count_sub+0xba/0x100 [ 676.264361] ? complete+0x1d/0x60 [ 676.264777] lock_torture_writer+0xb8/0x150 [dlm_locktorture] [ 676.265555] kthread+0x10a/0x130 [ 676.266007] ? kthread_complete_and_exit+0x20/0x20 [ 676.266616] ret_from_fork+0x22/0x30 [ 676.267097] </TASK> [ 676.267381] irq event stamp: 9579855 [ 676.267824] hardirqs last enabled at (9579863): [<ffffffffbb14e6f8>] __up_console_sem+0x58/0x60 [ 676.268896] hardirqs last disabled at (9579872): [<ffffffffbb14e6dd>] __up_console_sem+0x3d/0x60 [ 676.270008] softirqs last enabled at (9579798): [<ffffffffbc200349>] __do_softirq+0x349/0x4c7 [ 676.271438] softirqs last disabled at (9579897): [<ffffffffbb0d54c0>] irq_exit_rcu+0xb0/0xf0 [ 676.272796] ---[ end trace 0000000000000000 ]---
I reproduced this warning with dlm_locktorture test which is currently not upstream. However this patch fix the issue by make a additional refcount between dlm_lowcomms_new_msg() and dlm_lowcomms_commit_msg(). In case of the race the kref_put() in dlm_lowcomms_commit_msg() will be the final put.
--- fs/dlm/lowcomms.c | 4 ++++ 1 file changed, 4 insertions(+)
fs/dlm/lowcomms.c +4 -0
@@ -1336,6 +1336,8 @@ struct dlm_msg *dlm_lowcomms_new_msg(int nodeid, int len, gfp_t allocation,return NULL ; } +/* for dlm_lowcomms_commit_msg() */ +kref_get (&msg->ref);/* we assume if successful commit must called */ msg->idx = idx;return msg;
@@ -1375,6 +1377,8 @@ void dlm_lowcomms_commit_msg(struct dlm_msg *msg) {_dlm_lowcomms_commit_msg (msg);srcu_read_unlock (&connections_srcu, msg->idx); +/* because dlm_lowcomms_new_msg() */ +kref_put (&msg->ref, dlm_msg_release); }#endif
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 662/862 rcu: Avoid triggering strict-GP irq-work when RCU is idle
In reply to Greg Kroah-HartmanFrom: Zqiang <[email protected]>
[ Upstream commit 621189a1fe93cb2b34d62c5cdb9e258bca044813 ]
Kernels built with PREEMPT_RCU=y and RCU_STRICT_GRACE_PERIOD=y trigger irq-work from rcu_read_unlock(), and the resulting irq-work handler invokes rcu_preempt_deferred_qs_handle(). The point of this triggering is to force grace periods to end quickly in order to give tools like KASAN a better chance of detecting RCU usage bugs such as leaking RCU-protected pointers out of an RCU read-side critical section.
However, this irq-work triggering is unconditional. This works, but there is no point in doing this irq-work unless the current grace period is waiting on the running CPU or task, which is not the common case. After all, in the common case there are many rcu_read_unlock() calls per CPU per grace period.
This commit therefore triggers the irq-work only when the current grace period is waiting on the running CPU or task.
This change was tested as follows on a four-CPU system:
echo rcu_preempt_deferred_qs_handler > /sys/kernel/debug/tracing/set_ftrace_filter echo 1 > /sys/kernel/debug/tracing/function_profile_enabled
insmod rcutorture.ko
sleep 20
rmmod rcutorture.ko
echo 0 > /sys/kernel/debug/tracing/function_profile_enabled
echo > /sys/kernel/debug/tracing/set_ftrace_filter
This procedure produces results in this per-CPU set of files:
/sys/kernel/debug/tracing/trace_stat/function*
Sample output from one of these files is as follows:
Function Hit Time Avg s^2 -------- --- ---- --- --- rcu_preempt_deferred_qs_handle 838746 182650.3 us 0.217 us 0.004 us
The baseline sum of the "Hit" values (the number of calls to this function) was 3,319,015. With this commit, that sum was 1,140,359, for a 2.9x reduction. The worst-case variance across the CPUs was less than 25%, so this large effect size is statistically significant.
The raw data is available in the Link: URL.
--- kernel/rcu/tree_plugin.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
kernel/rcu/tree_plugin.h +2 -1
@@ -641,7 +641,8 @@ static void rcu_read_unlock_special(struct task_struct *t) expboost = (t->rcu_blocked_node &&READ_ONCE (t->rcu_blocked_node->exp_tasks)) || (rdp->grpmask &READ_ONCE (rnp->expmask)) || -IS_ENABLED (CONFIG_RCU_STRICT_GRACE_PERIOD ) || + (IS_ENABLED (CONFIG_RCU_STRICT_GRACE_PERIOD ) && + ((rdp->grpmask &READ_ONCE (rnp->qsmask)) || t->rcu_blocked_node)) || (IS_ENABLED (CONFIG_RCU_BOOST ) && irqs_were_disabled && t->rcu_blocked_node);// Need to defer quiescent state until everything is enabled.
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 663/862 rcu: Back off upon fill_page_cache_func() allocation failure
In reply to Greg Kroah-HartmanFrom: Michal Hocko <[email protected]>
[ Upstream commit 093590c16b447f53e66771c8579ae66c96f6ef61 ]
The fill_page_cache_func() function allocates couple of pages to store kvfree_rcu_bulk_data structures. This is a lightweight (GFP_NORETRY) allocation which can fail under memory pressure. The function will, however keep retrying even when the previous attempt has failed.
This retrying is in theory correct, but in practice the allocation is invoked from workqueue context, which means that if the memory reclaim gets stuck, these retries can hog the worker for quite some time. Although the workqueues subsystem automatically adjusts concurrency, such adjustment is not guaranteed to happen until the worker context sleeps. And the fill_page_cache_func() function's retry loop is not guaranteed to sleep (see the should_reclaim_retry() function).
And we have seen this function cause workqueue lockups:
kernel: BUG: workqueue lockup - pool cpus=93 node=1 flags=0x1 nice=0 stuck for 32s! [...]
kernel: pool 74: cpus=37 node=0 flags=0x1 nice=0 hung=32s workers=2 manager: 2146 kernel: pwq 498: cpus=249 node=1 flags=0x1 nice=0 active=4/256 refcnt=5 kernel: in-flight: 1917:fill_page_cache_func kernel: pending: dbs_work_handler, free_work, kfree_rcu_monitor
Originally, we thought that the root cause of this lockup was several retries with direct reclaim, but this is not yet confirmed. Furthermore, we have seen similar lockups without any heavy memory pressure. This suggests that there are other factors contributing to these lockups. However, it is not really clear that endless retries are desireable.
So let's make the fill_page_cache_func() function back off after allocation failure.
--- kernel/rcu/tree.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-)
kernel/rcu/tree.c +9 -8
@@ -3183,15 +3183,16 @@ static void fill_page_cache_func(struct work_struct *work) bnode = (struct kvfree_rcu_bulk_data *)__get_free_page (GFP_KERNEL | __GFP_NORETRY | __GFP_NOMEMALLOC | __GFP_NOWARN); -if (bnode) { -raw_spin_lock_irqsave (&krcp->lock, flags); - pushed =put_cached_bnode (krcp, bnode); -raw_spin_unlock_irqrestore (&krcp->lock, flags); +if (!bnode) +break ; -if (!pushed) { -free_page ((unsigned long ) bnode); -break ; - } +raw_spin_lock_irqsave (&krcp->lock, flags); + pushed =put_cached_bnode (krcp, bnode); +raw_spin_unlock_irqrestore (&krcp->lock, flags); + +if (!pushed) { +free_page ((unsigned long ) bnode); +break ; } }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 664/862 rcu-tasks: Convert RCU_LOCKDEP_WARN() to WARN_ONCE()
In reply to Greg Kroah-HartmanFrom: Zqiang <[email protected]>
[ Upstream commit fcd53c8a4dfa38bafb89efdd0b0f718f3a03f884 ]
Kernels built with CONFIG_PROVE_RCU=y and CONFIG_DEBUG_LOCK_ALLOC=y attempt to emit a warning when the synchronize_rcu_tasks_generic() function is called during early boot while the rcu_scheduler_active variable is RCU_SCHEDULER_INACTIVE. However the warnings is not actually be printed because the debug_lockdep_rcu_enabled() returns false, exactly because the rcu_scheduler_active variable is still equal to RCU_SCHEDULER_INACTIVE.
This commit therefore replaces RCU_LOCKDEP_WARN() with WARN_ONCE() to force these warnings to actually be printed.
--- kernel/rcu/tasks.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/rcu/tasks.h +1 -1
@@ -560,7 +560,7 @@ static int __noreturn rcu_tasks_kthread(void *arg)static void synchronize_rcu_tasks_generic (struct rcu_tasks *rtp) {/* Complain if the scheduler has not started. */ -RCU_LOCKDEP_WARN (rcu_scheduler_active ==RCU_SCHEDULER_INACTIVE , +WARN_ONCE (rcu_scheduler_active ==RCU_SCHEDULER_INACTIVE ,"synchronize_rcu_tasks called too soon" );// If the grace-period kthread is running, use it.
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 665/862 rcu-tasks: Ensure RCU Tasks Trace loops have quiescent states
In reply to Greg Kroah-HartmanFrom: Paul E. McKenney <[email protected]>
[ Upstream commit d6ad60635cafe900bcd11ad588d8accb36c36b1b ]
The RCU Tasks Trace grace-period kthread loops across all CPUs, and there can be quite a few CPUs, with some commercially available systems sporting well over a thousand of them. Some of these loops can feature IPIs, which can take some time. This commit therefore places a call to cond_resched_tasks_rcu_qs() in each such loop.
--- kernel/rcu/tasks.h | 3 +++ 1 file changed, 3 insertions(+)
kernel/rcu/tasks.h +3 -0
@@ -1500,6 +1500,7 @@ static void rcu_tasks_trace_pregp_step(struct list_head *hop)if (rcu_tasks_trace_pertask_prep (t, true))trc_add_holdout (t, hop);rcu_read_unlock (); +cond_resched_tasks_rcu_qs (); }// Only after all running tasks have been accounted for is it
@@ -1520,6 +1521,7 @@ static void rcu_tasks_trace_pregp_step(struct list_head *hop)raw_spin_lock_irqsave_rcu_node (rtpcp, flags); }raw_spin_unlock_irqrestore_rcu_node (rtpcp, flags); +cond_resched_tasks_rcu_qs (); }// Re-enable CPU hotplug now that the holdout list is populated.
@@ -1619,6 +1621,7 @@ static void check_all_holdout_tasks_trace(struct list_head *hop,trc_del_holdout (t); else if (needreport) show_stalled_task_trace(t, firstreport); +cond_resched_tasks_rcu_qs (); }// Re-enable CPU hotplug now that the holdout list scan has completed.
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 666/862 cpufreq: amd_pstate: fix wrong lowest perf fetch
In reply to Greg Kroah-HartmanFrom: Perry Yuan <[email protected]>
[ Upstream commit b185c5053c65b7704ead4537e4d4d9b33dc398dc ]
Fix the wrong lowest perf value reading which is used for new des_perf calculation by governor requested, the incorrect min_perf will get incorrect des_perf to be set , that will cause the system frequency changing unexpectedly.
--- drivers/cpufreq/amd-pstate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/cpufreq/amd-pstate.c +1 -1
@@ -322,7 +322,7 @@ static int amd_pstate_target(struct cpufreq_policy *policy,return -ENODEV ; cap_perf =READ_ONCE (cpudata->highest_perf); - min_perf =READ_ONCE (cpudata->lowest_nonlinear_perf); + min_perf =READ_ONCE (cpudata->lowest_perf); max_perf = cap_perf; freqs.old = policy->cur;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 667/862 ACPI: video: Add Toshiba Satellite/Portege Z830 quirk
In reply to Greg Kroah-HartmanFrom: Arvid Norlander <[email protected]>
[ Upstream commit 574160b8548deff8b80b174f03201e94ab8431e2 ]
Toshiba Satellite Z830 needs the quirk video_disable_backlight_sysfs_if for proper backlight control after suspend/resume cycles.
Toshiba Portege Z830 is simply the same laptop rebranded for certain markets (I looked through the manual to other language sections to confirm this) and thus also needs this quirk.
Thanks to Hans de Goede for suggesting this fix.
--- drivers/acpi/acpi_video.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
drivers/acpi/acpi_video.c +16 -0
@@ -496,6 +496,22 @@ static const struct dmi_system_id video_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE R830"), }, }, + { + .callback = video_disable_backlight_sysfs_if, + .ident = "Toshiba Satellite Z830", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE Z830"), + }, + }, + { + .callback = video_disable_backlight_sysfs_if, + .ident = "Toshiba Portege Z830", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE Z830"), + }, + }, /* * Some machine's _DOD IDs don't have bit 31(Device ID Scheme) set * but the IDs actually follow the Device ID Scheme.
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 668/862 fortify: Fix __compiletime_strlen() under UBSAN_BOUNDS_LOCAL
In reply to Greg Kroah-HartmanFrom: Kees Cook <[email protected]>
[ Upstream commit d07c0acb4f41cc42a0d97530946965b3e4fa68c1 ]
With CONFIG_FORTIFY=y and CONFIG_UBSAN_LOCAL_BOUNDS=y enabled, we observe a runtime panic while running Android's Compatibility Test Suite's (CTS) android.hardware.input.cts.tests. This is stemming from a strlen() call in hidinput_allocate().
__compiletime_strlen() is implemented in terms of __builtin_object_size(), then does an array access to check for NUL-termination. A quirk of __builtin_object_size() is that for strings whose values are runtime dependent, __builtin_object_size(str, 1 or 0) returns the maximum size of possible values when those sizes are determinable at compile time. Example:
static const char *v = "FOO BAR";
static const char *y = "FOO BA";
unsigned long x (int z) {
// Returns 8, which is:
// max(__builtin_object_size(v, 1), __builtin_object_size(y, 1))
return __builtin_object_size(z ? v : y, 1);}
So when FORTIFY_SOURCE is enabled, the current implementation of __compiletime_strlen() will try to access beyond the end of y at runtime using the size of v. Mixed with UBSAN_LOCAL_BOUNDS we get a fault.
hidinput_allocate() has a local C string whose value is control flow dependent on a switch statement, so __builtin_object_size(str, 1) evaluates to the maximum string length, making all other cases fault on the last character check. hidinput_allocate() could be cleaned up to avoid runtime calls to strlen() since the local variable can only have literal values, so there's no benefit to trying to fortify the strlen call site there.
Perform a __builtin_constant_p() check against index 0 earlier in the macro to filter out the control-flow-dependant case. Add a KUnit test for checking the expected behavioral characteristics of FORTIFY_SOURCE internals.
--- include/linux/fortify-string.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
include/linux/fortify-string.h +2 -1
@@ -19,7 +19,8 @@ void __write_overflow_field(size_t avail, size_t wanted) __compiletime_warning("unsigned char *__p = (unsigned char *)(p); \size_t __ret = (size_t )-1 ; \size_t __p_size =__builtin_object_size (p,1 ); \ -if (__p_size != (size_t )-1 ) { \ +if (__p_size != (size_t )-1 && \ +__builtin_constant_p (*__p)) { \size_t __p_len = __p_size -1 ; \if (__builtin_constant_p (__p[__p_len]) && \ __p[__p_len] =='\0' ) \
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 669/862 ACPI: tables: FPDT: Dont call acpi_os_map_memory() on invalid phys address
In reply to Greg Kroah-HartmanFrom: Hans de Goede <[email protected]>
[ Upstream commit 211391bf04b3c74e250c566eeff9cf808156c693 ]
On a Packard Bell Dot SC (Intel Atom N2600 model) there is a FPDT table which contains invalid physical addresses, with high bits set which fall outside the range of the CPU-s supported physical address range.
Calling acpi_os_map_memory() on such an invalid phys address leads to the below WARN_ON in ioremap triggering resulting in an oops/stacktrace.
Add code to verify the physical address before calling acpi_os_map_memory() to fix / avoid the oops.
[ 1.226900] ioremap: invalid physical address 3001000000000000 [ 1.226949] ------------[ cut here ]------------ [ 1.226962] WARNING: CPU: 1 PID: 1 at arch/x86/mm/ioremap.c:200 __ioremap_caller.cold+0x43/0x5f [ 1.226996] Modules linked in: [ 1.227016] CPU: 1 PID: 1 Comm: swapper/0 Not tainted 6.0.0-rc3+ #490 [ 1.227029] Hardware name: Packard Bell dot s/SJE01_CT, BIOS V1.10 07/23/2013 [ 1.227038] RIP: 0010:__ioremap_caller.cold+0x43/0x5f [ 1.227054] Code: 96 00 00 e9 f8 af 24 ff 89 c6 48 c7 c7 d8 0c 84 99 e8 6a 96 00 00 e9 76 af 24 ff 48 89 fe 48 c7 c7 a8 0c 84 99 e8 56 96 00 00 <0f> 0b e9 60 af 24 ff 48 8b 34 24 48 c7 c7 40 0d 84 99 e8 3f 96 00 [ 1.227067] RSP: 0000:ffffb18c40033d60 EFLAGS: 00010286 [ 1.227084] RAX: 0000000000000032 RBX: 3001000000000000 RCX: 0000000000000000 [ 1.227095] RDX: 0000000000000001 RSI: 00000000ffffdfff RDI: 00000000ffffffff [ 1.227105] RBP: 3001000000000000 R08: 0000000000000000 R09: ffffb18c40033c18 [ 1.227115] R10: 0000000000000003 R11: ffffffff99d62fe8 R12: 0000000000000008 [ 1.227124] R13: 0003001000000000 R14: 0000000000001000 R15: 3001000000000000 [ 1.227135] FS: 0000000000000000(0000) GS:ffff913a3c080000(0000) knlGS:0000000000000000 [ 1.227146] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 1.227156] CR2: 0000000000000000 CR3: 0000000018c26000 CR4: 00000000000006e0 [ 1.227167] Call Trace: [ 1.227176] <TASK> [ 1.227185] ? acpi_os_map_iomem+0x1c9/0x1e0 [ 1.227215] ? kmem_cache_alloc_trace+0x187/0x370 [ 1.227254] acpi_os_map_iomem+0x1c9/0x1e0 [ 1.227288] acpi_init_fpdt+0xa8/0x253 [ 1.227308] ? acpi_debugfs_init+0x1f/0x1f [ 1.227339] do_one_initcall+0x5a/0x300 [ 1.227406] ? rcu_read_lock_sched_held+0x3f/0x80 [ 1.227442] kernel_init_freeable+0x28b/0x2cc [ 1.227512] ? rest_init+0x170/0x170 [ 1.227538] kernel_init+0x16/0x140 [ 1.227552] ret_from_fork+0x1f/0x30 [ 1.227639] </TASK> [ 1.227647] irq event stamp: 186819 [ 1.227656] hardirqs last enabled at (186825): [<ffffffff98184a6e>] __up_console_sem+0x5e/0x70 [ 1.227672] hardirqs last disabled at (186830): [<ffffffff98184a53>] __up_console_sem+0x43/0x70 [ 1.227686] softirqs last enabled at (186576): [<ffffffff980fbc9d>] __irq_exit_rcu+0xed/0x160 [ 1.227701] softirqs last disabled at (186569): [<ffffffff980fbc9d>] __irq_exit_rcu+0xed/0x160 [ 1.227715] ---[ end trace 0000000000000000 ]---
--- drivers/acpi/acpi_fpdt.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+)
drivers/acpi/acpi_fpdt.c +22 -0
@@ -143,6 +143,23 @@ static const struct attribute_group boot_attr_group = {static struct kobject *fpdt_kobj; +#if definedCONFIG_X86 && definedCONFIG_PHYS_ADDR_T_64BIT +#include <linux/processor.h> +static bool fpdt_address_valid (u64 address) +{ +/* +* On some systems the table contains invalid addresses +* with unsuppored high address bits set, check for this. +*/ +return !(address >> boot_cpu_data.x86_phys_bits); +} +#else +static bool fpdt_address_valid (u64 address) +{ +return true; +} +#endif +static int fpdt_process_subtable (u64 address,u32 subtable_type) {struct fpdt_subtable_header *subtable_header;
@@ -151,6 +168,11 @@ static int fpdt_process_subtable(u64 address, u32 subtable_type)u32 length, offset;int result; +if (!fpdt_address_valid (address)) { +pr_info (FW_BUG "invalid physical address: 0x%llx!\n" , address); +return -EINVAL ; + } + subtable_header =acpi_os_map_memory (address,sizeof (*subtable_header));if (!subtable_header)return -ENOMEM ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 670/862 cpufreq: intel_pstate: Add Tigerlake support in no-HWP mode
In reply to Greg Kroah-HartmanFrom: Doug Smythies <[email protected]>
[ Upstream commit 71bb5c82aaaea007167f3ba68d3a669c74d7d55d ]
Users may disable HWP in firmware, in which case intel_pstate wouldn't load unless the CPU model is explicitly supported.
Add TIGERLAKE to the list of CPUs that can register intel_pstate while not advertising the HWP capability. Without this change, an TIGERLAKE in no-HWP mode could only use the acpi_cpufreq frequency scaling driver.
See also commits:d8de7a44e11f: cpufreq: intel_pstate: Add Skylake servers supportfbdc21e9b038: cpufreq: intel_pstate: Add Icelake servers support in no-HWP mode 706c5328851d: cpufreq: intel_pstate: Add Cometlake support in no-HWP mode
Reported by: M. Cargi Ari <[email protected]>
--- drivers/cpufreq/intel_pstate.c | 1 + 1 file changed, 1 insertion(+)
drivers/cpufreq/intel_pstate.c +1 -0
@@ -2416,6 +2416,7 @@ static const struct x86_cpu_id intel_pstate_cpu_ids[] = {X86_MATCH (SKYLAKE_X , core_funcs),X86_MATCH (COMETLAKE , core_funcs),X86_MATCH (ICELAKE_X , core_funcs), +X86_MATCH (TIGERLAKE , core_funcs), {} };MODULE_DEVICE_TABLE (x86cpu, intel_pstate_cpu_ids);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 671/862 MIPS: BCM47XX: Cast memcmp() of function to (void *)
In reply to Greg Kroah-HartmanFrom: Kees Cook <[email protected]>
[ Upstream commit 0dedcf6e3301836eb70cfa649052e7ce4fcd13ba ]
Clang is especially sensitive about argument type matching when using __overloaded functions (like memcmp(), etc). Help it see that function pointers are just "void *". Avoids this error:
arch/mips/bcm47xx/prom.c:89:8: error: no matching function for call to 'memcmp'
if (!memcmp(prom_init, prom_init + mem, 32))
^~~~~~include/linux/string.h:156:12: note: candidate function not viable: no known conversion from 'void (void)' to 'const void *' for 1st argument extern int memcmp(const void *,const void *,__kernel_size_t);
--- arch/mips/bcm47xx/prom.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/mips/bcm47xx/prom.c +2 -2
@@ -86,7 +86,7 @@ static __init void prom_init_mem(void)pr_debug ("Assume 128MB RAM\n" );break ; } -if (!memcmp (prom_init, prom_init + mem,32 )) +if (!memcmp ((void *)prom_init, (void *)prom_init + mem,32 ))break ; } lowmem = mem;
@@ -159,7 +159,7 @@ void __init bcm47xx_prom_highmem_init(void) off =EXTVBASE +__pa (off);for (extmem =128 <<20 ; extmem <512 <<20 ; extmem <<=1 ) { -if (!memcmp (prom_init, (void *)(off + extmem),16 )) +if (!memcmp ((void *)prom_init, (void *)(off + extmem),16 ))break ; } extmem -= lowmem;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 672/862 powercap: intel_rapl: fix UBSAN shift-out-of-bounds issue
In reply to Greg Kroah-HartmanFrom: Chao Qin <[email protected]>
[ Upstream commit 2d93540014387d1c73b9ccc4d7895320df66d01b ]
When value < time_unit, the parameter of ilog2() will be zero and the return value is -1. u64(-1) is too large for shift exponent and then will trigger shift-out-of-bounds:
shift exponent 18446744073709551615 is too large for 32-bit type 'int'
Call Trace: rapl_compute_time_window_core rapl_write_data_raw set_time_window store_constraint_time_window_us
--- drivers/powercap/intel_rapl_common.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/powercap/intel_rapl_common.c +3 -0
@@ -994,6 +994,9 @@ static u64 rapl_compute_time_window_core(struct rapl_package *rp, u64 value, y = value &0x1f ; value = (1 << y) * (4 + f) * rp->time_unit /4 ; }else { +if (value < rp->time_unit) +return 0 ; +do_div (value, rp->time_unit); y =ilog2 (value); f =div64_u64 (4 * (value - (1 << y)),1 << y);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 673/862 thermal: intel_powerclamp: Use get_cpu() instead of smp_processor_id() to avoid crash
In reply to Greg Kroah-HartmanFrom: Srinivas Pandruvada <[email protected]>
[ Upstream commit 68b99e94a4a2db6ba9b31fe0485e057b9354a640 ]
When CPU 0 is offline and intel_powerclamp is used to inject idle, it generates kernel BUG:
BUG: using smp_processor_id() in preemptible [00000000] code: bash/15687 caller is debug_smp_processor_id+0x17/0x20 CPU: 4 PID: 15687 Comm: bash Not tainted 5.19.0-rc7+ #57 Call Trace: <TASK> dump_stack_lvl+0x49/0x63 dump_stack+0x10/0x16 check_preemption_disabled+0xdd/0xe0 debug_smp_processor_id+0x17/0x20 powerclamp_set_cur_state+0x7f/0xf9 [intel_powerclamp]
...
...
Here CPU 0 is the control CPU by default and changed to the current CPU, if CPU 0 offlined. This check has to be performed under cpus_read_lock(), hence the above warning.
Use get_cpu() instead of smp_processor_id() to avoid this BUG.
--- drivers/thermal/intel/intel_powerclamp.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/thermal/intel/intel_powerclamp.c +4 -2
@@ -532,8 +532,10 @@ static int start_power_clamp(void)/* prefer BSP */ control_cpu =0 ; -if (!cpu_online (control_cpu)) - control_cpu =smp_processor_id (); +if (!cpu_online (control_cpu)) { + control_cpu =get_cpu (); +put_cpu (); + } clamping = true;schedule_delayed_work (&poll_pkg_cstate_work,0 );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 674/862 ARM: decompressor: Include .data.rel.ro.local
In reply to Greg Kroah-HartmanFrom: Kees Cook <[email protected]>
[ Upstream commit 1b64daf413acd86c2c13f5443f6b4ef3690c8061 ]
The .data.rel.ro.local section has the same semantics as .data.rel.ro here, so include it in the .rodata section of the decompressor. Additionally since the .printk_index section isn't usable outside of the core kernel, discard it in the decompressor. Avoids these warnings:
arm-linux-gnueabi-ld: warning: orphan section .data.rel.ro.local' from arch/arm/boot/compressed/fdt_rw.o' being placed in section `.data.rel.ro.local'
arm-linux-gnueabi-ld: warning: orphan section .printk_index' from arch/arm/boot/compressed/fdt_rw.o' being placed in section `.printk_index'
--- arch/arm/boot/compressed/vmlinux.lds.S | 2 ++ 1 file changed, 2 insertions(+)
arch/arm/boot/compressed/vmlinux.lds.S +2 -0
@@ -23,6 +23,7 @@ SECTIONS *(.ARM.extab*) *(.note.*) *(.rel.*) + *(.printk_index) /* * Discard any r/w data - this produces a link error if we have any, * which is required for PIC decompression. Local data generates
@@ -57,6 +58,7 @@ SECTIONS *(.rodata) *(.rodata.*) *(.data.rel.ro) + *(.data.rel.ro.*) } .piggydata : { *(.piggydata)
Signature · 9 lines
2.35.1 _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Greg Kroah-Hartman
maintainerPATCH 675/862 ACPI: x86: Add a quirk for Dell Inspiron 14 2-in-1 for StorageD3Enable
In reply to Greg Kroah-HartmanFrom: Mario Limonciello <[email protected]>
[ Upstream commit 018d6711c26e4bd26e20a819fcc7f8ab902608f3 ]
Dell Inspiron 14 2-in-1 has two ACPI nodes under GPP1 both with _ADR of 0, both without _HID. It's ambiguous which the kernel should take, but it seems to take "DEV0". Unfortunately "DEV0" is missing the device property StorageD3Enable which is present on "NVME".
To avoid this causing problems for suspend, add a quirk for this system to behave like StorageD3Enable property was found.
--- drivers/acpi/x86/utils.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-)
drivers/acpi/x86/utils.c +18 -1
@@ -207,9 +207,26 @@ static const struct x86_cpu_id storage_d3_cpu_ids[] = { {} }; +static const struct dmi_system_id force_storage_d3_dmi[] = { + { +/* +* _ADR is ambiguous between GPP1.DEV0 and GPP1.NVME +* but .NVME is needed to get StorageD3Enable node +* https://bugzilla.kernel.org/show_bug.cgi?id=216440 +*/ + .matches = { +DMI_MATCH (DMI_SYS_VENDOR ,"Dell Inc." ), +DMI_MATCH (DMI_PRODUCT_NAME ,"Inspiron 14 7425 2-in-1" ), + } + }, + {} +}; +bool force_storage_d3 (void ) { -return x86_match_cpu (storage_d3_cpu_ids); +const struct dmi_system_id *dmi_id =dmi_first_match (force_storage_d3_dmi); + +return dmi_id ||x86_match_cpu (storage_d3_cpu_ids); }/*
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 676/862 x86/entry: Work around Clang __bdos() bug
In reply to Greg Kroah-HartmanFrom: Kees Cook <[email protected]>
[ Upstream commit 3e1730842f142add55dc658929221521a9ea62b6 ]
Clang produces a false positive when building with CONFIG_FORTIFY_SOURCE=y and CONFIG_UBSAN_BOUNDS=y when operating on an array with a dynamic offset. Work around this by using a direct assignment of an empty instance. Avoids this warning:
../include/linux/fortify-string.h:309:4: warning: call to __write_overflow_field declared with 'warn ing' attribute: detected write beyond size of field (1st parameter); maybe use struct_group()? [-Wat tribute-warning]
__write_overflow_field(p_size_field, size);
^which was isolated to the memset() call in xen_load_idt().
Note that this looks very much like another bug that was worked around:
https://github.com/ClangBuiltLinux/linux/issues/1592
--- arch/x86/xen/enlighten_pv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
arch/x86/xen/enlighten_pv.c +2 -1
@@ -765,6 +765,7 @@ static void xen_load_idt(const struct desc_ptr *desc) {static DEFINE_SPINLOCK (lock);static struct trap_info traps[257 ]; +static const struct trap_info zero = { };unsigned out;trace_xen_cpu_load_idt (desc);
@@ -774,7 +775,7 @@ static void xen_load_idt(const struct desc_ptr *desc)memcpy (this_cpu_ptr (&idt_desc), desc,sizeof (idt_desc)); out =xen_convert_trap_info (desc, traps, false); -memset (&traps[out],0 ,sizeof (traps[0 ])); + traps[out] = zero;xen_mc_flush ();if (HYPERVISOR_set_trap_table (traps))
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 677/862 NFSD: Return nfserr_serverfault if splice_ok but buf->pages have data
In reply to Greg Kroah-HartmanFrom: Anna Schumaker <[email protected]>
[ Upstream commit 06981d560606ac48d61e5f4fff6738b925c93173 ]
This was discussed with Chuck as part of this patch set. Returning nfserr_resource was decided to not be the best error message here, and he suggested changing to nfserr_serverfault instead.
--- fs/nfsd/nfs4xdr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/nfsd/nfs4xdr.c +1 -1
@@ -3988,7 +3988,7 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr, }if (resp->xdr->buf->page_len && splice_ok) {WARN_ON_ONCE (1 ); -return nfserr_resource; +return nfserr_serverfault; }xdr_commit_encode (xdr);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 678/862 NFSD: fix use-after-free on source server when doing inter-server copy
In reply to Greg Kroah-HartmanFrom: Dai Ngo <[email protected]>
[ Upstream commit 019805fea91599b22dfa62ffb29c022f35abeb06 ]
Use-after-free occurred when the laundromat tried to free expired cpntf_state entry on the s2s_cp_stateids list after inter-server copy completed. The sc_cp_list that the expired copy state was inserted on was already freed.
When COPY completes, the Linux client normally sends LOCKU(lock_state x), FREE_STATEID(lock_state x) and CLOSE(open_state y) to the source server. The nfs4_put_stid call from nfsd4_free_stateid cleans up the copy state from the s2s_cp_stateids list before freeing the lock state's stid.
However, sometimes the CLOSE was sent before the FREE_STATEID request. When this happens, the nfsd4_close_open_stateid call from nfsd4_close frees all lock states on its st_locks list without cleaning up the copy state on the sc_cp_list list. When the time the FREE_STATEID arrives the server returns BAD_STATEID since the lock state was freed. This causes the use-after-free error to occur when the laundromat tries to free the expired cpntf_state.
This patch adds a call to nfs4_free_cpntf_statelist in nfsd4_close_open_stateid to clean up the copy state before calling free_ol_stateid_reaplist to free the lock state's stid on the reaplist.
--- fs/nfsd/nfs4state.c | 5 +++++ 1 file changed, 5 insertions(+)
fs/nfsd/nfs4state.c +5 -0
@@ -1049,6 +1049,7 @@ static struct nfs4_ol_stateid * nfs4_alloc_open_stateid(struct nfs4_client *clp)static void nfs4_free_deleg (struct nfs4_stid *stid) { +WARN_ON (!list_empty (&stid->sc_cp_list));kmem_cache_free (deleg_slab, stid);atomic_long_dec (&num_delegations); }
@@ -1462,6 +1463,7 @@ static void nfs4_free_ol_stateid(struct nfs4_stid *stid)release_all_access (stp);if (stp->st_stateowner)nfs4_put_stateowner (stp->st_stateowner); +WARN_ON (!list_empty (&stid->sc_cp_list));kmem_cache_free (stateid_slab, stid); }
@@ -6684,6 +6686,7 @@ static void nfsd4_close_open_stateid(struct nfs4_ol_stateid *s)struct nfs4_client *clp = s->st_stid.sc_client;bool unhashed;LIST_HEAD (reaplist); +struct nfs4_ol_stateid *stp;spin_lock (&clp->cl_lock); unhashed =unhash_open_stateid (s, &reaplist);
@@ -6692,6 +6695,8 @@ static void nfsd4_close_open_stateid(struct nfs4_ol_stateid *s)if (unhashed)put_ol_stateid_locked (s, &reaplist);spin_unlock (&clp->cl_lock); +list_for_each_entry (stp, &reaplist, st_locks) +nfs4_free_cpntf_statelist (clp->net, &stp->st_stid);free_ol_stateid_reaplist (&reaplist); }else {spin_unlock (&clp->cl_lock);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 679/862 libbpf: Ensure functions with always_inline attribute are inline
In reply to Greg Kroah-HartmanFrom: James Hilliard <[email protected]>
[ Upstream commit d25f40ff68aa61c838947bb9adee6c6b36e77453 ]
GCC expects the always_inline attribute to only be set on inline functions, as such we should make all functions with this attribute use the __always_inline macro which makes the function inline and sets the attribute.
Fixes errors like:/home/buildroot/bpf-next/tools/testing/selftests/bpf/tools/include/bpf/bpf_tracing.h:439:1: error: ‘always_inline’ function might not be inlinable [-Werror=attributes]
439 | ____##name(unsigned long long *ctx, ##args)
| ^~~~
--- tools/lib/bpf/bpf_tracing.h | 14 +++++++------- tools/lib/bpf/usdt.bpf.h | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-)
tools/lib/bpf/bpf_tracing.h +7 -7
@@ -426,7 +426,7 @@ struct pt_regs;*/ #define BPF_PROG(name, args...) \ name(unsigned long long *ctx); \ -static __attribute__((always_inline)) typeof(name(0)) \ +static __always_inline typeof(name(0)) \ ____##name(unsigned long long *ctx, ##args); \ typeof(name(0)) name(unsigned long long *ctx) \ { \
@@ -435,7 +435,7 @@ typeof(name(0)) name(unsigned long long *ctx) \ return ____##name(___bpf_ctx_cast(args)); \ _Pragma("GCC diagnostic pop") \ } \ -static __attribute__((always_inline)) typeof(name(0)) \ +static __always_inline typeof(name(0)) \ ____##name(unsigned long long *ctx, ##args)struct pt_regs ;
@@ -460,7 +460,7 @@ struct pt_regs;*/ #define BPF_KPROBE(name, args...) \ name(struct pt_regs *ctx); \ -static __attribute__((always_inline)) typeof(name(0)) \ +static __always_inline typeof(name(0)) \ ____##name(struct pt_regs *ctx, ##args); \ typeof(name(0)) name(struct pt_regs *ctx) \ { \
@@ -469,7 +469,7 @@ typeof(name(0)) name(struct pt_regs *ctx) \ return ____##name(___bpf_kprobe_args(args)); \ _Pragma("GCC diagnostic pop") \ } \ -static __attribute__((always_inline)) typeof(name(0)) \ +static __always_inline typeof(name(0)) \ ____##name(struct pt_regs *ctx, ##args)#define ___bpf_kretprobe_args0 () ctx
@@ -484,7 +484,7 @@ ____##name(struct pt_regs *ctx, ##args)*/ #define BPF_KRETPROBE(name, args...) \ name(struct pt_regs *ctx); \ -static __attribute__((always_inline)) typeof(name(0)) \ +static __always_inline typeof(name(0)) \ ____##name(struct pt_regs *ctx, ##args); \ typeof(name(0)) name(struct pt_regs *ctx) \ { \
@@ -540,7 +540,7 @@ static __always_inline typeof(name(0)) ____##name(struct pt_regs *ctx, ##args) #define BPF_KSYSCALL(name, args...) \ name(struct pt_regs *ctx); \ extern _Bool LINUX_HAS_SYSCALL_WRAPPER __kconfig; \ -static __attribute__((always_inline)) typeof(name(0)) \ +static __always_inline typeof(name(0)) \ ____##name(struct pt_regs *ctx, ##args); \ typeof(name(0)) name(struct pt_regs *ctx) \ { \
@@ -555,7 +555,7 @@ typeof(name(0)) name(struct pt_regs *ctx) \ return ____##name(___bpf_syscall_args(args)); \ _Pragma("GCC diagnostic pop") \ } \ -static __attribute__((always_inline)) typeof(name(0)) \ +static __always_inline typeof(name(0)) \ ____##name(struct pt_regs *ctx, ##args)#define BPF_KPROBE_SYSCALL BPF_KSYSCALL
tools/lib/bpf/usdt.bpf.h +2 -2
@@ -232,7 +232,7 @@ long bpf_usdt_cookie(struct pt_regs *ctx)*/ #define BPF_USDT(name, args...) \ name(struct pt_regs *ctx); \ -static __attribute__((always_inline)) typeof(name(0)) \ +static __always_inline typeof(name(0)) \ ____##name(struct pt_regs *ctx, ##args); \ typeof(name(0)) name(struct pt_regs *ctx) \ { \
@@ -241,7 +241,7 @@ typeof(name(0)) name(struct pt_regs *ctx) \ return ____##name(___bpf_usdt_args(args)); \ _Pragma("GCC diagnostic pop") \ } \ -static __attribute__((always_inline)) typeof(name(0)) \ +static __always_inline typeof(name(0)) \ ____##name(struct pt_regs *ctx, ##args)#endif /* __USDT_BPF_H__ */
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 680/862 libbpf: Do not require executable permission for shared libraries
In reply to Greg Kroah-HartmanFrom: Hengqi Chen <[email protected]>
[ Upstream commit 9e32084ef1c33a87a736d6ce3fcb95b60dac9aa1 ]
Currently, resolve_full_path() requires executable permission for both programs and shared libraries. This causes failures on distos like Debian since the shared libraries are not installed executable and Linux is not requiring shared libraries to have executable permissions. Let's remove executable permission check for shared libraries.
--- tools/lib/bpf/libbpf.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
tools/lib/bpf/libbpf.c +5 -3
@@ -10667,15 +10667,17 @@ static const char *arch_specific_lib_patstatic int resolve_full_path (const char *file,char *result,size_t result_sz) {const char *search_paths[3 ] = {}; -int i; +int i, perm;if (str_has_sfx (file,".so" ) ||strstr (file,".so." )) { search_paths[0 ] =getenv ("LD_LIBRARY_PATH" ); search_paths[1 ] ="/usr/lib64:/usr/lib" ; search_paths[2 ] =arch_specific_lib_paths (); + perm =R_OK ; }else { search_paths[0 ] =getenv ("PATH" ); search_paths[1 ] ="/usr/bin:/usr/sbin" ; + perm =R_OK |X_OK ; }for (i =0 ; i <ARRAY_SIZE (search_paths); i++) {
@@ -10694,8 +10696,8 @@ static int resolve_full_path(const charif (!seg_len)continue ;snprintf (result, result_sz,"%.*s/%s" , seg_len, s, file); -/* ensure it is an executable file/link */ -if (access (result,R_OK |X_OK ) <0 ) +/* ensure it has required permissions */ +if (access (result, perm) <0 )continue ;pr_debug ("resolved '%s' to '%s'\n" , file, result);return 0 ;
Greg Kroah-Hartman
maintainerPATCH 681/862 wifi: rtw88: phy: fix warning of possible buffer overflow
In reply to Greg Kroah-HartmanFrom: Zong-Zhe Yang <[email protected]>
[ Upstream commit 86331c7e0cd819bf0c1d0dcf895e0c90b0aa9a6f ]
reported by smatch
phy.c:854 rtw_phy_linear_2_db() error: buffer overflow 'db_invert_table[i]' 8 <= 8 (assuming for loop doesn't break)
However, it seems to be a false alarm because we prevent it originally via
if (linear >= db_invert_table[11][7])
return 96; /* maximum 96 dB */Still, we adjust the code to be more readable and avoid smatch warning.
--- drivers/net/wireless/realtek/rtw88/phy.c | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-)
drivers/net/wireless/realtek/rtw88/phy.c +8 -13
@@ -816,23 +816,18 @@ static u8 rtw_phy_linear_2_db(u64 linear)u8 j;u32 dB; -if (linear >= db_invert_table[11 ][7 ]) -return 96 ;/* maximum 96 dB */ -for (i =0 ; i <12 ; i++) { -if (i <=2 && (linear <<FRAC_BITS ) <= db_invert_table[i][7 ]) -break ; -else if (i >2 && linear <= db_invert_table[i][7 ]) -break ; +for (j =0 ; j <8 ; j++) { +if (i <=2 && (linear <<FRAC_BITS ) <= db_invert_table[i][j]) + goto cnt; +else if (i >2 && linear <= db_invert_table[i][j]) + goto cnt; + } } -for (j =0 ; j <8 ; j++) { -if (i <=2 && (linear <<FRAC_BITS ) <= db_invert_table[i][j]) -break ; -else if (i >2 && linear <= db_invert_table[i][j]) -break ; - } +return 96 ;/* maximum 96 dB */ +cnt:if (j ==0 && i ==0 ) goto end;
Signature · 1 line
2.35.1
RE: [PATCH 6.0 681/862] wifi: rtw88: phy: fix warning of possible buffer overflow
Quoted 17 lines
-----Original Message-----
From: Greg Kroah-Hartman <[email protected]>
Sent: Wednesday, October 19, 2022 4:33 PM
To: [email protected]
Cc: Greg Kroah-Hartman <[email protected]>; [email protected]; Kevin Yang <[email protected]>; Ping-Ke Shih <[email protected]>; Kalle Valo <[email protected]>; Sasha Levin <[email protected]>
Subject: [PATCH 6.0 681/862] wifi: rtw88: phy: fix warning of possible buffer overflowFrom: Zong-Zhe Yang <[email protected]>
[ Upstream commit
86331c7e0cd819bf0c1d0dcf895e0c90b0aa9a6f]reported by smatch
Quoted 8 lines
phy.c:854
rtw_phy_linear_2_db()error: buffer overflow 'db_invert_table[i]' 8 <= 8 (assuming for loop doesn't break)However, it seems to be a false alarm because we prevent it originally via
if (linear >= db_invert_table[11][7]) return 96; /* maximum 96 dB */Still, we adjust the code to be more readable and avoid smatch warning.
Like Pavel mentioned [1], this patch is to avoid smatch warning, not a really bug. So, shouldn't take this patch.
[1] https://lore.kernel.org/linux-wireless/[email protected]/
Quoted 53 lines
Signed-off-by Zong-Zhe Yang <[email protected]>Signed-off-by Ping-Ke Shih <[email protected]>Signed-off-by Kalle Valo <[email protected]>Signed-off-by Sasha Levin <[email protected]>--- drivers/net/wireless/realtek/rtw88/phy.c | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-)drivers/net/wireless/realtek/rtw88/phy.c +8
-14@@ -816,23 +816,18 @@ static u8 rtw_phy_linear_2_db(u64 linear)u8 j;u32 dB; -if (linear >= db_invert_table[11 ][7 ]) -return 96 ;/* maximum 96 dB */ -for (i =0 ; i <12 ; i++) { -if (i <=2 && (linear <<FRAC_BITS ) <= db_invert_table[i][7 ]) -break ; -else if (i >2 && linear <= db_invert_table[i][7 ]) -break ; +for (j =0 ; j <8 ; j++) { +if (i <=2 && (linear <<FRAC_BITS ) <= db_invert_table[i][j]) + goto cnt; +else if (i >2 && linear <= db_invert_table[i][j]) + goto cnt; + } } -for (j =0 ; j <8 ; j++) { -if (i <=2 && (linear <<FRAC_BITS ) <= db_invert_table[i][j]) -break ; -else if (i >2 && linear <= db_invert_table[i][j]) -break ; - } +return 96 ;/* maximum 96 dB */ +cnt:if (j ==0 && i ==0 ) goto end; --2.35.1
------Please consider the environment before printing this e-mail.
Greg Kroah-Hartman
maintainerRe: [PATCH 6.0 681/862] wifi: rtw88: phy: fix warning of possible buffer overflow
Quoted 24 lines · Ping-Ke Shih
Quoted 24 lines
-----Original Message-----
From: Greg Kroah-Hartman <[email protected]>
Sent: Wednesday, October 19, 2022 4:33 PM
To: [email protected]
Cc: Greg Kroah-Hartman <[email protected]>; [email protected]; Kevin Yang <[email protected]>; Ping-Ke Shih <[email protected]>; Kalle Valo <[email protected]>; Sasha Levin <[email protected]>
Subject: [PATCH 6.0 681/862] wifi: rtw88: phy: fix warning of possible buffer overflowFrom: Zong-Zhe Yang <[email protected]>
[ Upstream commit
86331c7e0cd819bf0c1d0dcf895e0c90b0aa9a6f]reported by smatch
phy.c:854
rtw_phy_linear_2_db()error: buffer overflow 'db_invert_table[i]' 8 <= 8 (assuming for loop doesn't break)However, it seems to be a false alarm because we prevent it originally via
if (linear >= db_invert_table[11][7]) return 96; /* maximum 96 dB */
Quoted 6 lines
Quoted 1 line
Still, we adjust the code to be more readable and avoid smatch warning.
Like Pavel mentioned [1], this patch is to avoid smatch warning, not a really bug. So, shouldn't take this patch.
[1] https://lore.kernel.org/linux-wireless/[email protected]/
Ok, will go drop now, thanks.
greg k-h
Greg Kroah-Hartman
maintainerPATCH 682/862 wifi: brcmfmac: fix invalid address access when enabling SCAN log level
In reply to Greg Kroah-HartmanFrom: Wright Feng <[email protected]>
[ Upstream commit aa666b68e73fc06d83c070d96180b9010cf5a960 ]
The variable i is changed when setting random MAC address and causes invalid address access when printing the value of pi->reqs[i]->reqid.
We replace reqs index with ri to fix the issue.
[ 136.726473] Unable to handle kernel access to user memory outside uaccess routines at virtual address 0000000000000000 [ 136.737365] Mem abort info: [ 136.740172] ESR = 0x96000004 [ 136.743359] Exception class = DABT (current EL), IL = 32 bits [ 136.749294] SET = 0, FnV = 0 [ 136.752481] EA = 0, S1PTW = 0 [ 136.755635] Data abort info: [ 136.758514] ISV = 0, ISS = 0x00000004 [ 136.762487] CM = 0, WnR = 0 [ 136.765522] user pgtable: 4k pages, 48-bit VAs, pgdp = 000000005c4e2577 [ 136.772265] [0000000000000000] pgd=0000000000000000 [ 136.777160] Internal error: Oops: 96000004 [#1] PREEMPT SMP [ 136.782732] Modules linked in: brcmfmac(O) brcmutil(O) cfg80211(O) compat(O) [ 136.789788] Process wificond (pid: 3175, stack limit = 0x00000000053048fb) [ 136.796664] CPU: 3 PID: 3175 Comm: wificond Tainted: G O 4.19.42-00001-g531a5f5 #1 [ 136.805532] Hardware name: Freescale i.MX8MQ EVK (DT) [ 136.810584] pstate: 60400005 (nZCv daif +PAN -UAO) [ 136.815429] pc : brcmf_pno_config_sched_scans+0x6cc/0xa80 [brcmfmac] [ 136.821811] lr : brcmf_pno_config_sched_scans+0x67c/0xa80 [brcmfmac] [ 136.828162] sp : ffff00000e9a3880 [ 136.831475] x29: ffff00000e9a3890 x28: ffff800020543400 [ 136.836786] x27: ffff8000b1008880 x26: ffff0000012bf6a0 [ 136.842098] x25: ffff80002054345c x24: ffff800088d22400 [ 136.847409] x23: ffff0000012bf638 x22: ffff0000012bf6d8 [ 136.852721] x21: ffff8000aced8fc0 x20: ffff8000ac164400 [ 136.858032] x19: ffff00000e9a3946 x18: 0000000000000000 [ 136.863343] x17: 0000000000000000 x16: 0000000000000000 [ 136.868655] x15: ffff0000093f3b37 x14: 0000000000000050 [ 136.873966] x13: 0000000000003135 x12: 0000000000000000 [ 136.879277] x11: 0000000000000000 x10: ffff000009a61888 [ 136.884589] x9 : 000000000000000f x8 : 0000000000000008 [ 136.889900] x7 : 303a32303d726464 x6 : ffff00000a1f957d [ 136.895211] x5 : 0000000000000000 x4 : ffff00000e9a3942 [ 136.900523] x3 : 0000000000000000 x2 : ffff0000012cead8 [ 136.905834] x1 : ffff0000012bf6d8 x0 : 0000000000000000 [ 136.911146] Call trace: [ 136.913623] brcmf_pno_config_sched_scans+0x6cc/0xa80 [brcmfmac] [ 136.919658] brcmf_pno_start_sched_scan+0xa4/0x118 [brcmfmac] [ 136.925430] brcmf_cfg80211_sched_scan_start+0x80/0xe0 [brcmfmac] [ 136.931636] nl80211_start_sched_scan+0x140/0x308 [cfg80211] [ 136.937298] genl_rcv_msg+0x358/0x3f4 [ 136.940960] netlink_rcv_skb+0xb4/0x118 [ 136.944795] genl_rcv+0x34/0x48 [ 136.947935] netlink_unicast+0x264/0x300 [ 136.951856] netlink_sendmsg+0x2e4/0x33c [ 136.955781] __sys_sendto+0x120/0x19c
--- .../net/wireless/broadcom/brcm80211/brcmfmac/pno.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c +6 -6
@@ -158,12 +158,12 @@ static int brcmf_pno_set_random(struct brcmf_if *ifp, struct brcmf_pno_info *pi)struct brcmf_pno_macaddr_le pfn_mac;u8 *mac_addr =NULL ;u8 *mac_mask =NULL ; -int err, i; +int err, i, ri; -for (i =0 ; i < pi->n_reqs; i++) -if (pi->reqs[i]->flags &NL80211_SCAN_FLAG_RANDOM_ADDR ) { - mac_addr = pi->reqs[i]->mac_addr; - mac_mask = pi->reqs[i]->mac_addr_mask; +for (ri =0 ; ri < pi->n_reqs; ri++) +if (pi->reqs[ri]->flags &NL80211_SCAN_FLAG_RANDOM_ADDR ) { + mac_addr = pi->reqs[ri]->mac_addr; + mac_mask = pi->reqs[ri]->mac_addr_mask;break ; }
@@ -185,7 +185,7 @@ static int brcmf_pno_set_random(struct brcmf_if *ifp, struct brcmf_pno_info *pi) pfn_mac.mac[0 ] |=0x02 ;brcmf_dbg (SCAN ,"enabling random mac: reqid=%llu mac=%pM\n" , - pi->reqs[i]->reqid, pfn_mac.mac); + pi->reqs[ri]->reqid, pfn_mac.mac); err =brcmf_fil_iovar_data_set (ifp,"pfn_macaddr" , &pfn_mac,sizeof (pfn_mac));if (err)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 683/862 bpftool: Clear errno after libcaps checks
In reply to Greg Kroah-HartmanFrom: Quentin Monnet <[email protected]>
[ Upstream commit cea558855c39b7f1f02ff50dcf701ca6596bc964 ]
When bpftool is linked against libcap, the library runs a "constructor" function to compute the number of capabilities of the running kernel [0], at the beginning of the execution of the program. As part of this, it performs multiple calls to prctl(). Some of these may fail, and set errno to a non-zero value:
# strace -e prctl ./bpftool version
prctl(PR_CAPBSET_READ, CAP_MAC_OVERRIDE) = 1
prctl(PR_CAPBSET_READ, 0x30 /* CAP_??? */) = -1 EINVAL (Invalid argument)
prctl(PR_CAPBSET_READ, CAP_CHECKPOINT_RESTORE) = 1
prctl(PR_CAPBSET_READ, 0x2c /* CAP_??? */) = -1 EINVAL (Invalid argument)
prctl(PR_CAPBSET_READ, 0x2a /* CAP_??? */) = -1 EINVAL (Invalid argument)
prctl(PR_CAPBSET_READ, 0x29 /* CAP_??? */) = -1 EINVAL (Invalid argument)
** fprintf added at the top of main(): we have errno == 1
./bpftool v7.0.0
using libbpf v1.0
features: libbfd, libbpf_strict, skeletons
+++ exited with 0 +++This has been addressed in libcap 2.63 [1], but until this version is available everywhere, we can fix it on bpftool side.
Let's clean errno at the beginning of the main() function, to make sure that these checks do not interfere with the batch mode, where we error out if errno is set after a bpftool command.
[0] https://git.kernel.org/pub/scm/libs/libcap/libcap.git/tree/libcap/cap_alloc.c?h=libcap-2.65#n20
[1] https://git.kernel.org/pub/scm/libs/libcap/libcap.git/commit/?id=f25a1b7e69f7b33e6afb58b3e38f3450b7d2d9a0
--- tools/bpf/bpftool/main.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
tools/bpf/bpftool/main.c +10 -0
@@ -435,6 +435,16 @@ int main(int argc, char **argv)setlinebuf (stdout); +#ifdef USE_LIBCAP +/* Libcap < 2.63 hooks before main() to compute the number of +* capabilities of the running kernel, and doing so it calls prctl() +* which may fail and set errno to non-zero. +* Let's reset errno to make sure this does not interfere with the +* batch mode. +*/ + errno =0 ; +#endif + last_do_help = do_help; pretty_output = false; json_output = false;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 684/862 net: ethernet: ti: davinci_mdio: Add workaround for errata i2329
In reply to Greg Kroah-HartmanFrom: Ravi Gunasekaran <[email protected]>
[ Upstream commit d04807b80691c6041ca8e3dcf1870d1bf1082c22 ]
On the CPSW and ICSS peripherals, there is a possibility that the MDIO interface returns corrupt data on MDIO reads or writes incorrect data on MDIO writes. There is also a possibility for the MDIO interface to become unavailable until the next peripheral reset.
The workaround is to configure the MDIO in manual mode and disable the MDIO state machine and emulate the MDIO protocol by reading and writing appropriate fields in MDIO_MANUAL_IF_REG register of the MDIO controller to manipulate the MDIO clock and data pins.
More details about the errata i2329 and the workaround is available in:
https://www.ti.com/lit/er/sprz487a/sprz487a.pdf
Add implementation to disable MDIO state machine, configure MDIO in manual mode and achieve MDIO read and writes via MDIO Bitbanging
--- drivers/net/ethernet/ti/davinci_mdio.c | 242 +++++++++++++++++++++++-- 1 file changed, 231 insertions(+), 11 deletions(-)
drivers/net/ethernet/ti/davinci_mdio.c +231 -11
@@ -26,6 +26,8 @@#include <linux/of_device.h> #include <linux/of_mdio.h> #include <linux/pinctrl/consumer.h> +#include <linux/mdio-bitbang.h> +#include <linux/sys_soc.h> /* * This timeout definition is a worst-case ultra defensive measure against
@@ -41,6 +43,7 @@struct davinci_mdio_of_param {int autosuspend_delay_ms; +bool manual_mode; };struct davinci_mdio_regs {
@@ -49,6 +52,15 @@ struct davinci_mdio_regs {#define CONTROL_IDLE BIT(31)#define CONTROL_ENABLE BIT(30)#define CONTROL_MAX_DIV (0xffff) +#define CONTROL_CLKDIV GENMASK(15, 0) + +#define MDIO_MAN_MDCLK_O BIT(2) +#define MDIO_MAN_OE BIT(1) +#define MDIO_MAN_PIN BIT(0) +#define MDIO_MANUALMODE BIT(31) + +#define MDIO_PIN 0 +u32 alive;u32 link;
@@ -59,7 +71,9 @@ struct davinci_mdio_regs {u32 userintmasked;u32 userintmaskset;u32 userintmaskclr; -u32 __reserved_1[20 ]; +u32 manualif; +u32 poll; +u32 __reserved_1[18 ];struct {u32 access;
@@ -79,6 +93,7 @@ static const struct mdio_platform_data default_pdata = {struct davinci_mdio_data {struct mdio_platform_data pdata; +struct mdiobb_ctrl bb_ctrl;struct davinci_mdio_regs __iomem *regs;struct clk *clk;struct device *dev;
@@ -90,6 +105,7 @@ struct davinci_mdio_data {*/ bool skip_scan;u32 clk_div; +bool manual_mode; };static void davinci_mdio_init_clk (struct davinci_mdio_data *data)
@@ -128,9 +144,122 @@ static void davinci_mdio_enable(struct davinci_mdio_data *data)writel (data->clk_div |CONTROL_ENABLE , &data->regs->control); } -static int davinci_mdio_reset (struct mii_bus *bus) +static void davinci_mdio_disable (struct davinci_mdio_data *data) +{ +u32 reg; + +/* Disable MDIO state machine */ + reg =readl (&data->regs->control); + + reg &= ~CONTROL_CLKDIV ; + reg |= data->clk_div; + + reg &= ~CONTROL_ENABLE ; +writel (reg, &data->regs->control); +} + +static void davinci_mdio_enable_manual_mode (struct davinci_mdio_data *data) +{ +u32 reg; +/* set manual mode */ + reg =readl (&data->regs->poll); + reg |=MDIO_MANUALMODE ; +writel (reg, &data->regs->poll); +} + +static void davinci_set_mdc (struct mdiobb_ctrl *ctrl,int level) +{ +struct davinci_mdio_data *data; +u32 reg; + + data = container_of(ctrl, struct davinci_mdio_data, bb_ctrl); + reg =readl (&data->regs->manualif); + +if (level) + reg |=MDIO_MAN_MDCLK_O ; +else + reg &= ~MDIO_MAN_MDCLK_O ; + +writel (reg, &data->regs->manualif); +} + +static void davinci_set_mdio_dir (struct mdiobb_ctrl *ctrl,int output) +{ +struct davinci_mdio_data *data; +u32 reg; + + data = container_of(ctrl, struct davinci_mdio_data, bb_ctrl); + reg =readl (&data->regs->manualif); + +if (output) + reg |=MDIO_MAN_OE ; +else + reg &= ~MDIO_MAN_OE ; + +writel (reg, &data->regs->manualif); +} + +static void davinci_set_mdio_data (struct mdiobb_ctrl *ctrl,int value) +{ +struct davinci_mdio_data *data; +u32 reg; + + data = container_of(ctrl, struct davinci_mdio_data, bb_ctrl); + reg =readl (&data->regs->manualif); + +if (value) + reg |=MDIO_MAN_PIN ; +else + reg &= ~MDIO_MAN_PIN ; + +writel (reg, &data->regs->manualif); +} + +static int davinci_get_mdio_data (struct mdiobb_ctrl *ctrl) +{ +struct davinci_mdio_data *data; +unsigned long reg; + + data = container_of(ctrl, struct davinci_mdio_data, bb_ctrl); + reg =readl (&data->regs->manualif); +return test_bit (MDIO_PIN , ®); +} + +static int davinci_mdiobb_read (struct mii_bus *bus,int phy,int reg) +{ +int ret; + + ret =pm_runtime_resume_and_get (bus->parent); +if (ret <0 ) +return ret; + + ret =mdiobb_read (bus, phy, reg); + +pm_runtime_mark_last_busy (bus->parent); +pm_runtime_put_autosuspend (bus->parent); + +return ret; +} + +static int davinci_mdiobb_write (struct mii_bus *bus,int phy,int reg, +u16 val) +{ +int ret; + + ret =pm_runtime_resume_and_get (bus->parent); +if (ret <0 ) +return ret; + + ret =mdiobb_write (bus, phy, reg, val); + +pm_runtime_mark_last_busy (bus->parent); +pm_runtime_put_autosuspend (bus->parent); + +return ret; +} + +static int davinci_mdio_common_reset (struct davinci_mdio_data *data) { -struct davinci_mdio_data *data = bus->priv;u32 phy_mask, ver;int ret;
@@ -138,6 +267,11 @@ static int davinci_mdio_reset(struct mii_bus *bus)if (ret <0 )return ret; +if (data->manual_mode) { +davinci_mdio_disable (data); +davinci_mdio_enable_manual_mode (data); + } +/* wait for scan logic to settle */ msleep (PHY_MAX_ADDR * data->access_time);
@@ -171,6 +305,23 @@ static int davinci_mdio_reset(struct mii_bus *bus)return 0 ; } +static int davinci_mdio_reset (struct mii_bus *bus) +{ +struct davinci_mdio_data *data = bus->priv; + +return davinci_mdio_common_reset (data); +} + +static int davinci_mdiobb_reset (struct mii_bus *bus) +{ +struct mdiobb_ctrl *ctrl = bus->priv; +struct davinci_mdio_data *data; + + data = container_of(ctrl, struct davinci_mdio_data, bb_ctrl); + +return davinci_mdio_common_reset (data); +} +/* wait until hardware is ready for another user access */ static inline int wait_for_user_access (struct davinci_mdio_data *data) {
@@ -318,6 +469,28 @@ static int davinci_mdio_probe_dt(struct mdio_platform_data *data,return 0 ; } +struct k3_mdio_soc_data { +bool manual_mode; +}; + +static const struct k3_mdio_soc_data am65_mdio_soc_data = { + .manual_mode = true, +}; + +static const struct soc_device_attribute k3_mdio_socinfo[] = { + { .family ="AM62X" , .revision ="SR1.0" , .data = &am65_mdio_soc_data }, + { .family ="AM64X" , .revision ="SR1.0" , .data = &am65_mdio_soc_data }, + { .family ="AM64X" , .revision ="SR2.0" , .data = &am65_mdio_soc_data }, + { .family ="AM65X" , .revision ="SR1.0" , .data = &am65_mdio_soc_data }, + { .family ="AM65X" , .revision ="SR2.0" , .data = &am65_mdio_soc_data }, + { .family ="J7200" , .revision ="SR1.0" , .data = &am65_mdio_soc_data }, + { .family ="J7200" , .revision ="SR2.0" , .data = &am65_mdio_soc_data }, + { .family ="J721E" , .revision ="SR1.0" , .data = &am65_mdio_soc_data }, + { .family ="J721E" , .revision ="SR2.0" , .data = &am65_mdio_soc_data }, + { .family ="J721S2" , .revision ="SR1.0" , .data = &am65_mdio_soc_data}, + {/* sentinel */ }, +}; +#if IS_ENABLED (CONFIG_OF )static const struct davinci_mdio_of_param of_cpsw_mdio_data = { .autosuspend_delay_ms = 100,
@@ -331,6 +504,14 @@ static const struct of_device_id davinci_mdio_of_mtable[] = {MODULE_DEVICE_TABLE (of, davinci_mdio_of_mtable);#endif +static const struct mdiobb_ops davinci_mdiobb_ops = { + .owner =THIS_MODULE , + .set_mdc = davinci_set_mdc, + .set_mdio_dir = davinci_set_mdio_dir, + .set_mdio_data = davinci_set_mdio_data, + .get_mdio_data = davinci_get_mdio_data, +}; +static int davinci_mdio_probe (struct platform_device *pdev) {struct mdio_platform_data *pdata =dev_get_platdata (&pdev->dev);
@@ -345,7 +526,26 @@ static int davinci_mdio_probe(struct platform_device *pdev)if (!data)return -ENOMEM ; - data->bus =devm_mdiobus_alloc (dev); + data->manual_mode = false; + data->bb_ctrl.ops = &davinci_mdiobb_ops; + +if (IS_ENABLED (CONFIG_OF ) && dev->of_node) { +const struct soc_device_attribute *soc_match_data; + + soc_match_data =soc_device_match (k3_mdio_socinfo); +if (soc_match_data && soc_match_data->data) { +const struct k3_mdio_soc_data *socdata = + soc_match_data->data; + + data->manual_mode = socdata->manual_mode; + } + } + +if (data->manual_mode) + data->bus =alloc_mdio_bitbang (&data->bb_ctrl); +else + data->bus =devm_mdiobus_alloc (dev); +if (!data->bus) {dev_err (dev,"failed to alloc mii bus\n" );return -ENOMEM ;
@@ -371,11 +571,20 @@ static int davinci_mdio_probe(struct platform_device *pdev) } data->bus->name =dev_name (dev); - data->bus->read = davinci_mdio_read; - data->bus->write = davinci_mdio_write; - data->bus->reset = davinci_mdio_reset; + +if (data->manual_mode) { + data->bus->read = davinci_mdiobb_read; + data->bus->write = davinci_mdiobb_write; + data->bus->reset = davinci_mdiobb_reset; + +dev_info (dev,"Configuring MDIO in manual mode\n" ); + }else { + data->bus->read = davinci_mdio_read; + data->bus->write = davinci_mdio_write; + data->bus->reset = davinci_mdio_reset; + data->bus->priv = data; + } data->bus->parent = dev; - data->bus->priv = data; data->clk =devm_clk_get (dev,"fck" );if (IS_ERR (data->clk)) {
@@ -433,9 +642,13 @@ static int davinci_mdio_remove(struct platform_device *pdev) {struct davinci_mdio_data *data =platform_get_drvdata (pdev); -if (data->bus) +if (data->bus) {mdiobus_unregister (data->bus); +if (data->manual_mode) +free_mdio_bitbang (data->bus); + } +pm_runtime_dont_use_autosuspend (&pdev->dev);pm_runtime_disable (&pdev->dev);
@@ -452,7 +665,9 @@ static int davinci_mdio_runtime_suspend(struct device *dev) ctrl =readl (&data->regs->control); ctrl &= ~CONTROL_ENABLE ;writel (ctrl, &data->regs->control); -wait_for_idle (data); + +if (!data->manual_mode) +wait_for_idle (data);return 0 ; }
@@ -461,7 +676,12 @@ static int davinci_mdio_runtime_resume(struct device *dev) {struct davinci_mdio_data *data =dev_get_drvdata (dev); -davinci_mdio_enable (data); +if (data->manual_mode) { +davinci_mdio_disable (data); +davinci_mdio_enable_manual_mode (data); + }else { +davinci_mdio_enable (data); + }return 0 ; }#endif
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 685/862 openvswitch: Fix double reporting of drops in dropwatch
In reply to Greg Kroah-HartmanFrom: Mike Pattrick <[email protected]>
[ Upstream commit 1100248a5c5ccd57059eb8d02ec077e839a23826 ]
Frames sent to userspace can be reported as dropped in ovs_dp_process_packet, however, if they are dropped in the netlink code then netlink_attachskb will report the same frame as dropped.
This patch checks for error codes which indicate that the frame has already been freed.
--- net/openvswitch/datapath.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
net/openvswitch/datapath.c +10 -3
@@ -252,10 +252,17 @@ void ovs_dp_process_packet(struct sk_buff *skb, struct sw_flow_key *key) upcall.mru =OVS_CB (skb)->mru; error =ovs_dp_upcall (dp, skb, key, &upcall,0 ); -if (unlikely (error)) -kfree_skb (skb); -else +switch (error) { +case 0 : +case -EAGAIN : +case -ERESTARTSYS : +case -EINTR :consume_skb (skb); +break ; +default : +kfree_skb (skb); +break ; + } stats_counter = &stats->n_missed; goto out; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 686/862 openvswitch: Fix overreporting of drops in dropwatch
In reply to Greg Kroah-HartmanFrom: Mike Pattrick <[email protected]>
[ Upstream commit c21ab2afa2c64896a7f0e3cbc6845ec63dcfad2e ]
Currently queue_userspace_packet will call kfree_skb for all frames, whether or not an error occurred. This can result in a single dropped frame being reported as multiple drops in dropwatch. This functions caller may also call kfree_skb in case of an error. This patch will consume the skbs instead and allow caller's to use kfree_skb.
--- net/openvswitch/datapath.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
net/openvswitch/datapath.c +3 -2
@@ -558,8 +558,9 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb, out:if (err)skb_tx_error (skb); -kfree_skb (user_skb); -kfree_skb (nskb); +consume_skb (user_skb); +consume_skb (nskb); +return err; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 687/862 tcp: annotate data-race around tcp_md5sig_pool_populated
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit aacd467c0a576e5e44d2de4205855dc0fe43f6fb ]
tcp_md5sig_pool_populated can be read while another thread changes its value.
The race has no consequence because allocations are protected with tcp_md5sig_mutex.
This patch adds READ_ONCE() and WRITE_ONCE() to document the race and silence KCSAN.
--- net/ipv4/tcp.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)
net/ipv4/tcp.c +10 -4
@@ -4444,12 +4444,16 @@ static void __tcp_alloc_md5sig_pool(void)* to memory. See smp_rmb() in tcp_get_md5sig_pool() */ smp_wmb (); - tcp_md5sig_pool_populated = true; +/* Paired with READ_ONCE() from tcp_alloc_md5sig_pool() +* and tcp_get_md5sig_pool(). +*/ +WRITE_ONCE (tcp_md5sig_pool_populated, true); }bool tcp_alloc_md5sig_pool (void ) { -if (unlikely (!tcp_md5sig_pool_populated)) { +/* Paired with WRITE_ONCE() from __tcp_alloc_md5sig_pool() */ +if (unlikely (!READ_ONCE (tcp_md5sig_pool_populated))) {mutex_lock (&tcp_md5sig_mutex);if (!tcp_md5sig_pool_populated) {
@@ -4460,7 +4464,8 @@ bool tcp_alloc_md5sig_pool(void)mutex_unlock (&tcp_md5sig_mutex); } -return tcp_md5sig_pool_populated; +/* Paired with WRITE_ONCE() from __tcp_alloc_md5sig_pool() */ +return READ_ONCE (tcp_md5sig_pool_populated); }EXPORT_SYMBOL (tcp_alloc_md5sig_pool);
@@ -4476,7 +4481,8 @@ struct tcp_md5sig_pool *tcp_get_md5sig_pool(void) {local_bh_disable (); -if (tcp_md5sig_pool_populated) { +/* Paired with WRITE_ONCE() from __tcp_alloc_md5sig_pool() */ +if (READ_ONCE (tcp_md5sig_pool_populated)) {/* coupled with smp_wmb() in __tcp_alloc_md5sig_pool() */ smp_rmb ();return this_cpu_ptr (&tcp_md5sig_pool);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 688/862 micrel: ksz8851: fixes struct pointer issue
In reply to Greg Kroah-HartmanFrom: Jerry Ray <[email protected]>
[ Upstream commit fef5de753ff01887cfa50990532c3890fccb9338 ]
Issue found during code review. This bug has no impact as long as the ks8851_net structure is the first element of the ks8851_net_spi structure. As long as the offset to the ks8851_net struct is zero, the container_of() macro is subtracting 0 and therefore no damage done. But if the ks8851_net_spi struct is ever modified such that the ks8851_net struct within it is no longer the first element of the struct, then the bug would manifest itself and cause problems.
struct ks8851_net is contained within ks8851_net_spi. ks is contained within kss.
kss is the priv_data of the netdev structure.
--- drivers/net/ethernet/micrel/ks8851_spi.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/net/ethernet/micrel/ks8851_spi.c +2 -3
@@ -413,7 +413,8 @@ static int ks8851_probe_spi(struct spi_device *spi) spi->bits_per_word =8 ; - ks =netdev_priv (netdev); + kss =netdev_priv (netdev); + ks = &kss->ks8851; ks->lock = ks8851_lock_spi; ks->unlock = ks8851_unlock_spi;
@@ -433,8 +434,6 @@ static int ks8851_probe_spi(struct spi_device *spi) IRQ_RXPSI) /* RX process stop */ ks->rc_ier = STD_IRQ; - kss =to_ks8851_spi (ks); - kss->spidev = spi;mutex_init (&kss->lock);INIT_WORK (&kss->tx_work, ks8851_tx_work);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 689/862 wifi: mac80211: accept STA changes without link changes
In reply to Greg Kroah-HartmanFrom: Johannes Berg <[email protected]>
[ Upstream commit b303835dabe0340f932ebb4e260d2229f79b0684 ]
If there's no link ID, then check that there are no changes to the link, and if so accept them, unless a new link is created. While at it, reject creating a new link without an address.
This fixes authorizing an MLD (peer) that has no link 0.
--- net/mac80211/cfg.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
net/mac80211/cfg.c +14 -0
@@ -1610,6 +1610,18 @@ static int sta_link_apply_parameters(struct ieee80211_local *local,rcu_dereference_protected (sta->link[link_id],lockdep_is_held (&local->sta_mtx)); +/* +* If there are no changes, then accept a link that doesn't exist, +* unless it's a new link. +*/ +if (params->link_id <0 && !new_link && + !params->link_mac && !params->txpwr_set && + !params->supported_rates_len && + !params->ht_capa && !params->vht_capa && + !params->he_capa && !params->eht_capa && + !params->opmode_notif_used) +return 0 ; +if (!link || !link_sta)return -EINVAL ;
@@ -1625,6 +1637,8 @@ static int sta_link_apply_parameters(struct ieee80211_local *local, params->link_mac)) {return -EINVAL ; } + }else if (new_link) { +return -EINVAL ; }if (params->txpwr_set) {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 690/862 x86/mce: Retrieve poison range from hardware
In reply to Greg Kroah-HartmanFrom: Jane Chu <[email protected]>
[ Upstream commit f9781bb18ed828e7b83b7bac4a4ad7cd497ee7d7 ]
When memory poison consumption machine checks fire, MCE notifier handlers like nfit_handle_mce() record the impacted physical address range which is reported by the hardware in the MCi_MISC MSR. The error information includes data about blast radius, i.e. how many cachelines did the hardware determine are impacted. A recent change
7917f9cdb503 ("acpi/nfit: rely on mce->misc to determine poison granularity")
updated nfit_handle_mce() to stop hard coding the blast radius value of 1 cacheline, and instead rely on the blast radius reported in 'struct mce' which can be up to 4K (64 cachelines).
It turns out that apei_mce_report_mem_error() had a similar problem in that it hard coded a blast radius of 4K rather than reading the blast radius from the error information. Fix apei_mce_report_mem_error() to convey the proper poison granularity.
--- arch/x86/kernel/cpu/mce/apei.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
arch/x86/kernel/cpu/mce/apei.c +12 -1
@@ -29,15 +29,26 @@void apei_mce_report_mem_error (int severity,struct cper_sec_mem_err *mem_err) {struct mce m; +int lsb;if (!(mem_err->validation_bits &CPER_MEM_VALID_PA ))return ; +/* +* Even if the ->validation_bits are set for address mask, +* to be extra safe, check and reject an error radius '0', +* and fall back to the default page size. +*/ +if (mem_err->validation_bits &CPER_MEM_VALID_PA_MASK ) + lsb =find_first_bit ((void *)&mem_err->physical_addr_mask,PAGE_SHIFT ); +else + lsb =PAGE_SHIFT ; +mce_setup (&m); m.bank =-1 ;/* Fake a memory read error with unknown channel */ m.status =MCI_STATUS_VAL |MCI_STATUS_EN |MCI_STATUS_ADDRV |MCI_STATUS_MISCV |0x9f ; - m.misc = (MCI_MISC_ADDR_PHYS <<6 ) |PAGE_SHIFT ; + m.misc = (MCI_MISC_ADDR_PHYS <<6 ) | lsb;if (severity >=GHES_SEV_RECOVERABLE ) m.status |=MCI_STATUS_UC ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 691/862 wifi: ath9k: avoid uninit memory read in ath9k_htc_rx_msg()
In reply to Greg Kroah-HartmanFrom: Tetsuo Handa <[email protected]>
[ Upstream commit b383e8abed41cc6ff1a3b34de75df9397fa4878c ]
syzbot is reporting uninit value at ath9k_htc_rx_msg() [1], for ioctl(USB_RAW_IOCTL_EP_WRITE) can call ath9k_hif_usb_rx_stream() with pkt_len = 0 but ath9k_hif_usb_rx_stream() uses __dev_alloc_skb(pkt_len + 32, GFP_ATOMIC) based on an assumption that pkt_len is valid. As a result, ath9k_hif_usb_rx_stream() allocates skb with uninitialized memory and ath9k_htc_rx_msg() is reading from uninitialized memory.
Since bytes accessed by ath9k_htc_rx_msg() is not known until ath9k_htc_rx_msg() is called, it would be difficult to check minimal valid pkt_len at "if (pkt_len > 2 * MAX_RX_BUF_SIZE) {" line in ath9k_hif_usb_rx_stream().
We have two choices. One is to workaround by adding __GFP_ZERO so that ath9k_htc_rx_msg() sees 0 if pkt_len is invalid. The other is to let ath9k_htc_rx_msg() validate pkt_len before accessing. This patch chose the latter.
Note that I'm not sure threshold condition is correct, for I can't find details on possible packet length used by this protocol.
--- drivers/net/wireless/ath/ath9k/htc_hst.c | 43 +++++++++++++++--------- 1 file changed, 28 insertions(+), 15 deletions(-)
drivers/net/wireless/ath/ath9k/htc_hst.c +28 -15
@@ -364,33 +364,27 @@ void ath9k_htc_txcompletion_cb(struct htc_target *htc_handle, }static void ath9k_htc_fw_panic_report (struct htc_target *htc_handle, -struct sk_buff *skb) +struct sk_buff *skb,u32 len) {uint32_t *pattern = (uint32_t *)skb->data; -switch (*pattern) { -case 0x33221199 : - { +if (*pattern ==0x33221199 && len >=sizeof (struct htc_panic_bad_vaddr )) {struct htc_panic_bad_vaddr *htc_panic; htc_panic = (struct htc_panic_bad_vaddr *) skb->data;dev_err (htc_handle->dev,"ath: firmware panic! " "exccause: 0x%08x; pc: 0x%08x; badvaddr: 0x%08x.\n" , htc_panic->exccause, htc_panic->pc, htc_panic->badvaddr); -break ; - } -case 0x33221299 : - { +return ; + } +if (*pattern ==0x33221299 ) {struct htc_panic_bad_epid *htc_panic; htc_panic = (struct htc_panic_bad_epid *) skb->data;dev_err (htc_handle->dev,"ath: firmware panic! " "bad epid: 0x%08x\n" , htc_panic->epid); -break ; - } -default : -dev_err (htc_handle->dev,"ath: unknown panic pattern!\n" ); -break ; +return ; } +dev_err (htc_handle->dev,"ath: unknown panic pattern!\n" ); }/*
@@ -411,16 +405,26 @@ void ath9k_htc_rx_msg(struct htc_target *htc_handle,if (!htc_handle || !skb)return ; +/* A valid message requires len >= 8. +* +* sizeof(struct htc_frame_hdr) == 8 +* sizeof(struct htc_ready_msg) == 8 +* sizeof(struct htc_panic_bad_vaddr) == 16 +* sizeof(struct htc_panic_bad_epid) == 8 +*/ +if (unlikely (len <sizeof (struct htc_frame_hdr ))) + goto invalid; htc_hdr = (struct htc_frame_hdr *) skb->data; epid = htc_hdr->endpoint_id;if (epid ==0x99 ) { -ath9k_htc_fw_panic_report (htc_handle, skb); +ath9k_htc_fw_panic_report (htc_handle, skb, len);kfree_skb (skb);return ; }if (epid <0 || epid >=ENDPOINT_MAX ) { +invalid:if (pipe_id !=USB_REG_IN_PIPE )dev_kfree_skb_any (skb);else
@@ -432,21 +436,30 @@ void ath9k_htc_rx_msg(struct htc_target *htc_handle,/* Handle trailer */ if (htc_hdr->flags &HTC_FLAGS_RECV_TRAILER ) { -if (be32_to_cpu (*(__be32 *) skb->data) ==0x00C60000 ) +if (be32_to_cpu (*(__be32 *) skb->data) ==0x00C60000 ) {/* Move past the Watchdog pattern */ htc_hdr = (struct htc_frame_hdr *)(skb->data +4 ); + len -=4 ; + } }/* Get the message ID */ +if (unlikely (len <sizeof (struct htc_frame_hdr ) +sizeof (__be16))) + goto invalid; msg_id = (__be16 *) ((void *) htc_hdr +sizeof (struct htc_frame_hdr ));/* Now process HTC messages */ switch (be16_to_cpu (*msg_id)) {case HTC_MSG_READY_ID : +if (unlikely (len <sizeof (struct htc_ready_msg ))) + goto invalid;htc_process_target_rdy (htc_handle, htc_hdr);break ;case HTC_MSG_CONNECT_SERVICE_RESPONSE_ID : +if (unlikely (len <sizeof (struct htc_frame_hdr ) + +sizeof (struct htc_conn_svc_rspmsg ))) + goto invalid;htc_process_conn_rsp (htc_handle, htc_hdr);break ;default :
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 692/862 thunderbolt: Add back Intel Falcon Ridge end-to-end flow control workaround
In reply to Greg Kroah-HartmanFrom: Mika Westerberg <[email protected]>
[ Upstream commit 54669e2f17cb5a4c41ade89427f074dc22cecb17 ]
As we are now enabling full end-to-end flow control to the Thunderbolt networking driver, in order for it to work properly on second generation Thunderbolt hardware (Falcon Ridge), we need to add back the workaround that was removed with commit 53f13319d131 ("thunderbolt: Get rid of E2E workaround"). However, this time we only apply it for Falcon Ridge controllers as a form of an additional quirk. For non-Falcon Ridge this does nothing.
While there fix a typo 'reqister' -> 'register' in the comment.
--- drivers/thunderbolt/nhi.c | 49 +++++++++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 7 deletions(-)
drivers/thunderbolt/nhi.c +42 -7
@@ -28,7 +28,11 @@#define RING_TYPE (ring) ((ring)->is_tx ? "TX ring" : "RX ring")#define RING_FIRST_USABLE_HOPID 1 - +/* +* Used with QUIRK_E2E to specify an unused HopID the Rx credits are +* transferred. +*/ +#define RING_E2E_RESERVED_HOPID RING_FIRST_USABLE_HOPID/* * Minimal number of vectors when we use MSI-X. Two for control channel * Rx/Tx and the rest four are for cross domain DMA paths.
@@ -38,7 +42,9 @@#define NHI_MAILBOX_TIMEOUT 500/* ms */ +/* Host interface quirks */ #define QUIRK_AUTO_CLEAR_INT BIT(0) +#define QUIRK_E2E BIT(1)static int ring_interrupt_index (struct tb_ring *ring) {
@@ -458,8 +464,18 @@ static void ring_release_msix(struct tb_ring *ring)static int nhi_alloc_hop (struct tb_nhi *nhi,struct tb_ring *ring) { +unsigned int start_hop =RING_FIRST_USABLE_HOPID ;int ret =0 ; +if (nhi->quirks &QUIRK_E2E ) { + start_hop =RING_FIRST_USABLE_HOPID +1 ; +if (ring->flags &RING_FLAG_E2E && !ring->is_tx) { +dev_dbg (&nhi->pdev->dev,"quirking E2E TX HopID %u -> %u\n" , + ring->e2e_tx_hop,RING_E2E_RESERVED_HOPID ); + ring->e2e_tx_hop =RING_E2E_RESERVED_HOPID ; + } + } +spin_lock_irq (&nhi->lock);if (ring->hop <0 ) {
@@ -469,7 +485,7 @@ static int nhi_alloc_hop(struct tb_nhi *nhi, struct tb_ring *ring)* Automatically allocate HopID from the non-reserved * range 1 .. hop_count - 1. */ -for (i =RING_FIRST_USABLE_HOPID ; i < nhi->hop_count; i++) { +for (i = start_hop; i < nhi->hop_count; i++) {if (ring->is_tx) {if (!nhi->tx_rings[i]) { ring->hop = i;
@@ -484,6 +500,11 @@ static int nhi_alloc_hop(struct tb_nhi *nhi, struct tb_ring *ring) } } +if (ring->hop >0 && ring->hop < start_hop) { +dev_warn (&nhi->pdev->dev,"invalid hop: %d\n" , ring->hop); + ret = -EINVAL ; + goto err_unlock; + }if (ring->hop <0 || ring->hop >= nhi->hop_count) {dev_warn (&nhi->pdev->dev,"invalid hop: %d\n" , ring->hop); ret = -EINVAL ;
@@ -1097,12 +1118,26 @@ static void nhi_shutdown(struct tb_nhi *nhi)static void nhi_check_quirks (struct tb_nhi *nhi) { -/* -* Intel hardware supports auto clear of the interrupt status -* reqister right after interrupt is being issued. -*/ -if (nhi->pdev->vendor ==PCI_VENDOR_ID_INTEL ) +if (nhi->pdev->vendor ==PCI_VENDOR_ID_INTEL ) { +/* +* Intel hardware supports auto clear of the interrupt +* status register right after interrupt is being +* issued. +*/ nhi->quirks |=QUIRK_AUTO_CLEAR_INT ; + +switch (nhi->pdev->device) { +case PCI_DEVICE_ID_INTEL_FALCON_RIDGE_2C_NHI : +case PCI_DEVICE_ID_INTEL_FALCON_RIDGE_4C_NHI : +/* +* Falcon Ridge controller needs the end-to-end +* flow control workaround to avoid losing Rx +* packets when RING_FLAG_E2E is set. +*/ + nhi->quirks |=QUIRK_E2E ; +break ; + } + } }static int nhi_check_iommu_pdev (struct pci_dev *pdev,void *data)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 693/862 x86/apic: Dont disable x2APIC if locked
In reply to Greg Kroah-HartmanFrom: Daniel Sneddon <[email protected]>
[ Upstream commit b8d1d163604bd1e600b062fb00de5dc42baa355f ]
The APIC supports two modes, legacy APIC (or xAPIC), and Extended APIC (or x2APIC). X2APIC mode is mostly compatible with legacy APIC, but it disables the memory-mapped APIC interface in favor of one that uses MSRs. The APIC mode is controlled by the EXT bit in the APIC MSR.
The MMIO/xAPIC interface has some problems, most notably the APIC LEAK [1]. This bug allows an attacker to use the APIC MMIO interface to extract data from the SGX enclave.
Introduce support for a new feature that will allow the BIOS to lock the APIC in x2APIC mode. If the APIC is locked in x2APIC mode and the kernel tries to disable the APIC or revert to legacy APIC mode a GP fault will occur.
Introduce support for a new MSR (IA32_XAPIC_DISABLE_STATUS) and handle the new locked mode when the LEGACY_XAPIC_DISABLED bit is set by preventing the kernel from trying to disable the x2APIC.
On platforms with the IA32_XAPIC_DISABLE_STATUS MSR, if SGX or TDX are enabled the LEGACY_XAPIC_DISABLED will be set by the BIOS. If legacy APIC is required, then it SGX and TDX need to be disabled in the BIOS.
[1]: https://aepicleak.com/aepicleak.pdf
--- .../admin-guide/kernel-parameters.txt | 4 ++ arch/x86/Kconfig | 7 ++- arch/x86/include/asm/cpu.h | 2 + arch/x86/include/asm/msr-index.h | 13 ++++++ arch/x86/kernel/apic/apic.c | 44 +++++++++++++++++-- 5 files changed, 65 insertions(+), 5 deletions(-)
Documentation/admin-guide/kernel-parameters.txt +4 -0
@@ -3805,6 +3805,10 @@ nox2apic [X86-64,APIC] Do not enable x2APIC mode. + NOTE: this parameter will be ignored on systems with the + LEGACY_XAPIC_DISABLED bit set in the + IA32_XAPIC_DISABLE_STATUS MSR. + nps_mtm_hs_ctr= [KNL,ARC] This parameter sets the maximum duration, in cycles, each HW thread of the CTOP can run
arch/x86/Kconfig +6 -1
@@ -448,6 +448,11 @@ config X86_X2APIC This allows 32-bit apic IDs (so it can support very large systems), and accesses the local apic via MSRs not via mmio. + Some Intel systems circa 2022 and later are locked into x2APIC mode + and can not fall back to the legacy APIC modes if SGX or TDX are + enabled in the BIOS. They will be unable to boot without enabling + this option. + If you don't know what to do here, say N. config X86_MPPARSE
@@ -1919,7 +1924,7 @@ endchoice config X86_SGX bool "Software Guard eXtensions (SGX)" - depends on X86_64 && CPU_SUP_INTEL + depends on X86_64 && CPU_SUP_INTEL && X86_X2APIC depends on CRYPTO=y depends on CRYPTO_SHA256=y select SRCU
arch/x86/include/asm/cpu.h +2 -0
@@ -94,4 +94,6 @@ static inline bool intel_cpu_signatures_match(unsigned int s1, unsigned int p1, return p1 & p2; } +extern u64 x86_read_arch_cap_msr (void ); +#endif /* _ASM_X86_CPU_H */
arch/x86/include/asm/msr-index.h +13 -0
@@ -155,6 +155,11 @@* Return Stack Buffer Predictions. */ +#define ARCH_CAP_XAPIC_DISABLE BIT(21)/* +* IA32_XAPIC_DISABLE_STATUS MSR +* supported +*/ +#define MSR_IA32_FLUSH_CMD 0x0000010b#define L1D_FLUSH BIT(0)/* * Writeback and invalidate the
@@ -1054,4 +1059,12 @@#define MSR_IA32_HW_FEEDBACK_PTR 0x17d0#define MSR_IA32_HW_FEEDBACK_CONFIG 0x17d1 +/* x2APIC locked status */ +#define MSR_IA32_XAPIC_DISABLE_STATUS 0xBD +#define LEGACY_XAPIC_DISABLED BIT(0)/* +* x2APIC mode is locked and +* disabling x2APIC will cause +* a #GP +*/ +#endif /* _ASM_X86_MSR_INDEX_H */
arch/x86/kernel/apic/apic.c +40 -4
86 lines not on this page · raw message
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 694/862 net: axienet: Switch to 64-bit RX/TX statistics
In reply to Greg Kroah-HartmanFrom: Robert Hancock <[email protected]>
[ Upstream commit cb45a8bf4693965e89d115cd2c510f12bc127c37 ]
The RX and TX byte/packet statistics in this driver could be overflowed relatively quickly on a 32-bit platform. Switch these stats to use the u64_stats infrastructure to avoid this.
--- drivers/net/ethernet/xilinx/xilinx_axienet.h | 12 ++++++ .../net/ethernet/xilinx/xilinx_axienet_main.c | 37 +++++++++++++++++-- 2 files changed, 45 insertions(+), 4 deletions(-)
drivers/net/ethernet/xilinx/xilinx_axienet.h +12 -0
@@ -402,6 +402,9 @@ struct axidma_bd {* @rx_bd_num: Size of RX buffer descriptor ring * @rx_bd_ci: Stores the index of the Rx buffer descriptor in the ring being * accessed currently. +* @rx_packets: RX packet count for statistics +* @rx_bytes: RX byte count for statistics +* @rx_stat_sync: Synchronization object for RX stats * @napi_tx: NAPI TX control structure * @tx_dma_cr: Nominal content of TX DMA control register * @tx_bd_v: Virtual address of the TX buffer descriptor ring
@@ -411,6 +414,9 @@ struct axidma_bd {* complete. Only updated at runtime by TX NAPI poll. * @tx_bd_tail: Stores the index of the next Tx buffer descriptor in the ring * to be populated. +* @tx_packets: TX packet count for statistics +* @tx_bytes: TX byte count for statistics +* @tx_stat_sync: Synchronization object for TX stats * @dma_err_task: Work structure to process Axi DMA errors * @tx_irq: Axidma TX IRQ number * @rx_irq: Axidma RX IRQ number
@@ -458,6 +464,9 @@ struct axienet_local {dma_addr_t rx_bd_p;u32 rx_bd_num;u32 rx_bd_ci; +u64_stats_t rx_packets; +u64_stats_t rx_bytes; +struct u64_stats_sync rx_stat_sync;struct napi_struct napi_tx;u32 tx_dma_cr;
@@ -466,6 +475,9 @@ struct axienet_local {u32 tx_bd_num;u32 tx_bd_ci;u32 tx_bd_tail; +u64_stats_t tx_packets; +u64_stats_t tx_bytes; +struct u64_stats_sync tx_stat_sync;struct work_struct dma_err_task;
drivers/net/ethernet/xilinx/xilinx_axienet_main.c +33 -4
@@ -752,8 +752,10 @@ static int axienet_tx_poll(struct napi_struct *napi, int budget)if (lp->tx_bd_ci >= lp->tx_bd_num) lp->tx_bd_ci %= lp->tx_bd_num; - ndev->stats.tx_packets += packets; - ndev->stats.tx_bytes += size; +u64_stats_update_begin (&lp->tx_stat_sync); +u64_stats_add (&lp->tx_packets, packets); +u64_stats_add (&lp->tx_bytes, size); +u64_stats_update_end (&lp->tx_stat_sync);/* Matches barrier in axienet_start_xmit */ smp_mb ();
@@ -984,8 +986,10 @@ static int axienet_rx_poll(struct napi_struct *napi, int budget) cur_p = &lp->rx_bd_v[lp->rx_bd_ci]; } - lp->ndev->stats.rx_packets += packets; - lp->ndev->stats.rx_bytes += size; +u64_stats_update_begin (&lp->rx_stat_sync); +u64_stats_add (&lp->rx_packets, packets); +u64_stats_add (&lp->rx_bytes, size); +u64_stats_update_end (&lp->rx_stat_sync);if (tail_p)axienet_dma_out_addr (lp,XAXIDMA_RX_TDESC_OFFSET , tail_p);
@@ -1292,10 +1296,32 @@ static int axienet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)return phylink_mii_ioctl (lp->phylink, rq, cmd); } +static void +axienet_get_stats64 (struct net_device *dev,struct rtnl_link_stats64 *stats) +{ +struct axienet_local *lp =netdev_priv (dev); +unsigned int start; + +netdev_stats_to_stats64 (stats, &dev->stats); + +do { + start =u64_stats_fetch_begin_irq (&lp->rx_stat_sync); + stats->rx_packets =u64_stats_read (&lp->rx_packets); + stats->rx_bytes =u64_stats_read (&lp->rx_bytes); + }while (u64_stats_fetch_retry_irq (&lp->rx_stat_sync, start)); + +do { + start =u64_stats_fetch_begin_irq (&lp->tx_stat_sync); + stats->tx_packets =u64_stats_read (&lp->tx_packets); + stats->tx_bytes =u64_stats_read (&lp->tx_bytes); + }while (u64_stats_fetch_retry_irq (&lp->tx_stat_sync, start)); +} +static const struct net_device_ops axienet_netdev_ops = { .ndo_open = axienet_open, .ndo_stop = axienet_stop, .ndo_start_xmit = axienet_start_xmit, + .ndo_get_stats64 = axienet_get_stats64, .ndo_change_mtu = axienet_change_mtu, .ndo_set_mac_address = netdev_set_mac_address, .ndo_validate_addr = eth_validate_addr,
@@ -1850,6 +1876,9 @@ static int axienet_probe(struct platform_device *pdev) lp->rx_bd_num =RX_BD_NUM_DEFAULT ; lp->tx_bd_num =TX_BD_NUM_DEFAULT ; +u64_stats_init (&lp->rx_stat_sync); +u64_stats_init (&lp->tx_stat_sync); +netif_napi_add (ndev, &lp->napi_rx, axienet_rx_poll,NAPI_POLL_WEIGHT );netif_napi_add (ndev, &lp->napi_tx, axienet_tx_poll,NAPI_POLL_WEIGHT );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 695/862 net-next: Fix IP_UNICAST_IF option behavior for connected sockets
In reply to Greg Kroah-HartmanFrom: Richard Gobert <[email protected]>
[ Upstream commit 0e4d354762cefd3e16b4cff8988ff276e45effc4 ]
The IP_UNICAST_IF socket option is used to set the outgoing interface for outbound packets.
The IP_UNICAST_IF socket option was added as it was needed by the Wine project, since no other existing option (SO_BINDTODEVICE socket option, IP_PKTINFO socket option or the bind function) provided the needed characteristics needed by the IP_UNICAST_IF socket option. [1] The IP_UNICAST_IF socket option works well for unconnected sockets, that is, the interface specified by the IP_UNICAST_IF socket option is taken into consideration in the route lookup process when a packet is being sent. However, for connected sockets, the outbound interface is chosen when connecting the socket, and in the route lookup process which is done when a packet is being sent, the interface specified by the IP_UNICAST_IF socket option is being ignored.
This inconsistent behavior was reported and discussed in an issue opened on systemd's GitHub project [2]. Also, a bug report was submitted in the kernel's bugzilla [3].
To understand the problem in more detail, we can look at what happens for UDP packets over IPv4 (The same analysis was done separately in the referenced systemd issue).
When a UDP packet is sent the udp_sendmsg function gets called and the following happens:
1. The oif member of the struct ipcm_cookie ipc (which stores the output interface of the packet) is initialized by the ipcm_init_sk function to inet->sk.sk_bound_dev_if (the device set by the SO_BINDTODEVICE socket option).
2. If the IP_PKTINFO socket option was set, the oif member gets overridden by the call to the ip_cmsg_send function.
3. If no output interface was selected yet, the interface specified by the IP_UNICAST_IF socket option is used.
4. If the socket is connected and no destination address is specified in the send function, the struct ipcm_cookie ipc is not taken into consideration and the cached route, that was calculated in the connect function is being used.
Thus, for a connected socket, the IP_UNICAST_IF sockopt isn't taken into consideration.
This patch corrects the behavior of the IP_UNICAST_IF socket option for connect()ed sockets by taking into consideration the IP_UNICAST_IF sockopt when connecting the socket.
In order to avoid reconnecting the socket, this option is still ignored when applied on an already connected socket until connect() is called again by the Richard Gobert.
Change the __ip4_datagram_connect function, which is called during socket connection, to take into consideration the interface set by the IP_UNICAST_IF socket option, in a similar way to what is done in the udp_sendmsg function.
[1] https://lore.kernel.org/netdev/1328685717.4736.4.camel@edumazet-laptop/T/
[2] https://github.com/systemd/systemd/issues/11935#issuecomment-618691018
[3] https://bugzilla.kernel.org/show_bug.cgi?id=210255
--- net/ipv4/datagram.c | 2 ++ tools/testing/selftests/net/fcnal-test.sh | 30 +++++++++++++++++++++++ tools/testing/selftests/net/nettest.c | 16 ++++++++++-- 3 files changed, 46 insertions(+), 2 deletions(-)
net/ipv4/datagram.c +2 -0
@@ -42,6 +42,8 @@ int __ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len oif = inet->mc_index;if (!saddr) saddr = inet->mc_addr; + }else if (!oif) { + oif = inet->uc_index; } fl4 = &inet->cork.fl.u.ip4; rt = ip_route_connect(fl4, usin->sin_addr.s_addr, saddr, oif,
tools/testing/selftests/net/fcnal-test.sh +30 -0
@@ -1466,6 +1466,13 @@ ipv4_udp_novrf() run_cmd nettest -D -r ${a} -d ${NSA_DEV} -S -0 ${NSA_IP} log_test_addr ${a} $? 0 "Client, device bind via IP_UNICAST_IF" + log_start + run_cmd_nsb nettest -D -s & + sleep 1 + run_cmd nettest -D -r ${a} -d ${NSA_DEV} -S -0 ${NSA_IP} -U + log_test_addr ${a} $? 0 "Client, device bind via IP_UNICAST_IF, with connect()" + + log_start show_hint "Should fail 'Connection refused'" run_cmd nettest -D -r ${a}
@@ -1525,6 +1532,13 @@ ipv4_udp_novrf() run_cmd nettest -D -d ${NSA_DEV} -S -r ${a} log_test_addr ${a} $? 0 "Global server, device client via IP_UNICAST_IF, local connection" + log_start + run_cmd nettest -s -D & + sleep 1 + run_cmd nettest -D -d ${NSA_DEV} -S -r ${a} -U + log_test_addr ${a} $? 0 "Global server, device client via IP_UNICAST_IF, local connection, with connect()" + + # IPv4 with device bind has really weird behavior - it overrides the # fib lookup, generates an rtable and tries to send the packet. This # causes failures for local traffic at different places
@@ -1550,6 +1564,15 @@ ipv4_udp_novrf() sleep 1 run_cmd nettest -D -r ${a} -d ${NSA_DEV} -S log_test_addr ${a} $? 1 "Global server, device client via IP_UNICAST_IF, local connection" + + log_start + show_hint "Should fail since addresses on loopback are out of device scope" + run_cmd nettest -D -s & + sleep 1 + run_cmd nettest -D -r ${a} -d ${NSA_DEV} -S -U + log_test_addr ${a} $? 1 "Global server, device client via IP_UNICAST_IF, local connection, with connect()" + + done a=${NSA_IP}
@@ -3157,6 +3180,13 @@ ipv6_udp_novrf() sleep 1 run_cmd nettest -6 -D -r ${a} -d ${NSA_DEV} -S log_test_addr ${a} $? 1 "Global server, device client via IP_UNICAST_IF, local connection" + + log_start + show_hint "Should fail 'No route to host' since addresses on loopback are out of device scope" + run_cmd nettest -6 -D -s & + sleep 1 + run_cmd nettest -6 -D -r ${a} -d ${NSA_DEV} -S -U + log_test_addr ${a} $? 1 "Global server, device client via IP_UNICAST_IF, local connection, with connect()" done a=${NSA_IP6}
tools/testing/selftests/net/nettest.c +14 -2
@@ -127,6 +127,9 @@ struct sock_args {/* ESP in UDP encap test */ int use_xfrm; + +/* use send() and connect() instead of sendto */ +int datagram_connect; };static int server_mode;
@@ -979,6 +982,11 @@ static int send_msg(int sd, void *addr, socklen_t alen, struct sock_args *args)log_err_errno ("write failed sending msg to peer" );return 1 ; } + }else if (args->datagram_connect) { +if (send (sd, msg, msglen,0 ) <0 ) { +log_err_errno ("send failed sending msg to peer" ); +return 1 ; + } }else if (args->ifindex && args->use_cmsg) {if (send_msg_cmsg (sd, addr, alen, args->ifindex, args->version))return 1 ;
@@ -1659,7 +1667,7 @@ static int connectsock(void *addr, socklen_t alen, struct sock_args *args)if (args->has_local_ip &&bind_socket (sd, args)) goto err; -if (args->type !=SOCK_STREAM ) +if (args->type !=SOCK_STREAM && !args->datagram_connect) goto out;if (args->password &&tcp_md5sig (sd, addr, alen, args))
@@ -1854,7 +1862,7 @@ static int ipc_parent(int cpid, int fd, struct sock_args *args)return client_status; } -#define GETOPT_STR "sr:l:c:p:t:g:P:DRn:M:X:m:d:I:BN:O:SCi6xL:0:1:2:3:Fbqf" +#define GETOPT_STR "sr:l:c:p:t:g:P:DRn:M:X:m:d:I:BN:O:SUCi6xL:0:1:2:3:Fbqf"#define OPT_FORCE_BIND_KEY_IFINDEX 1001#define OPT_NO_BIND_KEY_IFINDEX 1002
@@ -1891,6 +1899,7 @@ static void print_usage(char *prog)" -I dev bind socket to given device name - server mode\n" " -S use setsockopt (IP_UNICAST_IF or IP_MULTICAST_IF)\n" " to set device binding\n" +" -U Use connect() and send() for datagram sockets\n" " -f bind socket with the IP[V6]_FREEBIND option\n" " -C use cmsg and IP_PKTINFO to specify device binding\n" "\n"
@@ -2074,6 +2083,9 @@ int main(int argc, char *argv[])case 'x' : args.use_xfrm =1 ;break ; +case 'U' : + args.datagram_connect =1 ; +break ;default :print_usage (argv[0 ]);return 1 ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 696/862 xfrm: Update ipcomp_scratches with NULL when freed
In reply to Greg Kroah-HartmanFrom: Khalid Masum <[email protected]>
[ Upstream commit 8a04d2fc700f717104bfb95b0f6694e448a4537f ]
Currently if ipcomp_alloc_scratches() fails to allocate memory ipcomp_scratches holds obsolete address. So when we try to free the percpu scratches using ipcomp_free_scratches() it tries to vfree non existent vm area. Described below:
static void * __percpu *ipcomp_alloc_scratches(void)
{
...
scratches = alloc_percpu(void *);
if (!scratches)
return NULL;
ipcomp_scratches does not know about this allocation failure.
Therefore holding the old obsolete address.
...
}So when we free,
static void ipcomp_free_scratches(void)
{
...
scratches = ipcomp_scratches;Assigning obsolete address from ipcomp_scratches
if (!scratches)
return;
for_each_possible_cpu(i)
vfree(*per_cpu_ptr(scratches, i));
Trying to free non existent page, causing warning: trying to vfree
existent vm area.
...
}Fix this breakage by updating ipcomp_scrtches with NULL when scratches is freed
--- net/xfrm/xfrm_ipcomp.c | 1 + 1 file changed, 1 insertion(+)
net/xfrm/xfrm_ipcomp.c +1 -0
@@ -203,6 +203,7 @@ static void ipcomp_free_scratches(void)vfree (*per_cpu_ptr (scratches, i));free_percpu (scratches); + ipcomp_scratches =NULL ; }static void *__percpu *ipcomp_alloc_scratches (void )
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 697/862 wifi: ath11k: Register shutdown handler for WCN6750
In reply to Greg Kroah-HartmanFrom: Manikanta Pubbisetty <[email protected]>
[ Upstream commit ac41c2b642b136a1e633379fcb87a9db0ee07f5b ]
When the system shuts down, SMMU driver will be stopped and will not assist in IOVA translations. SMMU driver expects all of its consumers to shutdown before shutting down itself. WCN6750 being one of the consumer device should not perform any DMA operations after the SMMU has shutdown which will otherwise result in SMMU faults.
SMMU driver will call the shutdown() callback of all its consumer devices and the consumers shall stop further DMA activity after the invocation of their respective shutdown() callbacks.
Register the shutdown() callback to the platform core for WCN6750. Change will not impact other AHB ath11k devices.
Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.1.0.1-00887-QCAMSLSWPLZ-1
--- drivers/net/wireless/ath/ath11k/ahb.c | 58 ++++++++++++++++++++------ drivers/net/wireless/ath/ath11k/core.c | 2 + 2 files changed, 47 insertions(+), 13 deletions(-)
drivers/net/wireless/ath/ath11k/ahb.c +45 -13
@@ -1088,20 +1088,10 @@ static int ath11k_ahb_probe(struct platform_device *pdev)return ret; } -static int ath11k_ahb_remove (struct platform_device *pdev) +static void ath11k_ahb_remove_prepare (struct ath11k_base *ab) { -struct ath11k_base *ab =platform_get_drvdata (pdev);unsigned long left; -if (test_bit (ATH11K_FLAG_QMI_FAIL , &ab->dev_flags)) { -ath11k_ahb_power_down (ab); -ath11k_debugfs_soc_destroy (ab); -ath11k_qmi_deinit_service (ab); - goto qmi_fail; - } - -reinit_completion (&ab->driver_recovery); -if (test_bit (ATH11K_FLAG_RECOVERY , &ab->dev_flags)) { left =wait_for_completion_timeout (&ab->driver_recovery,ATH11K_AHB_RECOVERY_TIMEOUT );
@@ -1111,19 +1101,60 @@ static int ath11k_ahb_remove(struct platform_device *pdev)set_bit (ATH11K_FLAG_UNREGISTERING , &ab->dev_flags);cancel_work_sync (&ab->restart_work); +cancel_work_sync (&ab->qmi.event_work); +} + +static void ath11k_ahb_free_resources (struct ath11k_base *ab) +{ +struct platform_device *pdev = ab->pdev; -ath11k_core_deinit (ab); -qmi_fail:ath11k_ahb_free_irq (ab);ath11k_hal_srng_deinit (ab);ath11k_ahb_fw_resource_deinit (ab);ath11k_ce_free_pipes (ab);ath11k_core_free (ab);platform_set_drvdata (pdev,NULL ); +} + +static int ath11k_ahb_remove (struct platform_device *pdev) +{ +struct ath11k_base *ab =platform_get_drvdata (pdev); + +if (test_bit (ATH11K_FLAG_QMI_FAIL , &ab->dev_flags)) { +ath11k_ahb_power_down (ab); +ath11k_debugfs_soc_destroy (ab); +ath11k_qmi_deinit_service (ab); + goto qmi_fail; + } + +ath11k_ahb_remove_prepare (ab); +ath11k_core_deinit (ab); + +qmi_fail: +ath11k_ahb_free_resources (ab);return 0 ; } +static void ath11k_ahb_shutdown (struct platform_device *pdev) +{ +struct ath11k_base *ab =platform_get_drvdata (pdev); + +/* platform shutdown() & remove() are mutually exclusive. +* remove() is invoked during rmmod & shutdown() during +* system reboot/shutdown. +*/ +ath11k_ahb_remove_prepare (ab); + +if (!(test_bit (ATH11K_FLAG_REGISTERED , &ab->dev_flags))) + goto free_resources; + +ath11k_core_deinit (ab); + +free_resources: +ath11k_ahb_free_resources (ab); +} +static struct platform_driver ath11k_ahb_driver = { .driver = { .name ="ath11k" ,
@@ -1131,6 +1162,7 @@ static struct platform_driver ath11k_ahb_driver = { }, .probe = ath11k_ahb_probe, .remove = ath11k_ahb_remove, + .shutdown = ath11k_ahb_shutdown, };static int ath11k_ahb_init (void )
drivers/net/wireless/ath/ath11k/core.c +2 -0
@@ -1563,6 +1563,8 @@ static void ath11k_core_pre_reconfigure_recovery(struct ath11k_base *ab)wake_up (&ab->wmi_ab.tx_credits_wq);wake_up (&ab->peer_mapping_wq); + +reinit_completion (&ab->driver_recovery); }static void ath11k_core_post_reconfigure_recovery (struct ath11k_base *ab)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 698/862 rtw89: ser: leave lps with mutex
In reply to Greg Kroah-HartmanFrom: Zong-Zhe Yang <[email protected]>
[ Upstream commit 8676031bae1c91037d06341214f4150b33707c68 ]
Calling rtw89_leave_lps() should hold rtwdev::mutex. So, fix it.
--- drivers/net/wireless/realtek/rtw89/ser.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/wireless/realtek/rtw89/ser.c +3 -0
@@ -152,7 +152,10 @@ static void ser_state_run(struct rtw89_ser *ser, u8 evt)rtw89_debug (rtwdev,RTW89_DBG_SER ,"ser: %s receive %s\n" ,ser_st_name (ser),ser_ev_name (ser, evt)); +mutex_lock (&rtwdev->mutex);rtw89_leave_lps (rtwdev); +mutex_unlock (&rtwdev->mutex); + ser->st_tbl[ser->state].st_func (ser, evt); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 699/862 net: ftmac100: fix endianness-related issues from sparse
In reply to Greg Kroah-HartmanFrom: Sergei Antonov <[email protected]>
[ Upstream commit 9df696b3b3a4c96c3219eb87c7bf03fb50e490b8 ]
Sparse found a number of endianness-related issues of these kinds:
.../ftmac100.c:192:32: warning: restricted __le32 degrades to integer
.../ftmac100.c:208:23: warning: incorrect type in assignment (different base types).../ftmac100.c:208:23: expected unsigned int rxdes0.../ftmac100.c:208:23: got restricted __le32 [usertype]
.../ftmac100.c:249:23: warning: invalid assignment: &=.../ftmac100.c:249:23: left side has type unsigned int.../ftmac100.c:249:23: right side has type restricted __le32
.../ftmac100.c:527:16: warning: cast to restricted __le32
Change type of some fields from 'unsigned int' to '__le32' to fix it.
--- drivers/net/ethernet/faraday/ftmac100.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/net/ethernet/faraday/ftmac100.h +6 -6
@@ -122,9 +122,9 @@* Transmit descriptor, aligned to 16 bytes */ struct ftmac100_txdes { -unsigned int txdes0; -unsigned int txdes1; -unsigned int txdes2;/* TXBUF_BADR */ +__le32 txdes0; +__le32 txdes1; +__le32 txdes2;/* TXBUF_BADR */ unsigned int txdes3;/* not used by HW */ } __attribute__ ((aligned (16 )));
@@ -143,9 +143,9 @@ struct ftmac100_txdes {* Receive descriptor, aligned to 16 bytes */ struct ftmac100_rxdes { -unsigned int rxdes0; -unsigned int rxdes1; -unsigned int rxdes2;/* RXBUF_BADR */ +__le32 rxdes0; +__le32 rxdes1; +__le32 rxdes2;/* RXBUF_BADR */ unsigned int rxdes3;/* not used by HW */ } __attribute__ ((aligned (16 )));
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 700/862 iavf: Fix race between iavf_close and iavf_reset_task
In reply to Greg Kroah-HartmanFrom: Michal Jaron <[email protected]>
[ Upstream commit 11c12adcbc1598d91e73ab6ddfa41d25a01478ed ]
During stress tests with adding VF to namespace and changing vf's trust there was a race between iavf_reset_task and iavf_close. Sometimes when IAVF_FLAG_AQ_DISABLE_QUEUES from iavf_close was sent to PF after reset and before IAVF_AQ_GET_CONFIG was sent then PF returns error IAVF_NOT_SUPPORTED to disable queues request and following requests. There is need to get_config before other aq_required will be send but iavf_close clears all flags, if get_config was not sent before iavf_close, then it will not be send at all.
In case when IAVF_FLAG_AQ_GET_OFFLOAD_VLAN_V2_CAPS was sent before IAVF_FLAG_AQ_DISABLE_QUEUES then there was rtnl_lock deadlock between iavf_close and iavf_adminq_task until iavf_close timeouts and disable queues was sent after iavf_close ends.
There was also a problem with sending delete/add filters. Sometimes when filters was not yet added to PF and in iavf_close all filters was set to remove there might be a try to remove nonexistent filters on PF.
Add aq_required_tmp to save aq_required flags and send them after disable_queues will be handled. Clear flags given to iavf_down different than IAVF_FLAG_AQ_GET_CONFIG as this flag is necessary to sent other aq_required. Remove some flags that we don't want to send as we are in iavf_close and we want to disable interface. Remove filters which was not yet sent and send del filters flags only when there are filters to remove.
--- drivers/net/ethernet/intel/iavf/iavf_main.c | 177 ++++++++++++++++---- 1 file changed, 141 insertions(+), 36 deletions(-)
drivers/net/ethernet/intel/iavf/iavf_main.c +141 -36
@@ -1267,66 +1267,138 @@ static void iavf_up_complete(struct iavf_adapter *adapter) }/** -* iavf_down - Shutdown the connection processing +* iavf_clear_mac_vlan_filters - Remove mac and vlan filters not sent to PF +* yet and mark other to be removed. * @adapter: board private structure -* -* Expects to be called while holding the __IAVF_IN_CRITICAL_TASK bit lock. **/ -void iavf_down (struct iavf_adapter *adapter) +static void iavf_clear_mac_vlan_filters (struct iavf_adapter *adapter) { -struct net_device *netdev = adapter->netdev; -struct iavf_vlan_filter *vlf; -struct iavf_cloud_filter *cf; -struct iavf_fdir_fltr *fdir; -struct iavf_mac_filter *f; -struct iavf_adv_rss *rss; - -if (adapter->state <= __IAVF_DOWN_PENDING) -return ; - -netif_carrier_off (netdev); -netif_tx_disable (netdev); - adapter->link_up = false; -iavf_napi_disable_all (adapter); -iavf_irq_disable (adapter); +struct iavf_vlan_filter *vlf, *vlftmp; +struct iavf_mac_filter *f, *ftmp;spin_lock_bh (&adapter->mac_vlan_list_lock); -/* clear the sync flag on all filters */ __dev_uc_unsync (adapter->netdev,NULL );__dev_mc_unsync (adapter->netdev,NULL );/* remove all MAC filters */ -list_for_each_entry (f, &adapter->mac_filter_list, list) { - f->remove = true; +list_for_each_entry_safe (f, ftmp, &adapter->mac_filter_list, + list) { +if (f->add) { +list_del (&f->list); +kfree (f); + }else { + f->remove = true; + } }/* remove all VLAN filters */ -list_for_each_entry (vlf, &adapter->vlan_filter_list, list) { - vlf->remove = true; +list_for_each_entry_safe (vlf, vlftmp, &adapter->vlan_filter_list, + list) { +if (vlf->add) { +list_del (&vlf->list); +kfree (vlf); + }else { + vlf->remove = true; + } } -spin_unlock_bh (&adapter->mac_vlan_list_lock); +} + +/** +* iavf_clear_cloud_filters - Remove cloud filters not sent to PF yet and +* mark other to be removed. +* @adapter: board private structure +**/ +static void iavf_clear_cloud_filters (struct iavf_adapter *adapter) +{ +struct iavf_cloud_filter *cf, *cftmp;/* remove all cloud filters */ spin_lock_bh (&adapter->cloud_filter_list_lock); -list_for_each_entry (cf, &adapter->cloud_filter_list, list) { - cf->del = true; +list_for_each_entry_safe (cf, cftmp, &adapter->cloud_filter_list, + list) { +if (cf->add) { +list_del (&cf->list); +kfree (cf); + adapter->num_cloud_filters--; + }else { + cf->del = true; + } }spin_unlock_bh (&adapter->cloud_filter_list_lock); +} + +/** +* iavf_clear_fdir_filters - Remove fdir filters not sent to PF yet and mark +* other to be removed. +* @adapter: board private structure +**/ +static void iavf_clear_fdir_filters (struct iavf_adapter *adapter) +{ +struct iavf_fdir_fltr *fdir, *fdirtmp;/* remove all Flow Director filters */ spin_lock_bh (&adapter->fdir_fltr_lock); -list_for_each_entry (fdir, &adapter->fdir_list_head, list) { - fdir->state =IAVF_FDIR_FLTR_DEL_REQUEST ; +list_for_each_entry_safe (fdir, fdirtmp, &adapter->fdir_list_head, + list) { +if (fdir->state ==IAVF_FDIR_FLTR_ADD_REQUEST ) { +list_del (&fdir->list); +kfree (fdir); + adapter->fdir_active_fltr--; + }else { + fdir->state =IAVF_FDIR_FLTR_DEL_REQUEST ; + } }spin_unlock_bh (&adapter->fdir_fltr_lock); +} + +/** +* iavf_clear_adv_rss_conf - Remove adv rss conf not sent to PF yet and mark +* other to be removed. +* @adapter: board private structure +**/ +static void iavf_clear_adv_rss_conf (struct iavf_adapter *adapter) +{ +struct iavf_adv_rss *rss, *rsstmp;/* remove all advance RSS configuration */ spin_lock_bh (&adapter->adv_rss_lock); -list_for_each_entry (rss, &adapter->adv_rss_list_head, list) - rss->state =IAVF_ADV_RSS_DEL_REQUEST ; +list_for_each_entry_safe (rss, rsstmp, &adapter->adv_rss_list_head, + list) { +if (rss->state ==IAVF_ADV_RSS_ADD_REQUEST ) { +list_del (&rss->list); +kfree (rss); + }else { + rss->state =IAVF_ADV_RSS_DEL_REQUEST ; + } + }spin_unlock_bh (&adapter->adv_rss_lock); +} + +/** +* iavf_down - Shutdown the connection processing +* @adapter: board private structure +* +* Expects to be called while holding the __IAVF_IN_CRITICAL_TASK bit lock. +**/ +void iavf_down (struct iavf_adapter *adapter) +{ +struct net_device *netdev = adapter->netdev; + +if (adapter->state <= __IAVF_DOWN_PENDING) +return ; + +netif_carrier_off (netdev); +netif_tx_disable (netdev); + adapter->link_up = false; +iavf_napi_disable_all (adapter); +iavf_irq_disable (adapter); + +iavf_clear_mac_vlan_filters (adapter); +iavf_clear_cloud_filters (adapter); +iavf_clear_fdir_filters (adapter); +iavf_clear_adv_rss_conf (adapter);if (!(adapter->flags &IAVF_FLAG_PF_COMMS_FAILED )) {/* cancel any current operation */
@@ -1335,11 +1407,16 @@ void iavf_down(struct iavf_adapter *adapter)* here for this to complete. The watchdog is still running * and it will take care of this. */ - adapter->aq_required =IAVF_FLAG_AQ_DEL_MAC_FILTER ; - adapter->aq_required |=IAVF_FLAG_AQ_DEL_VLAN_FILTER ; - adapter->aq_required |=IAVF_FLAG_AQ_DEL_CLOUD_FILTER ; - adapter->aq_required |=IAVF_FLAG_AQ_DEL_FDIR_FILTER ; - adapter->aq_required |=IAVF_FLAG_AQ_DEL_ADV_RSS_CFG ; +if (!list_empty (&adapter->mac_filter_list)) + adapter->aq_required |=IAVF_FLAG_AQ_DEL_MAC_FILTER ; +if (!list_empty (&adapter->vlan_filter_list)) + adapter->aq_required |=IAVF_FLAG_AQ_DEL_VLAN_FILTER ; +if (!list_empty (&adapter->cloud_filter_list)) + adapter->aq_required |=IAVF_FLAG_AQ_DEL_CLOUD_FILTER ; +if (!list_empty (&adapter->fdir_list_head)) + adapter->aq_required |=IAVF_FLAG_AQ_DEL_FDIR_FILTER ; +if (!list_empty (&adapter->adv_rss_list_head)) + adapter->aq_required |=IAVF_FLAG_AQ_DEL_ADV_RSS_CFG ; adapter->aq_required |=IAVF_FLAG_AQ_DISABLE_QUEUES ; }
@@ -4178,6 +4255,7 @@ static int iavf_open(struct net_device *netdev)static int iavf_close (struct net_device *netdev) {struct iavf_adapter *adapter =netdev_priv (netdev); +u64 aq_to_restore;int status;mutex_lock (&adapter->crit_lock);
@@ -4190,6 +4268,29 @@ static int iavf_close(struct net_device *netdev)set_bit (__IAVF_VSI_DOWN, adapter->vsi.state);if (CLIENT_ENABLED (adapter)) adapter->flags |=IAVF_FLAG_CLIENT_NEEDS_CLOSE ; +/* We cannot send IAVF_FLAG_AQ_GET_OFFLOAD_VLAN_V2_CAPS before +* IAVF_FLAG_AQ_DISABLE_QUEUES because in such case there is rtnl +* deadlock with adminq_task() until iavf_close timeouts. We must send +* IAVF_FLAG_AQ_GET_CONFIG before IAVF_FLAG_AQ_DISABLE_QUEUES to make +* disable queues possible for vf. Give only necessary flags to +* iavf_down and save other to set them right before iavf_close() +* returns, when IAVF_FLAG_AQ_DISABLE_QUEUES will be already sent and +* iavf will be in DOWN state. +*/ + aq_to_restore = adapter->aq_required; + adapter->aq_required &=IAVF_FLAG_AQ_GET_CONFIG ; + +/* Remove flags which we do not want to send after close or we want to +* send before disable queues. +*/ + aq_to_restore &= ~(IAVF_FLAG_AQ_GET_CONFIG | +IAVF_FLAG_AQ_ENABLE_QUEUES | +IAVF_FLAG_AQ_CONFIGURE_QUEUES | +IAVF_FLAG_AQ_ADD_VLAN_FILTER | +IAVF_FLAG_AQ_ADD_MAC_FILTER | +IAVF_FLAG_AQ_ADD_CLOUD_FILTER | +IAVF_FLAG_AQ_ADD_FDIR_FILTER | +IAVF_FLAG_AQ_ADD_ADV_RSS_CFG );iavf_down (adapter);iavf_change_state (adapter, __IAVF_DOWN_PENDING);
@@ -4213,6 +4314,10 @@ static int iavf_close(struct net_device *netdev) msecs_to_jiffies(500));if (!status)netdev_warn (netdev,"Device resources not yet released\n" ); + +mutex_lock (&adapter->crit_lock); + adapter->aq_required |= aq_to_restore; +mutex_unlock (&adapter->crit_lock);return 0 ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 701/862 wifi: brcmfmac: fix use-after-free bug in brcmf_netdev_start_xmit()
In reply to Greg Kroah-HartmanFrom: Alexander Coffin <[email protected]>
[ Upstream commit 3f42faf6db431e04bf942d2ebe3ae88975723478 ]
Quoted 1 line
ret =
brcmf_proto_tx_queue_data(drvr, ifp->ifidx, skb);
may be schedule, and then complete before the line
Quoted 1 line
ndev->stats.tx_bytes+=skb->len;
[ 46.912801] ================================================================== [ 46.920552] BUG: KASAN: use-after-free in brcmf_netdev_start_xmit+0x718/0x8c8 [brcmfmac] [ 46.928673] Read of size 4 at addr ffffff803f5882e8 by task systemd-resolve/328 [ 46.935991] [ 46.937514] CPU: 1 PID: 328 Comm: systemd-resolve Tainted: G O 5.4.199-[REDACTED] #1 [ 46.947255] Hardware name: [REDACTED] [ 46.954568] Call trace: [ 46.957037] dump_backtrace+0x0/0x2b8 [ 46.960719] show_stack+0x24/0x30 [ 46.964052] dump_stack+0x128/0x194 [ 46.967557] print_address_description.isra.0+0x64/0x380 [ 46.972877] __kasan_report+0x1d4/0x240 [ 46.976723] kasan_report+0xc/0x18 [ 46.980138] __asan_report_load4_noabort+0x18/0x20 [ 46.985027] brcmf_netdev_start_xmit+0x718/0x8c8 [brcmfmac] [ 46.990613] dev_hard_start_xmit+0x1bc/0xda0 [ 46.994894] sch_direct_xmit+0x198/0xd08 [ 46.998827] __qdisc_run+0x37c/0x1dc0 [ 47.002500] __dev_queue_xmit+0x1528/0x21f8 [ 47.006692] dev_queue_xmit+0x24/0x30 [ 47.010366] neigh_resolve_output+0x37c/0x678 [ 47.014734] ip_finish_output2+0x598/0x2458 [ 47.018927] __ip_finish_output+0x300/0x730 [ 47.023118] ip_output+0x2e0/0x430 [ 47.026530] ip_local_out+0x90/0x140 [ 47.030117] igmpv3_sendpack+0x14c/0x228 [ 47.034049] igmpv3_send_cr+0x384/0x6b8 [ 47.037895] igmp_ifc_timer_expire+0x4c/0x118 [ 47.042262] call_timer_fn+0x1cc/0xbe8 [ 47.046021] __run_timers+0x4d8/0xb28 [ 47.049693] run_timer_softirq+0x24/0x40 [ 47.053626] __do_softirq+0x2c0/0x117c [ 47.057387] irq_exit+0x2dc/0x388 [ 47.060715] __handle_domain_irq+0xb4/0x158 [ 47.064908] gic_handle_irq+0x58/0xb0 [ 47.068581] el0_irq_naked+0x50/0x5c [ 47.072162] [ 47.073665] Allocated by task 328: [ 47.077083] save_stack+0x24/0xb0 [ 47.080410] __kasan_kmalloc.isra.0+0xc0/0xe0 [ 47.084776] kasan_slab_alloc+0x14/0x20 [ 47.088622] kmem_cache_alloc+0x15c/0x468 [ 47.092643] __alloc_skb+0xa4/0x498 [ 47.096142] igmpv3_newpack+0x158/0xd78 [ 47.099987] add_grhead+0x210/0x288 [ 47.103485] add_grec+0x6b0/0xb70 [ 47.106811] igmpv3_send_cr+0x2e0/0x6b8 [ 47.110657] igmp_ifc_timer_expire+0x4c/0x118 [ 47.115027] call_timer_fn+0x1cc/0xbe8 [ 47.118785] __run_timers+0x4d8/0xb28 [ 47.122457] run_timer_softirq+0x24/0x40 [ 47.126389] __do_softirq+0x2c0/0x117c [ 47.130142] [ 47.131643] Freed by task 180: [ 47.134712] save_stack+0x24/0xb0 [ 47.138041] __kasan_slab_free+0x108/0x180 [ 47.142146] kasan_slab_free+0x10/0x18 [ 47.145904] slab_free_freelist_hook+0xa4/0x1b0 [ 47.150444] kmem_cache_free+0x8c/0x528 [ 47.154292] kfree_skbmem+0x94/0x108 [ 47.157880] consume_skb+0x10c/0x5a8 [ 47.161466] __dev_kfree_skb_any+0x88/0xa0 [ 47.165598] brcmu_pkt_buf_free_skb+0x44/0x68 [brcmutil] [ 47.171023] brcmf_txfinalize+0xec/0x190 [brcmfmac] [ 47.176016] brcmf_proto_bcdc_txcomplete+0x1c0/0x210 [brcmfmac] [ 47.182056] brcmf_sdio_sendfromq+0x8dc/0x1e80 [brcmfmac] [ 47.187568] brcmf_sdio_dpc+0xb48/0x2108 [brcmfmac] [ 47.192529] brcmf_sdio_dataworker+0xc8/0x238 [brcmfmac] [ 47.197859] process_one_work+0x7fc/0x1a80 [ 47.201965] worker_thread+0x31c/0xc40 [ 47.205726] kthread+0x2d8/0x370 [ 47.208967] ret_from_fork+0x10/0x18 [ 47.212546] [ 47.214051] The buggy address belongs to the object at ffffff803f588280 [ 47.214051] which belongs to the cache skbuff_head_cache of size 208 [ 47.227086] The buggy address is located 104 bytes inside of [ 47.227086] 208-byte region [ffffff803f588280, ffffff803f588350) [ 47.238814] The buggy address belongs to the page: [ 47.243618] page:ffffffff00dd6200 refcount:1 mapcount:0 mapping:ffffff804b6bf800 index:0xffffff803f589900 compound_mapcount: 0 [ 47.255007] flags: 0x10200(slab|head) [ 47.258689] raw: 0000000000010200 ffffffff00dfa980 0000000200000002 ffffff804b6bf800 [ 47.266439] raw: ffffff803f589900 0000000080190018 00000001ffffffff 0000000000000000 [ 47.274180] page dumped because: kasan: bad access detected [ 47.279752] [ 47.281251] Memory state around the buggy address: [ 47.286051] ffffff803f588180: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ 47.293277] ffffff803f588200: fb fb fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ 47.300502] >ffffff803f588280: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ 47.307723] ^ [ 47.314343] ffffff803f588300: fb fb fb fb fb fb fb fb fb fb fc fc fc fc fc fc [ 47.321569] ffffff803f588380: fc fc fc fc fc fc fc fc fb fb fb fb fb fb fb fb [ 47.328789] ==================================================================
--- drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +2 -1
@@ -292,6 +292,7 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb,struct brcmf_pub *drvr = ifp->drvr;struct ethhdr *eh;int head_delta; +unsigned int tx_bytes = skb->len;brcmf_dbg (DATA ,"Enter, bsscfgidx=%d\n" , ifp->bsscfgidx);
@@ -366,7 +367,7 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb, ndev->stats.tx_dropped++; }else { ndev->stats.tx_packets++; - ndev->stats.tx_bytes += skb->len; + ndev->stats.tx_bytes += tx_bytes; }/* Return ok: we always eat the packet */
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 702/862 Bluetooth: btintel: Mark Intel controller to support LE_STATES quirk
In reply to Greg Kroah-HartmanFrom: Kiran K <[email protected]>
[ Upstream commit dd0a1794f4334ddbf9b7c5e7d642aaffff38c69b ]
HarrrisonPeak, CyclonePeak, SnowFieldPeak and SandyPeak controllers are marked to support HCI_QUIRK_LE_STATES.
--- drivers/bluetooth/btintel.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-)
drivers/bluetooth/btintel.c +8 -9
@@ -2439,15 +2439,20 @@ static int btintel_setup_combined(struct hci_dev *hdev) INTEL_ROM_LEGACY_NO_WBS_SUPPORT)) set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks); +if (ver.hw_variant ==0x08 && ver.fw_variant ==0x22 ) +set_bit (HCI_QUIRK_VALID_LE_STATES , + &hdev->quirks); err =btintel_legacy_rom_setup (hdev, &ver);break ;case 0x0b :/* SfP */ -case 0x0c :/* WsP */ case 0x11 :/* JfP */ case 0x12 :/* ThP */ case 0x13 :/* HrP */ case 0x14 :/* CcP */ +set_bit (HCI_QUIRK_VALID_LE_STATES , &hdev->quirks); + fallthrough; +case 0x0c :/* WsP */ /* Apply the device specific HCI quirks * * All Legacy bootloader devices support WBS
@@ -2455,11 +2460,6 @@ static int btintel_setup_combined(struct hci_dev *hdev)set_bit (HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED , &hdev->quirks); -/* Valid LE States quirk for JfP/ThP familiy */ -if (ver.hw_variant ==0x11 || ver.hw_variant ==0x12 ) -set_bit (HCI_QUIRK_VALID_LE_STATES , - &hdev->quirks); -/* Setup MSFT Extension support */ btintel_set_msft_opcode (hdev, ver.hw_variant);
@@ -2530,9 +2530,8 @@ static int btintel_setup_combined(struct hci_dev *hdev)*/ set_bit (HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED , &hdev->quirks); -/* Valid LE States quirk for JfP/ThP familiy */ -if (ver.hw_variant ==0x11 || ver.hw_variant ==0x12 ) -set_bit (HCI_QUIRK_VALID_LE_STATES , &hdev->quirks); +/* Set Valid LE States quirk */ +set_bit (HCI_QUIRK_VALID_LE_STATES , &hdev->quirks);/* Setup MSFT Extension support */ btintel_set_msft_opcode (hdev, ver.hw_variant);
Signature · 1 line
2.35.1