5.15.75-rc1 review
Subsystems (9)
Greg Kroah-Hartman
maintainerPATCH 146/530 nfsd: Fix a memory leak in an error handling path
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit fd1ef88049de09bc70d60b549992524cfc0e66ff ]
If this memdup_user() call fails, the memory allocated in a previous call a few lines above should be freed. Otherwise it leaks.
--- fs/nfsd/nfs4recover.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
fs/nfsd/nfs4recover.c +3 -1
@@ -815,8 +815,10 @@ __cld_pipe_inprogress_downcall(const struct cld_msg_v2 __user *cmsg, princhash.data =memdup_user ( &ci->cc_princhash.cp_data, princhashlen); -if (IS_ERR_OR_NULL (princhash.data)) +if (IS_ERR_OR_NULL (princhash.data)) { +kfree (name.data);return -EFAULT ; + } princhash.len = princhashlen; }else princhash.len =0 ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 147/530 SUNRPC: Fix svcxdr_init_decodes end-of-buffer calculation
In reply to Greg Kroah-HartmanFrom: Chuck Lever <[email protected]>
[ Upstream commit 90bfc37b5ab91c1a6165e3e5cfc49bf04571b762 ]
Ensure that stream-based argument decoding can't go past the actual end of the receive buffer. xdr_init_decode's calculation of the value of xdr->end over-estimates the end of the buffer because the Linux kernel RPC server code does not remove the size of the RPC header from rqstp->rq_arg before calling the upper layer's dispatcher.
The server-side still uses the svc_getnl() macros to decode the RPC call header. These macros reduce the length of the head iov but do not update the total length of the message in the buffer (buf->len).
A proper fix for this would be to replace the use of svc_getnl() and friends in the RPC header decoder, but that would be a large and invasive change that would be difficult to backport.
--- include/linux/sunrpc/svc.h | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-)
include/linux/sunrpc/svc.h +14 -3
@@ -566,16 +566,27 @@ static inline void svc_reserve_auth(struct svc_rqst *rqstp, int space) }/** -* svcxdr_init_decode - Prepare an xdr_stream for svc Call decoding +* svcxdr_init_decode - Prepare an xdr_stream for Call decoding * @rqstp: controlling server RPC transaction context * +* This function currently assumes the RPC header in rq_arg has +* already been decoded. Upon return, xdr->p points to the +* location of the upper layer header. */ static inline void svcxdr_init_decode (struct svc_rqst *rqstp) {struct xdr_stream *xdr = &rqstp->rq_arg_stream; -struct kvec *argv = rqstp->rq_arg.head; +struct xdr_buf *buf = &rqstp->rq_arg; +struct kvec *argv = buf->head; -xdr_init_decode (xdr, &rqstp->rq_arg, argv->iov_base,NULL ); +/* +* svc_getnl() and friends do not keep the xdr_buf's ::len +* field up to date. Refresh that field before initializing +* the argument decoding stream. +*/ + buf->len = buf->head->iov_len + buf->page_len + buf->tail->iov_len; + +xdr_init_decode (xdr, buf, argv->iov_base,NULL );xdr_set_scratch_page (xdr, rqstp->rq_scratch_page); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 148/530 SUNRPC: Fix svcxdr_init_encodes buflen calculation
In reply to Greg Kroah-HartmanFrom: Chuck Lever <[email protected]>
[ Upstream commit 1242a87da0d8cd2a428e96ca68e7ea899b0f4624 ]
Commit 2825a7f90753 ("nfsd4: allow encoding across page boundaries") added an explicit computation of the remaining length in the rq_res XDR buffer.
The computation appears to suffer from an "off-by-one" bug. Because buflen is too large by one page, XDR encoding can run off the end of the send buffer by eventually trying to use the struct page address in rq_page_end, which always contains NULL.
--- include/linux/sunrpc/svc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/sunrpc/svc.h +1 -1
@@ -609,7 +609,7 @@ static inline void svcxdr_init_encode(struct svc_rqst *rqstp) xdr->end = resv->iov_base +PAGE_SIZE - rqstp->rq_auth_slack; buf->len = resv->iov_len; xdr->page_ptr = buf->pages -1 ; - buf->buflen =PAGE_SIZE * (1 + rqstp->rq_page_end - buf->pages); + buf->buflen =PAGE_SIZE * (rqstp->rq_page_end - buf->pages); buf->buflen -= rqstp->rq_auth_slack; xdr->rqst =NULL ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 149/530 NFSD: Protect against send buffer overflow in NFSv2 READDIR
In reply to Greg Kroah-HartmanFrom: Chuck Lever <[email protected]>
[ Upstream commit 00b4492686e0497fdb924a9d4c8f6f99377e176c ]
Restore the previous limit on the @count argument to prevent a buffer overflow attack.
--- fs/nfsd/nfsproc.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
fs/nfsd/nfsproc.c +2 -3
@@ -557,12 +557,11 @@ static void nfsd_init_dirlist_pages(struct svc_rqst *rqstp,struct xdr_buf *buf = &resp->dirlist;struct xdr_stream *xdr = &resp->xdr; - count =clamp (count, (u32)(XDR_UNIT *2 ),svc_max_payload (rqstp)); -memset (buf,0 ,sizeof (*buf));/* Reserve room for the NULL ptr & eof flag (-2 words) */ - buf->buflen = count -XDR_UNIT *2 ; + buf->buflen =clamp (count, (u32)(XDR_UNIT *2 ), (u32 )PAGE_SIZE ); + buf->buflen -=XDR_UNIT *2 ; buf->pages = rqstp->rq_next_page; rqstp->rq_next_page++;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 150/530 NFSD: Fix handling of oversized NFSv4 COMPOUND requests
In reply to Greg Kroah-HartmanFrom: Chuck Lever <[email protected]>
[ Upstream commit 7518a3dc5ea249d4112156ce71b8b184eb786151 ]
If an NFS server returns NFS4ERR_RESOURCE on the first operation in an NFSv4 COMPOUND, there's no way for a client to know where the problem is and then simplify the compound to make forward progress.
So instead, make NFSD process as many operations in an oversized COMPOUND as it can and then return NFS4ERR_RESOURCE on the first operation it did not process.
pynfs NFSv4.0 COMP6 exercises this case, but checks only for the COMPOUND status code, not whether the server has processed any of the operations.
pynfs NFSv4.1 SEQ6 and SEQ7 exercise the NFSv4.1 case, which detects too many operations per COMPOUND by checking against the limits negotiated when the session was created.
--- fs/nfsd/nfs4proc.c | 19 +++++++++++++------ fs/nfsd/nfs4xdr.c | 11 +++-------- fs/nfsd/xdr4.h | 3 ++- 3 files changed, 18 insertions(+), 15 deletions(-)
fs/nfsd/nfs4proc.c +13 -6
@@ -2493,9 +2493,6 @@ nfsd4_proc_compound(struct svc_rqst *rqs status = nfserr_minor_vers_mismatch;if (nfsd_minorversion (nn, args->minorversion,NFSD_TEST ) <=0 ) goto out; - status = nfserr_resource; -if (args->opcnt >NFSD_MAX_OPS_PER_COMPOUND ) - goto out; status =nfs41_check_op_ordering (args);if (status) {
@@ -2508,10 +2505,20 @@ nfsd4_proc_compound(struct svc_rqst *rqs rqstp->rq_lease_breaker = (void **)&cstate->clp; -trace_nfsd_compound (rqstp, args->opcnt); +trace_nfsd_compound (rqstp, args->client_opcnt);while (!status && resp->opcnt < args->opcnt) { op = &args->ops[resp->opcnt++]; +if (unlikely (resp->opcnt ==NFSD_MAX_OPS_PER_COMPOUND )) { +/* If there are still more operations to process, +* stop here and report NFS4ERR_RESOURCE. */ +if (cstate->minorversion ==0 && + args->client_opcnt > resp->opcnt) { + op->status = nfserr_resource; + goto encode_op; + } + } +/* * The XDR decode routines may have pre-set op->status; * for example, if there is a miscellaneous XDR error
@@ -2587,8 +2594,8 @@ encode_op: status = op->status; } -trace_nfsd_compound_status (args->opcnt, resp->opcnt, status, -nfsd4_op_name (op->opnum)); +trace_nfsd_compound_status (args->client_opcnt, resp->opcnt, + status,nfsd4_op_name (op->opnum));nfsd4_cstate_clear_replay (cstate);nfsd4_increment_op_stats (op->opnum);
fs/nfsd/nfs4xdr.c +3 -8
@@ -2349,16 +2349,11 @@ nfsd4_decode_compound(struct nfsd4_compoif (xdr_stream_decode_u32 (argp->xdr, &argp->minorversion) <0 )return 0 ; -if (xdr_stream_decode_u32 (argp->xdr, &argp->opcnt) <0 ) +if (xdr_stream_decode_u32 (argp->xdr, &argp->client_opcnt) <0 )return 0 ; -/* -* NFS4ERR_RESOURCE is a more helpful error than GARBAGE_ARGS -* here, so we return success at the xdr level so that -* nfsd4_proc can handle this is an NFS-level error. -*/ -if (argp->opcnt >NFSD_MAX_OPS_PER_COMPOUND ) -return 1 ; + argp->opcnt =min_t (u32, argp->client_opcnt, +NFSD_MAX_OPS_PER_COMPOUND );if (argp->opcnt >ARRAY_SIZE (argp->iops)) { argp->ops =kzalloc (argp->opcnt *sizeof (*argp->ops),GFP_KERNEL );
fs/nfsd/xdr4.h +2 -1
@@ -688,9 +688,10 @@ struct nfsd4_compoundargs {struct svcxdr_tmpbuf *to_free;struct svc_rqst *rqstp; -u32 taglen;char * tag; +u32 taglen;u32 minorversion; +u32 client_opcnt;u32 opcnt;struct nfsd4_op *ops;struct nfsd4_op iops[8 ];
Greg Kroah-Hartman
maintainerPATCH 151/530 wifi: rtlwifi: 8192de: correct checking of IQK reload
In reply to Greg Kroah-HartmanFrom: Ping-Ke Shih <[email protected]>
[ Upstream commit 93fbc1ebd978cf408ef5765e9c1630fce9a8621b ]
Since IQK could spend time, we make a cache of IQK result matrix that looks like iqk_matrix[channel_idx].val[x][y], and we can reload the matrix if we have made a cache. To determine a cache is made, we check iqk_matrix[channel_idx].val[0][0].
The initial commit 7274a8c22980 ("rtlwifi: rtl8192de: Merge phy routines") make a mistake that checks incorrect iqk_matrix[channel_idx].val[0] that is always true, and this mistake is found by commit ee3db469dd31 ("wifi: rtlwifi: remove always-true condition pointed out by GCC 12"), so I recall the vendor driver to find fix and apply the correctness.
--- drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-)
drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c +4 -5
@@ -2386,11 +2386,10 @@ void rtl92d_phy_reload_iqk_setting(struct ieee80211_hw *hw, u8 channel)rtl_dbg (rtlpriv,COMP_SCAN ,DBG_LOUD ,"Just Read IQK Matrix reg for channel:%d....\n" , channel); -_rtl92d_phy_patha_fill_iqk_matrix (hw, true, - rtlphy->iqk_matrix[ - indexforchannel].value,0 , - (rtlphy->iqk_matrix[ - indexforchannel].value[0 ][2 ] ==0 )); +if (rtlphy->iqk_matrix[indexforchannel].value[0 ][0 ] !=0 ) +_rtl92d_phy_patha_fill_iqk_matrix (hw, true, + rtlphy->iqk_matrix[indexforchannel].value,0 , + rtlphy->iqk_matrix[indexforchannel].value[0 ][2 ] ==0 );if (IS_92D_SINGLEPHY (rtlhal->version)) {if ((rtlphy->iqk_matrix[ indexforchannel].value[0][4] != 0)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 152/530 wifi: ath10k: add peer map clean up for peer delete in ath10k_sta_state()
In reply to Greg Kroah-HartmanFrom: Wen Gong <[email protected]>
[ Upstream commit f020d9570a04df0762a2ac5c50cf1d8c511c9164 ]
When peer delete failed in a disconnect operation, use-after-free detected by KFENCE in below log. It is because for each vdev_id and address, it has only one struct ath10k_peer, it is allocated in ath10k_peer_map_event(). When connected to an AP, it has more than one HTT_T2H_MSG_TYPE_PEER_MAP reported from firmware, then the array peer_map of struct ath10k will be set muti-elements to the same ath10k_peer in ath10k_peer_map_event(). When peer delete failed in ath10k_sta_state(), the ath10k_peer will be free for the 1st peer id in array peer_map of struct ath10k, and then use-after-free happened for the 2nd peer id because they map to the same ath10k_peer.
And clean up all peers in array peer_map for the ath10k_peer, then user-after-free disappeared
peer map event log:
[ 306.911021] wlan0: authenticate with b0:2a:43:e6:75:0e [ 306.957187] ath10k_pci 0000:01:00.0: mac vdev 0 peer create b0:2a:43:e6:75:0e (new sta) sta 1 / 32 peer 1 / 33 [ 306.957395] ath10k_pci 0000:01:00.0: htt peer map vdev 0 peer b0:2a:43:e6:75:0e id 246 [ 306.957404] ath10k_pci 0000:01:00.0: htt peer map vdev 0 peer b0:2a:43:e6:75:0e id 198 [ 306.986924] ath10k_pci 0000:01:00.0: htt peer map vdev 0 peer b0:2a:43:e6:75:0e id 166
peer unmap event log:
[ 435.715691] wlan0: deauthenticating from b0:2a:43:e6:75:0e by local choice (Reason: 3=DEAUTH_LEAVING) [ 435.716802] ath10k_pci 0000:01:00.0: mac vdev 0 peer delete b0:2a:43:e6:75:0e sta ffff990e0e9c2b50 (sta gone) [ 435.717177] ath10k_pci 0000:01:00.0: htt peer unmap vdev 0 peer b0:2a:43:e6:75:0e id 246 [ 435.717186] ath10k_pci 0000:01:00.0: htt peer unmap vdev 0 peer b0:2a:43:e6:75:0e id 198 [ 435.717193] ath10k_pci 0000:01:00.0: htt peer unmap vdev 0 peer b0:2a:43:e6:75:0e id 166
use-after-free log:
[21705.888627] wlan0: deauthenticating from d0:76:8f:82:be:75 by local choice (Reason: 3=DEAUTH_LEAVING) [21713.799910] ath10k_pci 0000:01:00.0: failed to delete peer d0:76:8f:82:be:75 for vdev 0: -110 [21713.799925] ath10k_pci 0000:01:00.0: found sta peer d0:76:8f:82:be:75 (ptr 0000000000000000 id 102) entry on vdev 0 after it was supposedly removed [21713.799968] ================================================================== [21713.799991] BUG: KFENCE: use-after-free read in ath10k_sta_state+0x265/0xb8a [ath10k_core] [21713.799991] [21713.799997] Use-after-free read at 0x00000000abe1c75e (in kfence-#69): [21713.800010] ath10k_sta_state+0x265/0xb8a [ath10k_core] [21713.800041] drv_sta_state+0x115/0x677 [mac80211] [21713.800059] __sta_info_destroy_part2+0xb1/0x133 [mac80211] [21713.800076] __sta_info_flush+0x11d/0x162 [mac80211] [21713.800093] ieee80211_set_disassoc+0x12d/0x2f4 [mac80211] [21713.800110] ieee80211_mgd_deauth+0x26c/0x29b [mac80211] [21713.800137] cfg80211_mlme_deauth+0x13f/0x1bb [cfg80211] [21713.800153] nl80211_deauthenticate+0xf8/0x121 [cfg80211] [21713.800161] genl_rcv_msg+0x38e/0x3be [21713.800166] netlink_rcv_skb+0x89/0xf7 [21713.800171] genl_rcv+0x28/0x36 [21713.800176] netlink_unicast+0x179/0x24b [21713.800181] netlink_sendmsg+0x3a0/0x40e [21713.800187] sock_sendmsg+0x72/0x76 [21713.800192] ____sys_sendmsg+0x16d/0x1e3 [21713.800196] ___sys_sendmsg+0x95/0xd1 [21713.800200] __sys_sendmsg+0x85/0xbf [21713.800205] do_syscall_64+0x43/0x55 [21713.800210] entry_SYSCALL_64_after_hwframe+0x44/0xa9 [21713.800213] [21713.800219] kfence-#69: 0x000000009149b0d5-0x000000004c0697fb, size=1064, cache=kmalloc-2k [21713.800219] [21713.800224] allocated by task 13 on cpu 0 at 21705.501373s: [21713.800241] ath10k_peer_map_event+0x7e/0x154 [ath10k_core] [21713.800254] ath10k_htt_t2h_msg_handler+0x586/0x1039 [ath10k_core] [21713.800265] ath10k_htt_htc_t2h_msg_handler+0x12/0x28 [ath10k_core] [21713.800277] ath10k_htc_rx_completion_handler+0x14c/0x1b5 [ath10k_core] [21713.800283] ath10k_pci_process_rx_cb+0x195/0x1df [ath10k_pci] [21713.800294] ath10k_ce_per_engine_service+0x55/0x74 [ath10k_core] [21713.800305] ath10k_ce_per_engine_service_any+0x76/0x84 [ath10k_core] [21713.800310] ath10k_pci_napi_poll+0x49/0x144 [ath10k_pci] [21713.800316] net_rx_action+0xdc/0x361 [21713.800320] __do_softirq+0x163/0x29a [21713.800325] asm_call_irq_on_stack+0x12/0x20 [21713.800331] do_softirq_own_stack+0x3c/0x48 [21713.800337] __irq_exit_rcu+0x9b/0x9d [21713.800342] common_interrupt+0xc9/0x14d [21713.800346] asm_common_interrupt+0x1e/0x40 [21713.800351] ksoftirqd_should_run+0x5/0x16 [21713.800357] smpboot_thread_fn+0x148/0x211 [21713.800362] kthread+0x150/0x15f [21713.800367] ret_from_fork+0x22/0x30 [21713.800370] [21713.800374] freed by task 708 on cpu 1 at 21713.799953s: [21713.800498] ath10k_sta_state+0x2c6/0xb8a [ath10k_core] [21713.800515] drv_sta_state+0x115/0x677 [mac80211] [21713.800532] __sta_info_destroy_part2+0xb1/0x133 [mac80211] [21713.800548] __sta_info_flush+0x11d/0x162 [mac80211] [21713.800565] ieee80211_set_disassoc+0x12d/0x2f4 [mac80211] [21713.800581] ieee80211_mgd_deauth+0x26c/0x29b [mac80211] [21713.800598] cfg80211_mlme_deauth+0x13f/0x1bb [cfg80211] [21713.800614] nl80211_deauthenticate+0xf8/0x121 [cfg80211] [21713.800619] genl_rcv_msg+0x38e/0x3be [21713.800623] netlink_rcv_skb+0x89/0xf7 [21713.800628] genl_rcv+0x28/0x36 [21713.800632] netlink_unicast+0x179/0x24b [21713.800637] netlink_sendmsg+0x3a0/0x40e [21713.800642] sock_sendmsg+0x72/0x76 [21713.800646] ____sys_sendmsg+0x16d/0x1e3 [21713.800651] ___sys_sendmsg+0x95/0xd1 [21713.800655] __sys_sendmsg+0x85/0xbf [21713.800659] do_syscall_64+0x43/0x55 [21713.800663] entry_SYSCALL_64_after_hwframe+0x44/0xa9
Tested-on: QCA6174 hw3.2 PCI WLAN.RM.4.4.1-00288-QCARMSWPZ-1
--- drivers/net/wireless/ath/ath10k/mac.c | 54 ++++++++++++++------------- 1 file changed, 29 insertions(+), 25 deletions(-)
drivers/net/wireless/ath/ath10k/mac.c +29 -25
@@ -864,11 +864,36 @@ static int ath10k_peer_delete(struct ath10k *ar, u32 vdev_id, const u8 *addr)return 0 ; } +static void ath10k_peer_map_cleanup (struct ath10k *ar,struct ath10k_peer *peer) +{ +int peer_id, i; + +lockdep_assert_held (&ar->conf_mutex); + +for_each_set_bit (peer_id, peer->peer_ids, +ATH10K_MAX_NUM_PEER_IDS ) { + ar->peer_map[peer_id] =NULL ; + } + +/* Double check that peer is properly un-referenced from +* the peer_map +*/ +for (i =0 ; i <ARRAY_SIZE (ar->peer_map); i++) { +if (ar->peer_map[i] == peer) { +ath10k_warn (ar,"removing stale peer_map entry for %pM (ptr %pK idx %d)\n" , + peer->addr, peer, i); + ar->peer_map[i] =NULL ; + } + } + +list_del (&peer->list); +kfree (peer); + ar->num_peers--; +} +static void ath10k_peer_cleanup (struct ath10k *ar,u32 vdev_id) {struct ath10k_peer *peer, *tmp; -int peer_id; -int i;lockdep_assert_held (&ar->conf_mutex);
@@ -880,25 +905,7 @@ static void ath10k_peer_cleanup(struct ath10k *ar, u32 vdev_id)ath10k_warn (ar,"removing stale peer %pM from vdev_id %d\n" , peer->addr, vdev_id); -for_each_set_bit (peer_id, peer->peer_ids, -ATH10K_MAX_NUM_PEER_IDS ) { - ar->peer_map[peer_id] =NULL ; - } - -/* Double check that peer is properly un-referenced from -* the peer_map -*/ -for (i =0 ; i <ARRAY_SIZE (ar->peer_map); i++) { -if (ar->peer_map[i] == peer) { -ath10k_warn (ar,"removing stale peer_map entry for %pM (ptr %pK idx %d)\n" , - peer->addr, peer, i); - ar->peer_map[i] =NULL ; - } - } - -list_del (&peer->list); -kfree (peer); - ar->num_peers--; +ath10k_peer_map_cleanup (ar, peer); }spin_unlock_bh (&ar->data_lock); }
@@ -7580,10 +7587,7 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,/* Clean up the peer object as well since we * must have failed to do this above. */ -list_del (&peer->list); - ar->peer_map[i] =NULL ; -kfree (peer); - ar->num_peers--; +ath10k_peer_map_cleanup (ar, peer); } }spin_unlock_bh (&ar->data_lock);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 153/530 leds: lm3601x: Dont use mutex after it was destroyed
In reply to Greg Kroah-HartmanFrom: Uwe Kleine-König <[email protected]>
[ Upstream commit 32f7eed0c763a9b89f6b357ec54b48398fc7b99e ]
The mutex might still be in use until the devm cleanup callback devm_led_classdev_flash_release() is called. This only happens some time after lm3601x_remove() completed.
--- drivers/leds/flash/leds-lm3601x.c | 2 -- 1 file changed, 2 deletions(-)
drivers/leds/flash/leds-lm3601x.c +0 -2
@@ -444,8 +444,6 @@ static int lm3601x_remove(struct i2c_client *client) {struct lm3601x_led *led =i2c_get_clientdata (client); -mutex_destroy (&led->lock); -return regmap_update_bits (led->regmap,LM3601X_ENABLE_REG ,LM3601X_ENABLE_MASK ,LM3601X_MODE_STANDBY );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 154/530 bpf: Fix reference state management for synchronous callbacks
In reply to Greg Kroah-HartmanFrom: Kumar Kartikeya Dwivedi <[email protected]>
[ Upstream commit 9d9d00ac29d0ef7ce426964de46fa6b380357d0a ]
Currently, verifier verifies callback functions (sync and async) as if they will be executed once, (i.e. it explores execution state as if the function was being called once). The next insn to explore is set to start of subprog and the exit from nested frame is handled using curframe > 0 and prepare_func_exit. In case of async callback it uses a customized variant of push_stack simulating a kind of branch to set up custom state and execution context for the async callback.
While this approach is simple and works when callback really will be executed only once, it is unsafe for all of our current helpers which are for_each style, i.e. they execute the callback multiple times.
A callback releasing acquired references of the caller may do so multiple times, but currently verifier sees it as one call inside the frame, which then returns to caller. Hence, it thinks it released some reference that the cb e.g. got access through callback_ctx (register filled inside cb from spilled typed register on stack).
Similarly, it may see that an acquire call is unpaired inside the callback, so the caller will copy the reference state of callback and then will have to release the register with new ref_obj_ids. But again, the callback may execute multiple times, but the verifier will only account for acquired references for a single symbolic execution of the callback, which will cause leaks.
Note that for async callback case, things are different. While currently we have bpf_timer_set_callback which only executes it once, even for multiple executions it would be safe, as reference state is NULL and check_reference_leak would force program to release state before BPF_EXIT. The state is also unaffected by analysis for the caller frame. Hence async callback is safe.
Since we want the reference state to be accessible, e.g. for pointers loaded from stack through callback_ctx's PTR_TO_STACK, we still have to copy caller's reference_state to callback's bpf_func_state, but we enforce that whatever references it adds to that reference_state has been released before it hits BPF_EXIT. This requires introducing a new callback_ref member in the reference state to distinguish between caller vs callee references. Hence, check_reference_leak now errors out if it sees we are in callback_fn and we have not released callback_ref refs. Since there can be multiple nested callbacks, like frame 0 -> cb1 -> cb2 etc. we need to also distinguish between whether this particular ref belongs to this callback frame or parent, and only error for our own, so we store state->frameno (which is always non-zero for callbacks).
In short, callbacks can read parent reference_state, but cannot mutate it, to be able to use pointers acquired by the caller. They must only undo their changes (by releasing their own acquired_refs before BPF_EXIT) on top of caller reference_state before returning (at which point the caller and callback state will match anyway, so no need to copy it back to caller).
--- include/linux/bpf_verifier.h | 11 ++++++++++ kernel/bpf/verifier.c | 42 ++++++++++++++++++++++++++++-------- 2 files changed, 44 insertions(+), 9 deletions(-)
include/linux/bpf_verifier.h +11 -0
@@ -192,6 +192,17 @@ struct bpf_reference_state {* is used purely to inform the user of a reference leak. */ int insn_idx; +/* There can be a case like: +* main (frame 0) +* cb (frame 1) +* func (frame 3) +* cb (frame 4) +* Hence for frame 4, if callback_ref just stored boolean, it would be +* impossible to distinguish nested callback refs. Hence store the +* frameno and compare that to callback_ref in check_reference_leak when +* exiting a callback function. +*/ +int callback_ref; };/* state of the program:
kernel/bpf/verifier.c +33 -9
84 lines not on this page · raw message
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 155/530 wifi: mac80211: allow bw change during channel switch in mesh
In reply to Greg Kroah-HartmanFrom: Hari Chandrakanthan <[email protected]>
[ Upstream commit 6b75f133fe05c36c52d691ff21545d5757fff721 ]
Quoted 1 line
From 'IEEE Std 802.11-2020 section 11.8.8.4.1':
The mesh channel switch may be triggered by the need to avoid interference to a detected radar signal, or to reassign mesh STA channels to ensure the MBSS connectivity.
A 20/40 MHz MBSS may be changed to a 20 MHz MBSS and a 20 MHz MBSS may be changed to a 20/40 MHz MBSS.
Since the standard allows the change of bandwidth during the channel switch in mesh, remove the bandwidth check present in ieee80211_set_csa_beacon.
--- net/mac80211/cfg.c | 3 --- 1 file changed, 3 deletions(-)
net/mac80211/cfg.c +0 -3
@@ -3384,9 +3384,6 @@ static int ieee80211_set_csa_beacon(struct ieee80211_sub_if_data *sdata,case NL80211_IFTYPE_MESH_POINT : {struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; -if (params->chandef.width != sdata->vif.bss_conf.chandef.width) -return -EINVAL ; -/* changes into another band are not supported */ if (sdata->vif.bss_conf.chandef.chan->band != params->chandef.chan->band)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 156/530 bpftool: Fix a wrong type cast in btf_dumper_int
In reply to Greg Kroah-HartmanFrom: Lam Thai <[email protected]>
[ Upstream commit 7184aef9c0f7a81db8fd18d183ee42481d89bf35 ]
When data points to a boolean value, casting it to int * is problematic and could lead to a wrong value being passed to jsonw_bool. Change the cast to bool * instead.
--- tools/bpf/bpftool/btf_dumper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/bpf/bpftool/btf_dumper.c +1 -1
@@ -418,7 +418,7 @@ static int btf_dumper_int(const struct btf_type *t, __u8 bit_offset, *(char *)data);break ;case BTF_INT_BOOL : -jsonw_bool (jw, *(int *)data); +jsonw_bool (jw, *(bool *)data);break ;default :/* shouldn't happen */
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 157/530 spi: mt7621: Fix an error message in mt7621_spi_probe()
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit 2b2bf6b7faa9010fae10dc7de76627a3fdb525b3 ]
'status' is known to be 0 at this point. The expected error code is PTR_ERR(clk).
Switch to dev_err_probe() in order to display the expected error code (in a human readable way).
This also filters -EPROBE_DEFER cases, should it happen.
--- drivers/spi/spi-mt7621.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-)
drivers/spi/spi-mt7621.c +3 -5
@@ -340,11 +340,9 @@ static int mt7621_spi_probe(struct platform_device *pdev)return PTR_ERR (base); clk =devm_clk_get (&pdev->dev,NULL ); -if (IS_ERR (clk)) { -dev_err (&pdev->dev,"unable to get SYS clock, err=%d\n" , - status); -return PTR_ERR (clk); - } +if (IS_ERR (clk)) +return dev_err_probe (&pdev->dev,PTR_ERR (clk), +"unable to get SYS clock\n" ); status =clk_prepare_enable (clk);if (status)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 158/530 x86/resctrl: Fix to restore to original value when re-enabling hardware prefetch register
In reply to Greg Kroah-HartmanFrom: Kohei Tarumizu <[email protected]>
[ Upstream commit 499c8bb4693d1c8d8f3d6dd38e5bdde3ff5bd906 ]
The current pseudo_lock.c code overwrites the value of the MSR_MISC_FEATURE_CONTROL to 0 even if the original value is not 0. Therefore, modify it to save and restore the original values.
--- arch/x86/kernel/cpu/resctrl/pseudo_lock.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
arch/x86/kernel/cpu/resctrl/pseudo_lock.c +9 -3
@@ -420,6 +420,7 @@ static int pseudo_lock_fn(void *_rdtgrp)struct pseudo_lock_region *plr = rdtgrp->plr;u32 rmid_p, closid_p;unsigned long i; +u64 saved_msr;#ifdef CONFIG_KASAN /* * The registers used for local register variables are also used
@@ -463,6 +464,7 @@ static int pseudo_lock_fn(void *_rdtgrp)* the buffer and evict pseudo-locked memory read earlier from the * cache. */ + saved_msr =__rdmsr (MSR_MISC_FEATURE_CONTROL );__wrmsr (MSR_MISC_FEATURE_CONTROL , prefetch_disable_bits,0x0 ); closid_p =this_cpu_read (pqr_state.cur_closid); rmid_p =this_cpu_read (pqr_state.cur_rmid);
@@ -514,7 +516,7 @@ static int pseudo_lock_fn(void *_rdtgrp)__wrmsr (IA32_PQR_ASSOC , rmid_p, closid_p);/* Re-enable the hardware prefetcher(s) */ -wrmsr (MSR_MISC_FEATURE_CONTROL ,0x0 ,0x0 ); +wrmsrl (MSR_MISC_FEATURE_CONTROL , saved_msr);local_irq_enable (); plr->thread_done =1 ;
@@ -871,6 +873,7 @@ bool rdtgroup_pseudo_locked_in_hierarchy(struct rdt_domain *d)static int measure_cycles_lat_fn (void *_plr) {struct pseudo_lock_region *plr = _plr; +u32 saved_low, saved_high;unsigned long i;u64 start, end;void *mem_r;
@@ -879,6 +882,7 @@ static int measure_cycles_lat_fn(void *_plr)/* * Disable hardware prefetchers. */ +rdmsr (MSR_MISC_FEATURE_CONTROL , saved_low, saved_high);wrmsr (MSR_MISC_FEATURE_CONTROL , prefetch_disable_bits,0x0 ); mem_r =READ_ONCE (plr->kmem);/*
@@ -895,7 +899,7 @@ static int measure_cycles_lat_fn(void *_plr) end =rdtsc_ordered ();trace_pseudo_lock_mem_latency ((u32)(end - start)); } -wrmsr (MSR_MISC_FEATURE_CONTROL ,0x0 ,0x0 ); +wrmsr (MSR_MISC_FEATURE_CONTROL , saved_low, saved_high);local_irq_enable (); plr->thread_done =1 ;wake_up_interruptible (&plr->lock_thread_wq);
@@ -940,6 +944,7 @@ static int measure_residency_fn(struct perf_event_attr *miss_attr,u64 hits_before =0 , hits_after =0 , miss_before =0 , miss_after =0 ;struct perf_event *miss_event, *hit_event;int hit_pmcnum, miss_pmcnum; +u32 saved_low, saved_high;unsigned int line_size;unsigned int size;unsigned long i;
@@ -973,6 +978,7 @@ static int measure_residency_fn(struct perf_event_attr *miss_attr,/* * Disable hardware prefetchers. */ +rdmsr (MSR_MISC_FEATURE_CONTROL , saved_low, saved_high);wrmsr (MSR_MISC_FEATURE_CONTROL , prefetch_disable_bits,0x0 );/* Initialize rest of local variables */
@@ -1031,7 +1037,7 @@ static int measure_residency_fn(struct perf_event_attr *miss_attr,*/ rmb ();/* Re-enable hardware prefetchers */ -wrmsr (MSR_MISC_FEATURE_CONTROL ,0x0 ,0x0 ); +wrmsr (MSR_MISC_FEATURE_CONTROL , saved_low, saved_high);local_irq_enable (); out_hit:perf_event_release_kernel (hit_event);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 159/530 xsk: Fix backpressure mechanism on Tx
In reply to Greg Kroah-HartmanFrom: Maciej Fijalkowski <[email protected]>
[ Upstream commit c00c4461689e15ac2cc3b9a595a54e4d8afd3d77 ]
Commit d678cbd2f867 ("xsk: Fix handling of invalid descriptors in XSK TX batching API") fixed batch API usage against set of descriptors with invalid ones but introduced a problem when AF_XDP SW rings are smaller than HW ones. Mismatch of reported Tx'ed frames between HW generator and user space app was observed. It turned out that backpressure mechanism became a bottleneck when the amount of produced descriptors to CQ is lower than what we grabbed from XSK Tx ring.
Say that 512 entries had been taken from XSK Tx ring but we had only 490 free entries in CQ. Then callsite (ZC driver) will produce only 490 entries onto HW Tx ring but 512 entries will be released from Tx ring and this is what will be seen by the user space.
In order to fix this case, mix XSK Tx/CQ ring interractions by moving around internal functions and changing call order:
* pull out xskq_prod_nb_free() from xskq_prod_reserve_addr_batch() up to xsk_tx_peek_release_desc_batch();
** move xskq_cons_release_n() into xskq_cons_read_desc_batch()
After doing so, algorithm can be described as follows:
1. lookup Tx entries
2. use value from 1. to reserve space in CQ (*)
3. Read from Tx ring as much descriptors as value from 2 3a. release descriptors from XSK Tx ring (**)
4. Finally produce addresses to CQ
--- net/xdp/xsk.c | 22 +++++++++++----------- net/xdp/xsk_queue.h | 22 ++++++++++------------ 2 files changed, 21 insertions(+), 23 deletions(-)
net/xdp/xsk.c +11 -11
@@ -370,16 +370,15 @@ static u32 xsk_tx_peek_release_fallback(return nb_pkts; } -u32 xsk_tx_peek_release_desc_batch (struct xsk_buff_pool *pool,u32 max_entries) +u32 xsk_tx_peek_release_desc_batch (struct xsk_buff_pool *pool,u32 nb_pkts) {struct xdp_sock *xs; -u32 nb_pkts;rcu_read_lock ();if (!list_is_singular (&pool->xsk_tx_list)) {/* Fallback to the non-batched version */ rcu_read_unlock (); -return xsk_tx_peek_release_fallback (pool, max_entries); +return xsk_tx_peek_release_fallback (pool, nb_pkts); } xs = list_first_or_null_rcu(&pool->xsk_tx_list, struct xdp_sock, tx_list);
@@ -388,12 +387,7 @@ u32 xsk_tx_peek_release_desc_batch(struc goto out; } - max_entries =xskq_cons_nb_entries (xs->tx, max_entries); - nb_pkts =xskq_cons_read_desc_batch (xs->tx, pool, max_entries); -if (!nb_pkts) { - xs->tx->queue_empty_descs++; - goto out; - } + nb_pkts =xskq_cons_nb_entries (xs->tx, nb_pkts);/* This is the backpressure mechanism for the Tx path. Try to * reserve space in the completion queue for all packets, but
@@ -401,12 +395,18 @@ u32 xsk_tx_peek_release_desc_batch(struc* packets. This avoids having to implement any buffering in * the Tx path. */ - nb_pkts =xskq_prod_reserve_addr_batch (pool->cq, pool->tx_descs, nb_pkts); + nb_pkts =xskq_prod_nb_free (pool->cq, nb_pkts);if (!nb_pkts) goto out; -xskq_cons_release_n (xs->tx, max_entries); + nb_pkts =xskq_cons_read_desc_batch (xs->tx, pool, nb_pkts); +if (!nb_pkts) { + xs->tx->queue_empty_descs++; + goto out; + } +__xskq_cons_release (xs->tx); +xskq_prod_write_addr_batch (pool->cq, pool->tx_descs, nb_pkts); xs->sk.sk_write_space (&xs->sk); out:
net/xdp/xsk_queue.h +10 -12
@@ -201,6 +201,11 @@ static inline bool xskq_cons_read_desc(sreturn false; } +static inline void xskq_cons_release_n (struct xsk_queue *q,u32 cnt) +{ + q->cached_cons += cnt; +} +static inline u32 xskq_cons_read_desc_batch (struct xsk_queue *q,struct xsk_buff_pool *pool,u32 max) {
@@ -222,6 +227,8 @@ static inline u32 xskq_cons_read_desc_ba cached_cons++; } +/* Release valid plus any invalid entries */ +xskq_cons_release_n (q, cached_cons - q->cached_cons);return nb_entries; }
@@ -287,11 +294,6 @@ static inline void xskq_cons_release(str q->cached_cons++; } -static inline void xskq_cons_release_n (struct xsk_queue *q,u32 cnt) -{ - q->cached_cons += cnt; -} -static inline bool xskq_cons_is_full (struct xsk_queue *q) {/* No barriers needed since data is not accessed */
@@ -353,21 +355,17 @@ static inline int xskq_prod_reserve_addrreturn 0 ; } -static inline u32 xskq_prod_reserve_addr_batch (struct xsk_queue *q,struct xdp_desc *descs, -u32 max) +static inline void xskq_prod_write_addr_batch (struct xsk_queue *q,struct xdp_desc *descs, +u32 nb_entries) {struct xdp_umem_ring *ring = (struct xdp_umem_ring *)q->ring; -u32 nb_entries, i, cached_prod; - - nb_entries =xskq_prod_nb_free (q, max); +u32 i, cached_prod;/* A, matches D */ cached_prod = q->cached_prod;for (i =0 ; i < nb_entries; i++) ring->desc[cached_prod++ & q->ring_mask] = descs[i].addr; q->cached_prod = cached_prod; - -return nb_entries; } static inline int xskq_prod_reserve_desc(struct xsk_queue *q,
Greg Kroah-Hartman
maintainerPATCH 160/530 bpf: Disable preemption when increasing per-cpu map_locked
In reply to Greg Kroah-HartmanFrom: Hou Tao <[email protected]>
[ Upstream commit 2775da21628738ce073a3a6a806adcbaada0f091 ]
Per-cpu htab->map_locked is used to prohibit the concurrent accesses from both NMI and non-NMI contexts. But since commit 74d862b682f5 ("sched: Make migrate_disable/enable() independent of RT"), migrate_disable() is also preemptible under CONFIG_PREEMPT case, so now map_locked also disallows concurrent updates from normal contexts (e.g. userspace processes) unexpectedly as shown below:
process A process B
htab_map_update_elem()
htab_lock_bucket()
migrate_disable()
/* return 1 */
__this_cpu_inc_return()
/* preempted by B */
htab_map_update_elem()
/* the same bucket as A */
htab_lock_bucket()
migrate_disable()
/* return 2, so lock fails */
__this_cpu_inc_return()
return -EBUSYA fix that seems feasible is using in_nmi() in htab_lock_bucket() and only checking the value of map_locked for nmi context. But it will re-introduce dead-lock on bucket lock if htab_lock_bucket() is re-entered through non-tracing program (e.g. fentry program).
One cannot use preempt_disable() to fix this issue as htab_use_raw_lock being false causes the bucket lock to be a spin lock which can sleep and does not work with preempt_disable().
Therefore, use migrate_disable() when using the spinlock instead of preempt_disable() and defer fixing concurrent updates to when the kernel has its own BPF memory allocator.
--- kernel/bpf/hashtab.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-)
kernel/bpf/hashtab.c +18 -5
@@ -161,17 +161,25 @@ static inline int htab_lock_bucket(const struct bpf_htab *htab, unsigned long *pflags) {unsigned long flags; +bool use_raw_lock; hash = hash &HASHTAB_MAP_LOCK_MASK ; -migrate_disable (); + use_raw_lock =htab_use_raw_lock (htab); +if (use_raw_lock) +preempt_disable (); +else +migrate_disable ();if (unlikely (__this_cpu_inc_return (*(htab->map_locked[hash])) !=1 )) {__this_cpu_dec (*(htab->map_locked[hash])); -migrate_enable (); +if (use_raw_lock) +preempt_enable (); +else +migrate_enable ();return -EBUSY ; } -if (htab_use_raw_lock (htab)) +if (use_raw_lock)raw_spin_lock_irqsave (&b->raw_lock, flags);else spin_lock_irqsave (&b->lock, flags);
@@ -184,13 +192,18 @@ static inline void htab_unlock_bucket(const struct bpf_htab *htab, struct bucket *b, u32 hash, unsigned long flags) { + bool use_raw_lock = htab_use_raw_lock(htab); + hash = hash &HASHTAB_MAP_LOCK_MASK ; -if (htab_use_raw_lock (htab)) +if (use_raw_lock)raw_spin_unlock_irqrestore (&b->raw_lock, flags);else spin_unlock_irqrestore (&b->lock, flags);__this_cpu_dec (*(htab->map_locked[hash])); -migrate_enable (); +if (use_raw_lock) +preempt_enable (); +else +migrate_enable (); }static bool htab_lru_map_delete_node (void *arg,struct bpf_lru_node *node);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 161/530 bpf: Propagate error from htab_lock_bucket() to userspace
In reply to Greg Kroah-HartmanFrom: Hou Tao <[email protected]>
[ Upstream commit 66a7a92e4d0d091e79148a4c6ec15d1da65f4280 ]
In __htab_map_lookup_and_delete_batch() if htab_lock_bucket() returns -EBUSY, it will go to next bucket. Going to next bucket may not only skip the elements in current bucket silently, but also incur out-of-bound memory access or expose kernel memory to userspace if current bucket_cnt is greater than bucket_size or zero.
Fixing it by stopping batch operation and returning -EBUSY when htab_lock_bucket() fails, and the application can retry or skip the busy batch as needed.
--- kernel/bpf/hashtab.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
kernel/bpf/hashtab.c +5 -2
@@ -1671,8 +1671,11 @@ __htab_map_lookup_and_delete_batch(struct bpf_map *map,/* do not grab the lock unless need it (bucket_cnt > 0). */ if (locked) { ret =htab_lock_bucket (htab, b, batch, &flags); -if (ret) - goto next_batch; +if (ret) { +rcu_read_unlock (); +bpf_enable_instrumentation (); + goto after_loop; + } } bucket_cnt =0 ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 162/530 bpf: Use this_cpu_{inc|dec|inc_return} for bpf_task_storage_busy
In reply to Greg Kroah-HartmanFrom: Hou Tao <[email protected]>
[ Upstream commit 197827a05e13808c60f52632e9887eede63f1c16 ]
Now migrate_disable() does not disable preemption and under some architectures (e.g. arm64) __this_cpu_{inc|dec|inc_return} are neither preemption-safe nor IRQ-safe, so for fully preemptible kernel concurrent lookups or updates on the same task local storage and on the same CPU may make bpf_task_storage_busy be imbalanced, and bpf_task_storage_trylock() on the specific cpu will always fail.
Fixing it by using this_cpu_{inc|dec|inc_return} when manipulating bpf_task_storage_busy.
--- kernel/bpf/bpf_local_storage.c | 4 ++-- kernel/bpf/bpf_task_storage.c | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-)
kernel/bpf/bpf_local_storage.c +2 -2
@@ -506,11 +506,11 @@ void bpf_local_storage_map_free(struct bpf_local_storage_map *smap, struct bpf_local_storage_elem, map_node))) {if (busy_counter) {migrate_disable (); -__this_cpu_inc (*busy_counter); +this_cpu_inc (*busy_counter); }bpf_selem_unlink (selem);if (busy_counter) { -__this_cpu_dec (*busy_counter); +this_cpu_dec (*busy_counter);migrate_enable (); }cond_resched_rcu ();
kernel/bpf/bpf_task_storage.c +4 -4
@@ -25,20 +25,20 @@ static DEFINE_PER_CPU(int, bpf_task_storage_busy);static void bpf_task_storage_lock (void ) {migrate_disable (); -__this_cpu_inc (bpf_task_storage_busy); +this_cpu_inc (bpf_task_storage_busy); }static void bpf_task_storage_unlock (void ) { -__this_cpu_dec (bpf_task_storage_busy); +this_cpu_dec (bpf_task_storage_busy);migrate_enable (); }static bool bpf_task_storage_trylock (void ) {migrate_disable (); -if (unlikely (__this_cpu_inc_return (bpf_task_storage_busy) !=1 )) { -__this_cpu_dec (bpf_task_storage_busy); +if (unlikely (this_cpu_inc_return (bpf_task_storage_busy) !=1 )) { +this_cpu_dec (bpf_task_storage_busy);migrate_enable ();return false; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 163/530 Bluetooth: btusb: mediatek: fix WMT failure during runtime suspend
In reply to Greg Kroah-HartmanFrom: Sean Wang <[email protected]>
[ Upstream commit fd3f106677bac70437dc12e76c827294ed495a44 ]
WMT cmd/event doesn't follow up the generic HCI cmd/event handling, it needs constantly polling control pipe until the host received the WMT event, thus, we should require to specifically acquire PM counter on the USB to prevent the interface from entering auto suspended while WMT cmd/event in progress.
--- drivers/bluetooth/btusb.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
drivers/bluetooth/btusb.c +14 -0
@@ -2435,15 +2435,29 @@ static int btusb_mtk_hci_wmt_sync(struct hci_dev *hdev,set_bit (BTUSB_TX_WAIT_VND_EVT , &data->flags); +/* WMT cmd/event doesn't follow up the generic HCI cmd/event handling, +* it needs constantly polling control pipe until the host received the +* WMT event, thus, we should require to specifically acquire PM counter +* on the USB to prevent the interface from entering auto suspended +* while WMT cmd/event in progress. +*/ + err =usb_autopm_get_interface (data->intf); +if (err <0 ) + goto err_free_wc; + err =__hci_cmd_send (hdev,0xfc6f , hlen, wc);if (err <0 ) {clear_bit (BTUSB_TX_WAIT_VND_EVT , &data->flags); +usb_autopm_put_interface (data->intf); goto err_free_wc; }/* Submit control IN URB on demand to process the WMT event */ err =btusb_mtk_submit_wmt_recv_urb (hdev); + +usb_autopm_put_interface (data->intf); +if (err <0 ) goto err_free_wc;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 164/530 wifi: rtl8xxxu: tighten bounds checking in rtl8xxxu_read_efuse()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit 620d5eaeb9059636864bda83ca1c68c20ede34a5 ]
There some bounds checking to ensure that "map_addr" is not out of bounds before the start of the loop. But the checking needs to be done as we iterate through the loop because "map_addr" gets larger as we iterate.
--- .../net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +7 -7
@@ -1874,13 +1874,6 @@ static int rtl8xxxu_read_efuse(struct rtl8xxxu_priv *priv)/* We have 8 bits to indicate validity */ map_addr = offset *8 ; -if (map_addr >=EFUSE_MAP_LEN ) { -dev_warn (dev,"%s: Illegal map_addr (%04x), " -"efuse corrupt!\n" , - __func__, map_addr); - ret = -EINVAL ; - goto exit; - }for (i =0 ; i <EFUSE_MAX_WORD_UNIT ; i++) {/* Check word enable condition in the section */ if (word_mask &BIT (i)) {
@@ -1891,6 +1884,13 @@ static int rtl8xxxu_read_efuse(struct rtl8xxxu_priv *priv) ret =rtl8xxxu_read_efuse8 (priv, efuse_addr++, &val8);if (ret) goto exit; +if (map_addr >=EFUSE_MAP_LEN -1 ) { +dev_warn (dev,"%s: Illegal map_addr (%04x), " +"efuse corrupt!\n" , + __func__, map_addr); + ret = -EINVAL ; + goto exit; + } priv->efuse_wifi.raw[map_addr++] = val8; ret =rtl8xxxu_read_efuse8 (priv, efuse_addr++, &val8);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 165/530 wifi: rtw88: add missing destroy_workqueue() on error path in rtw_core_init()
In reply to Greg Kroah-HartmanFrom: Yang Yingliang <[email protected]>
[ Upstream commit b0ea758b30bbdf7c4323c78b7c50c05d2e1224d5 ]
Add the missing destroy_workqueue() before return from rtw_core_init() in error path.
--- drivers/net/wireless/realtek/rtw88/main.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/net/wireless/realtek/rtw88/main.c +6 -2
@@ -1869,7 +1869,7 @@ int rtw_core_init(struct rtw_dev *rtwdev) ret =rtw_load_firmware (rtwdev,RTW_NORMAL_FW );if (ret) {rtw_warn (rtwdev,"no firmware loaded\n" ); -return ret; + goto out; }if (chip->wow_fw_name) {
@@ -1879,11 +1879,15 @@ int rtw_core_init(struct rtw_dev *rtwdev)wait_for_completion (&rtwdev->fw.completion);if (rtwdev->fw.firmware)release_firmware (rtwdev->fw.firmware); -return ret; + goto out; } }return 0 ; + +out: +destroy_workqueue (rtwdev->tx_wq); +return ret; }EXPORT_SYMBOL (rtw_core_init);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 166/530 selftests/xsk: Avoid use-after-free on ctx
In reply to Greg Kroah-HartmanFrom: Ian Rogers <[email protected]>
[ Upstream commit af515a5587b8f45f19e11657746e0c89411b0380 ]
The put lowers the reference count to 0 and frees ctx, reading it afterwards is invalid. Move the put after the uses and determine the last use by the reference count being 1.
--- tools/lib/bpf/xsk.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
tools/lib/bpf/xsk.c +3 -3
@@ -1245,15 +1245,15 @@ void xsk_socket__delete(struct xsk_socket *xsk) ctx = xsk->ctx; umem = ctx->umem; -xsk_put_ctx (ctx, true); - -if (!ctx->refcount) { +if (ctx->refcount ==1 ) {xsk_delete_bpf_maps (xsk);close (ctx->prog_fd);if (ctx->has_bpf_link)close (ctx->link_fd); } +xsk_put_ctx (ctx, true); + err =xsk_get_mmap_offsets (xsk->fd, &off);if (!err) {if (xsk->rx) {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 167/530 spi: qup: add missing clk_disable_unprepare on error in spi_qup_resume()
In reply to Greg Kroah-HartmanFrom: Xu Qiang <[email protected]>
[ Upstream commit 70034320fdc597b8f58b4a43bb547f17c4c5557a ]
Add the missing clk_disable_unprepare() before return from spi_qup_resume() in the error handling case.
--- drivers/spi/spi-qup.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-)
drivers/spi/spi-qup.c +14 -3
@@ -1246,14 +1246,25 @@ static int spi_qup_resume(struct device *device)return ret; ret =clk_prepare_enable (controller->cclk); -if (ret) +if (ret) { +clk_disable_unprepare (controller->iclk);return ret; + } ret =spi_qup_set_state (controller,QUP_STATE_RESET );if (ret) -return ret; + goto disable_clk; + + ret =spi_master_resume (master); +if (ret) + goto disable_clk; - return spi_master_resume(master); +return 0 ; + +disable_clk: +clk_disable_unprepare (controller->cclk); +clk_disable_unprepare (controller->iclk); + return ret; }#endif /* CONFIG_PM_SLEEP */
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 168/530 spi: qup: add missing clk_disable_unprepare on error in spi_qup_pm_resume_runtime()
In reply to Greg Kroah-HartmanFrom: Xu Qiang <[email protected]>
[ Upstream commit 494a22765ce479c9f8ad181c5d24cffda9f534bb ]
Add the missing clk_disable_unprepare() before return from spi_qup_pm_resume_runtime() in the error handling case.
--- drivers/spi/spi-qup.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/spi/spi-qup.c +3 -1
@@ -1199,8 +1199,10 @@ static int spi_qup_pm_resume_runtime(struct device *device)return ret; ret =clk_prepare_enable (controller->cclk); -if (ret) +if (ret) { +clk_disable_unprepare (controller->iclk);return ret; + }/* Disable clocks auto gaiting */ config =readl_relaxed (controller->base +QUP_CONFIG );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 169/530 wifi: rtl8xxxu: Fix skb misuse in TX queue selection
In reply to Greg Kroah-HartmanFrom: Bitterblue Smith <[email protected]>
[ Upstream commit edd5747aa12ed61a5ecbfa58d3908623fddbf1e8 ]
rtl8xxxu_queue_select() selects the wrong TX queues because it's reading memory from the wrong address. It expects to find ieee80211_hdr at skb->data, but that's not the case after skb_push(). Move the call to rtl8xxxu_queue_select() before the call to skb_push().
--- drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +2 -1
@@ -4984,6 +4984,8 @@ static void rtl8xxxu_tx(struct ieee80211_hw *hw,if (control && control->sta) sta = control->sta; + queue =rtl8xxxu_queue_select (hw, skb); + tx_desc =skb_push (skb, tx_desc_size);memset (tx_desc,0 , tx_desc_size);
@@ -4996,7 +4998,6 @@ static void rtl8xxxu_tx(struct ieee80211_hw *hw, is_broadcast_ether_addr(ieee80211_get_DA(hdr))) tx_desc->txdw0 |= TXDESC_BROADMULTICAST; - queue =rtl8xxxu_queue_select (hw, skb); tx_desc->txdw1 =cpu_to_le32 (queue <<TXDESC_QUEUE_SHIFT );if (tx_info->control.hw_key) {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 170/530 spi: meson-spicc: do not rely on busy flag in pow2 clk ops
In reply to Greg Kroah-HartmanFrom: Neil Armstrong <[email protected]>
[ Upstream commit 36acf80fc0c4b5ebe6fa010b524d442ee7f08fd3 ]
Since [1], controller's busy flag isn't set anymore when the __spi_transfer_message_noqueue() is used instead of the __spi_pump_transfer_message() logic for spi_sync transfers.
Since the pow2 clock ops were limited to only be available when a transfer is ongoing (between prepare_transfer_hardware and unprepare_transfer_hardware callbacks), the only way to track this down is to check for the controller cur_msg.
[1] ae7d2346dc89 ("spi: Don't use the message queue if possible in spi_sync")
--- drivers/spi/spi-meson-spicc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/spi/spi-meson-spicc.c +3 -3
@@ -537,7 +537,7 @@ static unsigned long meson_spicc_pow2_recalc_rate(struct clk_hw *hw,struct clk_divider *divider =to_clk_divider (hw);struct meson_spicc_device *spicc =pow2_clk_to_spicc (divider); -if (!spicc->master->cur_msg || !spicc->master->busy) +if (!spicc->master->cur_msg)return 0 ;return clk_divider_ops.recalc_rate (hw, parent_rate);
@@ -549,7 +549,7 @@ static int meson_spicc_pow2_determine_rate(struct clk_hw *hw,struct clk_divider *divider =to_clk_divider (hw);struct meson_spicc_device *spicc =pow2_clk_to_spicc (divider); -if (!spicc->master->cur_msg || !spicc->master->busy) +if (!spicc->master->cur_msg)return -EINVAL ;return clk_divider_ops.determine_rate (hw, req);
@@ -561,7 +561,7 @@ static int meson_spicc_pow2_set_rate(struct clk_hw *hw, unsigned long rate,struct clk_divider *divider =to_clk_divider (hw);struct meson_spicc_device *spicc =pow2_clk_to_spicc (divider); -if (!spicc->master->cur_msg || !spicc->master->busy) +if (!spicc->master->cur_msg)return -EINVAL ;return clk_divider_ops.set_rate (hw, rate, parent_rate);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 171/530 bpf: btf: fix truncated last_member_type_id in btf_struct_resolve
In reply to Greg Kroah-HartmanFrom: Lorenz Bauer <[email protected]>
[ Upstream commit a37a32583e282d8d815e22add29bc1e91e19951a ]
When trying to finish resolving a struct member, btf_struct_resolve saves the member type id in a u16 temporary variable. This truncates the 32 bit type id value if it exceeds UINT16_MAX.
As a result, structs that have members with type ids > UINT16_MAX and which need resolution will fail with a message like this:
[67414] STRUCT ff_device size=120 vlen=12
effect_owners type_id=67434 bits_offset=960 Member exceeds struct_size
Fix this by changing the type of last_member_type_id to u32.
--- kernel/bpf/btf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/bpf/btf.c +1 -1
@@ -2983,7 +2983,7 @@ static int btf_struct_resolve(struct btf_verifier_env *env,if (v->next_member) {const struct btf_type *last_member_type;const struct btf_member *last_member; -u16 last_member_type_id; +u32 last_member_type_id; last_member =btf_type_member (v->t) + v->next_member -1 ; last_member_type_id = last_member->type;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 172/530 wifi: rtl8xxxu: gen2: Fix mistake in path B IQ calibration
In reply to Greg Kroah-HartmanFrom: Bitterblue Smith <[email protected]>
[ Upstream commit e963a19c64ac0d2f8785d36a27391abd91ac77aa ]
Found by comparing with the vendor driver. Currently this affects only the RTL8192EU, which is the only gen2 chip with 2 TX paths supported by this driver. It's unclear what kind of effect the mistake had in practice, since I don't have any RTL8192EU devices to test it.
--- drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +2 -2
@@ -2925,12 +2925,12 @@ bool rtl8xxxu_gen2_simularity_compare(struct rtl8xxxu_priv *priv, }if (!(simubitmap &0x30 ) && priv->tx_paths >1 ) { -/* path B RX OK */ +/* path B TX OK */ for (i =4 ; i <6 ; i++) result[3 ][i] = result[c1][i]; } -if (!(simubitmap &0x30 ) && priv->tx_paths >1 ) { +if (!(simubitmap &0xc0 ) && priv->tx_paths >1 ) {/* path B RX OK */ for (i =6 ; i <8 ; i++) result[3 ][i] = result[c1][i];
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 173/530 wifi: rtl8xxxu: Remove copy-paste leftover in gen2_update_rate_mask
In reply to Greg Kroah-HartmanFrom: Bitterblue Smith <[email protected]>
[ Upstream commit d5350756c03cdf18696295c6b11d7acc4dbf825c ]
It looks like a leftover from copying rtl8xxxu_update_rate_mask, which is used with the gen1 chips.
It wasn't causing any problems for my RTL8188FU test device, but it's clearly a mistake, so remove it.
--- drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +2 -3
@@ -4338,15 +4338,14 @@ void rtl8xxxu_gen2_update_rate_mask(struct rtl8xxxu_priv *priv, h2c.b_macid_cfg.ramask2 = (ramask >>16 ) &0xff ; h2c.b_macid_cfg.ramask3 = (ramask >>24 ) &0xff ; - h2c.ramask.arg =0x80 ; h2c.b_macid_cfg.data1 = rateid;if (sgi) h2c.b_macid_cfg.data1 |=BIT (7 ); h2c.b_macid_cfg.data2 = bw; -dev_dbg (&priv->udev->dev,"%s: rate mask %08x, arg %02x, size %zi\n" , - __func__, ramask, h2c.ramask.arg,sizeof (h2c.b_macid_cfg)); +dev_dbg (&priv->udev->dev,"%s: rate mask %08x, rateid %02x, sgi %d, size %zi\n" , + __func__, ramask, rateid, sgi,sizeof (h2c.b_macid_cfg));rtl8xxxu_gen2_h2c_cmd (priv, &h2c,sizeof (h2c.b_macid_cfg)); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 174/530 wifi: mt76: sdio: fix transmitting packet hangs
In reply to Greg Kroah-HartmanFrom: YN Chen <[email protected]>
[ Upstream commit 250b1827205846ff346a76044955cb79d4963f70 ]
Fix transmitting packets hangs with continuing to pull the pending packet from mac80211 queues when receiving Tx status notification from the device.
--- drivers/net/wireless/mediatek/mt76/sdio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/mediatek/mt76/sdio.c +1 -1
@@ -213,7 +213,7 @@ static void mt76s_status_worker(struct mt76_worker *w) }while (nframes >0 );if (resched) -mt76_worker_schedule (&dev->sdio.txrx_worker); +mt76_worker_schedule (&dev->tx_worker); }static void mt76s_tx_status_data (struct work_struct *work)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 175/530 wifi: mt76: mt7615: add mt7615_mutex_acquire/release in mt7615_sta_set_decap_offload
In reply to Greg Kroah-HartmanFrom: Lorenzo Bianconi <[email protected]>
[ Upstream commit 765c69d477a44c088e5d19e7758dfa4db418e3ba ]
Similar to mt7921 driver, introduce mt7615_mutex_acquire/release in mt7615_sta_set_decap_offload in order to avoid sending mcu commands while the device is in low-power state.
--- drivers/net/wireless/mediatek/mt76/mt7615/main.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/net/wireless/mediatek/mt76/mt7615/main.c +4 -0
@@ -1186,12 +1186,16 @@ static void mt7615_sta_set_decap_offload(struct ieee80211_hw *hw,struct mt7615_dev *dev =mt7615_hw_dev (hw);struct mt7615_sta *msta = (struct mt7615_sta *)sta->drv_priv; +mt7615_mutex_acquire (dev); +if (enabled)set_bit (MT_WCID_FLAG_HDR_TRANS , &msta->wcid.flags);else clear_bit (MT_WCID_FLAG_HDR_TRANS , &msta->wcid.flags);mt7615_mcu_set_sta_decap_offload (dev, vif, sta); + +mt7615_mutex_release (dev); }#ifdef CONFIG_PM
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 176/530 wifi: mt76: mt7915: do not check state before configuring implicit beamform
In reply to Greg Kroah-HartmanFrom: Howard Hsu <[email protected]>
[ Upstream commit d2b5bb6dfab29fe32bedefaade88dcd182c03a00 ]
Do not need to check running state before configuring implicit Tx beamform. It is okay to configure implicit Tx beamform in run time. Noted that the existing connected stations will be applied for new configuration only if they reconnected to the interface.
--- drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c +3 -3
@@ -12,9 +12,9 @@ mt7915_implicit_txbf_set(void *data, u64 val) {struct mt7915_dev *dev = data; -if (test_bit (MT76_STATE_RUNNING , &dev->mphy.state)) -return -EBUSY ; - +/* The existing connected stations shall reconnect to apply +* new implicit txbf configuration. +*/ dev->ibf = !!val;return mt7915_mcu_set_txbf (dev,MT_BF_TYPE_UPDATE );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 177/530 Bluetooth: RFCOMM: Fix possible deadlock on socket shutdown/release
In reply to Greg Kroah-HartmanFrom: Luiz Augusto von Dentz <[email protected]>
[ Upstream commit 812e92b824c1db16c9519f8624d48a9901a0d38f ]
Due to change to switch to use lock_sock inside rfcomm_sk_state_change the socket shutdown/release procedure can cause a deadlock:
rfcomm_sock_shutdown():
lock_sock();
__rfcomm_sock_close():
rfcomm_dlc_close():
__rfcomm_dlc_close():
rfcomm_dlc_lock();
rfcomm_sk_state_change():
lock_sock();To fix this when the call __rfcomm_sock_close is now done without holding the lock_sock since rfcomm_dlc_lock exists to protect the dlc data there is no need to use lock_sock in that code path.
--- net/bluetooth/rfcomm/sock.c | 3 +++ 1 file changed, 3 insertions(+)
net/bluetooth/rfcomm/sock.c +3 -0
@@ -902,7 +902,10 @@ static int rfcomm_sock_shutdown(struct socket *sock, int how)lock_sock (sk);if (!sk->sk_shutdown) { sk->sk_shutdown =SHUTDOWN_MASK ; + +release_sock (sk);__rfcomm_sock_close (sk); +lock_sock (sk);if (sock_flag (sk,SOCK_LINGER ) && sk->sk_lingertime && !(current->flags &PF_EXITING ))
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 178/530 net: fs_enet: Fix wrong check in do_pd_setup
In reply to Greg Kroah-HartmanFrom: Zheng Yongjun <[email protected]>
[ Upstream commit ec3f06b542a960806a81345042e4eee3f8c5dec4 ]
Should check of_iomap return value 'fep->fec.fecp' instead of 'fep->fcc.fccp'
--- drivers/net/ethernet/freescale/fs_enet/mac-fec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/freescale/fs_enet/mac-fec.c +1 -1
@@ -98,7 +98,7 @@ static int do_pd_setup(struct fs_enet_private *fep)return -EINVAL ; fep->fec.fecp =of_iomap (ofdev->dev.of_node,0 ); -if (!fep->fcc.fccp) +if (!fep->fec.fecp)return -EINVAL ;return 0 ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 179/530 bpf: Ensure correct locking around vulnerable function find_vpid()
In reply to Greg Kroah-HartmanFrom: Lee Jones <[email protected]>
[ Upstream commit 83c10cc362d91c0d8d25e60779ee52fdbbf3894d ]
The documentation for find_vpid() clearly states:
"Must be called with the tasklist_lock or rcu_read_lock() held."
Presently we do neither for find_vpid() instance in bpf_task_fd_query(). Add proper rcu_read_lock/unlock() to fix the issue.
--- kernel/bpf/syscall.c | 2 ++ 1 file changed, 2 insertions(+)
kernel/bpf/syscall.c +2 -0
@@ -4100,7 +4100,9 @@ static int bpf_task_fd_query(const union bpf_attr *attr,if (attr->task_fd_query.flags !=0 )return -EINVAL ; +rcu_read_lock (); task =get_pid_task (find_vpid (pid),PIDTYPE_PID ); +rcu_read_unlock ();if (!task)return -ENOENT ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 180/530 Bluetooth: hci_{ldisc,serdev}: check percpu_init_rwsem() failure
In reply to Greg Kroah-HartmanFrom: Tetsuo Handa <[email protected]>
[ Upstream commit 3124d320c22f3f4388d9ac5c8f37eaad0cefd6b1 ]
syzbot is reporting NULL pointer dereference at hci_uart_tty_close() [1], for rcu_sync_enter() is called without rcu_sync_init() due to hci_uart_tty_open() ignoring percpu_init_rwsem() failure.
While we are at it, fix that hci_uart_register_device() ignores percpu_init_rwsem() failure and hci_uart_unregister_device() does not call percpu_free_rwsem().
--- drivers/bluetooth/hci_ldisc.c | 7 +++++-- drivers/bluetooth/hci_serdev.c | 10 +++++++--- 2 files changed, 12 insertions(+), 5 deletions(-)
drivers/bluetooth/hci_ldisc.c +5 -2
@@ -490,6 +490,11 @@ static int hci_uart_tty_open(struct tty_struct *tty)BT_ERR ("Can't allocate control structure" );return -ENFILE ; } +if (percpu_init_rwsem (&hu->proto_lock)) { +BT_ERR ("Can't allocate semaphore structure" ); +kfree (hu); +return -ENOMEM ; + } tty->disc_data = hu; hu->tty = tty;
@@ -502,8 +507,6 @@ static int hci_uart_tty_open(struct tty_struct *tty)INIT_WORK (&hu->init_ready, hci_uart_init_work);INIT_WORK (&hu->write_work, hci_uart_write_work); -percpu_init_rwsem (&hu->proto_lock); -/* Flush any pending characters in the driver */ tty_driver_flush_buffer (tty);
drivers/bluetooth/hci_serdev.c +7 -3
@@ -301,11 +301,12 @@ int hci_uart_register_device(struct hci_uart *hu,serdev_device_set_client_ops (hu->serdev, &hci_serdev_client_ops); +if (percpu_init_rwsem (&hu->proto_lock)) +return -ENOMEM ; + err =serdev_device_open (hu->serdev);if (err) -return err; - -percpu_init_rwsem (&hu->proto_lock); + goto err_rwsem; err = p->open (hu);if (err)
@@ -378,6 +379,8 @@ int hci_uart_register_device(struct hci_uart *hu, p->close (hu); err_open:serdev_device_close (hu->serdev); +err_rwsem: +percpu_free_rwsem (&hu->proto_lock);return err; }EXPORT_SYMBOL_GPL (hci_uart_register_device);
@@ -399,5 +402,6 @@ void hci_uart_unregister_device(struct hci_uart *hu)clear_bit (HCI_UART_PROTO_READY , &hu->flags);serdev_device_close (hu->serdev); } +percpu_free_rwsem (&hu->proto_lock); }EXPORT_SYMBOL_GPL (hci_uart_unregister_device);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 181/530 netfilter: conntrack: fix the gc rescheduling delay
In reply to Greg Kroah-HartmanFrom: Antoine Tenart <[email protected]>
[ Upstream commit 95eabdd207024312876d0ebed90b4c977e050e85 ]
Commit 2cfadb761d3d ("netfilter: conntrack: revisit gc autotuning") changed the eviction rescheduling to the use average expiry of scanned entries (within 1-60s) by doing:
for (...) {
expires = clamp(nf_ct_expires(tmp), ...);
next_run += expires;
next_run /= 2;
}The issue is the above will make the average ('next_run' here) more dependent on the last expiration values than the firsts (for sets > 2). Depending on the expiration values used to compute the average, the result can be quite different than what's expected. To fix this we can do the following:
for (...) {
expires = clamp(nf_ct_expires(tmp), ...);
next_run += (expires - next_run) / ++count;
}--- net/netfilter/nf_conntrack_core.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
net/netfilter/nf_conntrack_core.c +8 -2
@@ -67,6 +67,7 @@ struct conntrack_gc_work {struct delayed_work dwork;u32 next_bucket;u32 avg_timeout; +u32 count;u32 start_time;bool exiting;bool early_drop;
@@ -1439,6 +1440,7 @@ static void gc_worker(struct work_struct *work)unsigned int expired_count =0 ;unsigned long next_run;s32 delta_time; +long count; gc_work = container_of(work, struct conntrack_gc_work, dwork.work);
@@ -1448,10 +1450,12 @@ static void gc_worker(struct work_struct *work)if (i ==0 ) { gc_work->avg_timeout =GC_SCAN_INTERVAL_INIT ; + gc_work->count =1 ; gc_work->start_time = start_time; } next_run = gc_work->avg_timeout; + count = gc_work->count; end_time = start_time +GC_SCAN_MAX_DURATION ;
@@ -1471,8 +1475,8 @@ static void gc_worker(struct work_struct *work)hlist_nulls_for_each_entry_rcu (h, n, &ct_hash[i], hnnode) {struct nf_conntrack_net *cnet; -unsigned long expires;struct net *net; +long expires; tmp =nf_ct_tuplehash_to_ctrack (h);
@@ -1486,6 +1490,7 @@ static void gc_worker(struct work_struct *work) gc_work->next_bucket = i; gc_work->avg_timeout = next_run; + gc_work->count = count; delta_time = nfct_time_stamp - gc_work->start_time;
@@ -1501,8 +1506,8 @@ static void gc_worker(struct work_struct *work) } expires =clamp (nf_ct_expires (tmp),GC_SCAN_INTERVAL_MIN ,GC_SCAN_INTERVAL_CLAMP ); + expires = (expires - (long )next_run) / ++count; next_run += expires; - next_run /=2u ;if (nf_conntrack_max95 ==0 ||gc_worker_skip_ct (tmp))continue ;
@@ -1540,6 +1545,7 @@ static void gc_worker(struct work_struct *work) delta_time = nfct_time_stamp - end_time;if (delta_time >0 && i < hashsz) { gc_work->avg_timeout = next_run; + gc_work->count = count; gc_work->next_bucket = i; next_run =0 ; goto early_exit;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 182/530 netfilter: conntrack: revisit the gc initial rescheduling bias
In reply to Greg Kroah-HartmanFrom: Antoine Tenart <[email protected]>
[ Upstream commit 2aa192757005f130b2dd3547dda6e462e761199f ]
The previous commit changed the way the rescheduling delay is computed which has a side effect: the bias is now represented as much as the other entries in the rescheduling delay which makes the logic to kick in only with very large sets, as the initial interval is very large (INT_MAX).
Revisit the GC initial bias to allow more frequent GC for smaller sets while still avoiding wakeups when a machine is mostly idle. We're moving from a large initial value to pretending we have 100 entries expiring at the upper bound. This way only a few entries having a small timeout won't impact much the rescheduling delay and non-idle machines will have enough entries to lower the delay when needed. This also improves readability as the initial bias is now linked to what is computed instead of being an arbitrary large value.
--- net/netfilter/nf_conntrack_core.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
net/netfilter/nf_conntrack_core.c +6 -4
@@ -86,10 +86,12 @@ static DEFINE_MUTEX(nf_conntrack_mutex);/* clamp timeouts to this value (TCP unacked) */ #define GC_SCAN_INTERVAL_CLAMP (300ul * HZ) -/* large initial bias so that we don't scan often just because we have -* three entries with a 1s timeout. +/* Initial bias pretending we have 100 entries at the upper bound so we don't +* wakeup often just because we have three entries with a 1s timeout while still +* allowing non-idle machines to wakeup more often when needed. */ -#define GC_SCAN_INTERVAL_INIT INT_MAX +#define GC_SCAN_INITIAL_COUNT 100 +#define GC_SCAN_INTERVAL_INIT GC_SCAN_INTERVAL_MAX#define GC_SCAN_MAX_DURATION msecs_to_jiffies(10)#define GC_SCAN_EXPIRED_MAX (64000u / HZ)
@@ -1450,7 +1452,7 @@ static void gc_worker(struct work_struct *work)if (i ==0 ) { gc_work->avg_timeout =GC_SCAN_INTERVAL_INIT ; - gc_work->count =1 ; + gc_work->count =GC_SCAN_INITIAL_COUNT ; gc_work->start_time = start_time; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 183/530 wifi: ath11k: fix number of VHT beamformee spatial streams
In reply to Greg Kroah-HartmanFrom: Jesus Fernandez Manzano <[email protected]>
[ Upstream commit 55b5ee3357d7bb98ee578cf9b84a652e7a1bc199 ]
The number of spatial streams used when acting as a beamformee in VHT mode are reported by the firmware as 7 (8 sts - 1) both in IPQ6018 and IPQ8074 which respectively have 2 and 4 sts each. So the firmware should report 1 (2 - 1) and 3 (4 - 1).
Fix this by checking that the number of VHT beamformee sts reported by the firmware is not greater than the number of receiving antennas - 1. The fix is based on the same approach used in this same function for sanitizing the number of sounding dimensions reported by the firmware.
Without this change, acting as a beamformee in VHT mode is not working properly.
Tested-on: IPQ6018 hw1.0 AHB WLAN.HK.2.5.0.1-01208-QCAHKSWPL_SILICONZ-1
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.5.0.1-01208-QCAHKSWPL_SILICONZ-1
--- drivers/net/wireless/ath/ath11k/mac.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-)
drivers/net/wireless/ath/ath11k/mac.c +20 -5
@@ -3684,6 +3684,8 @@ static int ath11k_mac_set_txbf_conf(struct ath11k_vif *arvif)if (vht_cap & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE )) { nsts = vht_cap &IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK ; nsts >>=IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT ; +if (nsts > (ar->num_rx_chains -1 )) + nsts = ar->num_rx_chains -1 ; value |=SM (nsts,WMI_TXBF_STS_CAP_OFFSET ); }
@@ -3724,7 +3726,7 @@ static int ath11k_mac_set_txbf_conf(struct ath11k_vif *arvif)static void ath11k_set_vht_txbf_cap (struct ath11k *ar,u32 *vht_cap) {bool subfer, subfee; -int sound_dim =0 ; +int sound_dim =0 , nsts =0 ; subfer = !!(*vht_cap & (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE )); subfee = !!(*vht_cap & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE ));
@@ -3734,6 +3736,11 @@ static void ath11k_set_vht_txbf_cap(struct ath11k *ar, u32 *vht_cap) subfer = false; } +if (ar->num_rx_chains <2 ) { + *vht_cap &= ~(IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE ); + subfee = false; + } +/* If SU Beaformer is not set, then disable MU Beamformer Capability */ if (!subfer) *vht_cap &= ~(IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE );
@@ -3746,7 +3753,9 @@ static void ath11k_set_vht_txbf_cap(struct ath11k *ar, u32 *vht_cap) sound_dim >>=IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT ; *vht_cap &= ~IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK ; -/* TODO: Need to check invalid STS and Sound_dim values set by FW? */ + nsts = (*vht_cap &IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK ); + nsts >>=IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT ; + *vht_cap &= ~IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK ;/* Enable Sounding Dimension Field only if SU BF is enabled */ if (subfer) {
@@ -3758,9 +3767,15 @@ static void ath11k_set_vht_txbf_cap(struct ath11k *ar, u32 *vht_cap) *vht_cap |= sound_dim; } -/* Use the STS advertised by FW unless SU Beamformee is not supported*/ -if (!subfee) - *vht_cap &= ~(IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK ); +/* Enable Beamformee STS Field only if SU BF is enabled */ +if (subfee) { +if (nsts > (ar->num_rx_chains -1 )) + nsts = ar->num_rx_chains -1 ; + + nsts <<=IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT ; + nsts &=IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK ; + *vht_cap |= nsts; + } } static struct ieee80211_sta_vht_cap
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 184/530 x86/microcode/AMD: Track patch allocation size explicitly
In reply to Greg Kroah-HartmanFrom: Kees Cook <[email protected]>
[ Upstream commit 712f210a457d9c32414df246a72781550bc23ef6 ]
In preparation for reducing the use of ksize(), record the actual allocation size for later memcpy(). This avoids copying extra (uninitialized!) bytes into the patch buffer when the requested allocation size isn't exactly the size of a kmalloc bucket. Additionally, fix potential future issues where runtime bounds checking will notice that the buffer was allocated to a smaller value than returned by ksize().
--- arch/x86/include/asm/microcode.h | 1 + arch/x86/kernel/cpu/microcode/amd.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-)
arch/x86/include/asm/microcode.h +1 -0
@@ -9,6 +9,7 @@struct ucode_patch {struct list_head plist;void *data;/* Intel uses only this one */ +unsigned int size;u32 patch_id;u16 equiv_cpu; };
arch/x86/kernel/cpu/microcode/amd.c +2 -1
@@ -782,6 +782,7 @@ static int verify_and_add_patch(u8 family, u8 *fw, unsigned int leftover,kfree (patch);return -EINVAL ; } + patch->size = *patch_size; mc_hdr = (struct microcode_header_amd *)(fw +SECTION_HDR_SIZE ); proc_id = mc_hdr->processor_rev_id;
@@ -863,7 +864,7 @@ load_microcode_amd(bool save, u8 family, const u8 *data, size_t size)return ret;memset (amd_ucode_patch,0 ,PATCH_MAX_SIZE ); -memcpy (amd_ucode_patch, p->data,min_t (u32,ksize (p->data),PATCH_MAX_SIZE )); +memcpy (amd_ucode_patch, p->data,min_t (u32, p->size,PATCH_MAX_SIZE ));return ret; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 185/530 x86/cpu: Include the header of init_ia32_feat_ctl()s prototype
In reply to Greg Kroah-HartmanFrom: Luciano Leão <[email protected]>
[ Upstream commit 30ea703a38ef76ca119673cd8bdd05c6e068e2ac ]
Include the header containing the prototype of init_ia32_feat_ctl(), solving the following warning:
$ make W=1 arch/x86/kernel/cpu/feat_ctl.o
arch/x86/kernel/cpu/feat_ctl.c:112:6: warning: no previous prototype for ‘init_ia32_feat_ctl’ [-Wmissing-prototypes]
112 | void init_ia32_feat_ctl(struct cpuinfo_x86 *c)This warning appeared after commit
5d5103595e9e5 ("x86/cpu: Reinitialize IA32_FEAT_CTL MSR on BSP during wakeup")
had moved the function init_ia32_feat_ctl()'s prototype from arch/x86/kernel/cpu/cpu.h to arch/x86/include/asm/cpu.h.
Note that, before the commit mentioned above, the header include "cpu.h" (arch/x86/kernel/cpu/cpu.h) was added by commit
0e79ad863df43 ("x86/cpu: Fix a -Wmissing-prototypes warning for init_ia32_feat_ctl()")
solely to fix init_ia32_feat_ctl()'s missing prototype. So, the header include "cpu.h" is no longer necessary.
[ bp: Massage commit message. ]
--- arch/x86/kernel/cpu/feat_ctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/kernel/cpu/feat_ctl.c +1 -1
@@ -1,11 +1,11 @@// SPDX-License-Identifier: GPL-2.0 #include <linux/tboot.h> +#include <asm/cpu.h> #include <asm/cpufeature.h> #include <asm/msr-index.h> #include <asm/processor.h> #include <asm/vmx.h> -#include "cpu.h" #undef pr_fmt#define pr_fmt (fmt) "x86/cpu: " fmt
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 186/530 spi: dw: Fix PM disable depth imbalance in dw_spi_bt1_probe
In reply to Greg Kroah-HartmanFrom: Zhang Qilong <[email protected]>
[ Upstream commit 618d815fc93477b1675878f3c04ff32657cc18b4 ]
The pm_runtime_enable will increase power disable depth. Thus a pairing decrement is needed on the error handling path to keep it balanced according to context.
--- drivers/spi/spi-dw-bt1.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/spi/spi-dw-bt1.c +3 -1
@@ -293,8 +293,10 @@ static int dw_spi_bt1_probe(struct platform_device *pdev)pm_runtime_enable (&pdev->dev); ret =dw_spi_add_host (&pdev->dev, dws); -if (ret) +if (ret) { +pm_runtime_disable (&pdev->dev); goto err_disable_clk; + }platform_set_drvdata (pdev, dwsbt1);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 187/530 spi/omap100k:Fix PM disable depth imbalance in omap1_spi100k_probe
In reply to Greg Kroah-HartmanFrom: Zhang Qilong <[email protected]>
[ Upstream commit 29f65f2171c85a9633daa380df14009a365f42f2 ]
The pm_runtime_enable will increase power disable depth. Thus a pairing decrement is needed on the error handling path to keep it balanced according to context.
--- drivers/spi/spi-omap-100k.c | 1 + 1 file changed, 1 insertion(+)
drivers/spi/spi-omap-100k.c +1 -0
@@ -412,6 +412,7 @@ static int omap1_spi100k_probe(struct platform_device *pdev)return status; err_fck: +pm_runtime_disable (&pdev->dev);clk_disable_unprepare (spi100k->fck); err_ick:clk_disable_unprepare (spi100k->ick);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 188/530 skmsg: Schedule psock work if the cached skb exists on the psock
In reply to Greg Kroah-HartmanFrom: Liu Jian <[email protected]>
[ Upstream commit bec217197b412d74168c6a42fc0f76d0cc9cad00 ]
In sk_psock_backlog function, for ingress direction skb, if no new data packet arrives after the skb is cached, the cached skb does not have a chance to be added to the receive queue of psock. As a result, the cached skb cannot be received by the upper-layer application. Fix this by reschedule the psock work to dispose the cached skb in sk_msg_recvmsg function.
--- net/core/skmsg.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
net/core/skmsg.c +8 -4
@@ -435,8 +435,10 @@ int sk_msg_recvmsg(struct sock *sk, struct sk_psock *psock, struct msghdr *msg,if (copied + copy > len) copy = len - copied; copy =copy_page_to_iter (page, sge->offset, copy, iter); -if (!copy) -return copied ? copied : -EFAULT ; +if (!copy) { + copied = copied ? copied : -EFAULT ; + goto out; + } copied += copy;if (likely (!peek)) {
@@ -456,7 +458,7 @@ int sk_msg_recvmsg(struct sock *sk, struct sk_psock *psock, struct msghdr *msg,* didn't copy the entire length lets just break. */ if (copy != sge->length) -return copied; + goto out;sk_msg_iter_var_next (i); }
@@ -478,7 +480,9 @@ int sk_msg_recvmsg(struct sock *sk, struct sk_psock *psock, struct msghdr *msg, } msg_rx =sk_psock_peek_msg (psock); } - +out: +if (psock->work_state.skb && copied >0 ) +schedule_work (&psock->work);return copied; }EXPORT_SYMBOL_GPL (sk_msg_recvmsg);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 189/530 i2c: mlxbf: support lock mechanism
In reply to Greg Kroah-HartmanFrom: Asmaa Mnebhi <[email protected]>
[ Upstream commit 86067ccfa1424a26491542d6f6d7546d40b61a10 ]
Linux is not the only entity using the BlueField I2C busses so support a lock mechanism provided by hardware to avoid issues when multiple entities are trying to access the same bus.
The lock is acquired whenever written explicitely or the lock register is read. So make sure it is always released at the end of a successful or failed transaction.
--- drivers/i2c/busses/i2c-mlxbf.c | 44 ++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 5 deletions(-)
drivers/i2c/busses/i2c-mlxbf.c +39 -5
@@ -306,6 +306,7 @@ static u64 mlxbf_i2c_corepll_frequency;* exact. */ #define MLXBF_I2C_SMBUS_TIMEOUT (300 * 1000)/* 300ms */ +#define MLXBF_I2C_SMBUS_LOCK_POLL_TIMEOUT (300 * 1000)/* 300ms */ /* Encapsulates timing parameters. */ struct mlxbf_i2c_timings {
@@ -514,6 +515,25 @@ static bool mlxbf_smbus_master_wait_for_idle(struct mlxbf_i2c_priv *priv)return false; } +/* +* wait for the lock to be released before acquiring it. +*/ +static bool mlxbf_i2c_smbus_master_lock (struct mlxbf_i2c_priv *priv) +{ +if (mlxbf_smbus_poll (priv->smbus->io,MLXBF_I2C_SMBUS_MASTER_GW , +MLXBF_I2C_MASTER_LOCK_BIT , true, +MLXBF_I2C_SMBUS_LOCK_POLL_TIMEOUT )) +return true; + +return false; +} + +static void mlxbf_i2c_smbus_master_unlock (struct mlxbf_i2c_priv *priv) +{ +/* Clear the gw to clear the lock */ +writel (0 , priv->smbus->io +MLXBF_I2C_SMBUS_MASTER_GW ); +} +static bool mlxbf_i2c_smbus_transaction_success (u32 master_status,u32 cause_status) {
@@ -705,10 +725,19 @@ mlxbf_i2c_smbus_start_transaction(struct mlxbf_i2c_priv *priv, slave = request->slave &GENMASK (6 ,0 ); addr = slave <<1 ; -/* First of all, check whether the HW is idle. */ -if (WARN_ON (!mlxbf_smbus_master_wait_for_idle (priv))) +/* +* Try to acquire the smbus gw lock before any reads of the GW register since +* a read sets the lock. +*/ +if (WARN_ON (!mlxbf_i2c_smbus_master_lock (priv)))return -EBUSY ; +/* Check whether the HW is idle */ +if (WARN_ON (!mlxbf_smbus_master_wait_for_idle (priv))) { + ret = -EBUSY ; + goto out_unlock; + } +/* Set first byte. */ data_desc[data_idx++] = addr;
@@ -732,8 +761,10 @@ mlxbf_i2c_smbus_start_transaction(struct mlxbf_i2c_priv *priv, write_en =1 ; write_len += operation->length;if (data_idx + operation->length > -MLXBF_I2C_MASTER_DATA_DESC_SIZE ) -return -ENOBUFS ; +MLXBF_I2C_MASTER_DATA_DESC_SIZE ) { + ret = -ENOBUFS ; + goto out_unlock; + }memcpy (data_desc + data_idx, operation->buffer, operation->length); data_idx += operation->length;
@@ -765,7 +796,7 @@ mlxbf_i2c_smbus_start_transaction(struct mlxbf_i2c_priv *priv, ret =mlxbf_i2c_smbus_enable (priv, slave, write_len, block_en, pec_en,0 );if (ret) -return ret; + goto out_unlock; }if (read_en) {
@@ -792,6 +823,9 @@ mlxbf_i2c_smbus_start_transaction(struct mlxbf_i2c_priv *priv, priv->smbus->io + MLXBF_I2C_SMBUS_MASTER_FSM); } +out_unlock: +mlxbf_i2c_smbus_master_unlock (priv); +return ret; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 190/530 Bluetooth: hci_core: Fix not handling link timeouts propertly
In reply to Greg Kroah-HartmanFrom: Luiz Augusto von Dentz <[email protected]>
[ Upstream commit 116523c8fac05d1d26f748fee7919a4ec5df67ea ]
Change that introduced the use of __check_timeout did not account for link types properly, it always assumes ACL_LINK is used thus causing hdev->acl_last_tx to be used even in case of LE_LINK and then again uses ACL_LINK with hci_link_tx_to.
To fix this __check_timeout now takes the link type as parameter and then procedure to use the right last_tx based on the link type and pass it to hci_link_tx_to.
--- net/bluetooth/hci_core.c | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-)
net/bluetooth/hci_core.c +23 -11
@@ -4673,15 +4673,27 @@ static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb)return DIV_ROUND_UP (skb->len -HCI_ACL_HDR_SIZE , hdev->block_len); } -static void __check_timeout (struct hci_dev *hdev,unsigned int cnt) +static void __check_timeout (struct hci_dev *hdev,unsigned int cnt,u8 type) { -if (!hci_dev_test_flag (hdev,HCI_UNCONFIGURED )) { -/* ACL tx timeout must be longer than maximum -* link supervision timeout (40.9 seconds) */ -if (!cnt &&time_after (jiffies, hdev->acl_last_tx + -HCI_ACL_TX_TIMEOUT )) -hci_link_tx_to (hdev,ACL_LINK ); +unsigned long last_tx; + +if (hci_dev_test_flag (hdev,HCI_UNCONFIGURED )) +return ; + +switch (type) { +case LE_LINK : + last_tx = hdev->le_last_tx; +break ; +default : + last_tx = hdev->acl_last_tx; +break ; } + +/* tx timeout must be longer than maximum link supervision timeout +* (40.9 seconds) +*/ +if (!cnt &&time_after (jiffies, last_tx +HCI_ACL_TX_TIMEOUT )) +hci_link_tx_to (hdev, type); }/* Schedule SCO */
@@ -4739,7 +4751,7 @@ static void hci_sched_acl_pkt(struct hci_dev *hdev)struct sk_buff *skb;int quote; -__check_timeout (hdev, cnt); +__check_timeout (hdev, cnt,ACL_LINK );while (hdev->acl_cnt && (chan =hci_chan_sent (hdev,ACL_LINK , "e))) {
@@ -4782,8 +4794,6 @@ static void hci_sched_acl_blk(struct hci_dev *hdev)int quote;u8 type; -__check_timeout (hdev, cnt); -BT_DBG ("%s" , hdev->name);if (hdev->dev_type ==HCI_AMP )
@@ -4791,6 +4801,8 @@ static void hci_sched_acl_blk(struct hci_dev *hdev)else type =ACL_LINK ; +__check_timeout (hdev, cnt, type); +while (hdev->block_cnt >0 && (chan =hci_chan_sent (hdev, type, "e))) {u32 priority = (skb_peek (&chan->data_q))->priority;
@@ -4864,7 +4876,7 @@ static void hci_sched_le(struct hci_dev *hdev) cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt; -__check_timeout (hdev, cnt); +__check_timeout (hdev, cnt,LE_LINK ); tmp = cnt;while (cnt && (chan =hci_chan_sent (hdev,LE_LINK , "e))) {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 191/530 xfrm: Reinject transport-mode packets through workqueue
In reply to Greg Kroah-HartmanFrom: Liu Jian <[email protected]>
[ Upstream commit 4f4920669d21e1060b7243e5118dc3b71ced1276 ]
The following warning is displayed when the tcp6-multi-diffip11 stress test case of the LTP test suite is tested:
watchdog: BUG: soft lockup - CPU#0 stuck for 22s! [ns-tcpserver:48198] CPU: 0 PID: 48198 Comm: ns-tcpserver Kdump: loaded Not tainted 6.0.0-rc6+ #39 Hardware name: QEMU KVM Virtual Machine, BIOS 0.0.0 02/06/2015 pstate: 80400005 (Nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : des3_ede_encrypt+0x27c/0x460 [libdes] lr : 0x3f
sp : ffff80000ceaa1b0
x29: ffff80000ceaa1b0 x28: ffff0000df056100 x27: ffff0000e51e5280
x26: ffff80004df75030 x25: ffff0000e51e4600 x24: 000000000000003b
x23: 0000000000802080 x22: 000000000000003d x21: 0000000000000038
x20: 0000000080000020 x19: 000000000000000a x18: 0000000000000033
x17: ffff0000e51e4780 x16: ffff80004e2d1448 x15: ffff80004e2d1248
x14: ffff0000e51e4680 x13: ffff80004e2d1348 x12: ffff80004e2d1548
x11: ffff80004e2d1848 x10: ffff80004e2d1648 x9 : ffff80004e2d1748 x8 : ffff80004e2d1948 x7 : 000000000bcaf83d x6 : 000000000000001b x5 : ffff80004e2d1048 x4 : 00000000761bf3bf x3 : 000000007f1dd0a3 x2 : ffff0000e51e4780 x1 : ffff0000e3b9a2f8 x0 : 00000000db44e872
Call trace: des3_ede_encrypt+0x27c/0x460 [libdes] crypto_des3_ede_encrypt+0x1c/0x30 [des_generic] crypto_cbc_encrypt+0x148/0x190 crypto_skcipher_encrypt+0x2c/0x40 crypto_authenc_encrypt+0xc8/0xfc [authenc] crypto_aead_encrypt+0x2c/0x40 echainiv_encrypt+0x144/0x1a0 [echainiv] crypto_aead_encrypt+0x2c/0x40 esp6_output_tail+0x1c8/0x5d0 [esp6] esp6_output+0x120/0x278 [esp6] xfrm_output_one+0x458/0x4ec xfrm_output_resume+0x6c/0x1f0 xfrm_output+0xac/0x4ac __xfrm6_output+0x130/0x270 xfrm6_output+0x60/0xec ip6_xmit+0x2ec/0x5bc inet6_csk_xmit+0xbc/0x10c __tcp_transmit_skb+0x460/0x8c0 tcp_write_xmit+0x348/0x890 __tcp_push_pending_frames+0x44/0x110 tcp_rcv_established+0x3c8/0x720 tcp_v6_do_rcv+0xdc/0x4a0 tcp_v6_rcv+0xc24/0xcb0 ip6_protocol_deliver_rcu+0xf0/0x574 ip6_input_finish+0x48/0x7c ip6_input+0x48/0xc0 ip6_rcv_finish+0x80/0x9c xfrm_trans_reinject+0xb0/0xf4 tasklet_action_common.constprop.0+0xf8/0x134 tasklet_action+0x30/0x3c __do_softirq+0x128/0x368 do_softirq+0xb4/0xc0 __local_bh_enable_ip+0xb0/0xb4 put_cpu_fpsimd_context+0x40/0x70 kernel_neon_end+0x20/0x40 sha1_base_do_update.constprop.0.isra.0+0x11c/0x140 [sha1_ce] sha1_ce_finup+0x94/0x110 [sha1_ce] crypto_shash_finup+0x34/0xc0 hmac_finup+0x48/0xe0 crypto_shash_finup+0x34/0xc0 shash_digest_unaligned+0x74/0x90 crypto_shash_digest+0x4c/0x9c shash_ahash_digest+0xc8/0xf0 shash_async_digest+0x28/0x34 crypto_ahash_digest+0x48/0xcc crypto_authenc_genicv+0x88/0xcc [authenc] crypto_authenc_encrypt+0xd8/0xfc [authenc] crypto_aead_encrypt+0x2c/0x40 echainiv_encrypt+0x144/0x1a0 [echainiv] crypto_aead_encrypt+0x2c/0x40 esp6_output_tail+0x1c8/0x5d0 [esp6] esp6_output+0x120/0x278 [esp6] xfrm_output_one+0x458/0x4ec xfrm_output_resume+0x6c/0x1f0 xfrm_output+0xac/0x4ac __xfrm6_output+0x130/0x270 xfrm6_output+0x60/0xec ip6_xmit+0x2ec/0x5bc inet6_csk_xmit+0xbc/0x10c __tcp_transmit_skb+0x460/0x8c0 tcp_write_xmit+0x348/0x890 __tcp_push_pending_frames+0x44/0x110 tcp_push+0xb4/0x14c tcp_sendmsg_locked+0x71c/0xb64 tcp_sendmsg+0x40/0x6c inet6_sendmsg+0x4c/0x80 sock_sendmsg+0x5c/0x6c __sys_sendto+0x128/0x15c __arm64_sys_sendto+0x30/0x40 invoke_syscall+0x50/0x120 el0_svc_common.constprop.0+0x170/0x194 do_el0_svc+0x38/0x4c el0_svc+0x28/0xe0 el0t_64_sync_handler+0xbc/0x13c el0t_64_sync+0x180/0x184
Get softirq info by bcc tool:
./softirqs -NT 10
Tracing soft irq event time... Hit Ctrl-C to end.
15:34:34
SOFTIRQ TOTAL_nsecs
block 158990
timer 20030920
sched 46577080net_rx 676746820
tasklet 9906067650
15:34:45
SOFTIRQ TOTAL_nsecs
block 86100
sched 38849790net_rx 676532470
timer 1163848790
tasklet 9409019620
15:34:55
SOFTIRQ TOTAL_nsecs
sched 58078450net_rx 475156720
timer 533832410
tasklet 9431333300
The tasklet software interrupt takes too much time. Therefore, the xfrm_trans_reinject executor is changed from tasklet to workqueue. Add add spin lock to protect the queue. This reduces the processing flow of the tcp_sendmsg function in this scenario.
--- net/xfrm/xfrm_input.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-)
net/xfrm/xfrm_input.c +13 -5
@@ -24,7 +24,8 @@#include "xfrm_inout.h" struct xfrm_trans_tasklet { -struct tasklet_struct tasklet; +struct work_struct work; +spinlock_t queue_lock;struct sk_buff_head queue; };
@@ -760,18 +761,22 @@ int xfrm_input_resume(struct sk_buff *skb, int nexthdr) }EXPORT_SYMBOL (xfrm_input_resume); -static void xfrm_trans_reinject (struct tasklet_struct *t) +static void xfrm_trans_reinject (struct work_struct *work) { -struct xfrm_trans_tasklet *trans =from_tasklet (trans, t, tasklet); + struct xfrm_trans_tasklet *trans = container_of(work, struct xfrm_trans_tasklet, work);struct sk_buff_head queue;struct sk_buff *skb;__skb_queue_head_init (&queue); +spin_lock_bh (&trans->queue_lock);skb_queue_splice_init (&trans->queue, &queue); +spin_unlock_bh (&trans->queue_lock); +local_bh_disable ();while ((skb =__skb_dequeue (&queue)))XFRM_TRANS_SKB_CB (skb)->finish (XFRM_TRANS_SKB_CB (skb)->net,NULL , skb); +local_bh_enable (); } int xfrm_trans_queue_net(struct net *net, struct sk_buff *skb,
@@ -789,8 +794,10 @@ int xfrm_trans_queue_net(struct net *net, struct sk_buff *skb,XFRM_TRANS_SKB_CB (skb)->finish = finish;XFRM_TRANS_SKB_CB (skb)->net = net; +spin_lock_bh (&trans->queue_lock);__skb_queue_tail (&trans->queue, skb); -tasklet_schedule (&trans->tasklet); +spin_unlock_bh (&trans->queue_lock); +schedule_work (&trans->work);return 0 ; }EXPORT_SYMBOL (xfrm_trans_queue_net);
@@ -817,7 +824,8 @@ void __init xfrm_input_init(void)struct xfrm_trans_tasklet *trans; trans = &per_cpu (xfrm_trans_tasklet, i); +spin_lock_init (&trans->queue_lock);__skb_queue_head_init (&trans->queue); -tasklet_setup (&trans->tasklet, xfrm_trans_reinject); +INIT_WORK (&trans->work, xfrm_trans_reinject); } }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 192/530 netfilter: nft_fib: Fix for rpath check with VRF devices
In reply to Greg Kroah-HartmanFrom: Phil Sutter <[email protected]>
[ Upstream commit 2a8a7c0eaa8747c16aa4a48d573aa920d5c00a5c ]
Analogous to commit b575b24b8eee3 ("netfilter: Fix rpfilter dropping vrf packets by mistake") but for nftables fib expression:
Add special treatment of VRF devices so that typical reverse path filtering via 'fib saddr . iif oif' expression works as expected.
--- net/ipv4/netfilter/nft_fib_ipv4.c | 3 +++ net/ipv6/netfilter/nft_fib_ipv6.c | 6 +++++- 2 files changed, 8 insertions(+), 1 deletion(-)
net/ipv4/netfilter/nft_fib_ipv4.c +3 -0
@@ -83,6 +83,9 @@ void nft_fib4_eval(const struct nft_expr *expr, struct nft_regs *regs,else oif =NULL ; +if (priv->flags &NFTA_FIB_F_IIF ) + fl4.flowi4_oif =l3mdev_master_ifindex_rcu (oif); +if (nft_hook (pkt) ==NF_INET_PRE_ROUTING &&nft_fib_is_loopback (pkt->skb,nft_in (pkt))) {nft_fib_store_result (dest, priv,nft_in (pkt));
net/ipv6/netfilter/nft_fib_ipv6.c +5 -1
@@ -37,6 +37,9 @@ static int nft_fib6_flowi_init(struct flowi6 *fl6, const struct nft_fib *priv,if (ipv6_addr_type (&fl6->daddr) &IPV6_ADDR_LINKLOCAL ) { lookup_flags |=RT6_LOOKUP_F_IFACE ; fl6->flowi6_oif =get_ifindex (dev ? dev : pkt->skb->dev); + }else if ((priv->flags &NFTA_FIB_F_IIF ) && + (netif_is_l3_master (dev) ||netif_is_l3_slave (dev))) { + fl6->flowi6_oif = dev->ifindex; }if (ipv6_addr_type (&fl6->saddr) &IPV6_ADDR_UNICAST )
@@ -193,7 +196,8 @@ void nft_fib6_eval(const struct nft_expr *expr, struct nft_regs *regs,if (rt->rt6i_flags & (RTF_REJECT |RTF_ANYCAST |RTF_LOCAL )) goto put_rt_err; -if (oif && oif != rt->rt6i_idev->dev) +if (oif && oif != rt->rt6i_idev->dev && +l3mdev_master_ifindex_rcu (rt->rt6i_idev->dev) != oif->ifindex) goto put_rt_err;nft_fib_store_result (dest, priv, rt->rt6i_idev->dev);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 193/530 spi: s3c64xx: Fix large transfers with DMA
In reply to Greg Kroah-HartmanFrom: Vincent Whitchurch <[email protected]>
[ Upstream commit 1224e29572f655facfcd850cf0f0a4784f36a903 ]
The COUNT_VALUE in the PACKET_CNT register is 16-bit so the maximum value is 65535. Asking the driver to transfer a larger size currently leads to the DMA transfer timing out. Implement ->max_transfer_size() and have the core split the transfer as needed.
--- drivers/spi/spi-s3c64xx.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/spi/spi-s3c64xx.c +9 -0
@@ -85,6 +85,7 @@#define S3C64XX_SPI_ST_TX_FIFORDY (1<<0)#define S3C64XX_SPI_PACKET_CNT_EN (1<<16) +#define S3C64XX_SPI_PACKET_CNT_MASK GENMASK(15, 0)#define S3C64XX_SPI_PND_TX_UNDERRUN_CLR (1<<4)#define S3C64XX_SPI_PND_TX_OVERRUN_CLR (1<<3)
@@ -661,6 +662,13 @@ static int s3c64xx_spi_prepare_message(struct spi_master *master,return 0 ; } +static size_t s3c64xx_spi_max_transfer_size (struct spi_device *spi) +{ +struct spi_controller *ctlr = spi->controller; + +return ctlr->can_dma ?S3C64XX_SPI_PACKET_CNT_MASK :SIZE_MAX ; +} +static int s3c64xx_spi_transfer_one (struct spi_master *master,struct spi_device *spi,struct spi_transfer *xfer)
@@ -1130,6 +1138,7 @@ static int s3c64xx_spi_probe(struct platform_device *pdev) master->prepare_transfer_hardware = s3c64xx_spi_prepare_transfer; master->prepare_message = s3c64xx_spi_prepare_message; master->transfer_one = s3c64xx_spi_transfer_one; + master->max_transfer_size = s3c64xx_spi_max_transfer_size; master->num_chipselect = sci->num_cs; master->dma_alignment =8 ; master->bits_per_word_mask = SPI_BPW_MASK(32) | SPI_BPW_MASK(16) |
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 194/530 wifi: rtl8xxxu: Fix AIFS written to REG_EDCA_*_PARAM
In reply to Greg Kroah-HartmanFrom: Bitterblue Smith <[email protected]>
[ Upstream commit 5574d3290449916397f3092dcd2bac92415498e1 ]
ieee80211_tx_queue_params.aifs is not supposed to be written directly to the REG_EDCA_*_PARAM registers. Instead process it like the vendor drivers do. It's kinda hacky but it works.
This change boosts the download speed and makes it more stable.
Tested with RTL8188FU but all the other supported chips should also benefit.
--- .../wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+)
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +49 -0
@@ -4507,6 +4507,53 @@ rtl8xxxu_wireless_mode(struct ieee80211_hw *hw, struct ieee80211_sta *sta)return network_type; } +static void rtl8xxxu_set_aifs (struct rtl8xxxu_priv *priv,u8 slot_time) +{ +u32 reg_edca_param[IEEE80211_NUM_ACS ] = { + [IEEE80211_AC_VO ] =REG_EDCA_VO_PARAM , + [IEEE80211_AC_VI ] =REG_EDCA_VI_PARAM , + [IEEE80211_AC_BE ] =REG_EDCA_BE_PARAM , + [IEEE80211_AC_BK ] =REG_EDCA_BK_PARAM , + }; +u32 val32; +u16 wireless_mode =0 ; +u8 aifs, aifsn, sifs; +int i; + +if (priv->vif) { +struct ieee80211_sta *sta; + +rcu_read_lock (); + sta =ieee80211_find_sta (priv->vif, priv->vif->bss_conf.bssid); +if (sta) + wireless_mode =rtl8xxxu_wireless_mode (priv->hw, sta); +rcu_read_unlock (); + } + +if (priv->hw->conf.chandef.chan->band ==NL80211_BAND_5GHZ || + (wireless_mode &WIRELESS_MODE_N_24G )) + sifs =16 ; +else + sifs =10 ; + +for (i =0 ; i <IEEE80211_NUM_ACS ; i++) { + val32 =rtl8xxxu_read32 (priv, reg_edca_param[i]); + +/* It was set in conf_tx. */ + aifsn = val32 &0xff ; + +/* aifsn not set yet or already fixed */ +if (aifsn <2 || aifsn >15 ) +continue ; + + aifs = aifsn * slot_time + sifs; + + val32 &= ~0xff ; + val32 |= aifs; +rtl8xxxu_write32 (priv, reg_edca_param[i], val32); + } +} +static void rtl8xxxu_bss_info_changed (struct ieee80211_hw *hw,struct ieee80211_vif *vif,struct ieee80211_bss_conf *bss_conf,u32 changed)
@@ -4592,6 +4639,8 @@ rtl8xxxu_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,else val8 =20 ;rtl8xxxu_write8 (priv,REG_SLOT , val8); + +rtl8xxxu_set_aifs (priv, val8); }if (changed &BSS_CHANGED_BSSID ) {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 195/530 vhost/vsock: Use kvmalloc/kvfree for larger packets.
In reply to Greg Kroah-HartmanFrom: Junichi Uekawa <[email protected]>
[ Upstream commit 0e3f72931fc47bb81686020cc643cde5d9cd0bb8 ]
When copying a large file over sftp over vsock, data size is usually 32kB, and kmalloc seems to fail to try to allocate 32 32kB regions.
vhost-5837: page allocation failure: order:4, mode:0x24040c0
Call Trace: [<ffffffffb6a0df64>] dump_stack+0x97/0xdb [<ffffffffb68d6aed>] warn_alloc_failed+0x10f/0x138 [<ffffffffb68d868a>] ? __alloc_pages_direct_compact+0x38/0xc8 [<ffffffffb664619f>] __alloc_pages_nodemask+0x84c/0x90d [<ffffffffb6646e56>] alloc_kmem_pages+0x17/0x19 [<ffffffffb6653a26>] kmalloc_order_trace+0x2b/0xdb [<ffffffffb66682f3>] __kmalloc+0x177/0x1f7 [<ffffffffb66e0d94>] ? copy_from_iter+0x8d/0x31d [<ffffffffc0689ab7>] vhost_vsock_handle_tx_kick+0x1fa/0x301 [vhost_vsock] [<ffffffffc06828d9>] vhost_worker+0xf7/0x157 [vhost] [<ffffffffb683ddce>] kthread+0xfd/0x105 [<ffffffffc06827e2>] ? vhost_dev_set_owner+0x22e/0x22e [vhost] [<ffffffffb683dcd1>] ? flush_kthread_worker+0xf3/0xf3 [<ffffffffb6eb332e>] ret_from_fork+0x4e/0x80 [<ffffffffb683dcd1>] ? flush_kthread_worker+0xf3/0xf3
Work around by doing kvmalloc instead.
--- drivers/vhost/vsock.c | 2 +- net/vmw_vsock/virtio_transport_common.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
drivers/vhost/vsock.c +1 -1
@@ -393,7 +393,7 @@ vhost_vsock_alloc_pkt(struct vhost_virtqueue *vq,return NULL ; } - pkt->buf =kmalloc (pkt->len,GFP_KERNEL ); + pkt->buf =kvmalloc (pkt->len,GFP_KERNEL );if (!pkt->buf) {kfree (pkt);return NULL ;
net/vmw_vsock/virtio_transport_common.c +1 -1
@@ -1342,7 +1342,7 @@ EXPORT_SYMBOL_GPL(virtio_transport_recv_pkt);void virtio_transport_free_pkt (struct virtio_vsock_pkt *pkt) { -kfree (pkt->buf); +kvfree (pkt->buf);kfree (pkt); }EXPORT_SYMBOL_GPL (virtio_transport_free_pkt);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 196/530 eth: alx: take rtnl_lock on resume
In reply to Greg Kroah-HartmanFrom: Jakub Kicinski <[email protected]>
[ Upstream commit 6ad1c94e1e7e374d88f0cfd77936dddb8339aaba ]
Zbynek reports that alx trips an rtnl assertion on resume:
RTNL: assertion failed at net/core/dev.c (2891)
RIP: 0010:netif_set_real_num_tx_queues+0x1ac/0x1c0 Call Trace: <TASK> __alx_open+0x230/0x570 [alx] alx_resume+0x54/0x80 [alx] ? pci_legacy_resume+0x80/0x80 dpm_run_callback+0x4a/0x150 device_resume+0x8b/0x190 async_resume+0x19/0x30 async_run_entry_fn+0x30/0x130 process_one_work+0x1e5/0x3b0
indeed the driver does not hold rtnl_lock during its internal close and re-open functions during suspend/resume. Note that this is not a huge bug as the driver implements its own locking, and does not implement changing the number of queues, but we need to silence the splat.
--- drivers/net/ethernet/atheros/alx/main.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/net/ethernet/atheros/alx/main.c +5 -0
@@ -1912,11 +1912,14 @@ static int alx_suspend(struct device *dev)if (!netif_running (alx->dev))return 0 ; + +rtnl_lock ();netif_device_detach (alx->dev);mutex_lock (&alx->mtx);__alx_stop (alx);mutex_unlock (&alx->mtx); +rtnl_unlock ();return 0 ; }
@@ -1927,6 +1930,7 @@ static int alx_resume(struct device *dev)struct alx_hw *hw = &alx->hw;int err; +rtnl_lock ();mutex_lock (&alx->mtx);alx_reset_phy (hw);
@@ -1943,6 +1947,7 @@ static int alx_resume(struct device *dev) unlock:mutex_unlock (&alx->mtx); +rtnl_unlock ();return err; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 197/530 mISDN: fix use-after-free bugs in l1oip timer handlers
In reply to Greg Kroah-HartmanFrom: Duoming Zhou <[email protected]>
[ Upstream commit 2568a7e0832ee30b0a351016d03062ab4e0e0a3f ]
The l1oip_cleanup() traverses the l1oip_ilist and calls release_card() to cleanup module and stack. However, release_card() calls del_timer() to delete the timers such as keep_tl and timeout_tl. If the timer handler is running, the del_timer() will not stop it and result in UAF bugs. One of the processes is shown below:
(cleanup routine) | (timer handler)
release_card() | l1oip_timeout()
... |
del_timer() | ...
... |
kfree(hc) //FREE |
| hc->timeout_on = 0 //USEFix by calling del_timer_sync() in release_card(), which makes sure the timer handlers have finished before the resources, such as l1oip and so on, have been deallocated.
What's more, the hc->workq and hc->socket_thread can kick those timers right back in. We add a bool flag to show if card is released. Then, check this flag in hc->workq and hc->socket_thread.
--- drivers/isdn/mISDN/l1oip.h | 1 + drivers/isdn/mISDN/l1oip_core.c | 13 +++++++------ 2 files changed, 8 insertions(+), 6 deletions(-)
drivers/isdn/mISDN/l1oip.h +1 -0
@@ -59,6 +59,7 @@ struct l1oip {int bundle;/* bundle channels in one frm */ int codec;/* codec to use for transmis. */ int limit;/* limit number of bchannels */ +bool shutdown;/* if card is released */ /* timer */ struct timer_list keep_tl;
drivers/isdn/mISDN/l1oip_core.c +7 -6
@@ -275,7 +275,7 @@ l1oip_socket_send(struct l1oip *hc, u8 localcodec, u8 channel, u32 chanmask, p = frame;/* restart timer */ -if (time_before (hc->keep_tl.expires, jiffies +5 *HZ )) +if (time_before (hc->keep_tl.expires, jiffies +5 *HZ ) && !hc->shutdown)mod_timer (&hc->keep_tl, jiffies +L1OIP_KEEPALIVE *HZ );else hc->keep_tl.expires = jiffies +L1OIP_KEEPALIVE *HZ ;
@@ -601,7 +601,9 @@ l1oip_socket_parse(struct l1oip *hc, struct sockaddr_in *sin, u8 *buf, int len) goto multiframe;/* restart timer */ -if (time_before (hc->timeout_tl.expires, jiffies +5 *HZ ) || !hc->timeout_on) { +if ((time_before (hc->timeout_tl.expires, jiffies +5 *HZ ) || + !hc->timeout_on) && + !hc->shutdown) { hc->timeout_on =1 ;mod_timer (&hc->timeout_tl, jiffies +L1OIP_TIMEOUT *HZ ); }else /* only adjust timer */
@@ -1232,11 +1234,10 @@ release_card(struct l1oip *hc) {int ch; -if (timer_pending (&hc->keep_tl)) -del_timer (&hc->keep_tl); + hc->shutdown = true; -if (timer_pending (&hc->timeout_tl)) -del_timer (&hc->timeout_tl); +del_timer_sync (&hc->keep_tl); +del_timer_sync (&hc->timeout_tl);cancel_work_sync (&hc->workq);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 198/530 sctp: handle the error returned from sctp_auth_asoc_init_active_key
In reply to Greg Kroah-HartmanFrom: Xin Long <[email protected]>
[ Upstream commit 022152aaebe116a25c39818a07e175a8cd3c1e11 ]
When it returns an error from sctp_auth_asoc_init_active_key(), the active_key is actually not updated. The old sh_key will be freeed while it's still used as active key in asoc. Then an use-after-free will be triggered when sending patckets, as found by syzbot:
sctp_auth_shkey_hold+0x22/0xa0 net/sctp/auth.c:112 sctp_set_owner_w net/sctp/socket.c:132 [inline] sctp_sendmsg_to_asoc+0xbd5/0x1a20 net/sctp/socket.c:1863 sctp_sendmsg+0x1053/0x1d50 net/sctp/socket.c:2025 inet_sendmsg+0x99/0xe0 net/ipv4/af_inet.c:819 sock_sendmsg_nosec net/socket.c:714 [inline] sock_sendmsg+0xcf/0x120 net/socket.c:734
This patch is to fix it by not replacing the sh_key when it returns errors from sctp_auth_asoc_init_active_key() in sctp_auth_set_key(). For sctp_auth_set_active_key(), old active_key_id will be set back to asoc->active_key_id when the same thing happens.
--- net/sctp/auth.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-)
net/sctp/auth.c +14 -4
@@ -863,12 +863,17 @@ int sctp_auth_set_key(struct sctp_endpoint *ep, }list_del_init (&shkey->key_list); -sctp_auth_shkey_release (shkey);list_add (&cur_key->key_list, sh_keys); -if (asoc && asoc->active_key_id == auth_key->sca_keynumber) -sctp_auth_asoc_init_active_key (asoc,GFP_KERNEL ); +if (asoc && asoc->active_key_id == auth_key->sca_keynumber && +sctp_auth_asoc_init_active_key (asoc,GFP_KERNEL )) { +list_del_init (&cur_key->key_list); +sctp_auth_shkey_release (cur_key); +list_add (&shkey->key_list, sh_keys); +return -ENOMEM ; + } +sctp_auth_shkey_release (shkey);return 0 ; }
@@ -902,8 +907,13 @@ int sctp_auth_set_active_key(struct sctp_endpoint *ep,return -EINVAL ;if (asoc) { +__u16 active_key_id = asoc->active_key_id; + asoc->active_key_id = key_id; -sctp_auth_asoc_init_active_key (asoc,GFP_KERNEL ); +if (sctp_auth_asoc_init_active_key (asoc,GFP_KERNEL )) { + asoc->active_key_id = active_key_id; +return -ENOMEM ; + } }else ep->active_key_id = key_id;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 199/530 tcp: fix tcp_cwnd_validate() to not forget is_cwnd_limited
In reply to Greg Kroah-HartmanFrom: Neal Cardwell <[email protected]>
[ Upstream commit f4ce91ce12a7c6ead19b128ffa8cff6e3ded2a14 ]
This commit fixes a bug in the tracking of max_packets_out and is_cwnd_limited. This bug can cause the connection to fail to remember that is_cwnd_limited is true, causing the connection to fail to grow cwnd when it should, causing throughput to be lower than it should be.
The following event sequence is an example that triggers the bug:
(a) The connection is cwnd_limited, but packets_out is not at its peak due to TSO deferral deciding not to send another skb yet. In such cases the connection can advance max_packets_seq and set tp->is_cwnd_limited to true and max_packets_out to a small number.
(b) Then later in the round trip the connection is pacing-limited (not cwnd-limited), and packets_out is larger. In such cases the connection would raise max_packets_out to a bigger number but (unexpectedly) flip tp->is_cwnd_limited from true to false.
This commit fixes that bug.
One straightforward fix would be to separately track (a) the next window after max_packets_out reaches a maximum, and (b) the next window after tp->is_cwnd_limited is set to true. But this would require consuming an extra u32 sequence number.
Instead, to save space we track only the most important information. Specifically, we track the strongest available signal of the degree to which the cwnd is fully utilized:
(1) If the connection is cwnd-limited then we remember that fact for the current window.
(2) If the connection not cwnd-limited then we track the maximum number of outstanding packets in the current window.
In particular, note that the new logic cannot trigger the buggy (a)/(b) sequence above because with the new logic a condition where tp->packets_out > tp->max_packets_out can only trigger an update of tp->is_cwnd_limited if tp->is_cwnd_limited is false.
This first showed up in a testing of a BBRv2 dev branch, but this buggy behavior highlighted a general issue with the tcp_cwnd_validate() logic that can cause cwnd to fail to increase at the proper rate for any TCP congestion control, including Reno or CUBIC.
--- include/linux/tcp.h | 2 +- include/net/tcp.h | 5 ++++- net/ipv4/tcp.c | 2 ++ net/ipv4/tcp_output.c | 19 ++++++++++++------- 4 files changed, 19 insertions(+), 9 deletions(-)
include/linux/tcp.h +1 -1
@@ -265,7 +265,7 @@ struct tcp_sock {u32 packets_out;/* Packets which are "in flight" */ u32 retrans_out;/* Retransmitted packets out */ u32 max_packets_out;/* max packets_out in last window */ -u32 max_packets_seq;/* right edge of max_packets_out flight */ +u32 cwnd_usage_seq;/* right edge of cwnd usage tracking flight */ u16 urg_data;/* Saved octet of OOB data and control flags */ u8 ecn_flags;/* ECN status bits. */
include/net/tcp.h +4 -1
@@ -1281,11 +1281,14 @@ static inline bool tcp_is_cwnd_limited(const struct sock *sk) {const struct tcp_sock *tp =tcp_sk (sk); +if (tp->is_cwnd_limited) +return true; +/* If in slow start, ensure cwnd grows to twice what was ACKed. */ if (tcp_in_slow_start (tp))return tcp_snd_cwnd (tp) <2 * tp->max_packets_out; -return tp->is_cwnd_limited; +return false; }/* BBR congestion control needs pacing.
net/ipv4/tcp.c +2 -0
@@ -3025,6 +3025,8 @@ int tcp_disconnect(struct sock *sk, int flags) tp->snd_ssthresh =TCP_INFINITE_SSTHRESH ;tcp_snd_cwnd_set (tp,TCP_INIT_CWND ); tp->snd_cwnd_cnt =0 ; + tp->is_cwnd_limited =0 ; + tp->max_packets_out =0 ; tp->window_clamp =0 ; tp->delivered =0 ; tp->delivered_ce =0 ;
net/ipv4/tcp_output.c +12 -7
@@ -1878,15 +1878,20 @@ static void tcp_cwnd_validate(struct sock *sk, bool is_cwnd_limited)const struct tcp_congestion_ops *ca_ops =inet_csk (sk)->icsk_ca_ops;struct tcp_sock *tp =tcp_sk (sk); -/* Track the maximum number of outstanding packets in each -* window, and remember whether we were cwnd-limited then. +/* Track the strongest available signal of the degree to which the cwnd +* is fully utilized. If cwnd-limited then remember that fact for the +* current window. If not cwnd-limited then track the maximum number of +* outstanding packets in the current window. (If cwnd-limited then we +* chose to not update tp->max_packets_out to avoid an extra else +* clause with no functional impact.) */ -if (!before (tp->snd_una, tp->max_packets_seq) || - tp->packets_out > tp->max_packets_out || - is_cwnd_limited) { - tp->max_packets_out = tp->packets_out; - tp->max_packets_seq = tp->snd_nxt; +if (!before (tp->snd_una, tp->cwnd_usage_seq) || + is_cwnd_limited || + (!tp->is_cwnd_limited && + tp->packets_out > tp->max_packets_out)) { tp->is_cwnd_limited = is_cwnd_limited; + tp->max_packets_out = tp->packets_out; + tp->cwnd_usage_seq = tp->snd_nxt; }if (tcp_is_cwnd_limited (sk)) {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 200/530 spi: Ensure that sg_table wont be used after being freed
In reply to Greg Kroah-HartmanFrom: Marek Szyprowski <[email protected]>
[ Upstream commit 8e9204cddcc3fea9affcfa411715ba4f66e97587 ]
SPI code checks for non-zero sgt->orig_nents to determine if the buffer has been DMA-mapped. Ensure that sg_table is really zeroed after free to avoid potential NULL pointer dereference if the given SPI xfer object is reused again without being DMA-mapped.
--- drivers/spi/spi.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/spi/spi.c +2 -0
@@ -1007,6 +1007,8 @@ void spi_unmap_buf(struct spi_controller *ctlr, struct device *dev,if (sgt->orig_nents) {dma_unmap_sg (dev, sgt->sgl, sgt->orig_nents, dir);sg_free_table (sgt); + sgt->orig_nents =0 ; + sgt->nents =0 ; } }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 201/530 hwmon: (pmbus/mp2888) Fix sensors readouts for MPS Multi-phase mp2888 controller
In reply to Greg Kroah-HartmanFrom: Oleksandr Shamray <[email protected]>
[ Upstream commit 525dd5aed67a2f4f7278116fb92a24e6a53e2622 ]
Fix scale factors for reading MPS Multi-phase mp2888 controller. Fixed sensors:
- PIN/POUT: based on vendor documentation, set bscale factor 0.5W/LSB
- IOUT: based on vendor documentation, set scale factor 0.25 A/LSB
--- drivers/hwmon/pmbus/mp2888.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-)
drivers/hwmon/pmbus/mp2888.c +6 -7
@@ -34,7 +34,7 @@ struct mp2888_data {int curr_sense_gain; }; -#define to_mp2888_data (x) container_of(x, struct mp2888_data, info) +#define to_mp2888_data (x) container_of(x, struct mp2888_data, info)static int mp2888_read_byte_data (struct i2c_client *client,int page,int reg) {
@@ -109,7 +109,7 @@ mp2888_read_phase(struct i2c_client *client, struct mp2888_data *data, int page,* - Kcs is the DrMOS current sense gain of power stage, which is obtained from the * register MP2888_MFR_VR_CONFIG1, bits 13-12 with the following selection of DrMOS * (data->curr_sense_gain): -* 00b - 5µA/A, 01b - 8.5µA/A, 10b - 9.7µA/A, 11b - 10µA/A. +* 00b - 8.5µA/A, 01b - 9.7µA/A, 1b - 10µA/A, 11b - 5µA/A. * - Rcs is the internal phase current sense resistor. This parameter depends on hardware * assembly. By default it is set to 1kΩ. In case of different assembly, user should * scale this parameter by dividing it by Rcs.
@@ -118,10 +118,9 @@ mp2888_read_phase(struct i2c_client *client, struct mp2888_data *data, int page,* because sampling of current occurrence of bit weight has a big deviation, especially for * light load. */ - ret =DIV_ROUND_CLOSEST (ret *100 -9800 , data->curr_sense_gain); - ret = (data->phase_curr_resolution) ? ret *2 : ret; + ret =DIV_ROUND_CLOSEST (ret *200 -19600 , data->curr_sense_gain);/* Scale according to total current resolution. */ - ret = (data->total_curr_resolution) ? ret *8 : ret *4 ; + ret = (data->total_curr_resolution) ? ret *2 : ret;return ret; }
@@ -212,7 +211,7 @@ static int mp2888_read_word_data(struct i2c_client *client, int page, int phase, ret =pmbus_read_word_data (client, page, phase, reg);if (ret <0 )return ret; - ret = data->total_curr_resolution ? ret *2 : ret; + ret = data->total_curr_resolution ? ret :DIV_ROUND_CLOSEST (ret,2 );break ;case PMBUS_POUT_OP_WARN_LIMIT : ret =pmbus_read_word_data (client, page, phase, reg);
@@ -223,7 +222,7 @@ static int mp2888_read_word_data(struct i2c_client *client, int page, int phase,* set 1. Actual power is reported with 0.5W or 1W respectively resolution. Scaling * is needed to match both. */ - ret = data->total_curr_resolution ? ret *4 : ret *2 ; + ret = data->total_curr_resolution ? ret *2 : ret;break ;/* * The below registers are not implemented by device or implemented not according to the
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 202/530 net: rds: dont hold sock lock when cancelling work from rds_tcp_reset_callbacks()
In reply to Greg Kroah-HartmanFrom: Tetsuo Handa <[email protected]>
[ Upstream commit a91b750fd6629354460282bbf5146c01b05c4859 ]
syzbot is reporting lockdep warning at rds_tcp_reset_callbacks() [1], for commit ac3615e7f3cffe2a ("RDS: TCP: Reduce code duplication in rds_tcp_reset_callbacks()") added cancel_delayed_work_sync() into a section protected by lock_sock() without realizing that rds_send_xmit() might call lock_sock().
We don't need to protect cancel_delayed_work_sync() using lock_sock(), for even if rds_{send,recv}_worker() re-queued this work while __flush_work()
from cancel_delayed_work_sync() was waiting for this work to complete,
retried rds_{send,recv}_worker() is no-op due to the absence of RDS_CONN_UP bit.
--- net/rds/tcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/rds/tcp.c +1 -1
@@ -166,10 +166,10 @@ void rds_tcp_reset_callbacks(struct socket *sock,*/ atomic_set (&cp->cp_state,RDS_CONN_RESETTING );wait_event (cp->cp_waitq, !test_bit (RDS_IN_XMIT , &cp->cp_flags)); -lock_sock (osock->sk);/* reset receive side state for rds_tcp_data_recv() for osock */ cancel_delayed_work_sync (&cp->cp_send_w);cancel_delayed_work_sync (&cp->cp_recv_w); +lock_sock (osock->sk);if (tc->t_tinc) {rds_inc_put (&tc->t_tinc->ti_inc); tc->t_tinc =NULL ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 203/530 bnx2x: fix potential memory leak in bnx2x_tpa_stop()
In reply to Greg Kroah-HartmanFrom: Jianglei Nie <[email protected]>
[ Upstream commit b43f9acbb8942b05252be83ac25a81cec70cc192 ]
bnx2x_tpa_stop() allocates a memory chunk from new_data with bnx2x_frag_alloc(). The new_data should be freed when gets some error. But when "pad + len > fp->rx_buf_size" is true, bnx2x_tpa_stop() returns without releasing the new_data, which will lead to a memory leak.
We should free the new_data with bnx2x_frag_free() when "pad + len > fp->rx_buf_size" is true.
--- drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +1 -0
@@ -788,6 +788,7 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp,BNX2X_ERR ("skb_put is about to fail... pad %d len %d rx_buf_size %d\n" , pad, len, fp->rx_buf_size);bnx2x_panic (); +bnx2x_frag_free (fp, new_data); return; }#endif
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 204/530 net: wwan: iosm: Call mutex_init before locking it
In reply to Greg Kroah-HartmanFrom: Maxim Mikityanskiy <[email protected]>
[ Upstream commit ba0fbdb95da5ddd8db457ce6ba09d16dd979a294 ]
wwan_register_ops calls wwan_create_default_link, which ends up in the ipc_wwan_newlink callback that locks ipc_wwan->if_mutex. However, this mutex is not yet initialized by that point. Fix it by moving mutex_init above the wwan_register_ops call. This also makes the order of operations in ipc_wwan_init symmetric to ipc_wwan_deinit.
--- drivers/net/wwan/iosm/iosm_ipc_wwan.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/net/wwan/iosm/iosm_ipc_wwan.c +3 -2
@@ -322,15 +322,16 @@ struct iosm_wwan *ipc_wwan_init(struct iosm_imem *ipc_imem, struct device *dev) ipc_wwan->dev = dev; ipc_wwan->ipc_imem = ipc_imem; +mutex_init (&ipc_wwan->if_mutex); +/* WWAN core will create a netdev for the default IP MUX channel */ if (wwan_register_ops (ipc_wwan->dev, &iosm_wwan_ops, ipc_wwan,IP_MUX_SESSION_DEFAULT )) { +mutex_destroy (&ipc_wwan->if_mutex);kfree (ipc_wwan);return NULL ; } -mutex_init (&ipc_wwan->if_mutex); -return ipc_wwan; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 205/530 net/ieee802154: reject zero-sized raw_sendmsg()
In reply to Greg Kroah-HartmanFrom: Tetsuo Handa <[email protected]>
[ Upstream commit 3a4d061c699bd3eedc80dc97a4b2a2e1af83c6f5 ]
syzbot is hitting skb_assert_len() warning at raw_sendmsg() for ieee802154 socket. What commit dc633700f00f726e ("net/af_packet: check len when min_header_len equals to 0") does also applies to ieee802154 socket.
--- net/ieee802154/socket.c | 3 +++ 1 file changed, 3 insertions(+)
net/ieee802154/socket.c +3 -0
@@ -251,6 +251,9 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t size)return -EOPNOTSUPP ; } +if (!size) +return -EINVAL ; +lock_sock (sk);if (!sk->sk_bound_dev_if) dev =dev_getfirstbyhwtype (sock_net (sk),ARPHRD_IEEE802154 );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 206/530 once: add DO_ONCE_SLOW() for sleepable contexts
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit 62c07983bef9d3e78e71189441e1a470f0d1e653 ]
Christophe Leroy reported a ~80ms latency spike
happening at first TCP connect() time.
This is because __inet_hash_connect() uses get_random_once()
to populate a perturbation table which became quite big
after commit 4c2c8f03a5ab ("tcp: increase source port perturb table to 2^16")
get_random_once() uses DO_ONCE(), which block hard irqs for the duration of the operation.
This patch adds DO_ONCE_SLOW() which uses a mutex instead of a spinlock for operations where we prefer to stay in process context.
Then __inet_hash_connect() can use get_random_slow_once() to populate its perturbation table.
--- include/linux/once.h | 28 ++++++++++++++++++++++++++++ lib/once.c | 30 ++++++++++++++++++++++++++++++ net/ipv4/inet_hashtables.c | 4 ++-- 3 files changed, 60 insertions(+), 2 deletions(-)
include/linux/once.h +28 -0
@@ -5,10 +5,18 @@#include <linux/types.h> #include <linux/jump_label.h> +/* Helpers used from arbitrary contexts. +* Hard irqs are blocked, be cautious. +*/ bool __do_once_start (bool *done,unsigned long *flags);void __do_once_done (bool *done,struct static_key_true *once_key,unsigned long *flags,struct module *mod); +/* Variant for process contexts only. */ +bool __do_once_slow_start (bool *done); +void __do_once_slow_done (bool *done,struct static_key_true *once_key, +struct module *mod); +/* Call a function exactly once. The idea of DO_ONCE() is to perform * a function call such as initialization of random seeds, etc, only * once, where DO_ONCE() can live in the fast-path. After @func has
@@ -52,9 +60,29 @@ void __do_once_done(bool *done, struct static_key_true *once_key, ___ret; \ }) +/* Variant of DO_ONCE() for process/sleepable contexts. */ +#define DO_ONCE_SLOW (func, ...) \ + ({ \ + bool ___ret = false; \ + static bool __section(".data.once") ___done = false; \ + static DEFINE_STATIC_KEY_TRUE(___once_key); \ + if (static_branch_unlikely(&___once_key)) { \ + ___ret = __do_once_slow_start(&___done); \ + if (unlikely(___ret)) { \ + func(__VA_ARGS__); \ + __do_once_slow_done(&___done, &___once_key, \ + THIS_MODULE); \ + } \ + } \ + ___ret; \ + }) +#define get_random_once (buf, nbytes) \ DO_ONCE(get_random_bytes, (buf), (nbytes))#define get_random_once_wait (buf, nbytes) \ DO_ONCE(get_random_bytes_wait, (buf), (nbytes)) \ +#define get_random_slow_once (buf, nbytes) \ + DO_ONCE_SLOW(get_random_bytes, (buf), (nbytes)) +#endif /* _LINUX_ONCE_H */
lib/once.c +30 -0
@@ -66,3 +66,33 @@ void __do_once_done(bool *done, struct static_key_true *once_key,once_disable_jump (once_key, mod); }EXPORT_SYMBOL (__do_once_done); + +static DEFINE_MUTEX (once_mutex); + +bool __do_once_slow_start (bool *done) +__acquires (once_mutex) +{ +mutex_lock (&once_mutex); +if (*done) { +mutex_unlock (&once_mutex); +/* Keep sparse happy by restoring an even lock count on +* this mutex. In case we return here, we don't call into +* __do_once_done but return early in the DO_ONCE_SLOW() macro. +*/ +__acquire (once_mutex); +return false; + } + +return true; +} +EXPORT_SYMBOL (__do_once_slow_start); + +void __do_once_slow_done (bool *done,struct static_key_true *once_key, +struct module *mod) +__releases (once_mutex) +{ + *done = true; +mutex_unlock (&once_mutex); +once_disable_jump (once_key, mod); +} +EXPORT_SYMBOL (__do_once_slow_done);
net/ipv4/inet_hashtables.c +2 -2
@@ -771,8 +771,8 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row,if (likely (remaining >1 )) remaining &= ~1U ; -net_get_random_once (table_perturb, -INET_TABLE_PERTURB_SIZE *sizeof (*table_perturb)); +get_random_slow_once (table_perturb, +INET_TABLE_PERTURB_SIZE *sizeof (*table_perturb)); index = port_offset & (INET_TABLE_PERTURB_SIZE -1 ); offset =READ_ONCE (table_perturb[index]) + (port_offset >>32 );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 207/530 net: mvpp2: fix mvpp2 debugfs leak
In reply to Greg Kroah-HartmanFrom: Russell King (Oracle) <[email protected]>
[ Upstream commit 0152dfee235e87660f52a117fc9f70dc55956bb4 ]
When mvpp2 is unloaded, the driver specific debugfs directory is not removed, which technically leads to a memory leak. However, this directory is only created when the first device is probed, so the hardware is present. Removing the module is only something a developer would to when e.g. testing out changes, so the module would be reloaded. So this memory leak is minor.
The original attempt in commit fe2c9c61f668 ("net: mvpp2: debugfs: fix memory leak when using debugfs_lookup()") that was labelled as a memory leak fix was not, it fixed a refcount leak, but in doing so created a problem when the module is reloaded - the directory already exists, but mvpp2_root is NULL, so we lose all debugfs entries. This fix has been reverted.
This is the alternative fix, where we remove the offending directory whenever the driver is unloaded.
--- drivers/net/ethernet/marvell/mvpp2/mvpp2.h | 1 + drivers/net/ethernet/marvell/mvpp2/mvpp2_debugfs.c | 10 ++++++++-- drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 13 ++++++++++++- 3 files changed, 21 insertions(+), 3 deletions(-)
drivers/net/ethernet/marvell/mvpp2/mvpp2.h +1 -0
@@ -1529,6 +1529,7 @@ u32 mvpp2_read(struct mvpp2 *priv, u32 offset);void mvpp2_dbgfs_init (struct mvpp2 *priv,const char *name);void mvpp2_dbgfs_cleanup (struct mvpp2 *priv); +void mvpp2_dbgfs_exit (void );void mvpp23_rx_fifo_fc_en (struct mvpp2 *priv,int port,bool en);
drivers/net/ethernet/marvell/mvpp2/mvpp2_debugfs.c +8 -2
@@ -691,6 +691,13 @@ static int mvpp2_dbgfs_port_init(struct dentry *parent,return 0 ; } +static struct dentry *mvpp2_root; + +void mvpp2_dbgfs_exit (void ) +{ +debugfs_remove (mvpp2_root); +} +void mvpp2_dbgfs_cleanup (struct mvpp2 *priv) {debugfs_remove_recursive (priv->dbgfs_dir);
@@ -700,10 +707,9 @@ void mvpp2_dbgfs_cleanup(struct mvpp2 *priv)void mvpp2_dbgfs_init (struct mvpp2 *priv,const char *name) { -struct dentry *mvpp2_dir, *mvpp2_root; +struct dentry *mvpp2_dir;int ret, i; - mvpp2_root =debugfs_lookup (MVPP2_DRIVER_NAME ,NULL );if (!mvpp2_root) mvpp2_root =debugfs_create_dir (MVPP2_DRIVER_NAME ,NULL );
drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +12 -1
@@ -7710,7 +7710,18 @@ static struct platform_driver mvpp2_driver = { }, }; -module_platform_driver (mvpp2_driver); +static int __init mvpp2_driver_init (void ) +{ +return platform_driver_register (&mvpp2_driver); +} +module_init (mvpp2_driver_init); + +static void __exit mvpp2_driver_exit(void) +{ +platform_driver_unregister (&mvpp2_driver); +mvpp2_dbgfs_exit (); +} +module_exit (mvpp2_driver_exit);MODULE_DESCRIPTION ("Marvell PPv2 Ethernet Driver - www.marvell.com" );MODULE_AUTHOR ("Marcin Wojtas <[email protected]>" );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 208/530 drm: bridge: adv7511: fix CEC power down control register offset
In reply to Greg Kroah-HartmanFrom: Alvin Šipraga <[email protected]>
[ Upstream commit 1d22b6033ea113a4c3850dfa2c0770885c81aec8 ]
The ADV7511_REG_CEC_CTRL = 0xE2 register is part of the main register map - not the CEC register map. As such, we shouldn't apply an offset to the register address. Doing so will cause us to address a bogus register for chips with a CEC register map offset (e.g. ADV7533).
--- drivers/gpu/drm/bridge/adv7511/adv7511.h | 5 +---- drivers/gpu/drm/bridge/adv7511/adv7511_cec.c | 4 ++-- 2 files changed, 3 insertions(+), 6 deletions(-)
drivers/gpu/drm/bridge/adv7511/adv7511.h +1 -4
@@ -387,10 +387,7 @@ void adv7511_cec_irq_process(struct adv7511 *adv7511, unsigned int irq1);#else static inline int adv7511_cec_init (struct device *dev,struct adv7511 *adv7511) { -unsigned int offset = adv7511->type ==ADV7533 ? -ADV7533_REG_CEC_OFFSET :0 ; - -regmap_write (adv7511->regmap,ADV7511_REG_CEC_CTRL + offset, +regmap_write (adv7511->regmap,ADV7511_REG_CEC_CTRL ,ADV7511_CEC_CTRL_POWER_DOWN );return 0 ; }
drivers/gpu/drm/bridge/adv7511/adv7511_cec.c +2 -2
@@ -316,7 +316,7 @@ int adv7511_cec_init(struct device *dev, struct adv7511 *adv7511) goto err_cec_alloc; } -regmap_write (adv7511->regmap,ADV7511_REG_CEC_CTRL + offset,0 ); +regmap_write (adv7511->regmap,ADV7511_REG_CEC_CTRL ,0 );/* cec soft reset */ regmap_write (adv7511->regmap_cec,ADV7511_REG_CEC_SOFT_RESET + offset,0x01 );
@@ -343,7 +343,7 @@ int adv7511_cec_init(struct device *dev, struct adv7511 *adv7511)dev_info (dev,"Initializing CEC failed with error %d, disabling CEC\n" , ret); err_cec_parse_dt: -regmap_write (adv7511->regmap,ADV7511_REG_CEC_CTRL + offset, +regmap_write (adv7511->regmap,ADV7511_REG_CEC_CTRL ,ADV7511_CEC_CTRL_POWER_DOWN );return ret == -EPROBE_DEFER ? ret :0 ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 209/530 drm: bridge: adv7511: unregister cec i2c device after cec adapter
In reply to Greg Kroah-HartmanFrom: Alvin Šipraga <[email protected]>
[ Upstream commit 40cdb02cb9f965732eb543d47f15bef8d10f0f5f ]
cec_unregister_adapter() assumes that the underlying adapter ops are callable. For example, if the CEC adapter currently has a valid physical address, then the unregistration procedure will invalidate the physical address by setting it to f.f.f.f. Whence the following kernel oops observed after removing the adv7511 module:
Unable to handle kernel execution of user memory at virtual address 0000000000000000
Internal error: Oops: 86000004 [#1] PREEMPT_RT SMP
Call trace:
0x0
adv7511_cec_adap_log_addr+0x1ac/0x1c8 [adv7511]
cec_adap_unconfigure+0x44/0x90 [cec]
__cec_s_phys_addr.part.0+0x68/0x230 [cec]
__cec_s_phys_addr+0x40/0x50 [cec]
cec_unregister_adapter+0xb4/0x118 [cec]
adv7511_remove+0x60/0x90 [adv7511]
i2c_device_remove+0x34/0xe0
device_release_driver_internal+0x114/0x1f0
driver_detach+0x54/0xe0
bus_remove_driver+0x60/0xd8
driver_unregister+0x34/0x60
i2c_del_driver+0x2c/0x68
adv7511_exit+0x1c/0x67c [adv7511]
__arm64_sys_delete_module+0x154/0x288
invoke_syscall+0x48/0x100
el0_svc_common.constprop.0+0x48/0xe8
do_el0_svc+0x28/0x88
el0_svc+0x1c/0x50
el0t_64_sync_handler+0xa8/0xb0
el0t_64_sync+0x15c/0x160
Code: bad PC value
---[ end trace 0000000000000000 ]---Protect against this scenario by unregistering i2c_cec after unregistering the CEC adapter. Duly disable the CEC clock afterwards too.
--- drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +2 -2
@@ -1326,8 +1326,6 @@ static int adv7511_remove(struct i2c_client *i2c)if (adv7511->type ==ADV7533 || adv7511->type ==ADV7535 )adv7533_detach_dsi (adv7511); -i2c_unregister_device (adv7511->i2c_cec); -clk_disable_unprepare (adv7511->cec_clk);adv7511_uninit_regulators (adv7511);
@@ -1336,6 +1334,8 @@ static int adv7511_remove(struct i2c_client *i2c)adv7511_audio_exit (adv7511);cec_unregister_adapter (adv7511->cec_adap); +i2c_unregister_device (adv7511->i2c_cec); +clk_disable_unprepare (adv7511->cec_clk);i2c_unregister_device (adv7511->i2c_packet);i2c_unregister_device (adv7511->i2c_edid);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 210/530 drm/bridge: Avoid uninitialized variable warning
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit 7d1202738efda60155d98b370b3c70d336be0eea ]
This code works, but technically it uses "num_in_bus_fmts" before it has been initialized so it leads to static checker warnings and probably KMEMsan warnings at run time. Initialize the variable to zero to silence the warning.
--- drivers/gpu/drm/drm_bridge.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/drm_bridge.c +2 -2
@@ -762,8 +762,8 @@ static int select_bus_fmt_recursive(struct drm_bridge *first_bridge, struct drm_connector_state *conn_state, u32 out_bus_fmt) { +unsigned int i, num_in_bus_fmts =0 ;struct drm_bridge_state *cur_state; -unsigned int num_in_bus_fmts, i;struct drm_bridge *prev_bridge;u32 *in_bus_fmts;int ret;
@@ -884,7 +884,7 @@ drm_atomic_bridge_chain_select_bus_fmts(struct drm_bridge *bridge,struct drm_connector *conn = conn_state->connector;struct drm_encoder *encoder = bridge->encoder;struct drm_bridge_state *last_bridge_state; -unsigned int i, num_out_bus_fmts; +unsigned int i, num_out_bus_fmts =0 ;struct drm_bridge *last_bridge;u32 *out_bus_fmts;int ret =0 ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 211/530 drm/mipi-dsi: Detach devices when removing the host
In reply to Greg Kroah-HartmanFrom: Maxime Ripard <[email protected]>
[ Upstream commit 668a8f17b5290d04ef7343636a5588a0692731a1 ]
Whenever the MIPI-DSI host is unregistered, the code of mipi_dsi_host_unregister() loops over every device currently found on that bus and will unregister it.
However, it doesn't detach it from the bus first, which leads to all kind of resource leaks if the host wants to perform some clean up whenever a device is detached.
--- drivers/gpu/drm/drm_mipi_dsi.c | 1 + 1 file changed, 1 insertion(+)
drivers/gpu/drm/drm_mipi_dsi.c +1 -0
@@ -300,6 +300,7 @@ static int mipi_dsi_remove_device_fn(struct device *dev, void *priv) {struct mipi_dsi_device *dsi =to_mipi_dsi_device (dev); +mipi_dsi_detach (dsi);mipi_dsi_device_unregister (dsi);return 0 ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 212/530 drm/virtio: Correct drm_gem_shmem_get_sg_table() error handling
In reply to Greg Kroah-HartmanFrom: Dmitry Osipenko <[email protected]>
[ Upstream commit 64b88afbd92fbf434759d1896a7cf705e1c00e79 ]
Previous commit fixed checking of the ERR_PTR value returned by drm_gem_shmem_get_sg_table(), but it missed to zero out the shmem->pages, which will crash virtio_gpu_cleanup_object(). Add the missing zeroing of the shmem->pages.
--- drivers/gpu/drm/virtio/virtgpu_object.c | 1 + 1 file changed, 1 insertion(+)
drivers/gpu/drm/virtio/virtgpu_object.c +1 -0
@@ -169,6 +169,7 @@ static int virtio_gpu_object_shmem_init(struct virtio_gpu_device *vgdev, shmem->pages =drm_gem_shmem_get_sg_table (&bo->base);if (IS_ERR (shmem->pages)) {drm_gem_shmem_unpin (&bo->base); + shmem->pages =NULL ;return PTR_ERR (shmem->pages); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 213/530 drm/bridge: parade-ps8640: Fix regulator supply order
In reply to Greg Kroah-HartmanFrom: Chen-Yu Tsai <[email protected]>
[ Upstream commit fc94224c2e0ae8d83ac511a3ef4962178505469d ]
The datasheet says that VDD12 must be enabled and at full voltage before VDD33 is enabled.
Reorder the bulk regulator supply names so that VDD12 is enabled before VDD33. Any enable ramp delays should be handled by setting proper constraints on the regulators.
--- drivers/gpu/drm/bridge/parade-ps8640.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/bridge/parade-ps8640.c +2 -2
@@ -333,8 +333,8 @@ static int ps8640_probe(struct i2c_clienif (IS_ERR (ps_bridge->panel_bridge))return PTR_ERR (ps_bridge->panel_bridge); - ps_bridge->supplies[0 ].supply ="vdd33" ; - ps_bridge->supplies[1 ].supply ="vdd12" ; + ps_bridge->supplies[0 ].supply ="vdd12" ; + ps_bridge->supplies[1 ].supply ="vdd33" ; ret =devm_regulator_bulk_get (dev,ARRAY_SIZE (ps_bridge->supplies), ps_bridge->supplies);if (ret)
Greg Kroah-Hartman
maintainerPATCH 214/530 drm/dp_mst: fix drm_dp_dpcd_read return value checks
In reply to Greg Kroah-HartmanFrom: Simon Ser <[email protected]>
[ Upstream commit 2ac6cdd581f48c8f68747156fde5868486a44985 ]
drm_dp_dpcd_read returns the number of bytes read. The previous code would print garbage on DPCD error, and would exit with on error on success.
--- drivers/gpu/drm/drm_dp_mst_topology.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/gpu/drm/drm_dp_mst_topology.c +3 -3
@@ -4899,14 +4899,14 @@ void drm_dp_mst_dump_topology(struct seq_file *m,seq_printf (m,"dpcd: %*ph\n" ,DP_RECEIVER_CAP_SIZE , buf); ret =drm_dp_dpcd_read (mgr->aux,DP_FAUX_CAP , buf,2 ); -if (ret) { +if (ret !=2 ) {seq_printf (m,"faux/mst read failed\n" ); goto out; }seq_printf (m,"faux/mst: %*ph\n" ,2 , buf); ret =drm_dp_dpcd_read (mgr->aux,DP_MSTM_CTRL , buf,1 ); -if (ret) { +if (ret !=1 ) {seq_printf (m,"mst ctrl read failed\n" ); goto out; }
@@ -4914,7 +4914,7 @@ void drm_dp_mst_dump_topology(struct seq_file *m,/* dump the standard OUI branch header */ ret =drm_dp_dpcd_read (mgr->aux,DP_BRANCH_OUI , buf,DP_BRANCH_OUI_HEADER_SIZE ); -if (ret) { +if (ret !=DP_BRANCH_OUI_HEADER_SIZE ) {seq_printf (m,"branch oui read failed\n" ); goto out; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 215/530 drm:pl111: Add of_node_put() when breaking out of for_each_available_child_of_node()
In reply to Greg Kroah-HartmanFrom: Liang He <[email protected]>
[ Upstream commit e0686dc6f2252e009c455fe99e2ce9d62a60eb47 ]
The reference 'child' in the iteration of for_each_available_child_of_node() is only escaped out into a local variable which is only used to check its value. So we still need to the of_node_put() when breaking of the for_each_available_child_of_node() which will automatically increase and decrease the refcount.
--- drivers/gpu/drm/pl111/pl111_versatile.c | 1 + 1 file changed, 1 insertion(+)
drivers/gpu/drm/pl111/pl111_versatile.c +1 -0
@@ -402,6 +402,7 @@ static int pl111_vexpress_clcd_init(struct device *dev, struct device_node *np,if (of_device_is_compatible (child,"arm,pl111" )) { has_coretile_clcd = true; ct_clcd = child; +of_node_put (child);break ; }if (of_device_is_compatible (child,"arm,hdlcd" )) {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 216/530 ASoC: mt6359: fix tests for platform_get_irq() failure
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit 51eea3a6fb4d39c2cc71824e6eee5949d7ae4d1c ]
The platform_get_irq() returns negative error codes. It can't actually return zero, but if it did that should be treated as success.
--- sound/soc/codecs/mt6359-accdet.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
sound/soc/codecs/mt6359-accdet.c +3 -3
@@ -965,7 +965,7 @@ static int mt6359_accdet_probe(struct platform_device *pdev)mutex_init (&priv->res_lock); priv->accdet_irq =platform_get_irq (pdev,0 ); -if (priv->accdet_irq) { +if (priv->accdet_irq >=0 ) { ret = devm_request_threaded_irq(&pdev->dev, priv->accdet_irq, NULL, mt6359_accdet_irq, IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
@@ -979,7 +979,7 @@ static int mt6359_accdet_probe(struct platform_device *pdev)if (priv->caps &ACCDET_PMIC_EINT0 ) { priv->accdet_eint0 =platform_get_irq (pdev,1 ); -if (priv->accdet_eint0) { +if (priv->accdet_eint0 >=0 ) { ret = devm_request_threaded_irq(&pdev->dev, priv->accdet_eint0, NULL, mt6359_accdet_irq,
@@ -994,7 +994,7 @@ static int mt6359_accdet_probe(struct platform_device *pdev) } }else if (priv->caps &ACCDET_PMIC_EINT1 ) { priv->accdet_eint1 =platform_get_irq (pdev,2 ); -if (priv->accdet_eint1) { +if (priv->accdet_eint1 >=0 ) { ret = devm_request_threaded_irq(&pdev->dev, priv->accdet_eint1, NULL, mt6359_accdet_irq,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 217/530 platform/chrome: fix double-free in chromeos_laptop_prepare()
In reply to Greg Kroah-HartmanFrom: Rustam Subkhankulov <[email protected]>
[ Upstream commit 6ad4194d6a1e1d11b285989cd648ef695b4a93c0 ]
If chromeos_laptop_prepare_i2c_peripherals() fails after allocating memory for 'cros_laptop->i2c_peripherals', this memory is freed at 'err_out' label and nonzero value is returned. Then chromeos_laptop_destroy() is called, resulting in double-free error.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
--- drivers/platform/chrome/chromeos_laptop.c | 24 ++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-)
drivers/platform/chrome/chromeos_laptop.c +13 -11
@@ -740,6 +740,7 @@ static int __init chromeos_laptop_prepare_i2c_peripherals(struct chromeos_laptop *cros_laptop, const struct chromeos_laptop *src) { + struct i2c_peripheral *i2c_peripherals;struct i2c_peripheral *i2c_dev;struct i2c_board_info *info;int i;
@@ -748,17 +749,15 @@ chromeos_laptop_prepare_i2c_peripherals(struct chromeos_laptop *cros_laptop,if (!src->num_i2c_peripherals)return 0 ; - cros_laptop->i2c_peripherals =kmemdup (src->i2c_peripherals, - src->num_i2c_peripherals * -sizeof (*src->i2c_peripherals), -GFP_KERNEL ); -if (!cros_laptop->i2c_peripherals) + i2c_peripherals =kmemdup (src->i2c_peripherals, + src->num_i2c_peripherals * +sizeof (*src->i2c_peripherals), +GFP_KERNEL ); +if (!i2c_peripherals)return -ENOMEM ; - cros_laptop->num_i2c_peripherals = src->num_i2c_peripherals; - -for (i =0 ; i < cros_laptop->num_i2c_peripherals; i++) { - i2c_dev = &cros_laptop->i2c_peripherals[i]; +for (i =0 ; i < src->num_i2c_peripherals; i++) { + i2c_dev = &i2c_peripherals[i]; info = &i2c_dev->board_info; error =chromeos_laptop_setup_irq (i2c_dev);
@@ -775,16 +774,19 @@ chromeos_laptop_prepare_i2c_peripherals(struct chromeos_laptop *cros_laptop, } } + cros_laptop->i2c_peripherals = i2c_peripherals; + cros_laptop->num_i2c_peripherals = src->num_i2c_peripherals; +return 0 ; err_out:while (--i >=0 ) { - i2c_dev = &cros_laptop->i2c_peripherals[i]; + i2c_dev = &i2c_peripherals[i]; info = &i2c_dev->board_info;if (!IS_ERR_OR_NULL (info->fwnode))fwnode_remove_software_node (info->fwnode); } -kfree (cros_laptop->i2c_peripherals); +kfree (i2c_peripherals);return error; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 218/530 platform/chrome: fix memory corruption in ioctl
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit 8a07b45fd3c2dda24fad43639be5335a4595196a ]
If "s_mem.bytes" is larger than the buffer size it leads to memory corruption.
--- drivers/platform/chrome/cros_ec_chardev.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/platform/chrome/cros_ec_chardev.c +3 -0
@@ -327,6 +327,9 @@ static long cros_ec_chardev_ioctl_readmem(struct cros_ec_dev *ec,if (copy_from_user (&s_mem, arg,sizeof (s_mem)))return -EFAULT ; +if (s_mem.bytes >sizeof (s_mem.buffer)) +return -EINVAL ; + num = ec_dev->cmd_readmem (ec_dev, s_mem.offset, s_mem.bytes, s_mem.buffer);if (num <=0 )
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 219/530 ASoC: tas2764: Allow mono streams
In reply to Greg Kroah-HartmanFrom: Martin Povišer <[email protected]>
[ Upstream commit 23204d928a27146d13e11c9383632775345ecca8 ]
The part is a mono speaker amp, but it can do downmix and switch between left and right channel, so the right channel range is 1 to 2.
(This mirrors commit bf54d97a835d ("ASoC: tas2770: Allow mono streams") which was a fix to the tas2770 driver.)
--- sound/soc/codecs/tas2764.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/soc/codecs/tas2764.c +1 -1
@@ -485,7 +485,7 @@ static struct snd_soc_dai_driver tas2764_dai_driver[] = { .id = 0, .playback = { .stream_name = "ASI1 Playback", - .channels_min = 2, + .channels_min = 1, .channels_max = 2, .rates = TAS2764_RATES, .formats = TAS2764_FORMATS,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 220/530 ASoC: tas2764: Drop conflicting set_bias_level power setting
In reply to Greg Kroah-HartmanFrom: Martin Povišer <[email protected]>
[ Upstream commit 09273f38832406db19a8907a934687cc10660a6b ]
The driver is setting the PWR_CTRL field in both the set_bias_level callback and on DAPM events of the DAC widget (and also in the mute_stream method). Drop the set_bias_level callback altogether as the power setting it does is in conflict with the other code paths.
(This mirrors commit c8a6ae3fe1c8 ("ASoC: tas2770: Drop conflicting set_bias_level power setting") which was a fix to the tas2770 driver.)
--- sound/soc/codecs/tas2764.c | 33 --------------------------------- 1 file changed, 33 deletions(-)
sound/soc/codecs/tas2764.c +0 -33
@@ -50,38 +50,6 @@ static void tas2764_reset(struct tas2764_priv *tas2764)usleep_range (1000 ,2000 ); } -static int tas2764_set_bias_level (struct snd_soc_component *component, -enum snd_soc_bias_level level) -{ -struct tas2764_priv *tas2764 =snd_soc_component_get_drvdata (component); - -switch (level) { -case SND_SOC_BIAS_ON : -snd_soc_component_update_bits (component,TAS2764_PWR_CTRL , -TAS2764_PWR_CTRL_MASK , -TAS2764_PWR_CTRL_ACTIVE ); -break ; -case SND_SOC_BIAS_STANDBY : -case SND_SOC_BIAS_PREPARE : -snd_soc_component_update_bits (component,TAS2764_PWR_CTRL , -TAS2764_PWR_CTRL_MASK , -TAS2764_PWR_CTRL_MUTE ); -break ; -case SND_SOC_BIAS_OFF : -snd_soc_component_update_bits (component,TAS2764_PWR_CTRL , -TAS2764_PWR_CTRL_MASK , -TAS2764_PWR_CTRL_SHUTDOWN ); -break ; - -default : -dev_err (tas2764->dev, -"wrong power level setting %d\n" , level); -return -EINVAL ; - } - -return 0 ; -} -#ifdef CONFIG_PM static int tas2764_codec_suspend (struct snd_soc_component *component) {
@@ -549,7 +517,6 @@ static const struct snd_soc_component_driver soc_component_driver_tas2764 = { .probe = tas2764_codec_probe, .suspend = tas2764_codec_suspend, .resume = tas2764_codec_resume, - .set_bias_level = tas2764_set_bias_level, .controls = tas2764_snd_controls, .num_controls = ARRAY_SIZE(tas2764_snd_controls), .dapm_widgets = tas2764_dapm_widgets,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 221/530 ASoC: tas2764: Fix mute/unmute
In reply to Greg Kroah-HartmanFrom: Martin Povišer <[email protected]>
[ Upstream commit f5ad67f13623548e5aff847f89700c178aaf2a98 ]
Because the PWR_CTRL field is modeled as the power state of the DAC widget, and at the same time it is used to implement mute/unmute, we need some additional book-keeping to have the right end result no matter the sequence of calls. Without this fix, one permanently mutes an ongoing stream by toggling the associated speaker pin control.
(This mirrors commit 1e5907bcb3a3 ("ASoC: tas2770: Fix handling of mute/unmute") which was a fix to the tas2770 driver.)
--- sound/soc/codecs/tas2764.c | 57 +++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 25 deletions(-)
sound/soc/codecs/tas2764.c +32 -25
@@ -34,6 +34,9 @@ struct tas2764_priv {int v_sense_slot;int i_sense_slot; + +bool dac_powered; +bool unmuted; };static void tas2764_reset (struct tas2764_priv *tas2764)
@@ -50,6 +53,26 @@ static void tas2764_reset(struct tas2764_priv *tas2764)usleep_range (1000 ,2000 ); } +static int tas2764_update_pwr_ctrl (struct tas2764_priv *tas2764) +{ +struct snd_soc_component *component = tas2764->component; +unsigned int val; +int ret; + +if (tas2764->dac_powered) + val = tas2764->unmuted ? +TAS2764_PWR_CTRL_ACTIVE :TAS2764_PWR_CTRL_MUTE ; +else + val =TAS2764_PWR_CTRL_SHUTDOWN ; + + ret =snd_soc_component_update_bits (component,TAS2764_PWR_CTRL , +TAS2764_PWR_CTRL_MASK , val); +if (ret <0 ) +return ret; + +return 0 ; +} +#ifdef CONFIG_PM static int tas2764_codec_suspend (struct snd_soc_component *component) {
@@ -82,9 +105,7 @@ static int tas2764_codec_resume(struct snd_soc_component *component)usleep_range (1000 ,2000 ); } - ret =snd_soc_component_update_bits (component,TAS2764_PWR_CTRL , -TAS2764_PWR_CTRL_MASK , -TAS2764_PWR_CTRL_ACTIVE ); + ret =tas2764_update_pwr_ctrl (tas2764);if (ret <0 )return ret;
@@ -118,14 +139,12 @@ static int tas2764_dac_event(struct snd_soc_dapm_widget *w,switch (event) {case SND_SOC_DAPM_POST_PMU : - ret =snd_soc_component_update_bits (component,TAS2764_PWR_CTRL , -TAS2764_PWR_CTRL_MASK , -TAS2764_PWR_CTRL_MUTE ); + tas2764->dac_powered = true; + ret =tas2764_update_pwr_ctrl (tas2764);break ;case SND_SOC_DAPM_PRE_PMD : - ret =snd_soc_component_update_bits (component,TAS2764_PWR_CTRL , -TAS2764_PWR_CTRL_MASK , -TAS2764_PWR_CTRL_SHUTDOWN ); + tas2764->dac_powered = false; + ret =tas2764_update_pwr_ctrl (tas2764);break ;default :dev_err (tas2764->dev,"Unsupported event\n" );
@@ -170,17 +189,11 @@ static const struct snd_soc_dapm_route tas2764_audio_map[] = {static int tas2764_mute (struct snd_soc_dai *dai,int mute,int direction) { -struct snd_soc_component *component = dai->component; -int ret; - - ret =snd_soc_component_update_bits (component,TAS2764_PWR_CTRL , -TAS2764_PWR_CTRL_MASK , - mute ?TAS2764_PWR_CTRL_MUTE :0 ); +struct tas2764_priv *tas2764 = +snd_soc_component_get_drvdata (dai->component); -if (ret <0 ) -return ret; - -return 0 ; + tas2764->unmuted = !mute; +return tas2764_update_pwr_ctrl (tas2764); }static int tas2764_set_bitwidth (struct tas2764_priv *tas2764,int bitwidth)
@@ -494,12 +507,6 @@ static int tas2764_codec_probe(struct snd_soc_component *component)if (ret <0 )return ret; - ret =snd_soc_component_update_bits (component,TAS2764_PWR_CTRL , -TAS2764_PWR_CTRL_MASK , -TAS2764_PWR_CTRL_MUTE ); -if (ret <0 ) -return ret; -return 0 ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 222/530 platform/x86: msi-laptop: Fix old-ec check for backlight registering
In reply to Greg Kroah-HartmanFrom: Hans de Goede <[email protected]>
[ Upstream commit 83ac7a1c2ed5f17caa07cbbc84bad3c05dc3bf22 ]
Commit 2cc6c717799f ("msi-laptop: Port to new backlight interface selection API") replaced this check:
if (!quirks->old_ec_model || acpi_video_backlight_support())
pr_info("Brightness ignored, ...");
else
do_register();With:
if (quirks->old_ec_model || acpi_video_get_backlight_type() == acpi_backlight_vendor) do_register();
But since the do_register() part was part of the else branch, the entire condition should be inverted. So not only the 2 statements on either side of the || should be inverted, but the || itself should be replaced with a &&.
In practice this has likely not been an issue because the new-ec models (old_ec_model==false) likely all support ACPI video backlight control, making acpi_video_get_backlight_type() return acpi_backlight_video turning the second part of the || also false when old_ec_model == false.
--- drivers/platform/x86/msi-laptop.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/platform/x86/msi-laptop.c +1 -2
@@ -1048,8 +1048,7 @@ static int __init msi_init(void)return -EINVAL ;/* Register backlight stuff */ - -if (quirks->old_ec_model || +if (quirks->old_ec_model &&acpi_video_get_backlight_type () == acpi_backlight_vendor) {struct backlight_properties props;memset (&props,0 ,sizeof (struct backlight_properties ));
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 223/530 platform/x86: msi-laptop: Fix resource cleanup
In reply to Greg Kroah-HartmanFrom: Hans de Goede <[email protected]>
[ Upstream commit 5523632aa10f906dfe2eb714ee748590dc7fc6b1 ]
Fix the input-device not getting free-ed on probe-errors and fix the msi_touchpad_dwork not getting cancelled on neither probe-errors nor on remove.
--- drivers/platform/x86/msi-laptop.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/platform/x86/msi-laptop.c +3 -0
@@ -1116,6 +1116,8 @@ static int __init msi_init(void) fail_create_group:if (quirks->load_scm_model) {i8042_remove_filter (msi_laptop_i8042_filter); +cancel_delayed_work_sync (&msi_touchpad_dwork); +input_unregister_device (msi_laptop_input_dev);cancel_delayed_work_sync (&msi_rfkill_dwork);cancel_work_sync (&msi_rfkill_work);rfkill_cleanup ();
@@ -1136,6 +1138,7 @@ static void __exit msi_cleanup(void) {if (quirks->load_scm_model) {i8042_remove_filter (msi_laptop_i8042_filter); +cancel_delayed_work_sync (&msi_touchpad_dwork);input_unregister_device (msi_laptop_input_dev);cancel_delayed_work_sync (&msi_rfkill_dwork);cancel_work_sync (&msi_rfkill_work);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 224/530 platform/chrome: cros_ec_typec: Correct alt mode index
In reply to Greg Kroah-HartmanFrom: Prashant Malani <[email protected]>
[ Upstream commit 4e477663e396f48c5cfc5f2d75d4b514f409516a ]
Alt mode indices used by USB PD (Power Delivery) start with 1, not 0.
Update the alt mdoe registration code to factor this in to the alt mode descriptor.
--- drivers/platform/chrome/cros_ec_typec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/platform/chrome/cros_ec_typec.c +1 -1
@@ -691,7 +691,7 @@ static int cros_typec_register_altmodes(struct cros_typec_data *typec, int port_for (j =0 ; j < sop_disc->svids[i].mode_count; j++) {memset (&desc,0 ,sizeof (desc)); desc.svid = sop_disc->svids[i].svid; - desc.mode = j; + desc.mode = j +1 ; desc.vdo = sop_disc->svids[i].mode_vdo[j];if (is_partner)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 225/530 drm/amdgpu: add missing pci_disable_device() in amdgpu_pmops_runtime_resume()
In reply to Greg Kroah-HartmanFrom: Yang Yingliang <[email protected]>
[ Upstream commit 6b11af6d1c8f5d4135332bb932baaa06e511173d ]
Add missing pci_disable_device() if amdgpu_device_resume() fails.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +4 -1
@@ -2415,8 +2415,11 @@ static int amdgpu_pmops_runtime_resume(struct device *dev)amdgpu_device_baco_exit (drm_dev); } ret =amdgpu_device_resume (drm_dev, false); -if (ret) +if (ret) { +if (amdgpu_device_supports_px (drm_dev)) +pci_disable_device (pdev);return ret; + }if (amdgpu_device_supports_px (drm_dev)) drm_dev->switch_power_state =DRM_SWITCH_POWER_ON ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 226/530 drm/bridge: megachips: Fix a null pointer dereference bug
In reply to Greg Kroah-HartmanFrom: Zheyu Ma <[email protected]>
[ Upstream commit 1ff673333d46d2c1b053ebd0c1c7c7c79e36943e ]
When removing the module we will get the following warning:
[ 31.911505] i2c-core: driver [stdp2690-ge-b850v3-fw] unregistered [ 31.912484] general protection fault, probably for non-canonical address 0xdffffc0000000001: 0000 [#1] PREEMPT SMP KASAN PTI [ 31.913338] KASAN: null-ptr-deref in range [0x0000000000000008-0x000000000000000f] [ 31.915280] RIP: 0010:drm_bridge_remove+0x97/0x130 [ 31.921825] Call Trace: [ 31.922533] stdp4028_ge_b850v3_fw_remove+0x34/0x60 [megachips_stdpxxxx_ge_b850v3_fw] [ 31.923139] i2c_device_remove+0x181/0x1f0
The two bridges (stdp2690, stdp4028) do not probe at the same time, so the driver does not call ge_b850v3_resgiter() when probing, causing the driver to try to remove the object that has not been initialized.
Fix this by checking whether both the bridges are probed.
--- drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c +3 -1
@@ -296,7 +296,9 @@ static void ge_b850v3_lvds_remove(void)* This check is to avoid both the drivers * removing the bridge in their remove() function */ -if (!ge_b850v3_lvds_ptr) +if (!ge_b850v3_lvds_ptr || + !ge_b850v3_lvds_ptr->stdp2690_i2c || + !ge_b850v3_lvds_ptr->stdp4028_i2c) goto out;drm_bridge_remove (&ge_b850v3_lvds_ptr->bridge);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 227/530 ASoC: rsnd: Add check for rsnd_mod_power_on
In reply to Greg Kroah-HartmanFrom: Jiasheng Jiang <[email protected]>
[ Upstream commit 376be51caf8871419bbcbb755e1e615d30dc3153 ]
As rsnd_mod_power_on() can return negative numbers, it should be better to check the return value and deal with the exception.
--- sound/soc/sh/rcar/ctu.c | 6 +++++- sound/soc/sh/rcar/dvc.c | 6 +++++- sound/soc/sh/rcar/mix.c | 6 +++++- sound/soc/sh/rcar/src.c | 5 ++++- sound/soc/sh/rcar/ssi.c | 4 +++- 5 files changed, 22 insertions(+), 5 deletions(-)
sound/soc/sh/rcar/ctu.c +5 -1
@@ -171,7 +171,11 @@ static int rsnd_ctu_init(struct rsnd_mod *mod,struct rsnd_dai_stream *io, struct rsnd_priv *priv) { -rsnd_mod_power_on (mod ); + int ret; + + ret =rsnd_mod_power_on (mod); +if (ret <0 ) +return ret;rsnd_ctu_activation (mod);
sound/soc/sh/rcar/dvc.c +5 -1
@@ -186,7 +186,11 @@ static int rsnd_dvc_init(struct rsnd_mod *mod,struct rsnd_dai_stream *io, struct rsnd_priv *priv) { -rsnd_mod_power_on (mod ); + int ret; + + ret =rsnd_mod_power_on (mod); +if (ret <0 ) +return ret;rsnd_dvc_activation (mod);
sound/soc/sh/rcar/mix.c +5 -1
@@ -146,7 +146,11 @@ static int rsnd_mix_init(struct rsnd_mod *mod,struct rsnd_dai_stream *io, struct rsnd_priv *priv) { -rsnd_mod_power_on (mod ); + int ret; + + ret =rsnd_mod_power_on (mod); +if (ret <0 ) +return ret;rsnd_mix_activation (mod);
sound/soc/sh/rcar/src.c +4 -1
@@ -463,11 +463,14 @@ static int rsnd_src_init(struct rsnd_mod *mod, struct rsnd_priv *priv) {struct rsnd_src *src =rsnd_mod_to_src (mod); +int ret;/* reset sync convert_rate */ src->sync.val =0 ; -rsnd_mod_power_on (mod); + ret =rsnd_mod_power_on (mod); +if (ret <0 ) +return ret;rsnd_src_activation (mod);
sound/soc/sh/rcar/ssi.c +3 -1
@@ -480,7 +480,9 @@ static int rsnd_ssi_init(struct rsnd_mod *mod, ssi->usrcnt++; -rsnd_mod_power_on (mod); + ret =rsnd_mod_power_on (mod); +if (ret <0 ) +return ret;rsnd_ssi_config_init (mod, io);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 228/530 ALSA: hda: beep: Simplify keep-power-at-enable behavior
In reply to Greg Kroah-HartmanFrom: Takashi Iwai <[email protected]>
[ Upstream commit 4c8d695cb9bc5f6fd298a586602947b2fc099a64 ]
The recent fix for IDT codecs to keep the power up while the beep is enabled can be better integrated into the beep helper code. This patch cleans up the code with refactoring.
--- sound/pci/hda/hda_beep.c | 15 +++++++++++++-- sound/pci/hda/hda_beep.h | 1 + sound/pci/hda/patch_sigmatel.c | 25 ++----------------------- 3 files changed, 16 insertions(+), 25 deletions(-)
sound/pci/hda/hda_beep.c +13 -2
@@ -118,6 +118,12 @@ static int snd_hda_beep_event(struct input_dev *dev, unsigned int type,return 0 ; } +static void turn_on_beep (struct hda_beep *beep) +{ +if (beep->keep_power_at_enable) +snd_hda_power_up_pm (beep->codec); +} +static void turn_off_beep (struct hda_beep *beep) {cancel_work_sync (&beep->beep_work);
@@ -125,6 +131,8 @@ static void turn_off_beep(struct hda_beep *beep)/* turn off beep */ generate_tone (beep,0 ); } +if (beep->keep_power_at_enable) +snd_hda_power_down_pm (beep->codec); }/**
@@ -140,7 +148,9 @@ int snd_hda_enable_beep_device(struct hda_codec *codec, int enable) enable = !!enable;if (beep->enabled != enable) { beep->enabled = enable; -if (!enable) +if (enable) +turn_on_beep (beep); +else turn_off_beep (beep);return 1 ; }
@@ -167,7 +177,8 @@ static int beep_dev_disconnect(struct snd_device *device)input_unregister_device (beep->dev); else input_free_device(beep->dev); -turn_off_beep (beep); +if (beep->enabled) +turn_off_beep (beep);return 0 ; }
sound/pci/hda/hda_beep.h +1 -0
@@ -25,6 +25,7 @@ struct hda_beep { unsigned int enabled:1; unsigned int linear_tone:1; /* linear tone for IDT/STAC codec */ unsigned int playing:1; + unsigned int keep_power_at_enable:1; /* set by driver */struct work_struct beep_work;/* scheduled task for beep event */ struct mutex mutex;void (*power_hook)(struct hda_beep *beep,bool on);
sound/pci/hda/patch_sigmatel.c +2 -23
@@ -4311,6 +4311,8 @@ static int stac_parse_auto_config(struct hda_codec *codec)if (codec->beep) {/* IDT/STAC codecs have linear beep tone parameter */ codec->beep->linear_tone = spec->linear_tone_beep; +/* keep power up while beep is enabled */ + codec->beep->keep_power_at_enable =1 ;/* if no beep switch is available, make its own one */ caps =query_amp_caps (codec, nid,HDA_OUTPUT );if (!(caps &AC_AMPCAP_MUTE )) {
@@ -4444,28 +4446,6 @@ static int stac_suspend(struct hda_codec *codec) return 0; } - -static int stac_check_power_status (struct hda_codec *codec,hda_nid_t nid) -{ -#ifdef CONFIG_SND_HDA_INPUT_BEEP -struct sigmatel_spec *spec = codec->spec; -#endif -int ret =snd_hda_gen_check_power_status (codec, nid); - -#ifdef CONFIG_SND_HDA_INPUT_BEEP -if (nid == spec->gen.beep_nid && codec->beep) { -if (codec->beep->enabled != spec->beep_power_on) { - spec->beep_power_on = codec->beep->enabled; -if (spec->beep_power_on) -snd_hda_power_up_pm (codec); -else -snd_hda_power_down_pm (codec); - } - ret |= spec->beep_power_on; - } -#endif -return ret; -}#else #define stac_suspend NULL#endif /* CONFIG_PM */
@@ -4478,7 +4458,6 @@ static const struct hda_codec_ops stac_patch_ops = { .unsol_event = snd_hda_jack_unsol_event, #ifdef CONFIG_PM .suspend = stac_suspend, - .check_power_status = stac_check_power_status,#endif };
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 229/530 drm/bochs: fix blanking
In reply to Greg Kroah-HartmanFrom: Gerd Hoffmann <[email protected]>
[ Upstream commit e740ceb53e4579a7a4063712cebecac3c343b189 ]
VGA_IS1_RC is the color mode register (VGA_IS1_RM the one for monochrome mode, note C vs. M at the end). So when using VGA_IS1_RC make sure the vga device is actually in color mode and set the corresponding bit in the misc register.
Reproducible when booting VMs in UEFI mode with some edk2 versions (edk2 fix is on the way too). Doesn't happen in BIOS mode because in that case the vgabios already flips the bit.
--- drivers/gpu/drm/tiny/bochs.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/gpu/drm/tiny/bochs.c +2 -0
@@ -305,6 +305,8 @@ static void bochs_hw_fini(struct drm_device *dev)static void bochs_hw_blank (struct bochs_device *bochs,bool blank) {DRM_DEBUG_DRIVER ("hw_blank %d\n" , blank); +/* enable color bit (so VGA_IS1_RC access works) */ +bochs_vga_writeb (bochs,VGA_MIS_W ,VGA_MIS_COLOR );/* discard ar_flip_flop */ (void )bochs_vga_readb (bochs,VGA_IS1_RC );/* blank or unblank; we need only update index and set 0x20 */
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 230/530 drm/omap: dss: Fix refcount leak bugs
In reply to Greg Kroah-HartmanFrom: Liang He <[email protected]>
[ Upstream commit 8b42057e62120813ebe9274f508fa785b7cab33a ]
In dss_init_ports() and __dss_uninit_ports(), we should call of_node_put() for the reference returned by of_graph_get_port_by_id() in fail path or when it is not used anymore.
--- drivers/gpu/drm/omapdrm/dss/dss.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/gpu/drm/omapdrm/dss/dss.c +3 -0
@@ -1176,6 +1176,7 @@ static void __dss_uninit_ports(struct dss_device *dss, unsigned int num_ports)default :break ; } +of_node_put (port); } }
@@ -1208,11 +1209,13 @@ static int dss_init_ports(struct dss_device *dss)default :break ; } +of_node_put (port); }return 0 ; error: +of_node_put (port);__dss_uninit_ports (dss, i);return r; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 231/530 drm/amdgpu: Fix memory leak in hpd_rx_irq_create_workqueue()
In reply to Greg Kroah-HartmanFrom: Rafael Mendonca <[email protected]>
[ Upstream commit 7136f956c73c4ba50bfeb61653dfd6a9669ea915 ]
If construction of the array of work queues to handle hpd_rx_irq offload work fails, we need to unwind. Destroy all the created workqueues and the allocated memory for the hpd_rx_irq_offload_work_queue struct array.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +9 -1
@@ -1307,13 +1307,21 @@ static struct hpd_rx_irq_offload_work_queue *hpd_rx_irq_create_workqueue(structif (hpd_rx_offload_wq[i].wq ==NULL ) {DRM_ERROR ("create amdgpu_dm_hpd_rx_offload_wq fail!" ); -return NULL ; + goto out_err; }spin_lock_init (&hpd_rx_offload_wq[i].offload_lock); }return hpd_rx_offload_wq; + +out_err: +for (i =0 ; i < max_caps; i++) { +if (hpd_rx_offload_wq[i].wq) +destroy_workqueue (hpd_rx_offload_wq[i].wq); + } +kfree (hpd_rx_offload_wq); +return NULL ; }struct amdgpu_stutter_quirk {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 232/530 mmc: au1xmmc: Fix an error handling path in au1xmmc_probe()
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit 5cbedf52608cc3cbc1c2a9a861fb671620427a20 ]
If clk_prepare_enable() fails, there is no point in calling clk_disable_unprepare() in the error handling path.
Move the out_clk label at the right place.
--- drivers/mmc/host/au1xmmc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/mmc/host/au1xmmc.c +2 -1
@@ -1095,8 +1095,9 @@ static int au1xmmc_probe(struct platform_device *pdev)if (host->platdata && host->platdata->cd_setup && !(mmc->caps &MMC_CAP_NEEDS_POLL )) host->platdata->cd_setup (mmc,0 ); -out_clk: +clk_disable_unprepare (host->clk); +out_clk:clk_put (host->clk); out_irq:free_irq (host->irq, host);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 233/530 ASoC: eureka-tlv320: Hold reference returned from of_find_xxx API
In reply to Greg Kroah-HartmanFrom: Liang He <[email protected]>
[ Upstream commit bfb735a3ceff0bab6473bac275da96f9b2a06dec ]
In eukrea_tlv320_probe(), we need to hold the reference returned from of_find_compatible_node() which has increased the refcount and then call of_node_put() with it when done.
--- sound/soc/fsl/eukrea-tlv320.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
sound/soc/fsl/eukrea-tlv320.c +5 -3
@@ -86,7 +86,7 @@ static int eukrea_tlv320_probe(struct platform_device *pdev)int ret;int int_port =0 , ext_port;struct device_node *np = pdev->dev.of_node; -struct device_node *ssi_np =NULL , *codec_np =NULL ; +struct device_node *ssi_np =NULL , *codec_np =NULL , *tmp_np =NULL ; eukrea_tlv320.dev = &pdev->dev;if (np) {
@@ -143,7 +143,7 @@ static int eukrea_tlv320_probe(struct platform_device *pdev) }if (machine_is_eukrea_cpuimx27 () || -of_find_compatible_node (NULL ,NULL ,"fsl,imx21-audmux" )) { + (tmp_np =of_find_compatible_node (NULL ,NULL ,"fsl,imx21-audmux" ))) { imx_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0, IMX_AUDMUX_V1_PCR_SYN | IMX_AUDMUX_V1_PCR_TFSDIR |
@@ -158,10 +158,11 @@ static int eukrea_tlv320_probe(struct platform_device *pdev)IMX_AUDMUX_V1_PCR_SYN |IMX_AUDMUX_V1_PCR_RXDSEL (MX27_AUDMUX_HPCR1_SSI0 ) ); +of_node_put (tmp_np); }else if (machine_is_eukrea_cpuimx25sd () ||machine_is_eukrea_cpuimx35sd () ||machine_is_eukrea_cpuimx51sd () || -of_find_compatible_node (NULL ,NULL ,"fsl,imx31-audmux" )) { + (tmp_np =of_find_compatible_node (NULL ,NULL ,"fsl,imx31-audmux" ))) {if (!np) ext_port =machine_is_eukrea_cpuimx25sd () ?4 :3 ;
@@ -178,6 +179,7 @@ static int eukrea_tlv320_probe(struct platform_device *pdev)IMX_AUDMUX_V2_PTCR_SYN ,IMX_AUDMUX_V2_PDCR_RXDSEL (int_port) ); +of_node_put (tmp_np); }else {if (np) {/* The eukrea,asoc-tlv320 driver was explicitly
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 234/530 drm/msm/dpu: index dpu_kms->hw_vbif using vbif_idx
In reply to Greg Kroah-HartmanFrom: Dmitry Baryshkov <[email protected]>
[ Upstream commit 7538f80ae0d98bf51eb89eee5344aec219902d42 ]
Remove loops over hw_vbif. Instead always VBIF's idx as an index in the array. This fixes an error in dpu_kms_hw_init(), where we fill dpu_kms->hw_vbif[i], but check for an error pointer at dpu_kms->hw_vbif[vbif_idx].
Patchwork: https://patchwork.freedesktop.org/patch/489569/
--- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 12 ++++------ drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c | 29 +++++++++++------------- 2 files changed, 18 insertions(+), 23 deletions(-)
drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +5 -7
@@ -725,12 +725,10 @@ static void _dpu_kms_hw_destroy(struct dpu_kms *dpu_kms)_dpu_kms_mmu_destroy (dpu_kms);if (dpu_kms->catalog) { -for (i =0 ; i < dpu_kms->catalog->vbif_count; i++) { -u32 vbif_idx = dpu_kms->catalog->vbif[i].id; - -if ((vbif_idx <VBIF_MAX ) && dpu_kms->hw_vbif[vbif_idx]) { -dpu_hw_vbif_destroy (dpu_kms->hw_vbif[vbif_idx]); - dpu_kms->hw_vbif[vbif_idx] =NULL ; +for (i =0 ; i <ARRAY_SIZE (dpu_kms->hw_vbif); i++) { +if (dpu_kms->hw_vbif[i]) { +dpu_hw_vbif_destroy (dpu_kms->hw_vbif[i]); + dpu_kms->hw_vbif[i] =NULL ; } } }
@@ -1049,7 +1047,7 @@ static int dpu_kms_hw_init(struct msm_kms *kms)for (i =0 ; i < dpu_kms->catalog->vbif_count; i++) {u32 vbif_idx = dpu_kms->catalog->vbif[i].id; - dpu_kms->hw_vbif[i] =dpu_hw_vbif_init (vbif_idx, + dpu_kms->hw_vbif[vbif_idx] =dpu_hw_vbif_init (vbif_idx, dpu_kms->vbif[vbif_idx], dpu_kms->catalog);if (IS_ERR_OR_NULL (dpu_kms->hw_vbif[vbif_idx])) { rc =PTR_ERR (dpu_kms->hw_vbif[vbif_idx]);
drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c +13 -16
@@ -11,6 +11,14 @@#include "dpu_hw_vbif.h" #include "dpu_trace.h" +static struct dpu_hw_vbif *dpu_get_vbif (struct dpu_kms *dpu_kms,enum dpu_vbif vbif_idx) +{ +if (vbif_idx <ARRAY_SIZE (dpu_kms->hw_vbif)) +return dpu_kms->hw_vbif[vbif_idx]; + +return NULL ; +} +/** * _dpu_vbif_wait_for_xin_halt - wait for the xin to halt * @vbif: Pointer to hardware vbif driver
@@ -148,20 +156,15 @@ static u32 _dpu_vbif_get_ot_limit(struct dpu_hw_vbif *vbif,void dpu_vbif_set_ot_limit (struct dpu_kms *dpu_kms,struct dpu_vbif_set_ot_params *params) { -struct dpu_hw_vbif *vbif =NULL ; +struct dpu_hw_vbif *vbif;struct dpu_hw_mdp *mdp;bool forced_on = false;u32 ot_lim; -int ret, i; +int ret; mdp = dpu_kms->hw_mdp; -for (i =0 ; i <ARRAY_SIZE (dpu_kms->hw_vbif); i++) { -if (dpu_kms->hw_vbif[i] && - dpu_kms->hw_vbif[i]->idx == params->vbif_idx) - vbif = dpu_kms->hw_vbif[i]; - } - + vbif =dpu_get_vbif (dpu_kms, params->vbif_idx);if (!vbif || !mdp) {DRM_DEBUG_ATOMIC ("invalid arguments vbif %d mdp %d\n" , vbif !=NULL , mdp !=NULL );
@@ -204,7 +207,7 @@ void dpu_vbif_set_ot_limit(struct dpu_kms *dpu_kms,void dpu_vbif_set_qos_remap (struct dpu_kms *dpu_kms,struct dpu_vbif_set_qos_params *params) { -struct dpu_hw_vbif *vbif =NULL ; +struct dpu_hw_vbif *vbif;struct dpu_hw_mdp *mdp;bool forced_on = false;const struct dpu_vbif_qos_tbl *qos_tbl;
@@ -216,13 +219,7 @@ void dpu_vbif_set_qos_remap(struct dpu_kms *dpu_kms, } mdp = dpu_kms->hw_mdp; -for (i =0 ; i <ARRAY_SIZE (dpu_kms->hw_vbif); i++) { -if (dpu_kms->hw_vbif[i] && - dpu_kms->hw_vbif[i]->idx == params->vbif_idx) { - vbif = dpu_kms->hw_vbif[i]; -break ; - } - } + vbif =dpu_get_vbif (dpu_kms, params->vbif_idx);if (!vbif || !vbif->cap) {DPU_ERROR ("invalid vbif %d\n" , params->vbif_idx);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 235/530 drm/msm/dp: correct 1.62G link rate at dp_catalog_ctrl_config_msa()
In reply to Greg Kroah-HartmanFrom: Kuogee Hsieh <[email protected]>
[ Upstream commit aa0bff10af1c4b92e6b56e3e1b7f81c660d3ba78 ]
At current implementation there is an extra 0 at 1.62G link rate which cause no correct pixel_div selected for 1.62G link rate to calculate mvid and nvid. This patch delete the extra 0 to have mvid and nvid be calculated correctly.
Changes in v2:
-- fix Fixes tag's text
Changes in v3:
-- fix misspelling of "Reviewed-by"
Patchwork: https://patchwork.freedesktop.org/patch/499328/
--- drivers/gpu/drm/msm/dp/dp_catalog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/msm/dp/dp_catalog.c +1 -1
@@ -437,7 +437,7 @@ void dp_catalog_ctrl_config_msa(struct dp_catalog *dp_catalog,if (rate == link_rate_hbr3) pixel_div =6 ; -else if (rate ==1620000 || rate ==270000 ) +else if (rate ==162000 || rate ==270000 ) pixel_div =2 ;else if (rate == link_rate_hbr2) pixel_div =4 ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 236/530 drm/vmwgfx: Fix memory leak in vmw_mksstat_add_ioctl()
In reply to Greg Kroah-HartmanFrom: Rafael Mendonca <[email protected]>
[ Upstream commit a40c7f61d12fbd1e785e59140b9efd57127c0c33 ]
If the copy of the description string from userspace fails, then the page for the instance descriptor doesn't get freed before returning -EFAULT, which leads to a memleak.
--- drivers/gpu/drm/vmwgfx/vmwgfx_msg.c | 1 + 1 file changed, 1 insertion(+)
drivers/gpu/drm/vmwgfx/vmwgfx_msg.c +1 -0
@@ -1076,6 +1076,7 @@ int vmw_mksstat_add_ioctl(struct drm_device *dev, void *data,if (desc_len <0 ) {atomic_set (&dev_priv->mksstat_user_pids[slot],0 ); +__free_page (page);return -EFAULT ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 237/530 ASoC: codecs: tx-macro: fix kcontrol put
In reply to Greg Kroah-HartmanFrom: Srinivas Kandagatla <[email protected]>
[ Upstream commit c1057a08af438e0cf5450c1d977a3011198ed2f8 ]
tx_macro_tx_mixer_put() and tx_macro_dec_mode_put() currently returns zero eventhough it changes the value.
Fix this, so that change notifications are sent correctly.
--- sound/soc/codecs/lpass-tx-macro.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
sound/soc/codecs/lpass-tx-macro.c +11 -2
@@ -815,17 +815,23 @@ static int tx_macro_tx_mixer_put(struct snd_kcontrol *kcontrol,struct tx_macro *tx =snd_soc_component_get_drvdata (component);if (enable) { +if (tx->active_decimator[dai_id] == dec_id) +return 0 ; +set_bit (dec_id, &tx->active_ch_mask[dai_id]); tx->active_ch_cnt[dai_id]++; tx->active_decimator[dai_id] = dec_id; }else { +if (tx->active_decimator[dai_id] ==-1 ) +return 0 ; + tx->active_ch_cnt[dai_id]--;clear_bit (dec_id, &tx->active_ch_mask[dai_id]); tx->active_decimator[dai_id] =-1 ; }snd_soc_dapm_mixer_update_power (widget->dapm, kcontrol, enable, update); -return 0 ; +return 1 ; } static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w,
@@ -1011,9 +1017,12 @@ static int tx_macro_dec_mode_put(struct snd_kcontrol *kcontrol,int path = e->shift_l;struct tx_macro *tx =snd_soc_component_get_drvdata (component); +if (tx->dec_mode[path] == value) +return 0 ; + tx->dec_mode[path] = value; -return 0 ; +return 1 ; } static int tx_macro_get_bcs(struct snd_kcontrol *kcontrol,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 238/530 ASoC: da7219: Fix an error handling path in da7219_register_dai_clks()
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit abb4e4349afe7eecdb0499582f1c777031e3a7c8 ]
If clk_hw_register() fails, the corresponding clk should not be unregistered.
To handle errors from loops, clean up partial iterations before doing the goto. So add a clk_hw_unregister().
Then use a while (--i >= 0) loop in the unwind section.
--- sound/soc/codecs/da7219.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
sound/soc/codecs/da7219.c +3 -2
@@ -2196,6 +2196,7 @@ static int da7219_register_dai_clks(struct snd_soc_component *component) dai_clk_lookup =clkdev_hw_create (dai_clk_hw, init.name,"%s" ,dev_name (dev));if (!dai_clk_lookup) { +clk_hw_unregister (dai_clk_hw); ret = -ENOMEM ; goto err; }else {
@@ -2217,12 +2218,12 @@ static int da7219_register_dai_clks(struct snd_soc_component *component)return 0 ; err: -do { +while (--i >=0 ) {if (da7219->dai_clks_lookup[i])clkdev_drop (da7219->dai_clks_lookup[i]);clk_hw_unregister (&da7219->dai_clks_hw[i]); - }while (i-- >0 ); + }if (np)kfree (da7219->clk_hw_data);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 239/530 ALSA: dmaengine: increment buffer pointer atomically
In reply to Greg Kroah-HartmanFrom: Andreas Pape <[email protected]>
[ Upstream commit d1c442019594692c64a70a86ad88eb5b6db92216 ]
Setting pointer and afterwards checking for wraparound leads to the possibility of returning the inconsistent pointer position.
This patch increments buffer pointer atomically to avoid this issue.
--- sound/core/pcm_dmaengine.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
sound/core/pcm_dmaengine.c +5 -3
@@ -132,12 +132,14 @@ EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_set_config_from_dai_data);static void dmaengine_pcm_dma_complete (void *arg) { +unsigned int new_pos;struct snd_pcm_substream *substream = arg;struct dmaengine_pcm_runtime_data *prtd =substream_to_prtd (substream); - prtd->pos +=snd_pcm_lib_period_bytes (substream); -if (prtd->pos >=snd_pcm_lib_buffer_bytes (substream)) - prtd->pos =0 ; + new_pos = prtd->pos +snd_pcm_lib_period_bytes (substream); +if (new_pos >=snd_pcm_lib_buffer_bytes (substream)) + new_pos =0 ; + prtd->pos = new_pos;snd_pcm_period_elapsed (substream); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 240/530 mmc: wmt-sdmmc: Fix an error handling path in wmt_mci_probe()
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit cb58188ad90a61784a56a64f5107faaf2ad323e7 ]
A dma_free_coherent() call is missing in the error handling path of the probe, as already done in the remove function.
--- drivers/mmc/host/wmt-sdmmc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/mmc/host/wmt-sdmmc.c +4 -1
@@ -849,7 +849,7 @@ static int wmt_mci_probe(struct platform_device *pdev)if (IS_ERR (priv->clk_sdmmc)) {dev_err (&pdev->dev,"Error getting clock\n" ); ret =PTR_ERR (priv->clk_sdmmc); - goto fail5; + goto fail5_and_a_half; } ret =clk_prepare_enable (priv->clk_sdmmc);
@@ -866,6 +866,9 @@ static int wmt_mci_probe(struct platform_device *pdev)return 0 ; fail6:clk_put (priv->clk_sdmmc); +fail5_and_a_half: +dma_free_coherent (&pdev->dev, mmc->max_blk_count *16 , + priv->dma_desc_buffer, priv->dma_desc_device_addr); fail5:free_irq (dma_irq, priv); fail4:
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 241/530 ASoC: wm8997: Fix PM disable depth imbalance in wm8997_probe
In reply to Greg Kroah-HartmanFrom: Zhang Qilong <[email protected]>
[ Upstream commit 41a736ac20602f64773e80f0f5b32cde1830a44a ]
The pm_runtime_enable will increase power disable depth. Thus a pairing decrement is needed on the error handling path to keep it balanced according to context. We fix it by moving pm_runtime_enable to the endding of wm8997_probe
--- sound/soc/codecs/wm8997.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
sound/soc/codecs/wm8997.c +3 -3
@@ -1162,9 +1162,6 @@ static int wm8997_probe(struct platform_device *pdev)regmap_update_bits (arizona->regmap, wm8997_digital_vu[i],WM8997_DIG_VU ,WM8997_DIG_VU ); -pm_runtime_enable (&pdev->dev); -pm_runtime_idle (&pdev->dev); -arizona_init_common (arizona); ret =arizona_init_vol_limit (arizona);
@@ -1183,6 +1180,9 @@ static int wm8997_probe(struct platform_device *pdev) goto err_spk_irqs; } +pm_runtime_enable (&pdev->dev); +pm_runtime_idle (&pdev->dev); +return ret; err_spk_irqs:
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 242/530 ASoC: wm5110: Fix PM disable depth imbalance in wm5110_probe
In reply to Greg Kroah-HartmanFrom: Zhang Qilong <[email protected]>
[ Upstream commit 86b46bf1feb83898d89a2b4a8d08d21e9ea277a7 ]
The pm_runtime_enable will increase power disable depth. Thus a pairing decrement is needed on the error handling path to keep it balanced according to context. We fix it by moving pm_runtime_enable to the endding of wm5110_probe.
--- sound/soc/codecs/wm5110.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
sound/soc/codecs/wm5110.c +3 -3
@@ -2458,9 +2458,6 @@ static int wm5110_probe(struct platform_device *pdev)regmap_update_bits (arizona->regmap, wm5110_digital_vu[i],WM5110_DIG_VU ,WM5110_DIG_VU ); -pm_runtime_enable (&pdev->dev); -pm_runtime_idle (&pdev->dev); - ret =arizona_request_irq (arizona,ARIZONA_IRQ_DSP_IRQ1 ,"ADSP2 Compressed IRQ" , wm5110_adsp2_irq, wm5110);
@@ -2493,6 +2490,9 @@ static int wm5110_probe(struct platform_device *pdev) goto err_spk_irqs; } +pm_runtime_enable (&pdev->dev); +pm_runtime_idle (&pdev->dev); +return ret; err_spk_irqs:
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 243/530 ASoC: wm5102: Fix PM disable depth imbalance in wm5102_probe
In reply to Greg Kroah-HartmanFrom: Zhang Qilong <[email protected]>
[ Upstream commit fcbb60820cd3008bb44334a0395e5e57ccb77329 ]
The pm_runtime_enable will increase power disable depth. Thus a pairing decrement is needed on the error handling path to keep it balanced according to context. We fix it by moving pm_runtime_enable to the endding of wm5102_probe.
--- sound/soc/codecs/wm5102.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
sound/soc/codecs/wm5102.c +3 -3
@@ -2087,9 +2087,6 @@ static int wm5102_probe(struct platform_device *pdev)regmap_update_bits (arizona->regmap, wm5102_digital_vu[i],WM5102_DIG_VU ,WM5102_DIG_VU ); -pm_runtime_enable (&pdev->dev); -pm_runtime_idle (&pdev->dev); - ret =arizona_request_irq (arizona,ARIZONA_IRQ_DSP_IRQ1 ,"ADSP2 Compressed IRQ" , wm5102_adsp2_irq, wm5102);
@@ -2122,6 +2119,9 @@ static int wm5102_probe(struct platform_device *pdev) goto err_spk_irqs; } +pm_runtime_enable (&pdev->dev); +pm_runtime_idle (&pdev->dev); +return ret; err_spk_irqs:
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 244/530 ASoC: mt6660: Fix PM disable depth imbalance in mt6660_i2c_probe
In reply to Greg Kroah-HartmanFrom: Zhang Qilong <[email protected]>
[ Upstream commit b73f11e895e140537e7f8c7251211ccd3ce0782b ]
The pm_runtime_enable will increase power disable depth. Thus a pairing decrement is needed on the error handling path to keep it balanced according to context. We fix it by moving pm_runtime_enable to the endding of mt6660_i2c_probe.
--- sound/soc/codecs/mt6660.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
sound/soc/codecs/mt6660.c +6 -2
@@ -504,13 +504,17 @@ static int mt6660_i2c_probe(struct i2c_client *client,dev_err (chip->dev,"read chip revision fail\n" ); goto probe_fail; } -pm_runtime_set_active (chip->dev); -pm_runtime_enable (chip->dev); ret =devm_snd_soc_register_component (chip->dev, &mt6660_component_driver, &mt6660_codec_dai,1 ); +if (!ret) { +pm_runtime_set_active (chip->dev); +pm_runtime_enable (chip->dev); + } +return ret; + probe_fail:_mt6660_chip_power_on (chip,0 );mutex_destroy (&chip->io_lock);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 245/530 ALSA: hda/hdmi: Dont skip notification handling during PM operation
In reply to Greg Kroah-HartmanFrom: Takashi Iwai <[email protected]>
[ Upstream commit 5226c7b9784eee215e3914f440b3c2e1764f67a8 ]
The HDMI driver skips the notification handling from the graphics driver when the codec driver is being in the PM operation. This behavior was introduced by the commit eb399d3c99d8 ("ALSA: hda - Skip ELD notification during PM process"). This skip may cause a problem, as we may miss the ELD update when the connection/disconnection happens right at the runtime-PM operation of the audio codec.
Although this workaround was valid at that time, it's no longer true; the fix was required just because the ELD update procedure needed to wake up the audio codec, which had lead to a runtime-resume during a runtime-suspend. Meanwhile, the ELD update procedure doesn't need a codec wake up any longer since the commit 788d441a164c ("ALSA: hda - Use component ops for i915 HDMI/DP audio jack handling"); i.e. there is no much reason for skipping the notification.
Let's drop those checks for addressing the missing notification.
--- sound/pci/hda/patch_hdmi.c | 6 ------ 1 file changed, 6 deletions(-)
sound/pci/hda/patch_hdmi.c +0 -6
@@ -2685,9 +2685,6 @@ static void generic_acomp_pin_eld_notify(void *audio_ptr, int port, int dev_id)*/ if (codec->core.dev.power.power_state.event ==PM_EVENT_SUSPEND )return ; -/* ditto during suspend/resume process itself */ -if (snd_hdac_is_in_pm (&codec->core)) -return ;check_presence_and_report (codec, pin_nid, dev_id); }
@@ -2871,9 +2868,6 @@ static void intel_pin_eld_notify(void *audio_ptr, int port, int pipe)*/ if (codec->core.dev.power.power_state.event ==PM_EVENT_SUSPEND )return ; -/* ditto during suspend/resume process itself */ -if (snd_hdac_is_in_pm (&codec->core)) -return ;snd_hdac_i915_set_bclk (&codec->bus->core);check_presence_and_report (codec, pin_nid, dev_id);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 246/530 memory: pl353-smc: Fix refcount leak bug in pl353_smc_probe()
In reply to Greg Kroah-HartmanFrom: Liang He <[email protected]>
[ Upstream commit 61b3c876c1cbdb1efd1f52a1f348580e6e14efb6 ]
The break of for_each_available_child_of_node() needs a corresponding of_node_put() when the reference 'child' is not used anymore. Here we do not need to call of_node_put() in fail path as '!match' means no break.
While the of_platform_device_create() will created a new reference by 'child' but it has considered the refcounting.
--- drivers/memory/pl353-smc.c | 1 + 1 file changed, 1 insertion(+)
drivers/memory/pl353-smc.c +1 -0
@@ -122,6 +122,7 @@ static int pl353_smc_probe(struct amba_device *adev, const struct amba_id *id) }of_platform_device_create (child,NULL , &adev->dev); +of_node_put (child);return 0 ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 247/530 memory: of: Fix refcount leak bug in of_get_ddr_timings()
In reply to Greg Kroah-HartmanFrom: Liang He <[email protected]>
[ Upstream commit 05215fb32010d4afb68fbdbb4d237df6e2d4567b ]
We should add the of_node_put() when breaking out of for_each_child_of_node() as it will automatically increase and decrease the refcount.
--- drivers/memory/of_memory.c | 1 + 1 file changed, 1 insertion(+)
drivers/memory/of_memory.c +1 -0
@@ -134,6 +134,7 @@ const struct lpddr2_timings *of_get_ddr_timings(struct device_node *np_ddr,for_each_child_of_node (np_ddr, np_tim) {if (of_device_is_compatible (np_tim, tim_compat)) {if (of_do_get_timings (np_tim, &timings[i])) { +of_node_put (np_tim);devm_kfree (dev, timings); goto default_timings; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 248/530 memory: of: Fix refcount leak bug in of_lpddr3_get_ddr_timings()
In reply to Greg Kroah-HartmanFrom: Liang He <[email protected]>
[ Upstream commit 48af14fb0eaa63d9aa68f59fb0b205ec55a95636 ]
We should add the of_node_put() when breaking out of for_each_child_of_node() as it will automatically increase and decrease the refcount.
--- drivers/memory/of_memory.c | 1 + 1 file changed, 1 insertion(+)
drivers/memory/of_memory.c +1 -0
@@ -283,6 +283,7 @@ const struct lpddr3_timingsif (of_device_is_compatible (np_tim, tim_compat)) {if (of_lpddr3_do_get_timings (np_tim, &timings[i])) {devm_kfree (dev, timings); +of_node_put (np_tim); goto default_timings; } i++;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 249/530 locks: fix TOCTOU race when granting write lease
In reply to Greg Kroah-HartmanFrom: Amir Goldstein <[email protected]>
[ Upstream commit d6da19c9cace63290ccfccb1fc35151ffefc0bec ]
Thread A trying to acquire a write lease checks the value of i_readcount and i_writecount in check_conflicting_open() to verify that its own fd is the only fd referencing the file.
Thread B trying to open the file for read will call break_lease() in do_dentry_open() before incrementing i_readcount, which leaves a small window where thread A can acquire the write lease and then thread B completes the open of the file for read without breaking the write lease that was acquired by thread A.
Fix this race by incrementing i_readcount before checking for existing leases, same as the case with i_writecount.
Use a helper put_file_access() to decrement i_readcount or i_writecount in do_dentry_open() and __fput().
--- fs/file_table.c | 7 +------ fs/internal.h | 10 ++++++++++ fs/open.c | 11 ++++------- 3 files changed, 15 insertions(+), 13 deletions(-)
fs/file_table.c +1 -6
@@ -284,12 +284,7 @@ static void __fput(struct file *file) }fops_put (file->f_op);put_pid (file->f_owner.pid); -if ((mode & (FMODE_READ |FMODE_WRITE )) ==FMODE_READ ) -i_readcount_dec (inode); -if (mode &FMODE_WRITER ) { -put_write_access (inode); -__mnt_drop_write (mnt); - } +put_file_access (file);dput (dentry);if (unlikely (mode &FMODE_NEED_UNMOUNT ))dissolve_on_fput (mnt);
fs/internal.h +10 -0
@@ -100,6 +100,16 @@ extern void chroot_fs_refs(const struct path *, const struct path *);extern struct file *alloc_empty_file (int ,const struct cred *);extern struct file *alloc_empty_file_noaccount (int ,const struct cred *); +static inline void put_file_access (struct file *file) +{ +if ((file->f_mode & (FMODE_READ |FMODE_WRITE )) ==FMODE_READ ) { +i_readcount_dec (file->f_inode); + }else if (file->f_mode &FMODE_WRITER ) { +put_write_access (file->f_inode); +__mnt_drop_write (file->f_path.mnt); + } +} +/* * super.c */
fs/open.c +4 -7
@@ -786,7 +786,9 @@ static int do_dentry_open(struct file *f,return 0 ; } -if (f->f_mode &FMODE_WRITE && !special_file (inode->i_mode)) { +if ((f->f_mode & (FMODE_READ |FMODE_WRITE )) ==FMODE_READ ) { +i_readcount_inc (inode); + }else if (f->f_mode &FMODE_WRITE && !special_file (inode->i_mode)) { error =get_write_access (inode);if (unlikely (error)) goto cleanup_file;
@@ -826,8 +828,6 @@ static int do_dentry_open(struct file *f, goto cleanup_all; } f->f_mode |=FMODE_OPENED ; -if ((f->f_mode & (FMODE_READ |FMODE_WRITE )) ==FMODE_READ ) -i_readcount_inc (inode);if ((f->f_mode &FMODE_READ ) &&likely (f->f_op->read || f->f_op->read_iter)) f->f_mode |=FMODE_CAN_READ ;
@@ -880,10 +880,7 @@ static int do_dentry_open(struct file *f,if (WARN_ON_ONCE (error >0 )) error = -EINVAL ;fops_put (f->f_op); -if (f->f_mode &FMODE_WRITER ) { -put_write_access (inode); -__mnt_drop_write (f->f_path.mnt); - } +put_file_access (f); cleanup_file:path_put (&f->f_path); f->f_path.mnt =NULL ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 250/530 soc: qcom: smsm: Fix refcount leak bugs in qcom_smsm_probe()
In reply to Greg Kroah-HartmanFrom: Liang He <[email protected]>
[ Upstream commit af8f6f39b8afd772fda4f8e61823ef8c021bf382 ]
There are two refcount leak bugs in qcom_smsm_probe():
(1) The 'local_node' is escaped out from for_each_child_of_node() as the break of iteration, we should call of_node_put() for it in error path or when it is not used anymore.
(2) The 'node' is escaped out from for_each_available_child_of_node() as the 'goto', we should call of_node_put() for it in goto target.
--- drivers/soc/qcom/smsm.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-)
drivers/soc/qcom/smsm.c +13 -7
@@ -526,7 +526,7 @@ static int qcom_smsm_probe(struct platform_device *pdev)for (id =0 ; id < smsm->num_hosts; id++) { ret =smsm_parse_ipc (smsm, id);if (ret <0 ) -return ret; + goto out_put; }/* Acquire the main SMSM state vector */
@@ -534,13 +534,14 @@ static int qcom_smsm_probe(struct platform_device *pdev) smsm->num_entries * sizeof(u32));if (ret <0 && ret != -EEXIST ) {dev_err (&pdev->dev,"unable to allocate shared state entry\n" ); -return ret; + goto out_put; } states =qcom_smem_get (QCOM_SMEM_HOST_ANY ,SMEM_SMSM_SHARED_STATE ,NULL );if (IS_ERR (states)) {dev_err (&pdev->dev,"Unable to acquire shared state entry\n" ); -return PTR_ERR (states); + ret =PTR_ERR (states); + goto out_put; }/* Acquire the list of interrupt mask vectors */
@@ -548,13 +549,14 @@ static int qcom_smsm_probe(struct platform_device *pdev) ret =qcom_smem_alloc (QCOM_SMEM_HOST_ANY ,SMEM_SMSM_CPU_INTR_MASK , size);if (ret <0 && ret != -EEXIST ) {dev_err (&pdev->dev,"unable to allocate smsm interrupt mask\n" ); -return ret; + goto out_put; } intr_mask =qcom_smem_get (QCOM_SMEM_HOST_ANY ,SMEM_SMSM_CPU_INTR_MASK ,NULL );if (IS_ERR (intr_mask)) {dev_err (&pdev->dev,"unable to acquire shared memory interrupt mask\n" ); -return PTR_ERR (intr_mask); + ret =PTR_ERR (intr_mask); + goto out_put; }/* Setup the reference to the local state bits */
@@ -565,7 +567,8 @@ static int qcom_smsm_probe(struct platform_device *pdev) smsm->state =qcom_smem_state_register (local_node, &smsm_state_ops, smsm);if (IS_ERR (smsm->state)) {dev_err (smsm->dev,"failed to register qcom_smem_state\n" ); -return PTR_ERR (smsm->state); + ret =PTR_ERR (smsm->state); + goto out_put; }/* Register handlers for remote processor entries of interest. */
@@ -595,16 +598,19 @@ static int qcom_smsm_probe(struct platform_device *pdev) }platform_set_drvdata (pdev, smsm); +of_node_put (local_node);return 0 ; unwind_interfaces: +of_node_put (node);for (id =0 ; id < smsm->num_entries; id++)if (smsm->entries[id].domain)irq_domain_remove (smsm->entries[id].domain);qcom_smem_state_unregister (smsm->state); - +out_put: +of_node_put (local_node);return ret; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 251/530 soc: qcom: smem_state: Add refcounting for the state->of_node
In reply to Greg Kroah-HartmanFrom: Liang He <[email protected]>
[ Upstream commit 90681f53b9381c23ff7762a3b13826d620c272de ]
In qcom_smem_state_register() and qcom_smem_state_release(), we should better use of_node_get() and of_node_put() for the reference creation and destruction of 'device_node'.
--- drivers/soc/qcom/smem_state.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/soc/qcom/smem_state.c +2 -1
@@ -136,6 +136,7 @@ static void qcom_smem_state_release(struct kref *ref) struct qcom_smem_state *state = container_of(ref, struct qcom_smem_state, refcount);list_del (&state->list); +of_node_put (state->of_node);kfree (state); }
@@ -205,7 +206,7 @@ struct qcom_smem_state *qcom_smem_state_register(struct device_node *of_node,kref_init (&state->refcount); - state->of_node = of_node; + state->of_node =of_node_get (of_node); state->ops = *ops; state->priv = priv;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 252/530 ARM: dts: imx6qdl-kontron-samx6i: hook up DDC i2c bus
In reply to Greg Kroah-HartmanFrom: Lucas Stach <[email protected]>
[ Upstream commit afd8f77957e3e83adf21d9229c61ff37f44a177a ]
i2c2 is routed to the pins dedicated as DDC in the module standard. Reduce clock rate to 100kHz to be in line with VESA standard and hook this bus up to the HDMI node.
--- arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi +5 -1
@@ -263,6 +263,10 @@ phy-reset-gpios = <&gpio1 25 GPIO_ACTIVE_LOW>; }; +&hdmi { + ddc-i2c-bus = <&i2c2>; +}; + &i2c_intern { pmic@8 { compatible = "fsl,pfuze100";
@@ -387,7 +391,7 @@ /* HDMI_CTRL */ &i2c2 { - clock-frequency = <375000>; + clock-frequency = <100000>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c2>; };
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 253/530 ARM: dts: turris-omnia: Fix mpp26 pin name and comment
In reply to Greg Kroah-HartmanFrom: Marek Behún <[email protected]>
[ Upstream commit 49e93898f0dc177e645c22d0664813567fd9ec00 ]
There is a bug in Turris Omnia's schematics, whereupon the MPP[26] pin, which is routed to CN11 pin header, is documented as SPI CS1, but MPP[26] pin does not support this function. Instead it controls chip select 2 if in "spi0" mode.
Fix the name of the pin node in pinctrl node and fix the comment in SPI node.
--- arch/arm/boot/dts/armada-385-turris-omnia.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm/boot/dts/armada-385-turris-omnia.dts +2 -2
@@ -471,7 +471,7 @@ marvell,function = "spi0"; }; - spi0cs1_pins: spi0cs1-pins { + spi0cs2_pins: spi0cs2-pins { marvell,pins = "mpp26"; marvell,function = "spi0"; };
@@ -506,7 +506,7 @@ }; }; - /* MISO, MOSI, SCLK and CS1 are routed to pin header CN11 */ + /* MISO, MOSI, SCLK and CS2 are routed to pin header CN11 */ }; &uart0 {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 254/530 ARM: dts: kirkwood: lsxl: fix serial line
In reply to Greg Kroah-HartmanFrom: Michael Walle <[email protected]>
[ Upstream commit 04eabc6ac10fda9424606d9a7ab6ab9a5d95350a ]
Commit 327e15428977 ("ARM: dts: kirkwood: consolidate common pinctrl settings") unknowingly broke the serial output on this board. Before this commit, the pinmux was still configured by the bootloader and the kernel didn't reconfigured it again. This was an oversight by the initial board support where the pinmux for the serial line was never configured by the kernel. But with this commit, the serial line will be reconfigured to the wrong pins. This is especially confusing, because the output still works, but the input doesn't. Presumingly, the input is reconfigured to MPP10, but the output is connected to both MPP11 and MPP5.
Override the pinmux in the board device tree.
--- arch/arm/boot/dts/kirkwood-lsxl.dtsi | 5 +++++ 1 file changed, 5 insertions(+)
arch/arm/boot/dts/kirkwood-lsxl.dtsi +5 -0
@@ -10,6 +10,11 @@ ocp@f1000000 { pinctrl: pin-controller@10000 { + /* Non-default UART pins */ + pmx_uart0: pmx-uart0 { + marvell,pins = "mpp4", "mpp5"; + }; + pmx_power_hdd: pmx-power-hdd { marvell,pins = "mpp10"; marvell,function = "gpo";
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 255/530 ARM: dts: kirkwood: lsxl: remove first ethernet port
In reply to Greg Kroah-HartmanFrom: Michael Walle <[email protected]>
[ Upstream commit 2d528eda7c96ce5c70f895854ecd5684bd5d80b9 ]
Both the Linkstation LS-CHLv2 and the LS-XHL have only one ethernet port. This has always been wrong, i.e. the board code used to set up both ports, but the driver will play nice and return -ENODEV if the assiciated PHY is not found. Nevertheless, it is wrong. Remove it.
--- arch/arm/boot/dts/kirkwood-lsxl.dtsi | 11 ----------- 1 file changed, 11 deletions(-)
arch/arm/boot/dts/kirkwood-lsxl.dtsi +0 -11
@@ -218,22 +218,11 @@ &mdio { status = "okay"; - ethphy0: ethernet-phy@0 { - reg = <0>; - }; - ethphy1: ethernet-phy@8 { reg = <8>; }; }; -ð0 { - status = "okay"; - ethernet0-port@0 { - phy-handle = <ðphy0>; - }; -}; - ð1 { status = "okay"; ethernet1-port@0 {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 256/530 ia64: export memory_add_physaddr_to_nid to fix cxl build error
In reply to Greg Kroah-HartmanFrom: Randy Dunlap <[email protected]>
[ Upstream commit 97c318bfbe84efded246e80428054f300042f110 ]
cxl_pmem.ko uses memory_add_physaddr_to_nid() but ia64 does not export it, so this causes a build error:
ERROR: modpost: "memory_add_physaddr_to_nid" [drivers/cxl/cxl_pmem.ko] undefined!
Fix this by exporting that function.
--- arch/ia64/mm/numa.c | 1 + 1 file changed, 1 insertion(+)
arch/ia64/mm/numa.c +1 -0
@@ -75,5 +75,6 @@ int memory_add_physaddr_to_nid(u64 addr)return 0 ;return nid; } +EXPORT_SYMBOL (memory_add_physaddr_to_nid);#endif #endif
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 257/530 soc/tegra: fuse: Drop Kconfig dependency on TEGRA20_APB_DMA
In reply to Greg Kroah-HartmanFrom: Dmitry Osipenko <[email protected]>
[ Upstream commit 2254182807fc09ba9dec9a42ef239e373796f1b2 ]
The DMA subsystem could be entirely disabled in Kconfig and then the TEGRA20_APB_DMA option isn't available too. Hence kernel configuration fails if DMADEVICES Kconfig option is disabled due to the unsatisfiable dependency.
The FUSE driver isn't a critical driver and currently it only provides NVMEM interface to userspace which isn't known to be widely used, and thus, it's fine if FUSE driver fails to load.
Let's remove the erroneous Kconfig dependency and let the FUSE driver to fail the probing if DMA is unavailable.
--- drivers/soc/tegra/Kconfig | 1 - 1 file changed, 1 deletion(-)
drivers/soc/tegra/Kconfig +0 -1
@@ -136,7 +136,6 @@ config SOC_TEGRA_FUSE def_bool y depends on ARCH_TEGRA select SOC_BUS - select TEGRA20_APB_DMA if ARCH_TEGRA_2x_SOC config SOC_TEGRA_FLOWCTRL bool
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 258/530 arm64: dts: ti: k3-j7200: fix main pinmux range
In reply to Greg Kroah-HartmanFrom: Matt Ranostay <[email protected]>
[ Upstream commit 0d0a0b4413460383331088b2203ba09a6971bc3a ]
Range size of 0x2b4 was incorrect since there isn't 173 configurable pins for muxing. Additionally there is a non-addressable region in the mapping which requires splitting into two ranges.
main_pmx0 -> 67 pinsmain_pmx1 -> 3 pins
--- arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts | 10 ++++++---- arch/arm64/boot/dts/ti/k3-j7200-main.dtsi | 11 ++++++++++- 2 files changed, 16 insertions(+), 5 deletions(-)
arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts +6 -4
@@ -131,15 +131,17 @@ >; }; - main_usbss0_pins_default: main-usbss0-pins-default { + vdd_sd_dv_pins_default: vdd-sd-dv-pins-default { pinctrl-single,pins = < - J721E_IOPAD(0x120, PIN_OUTPUT, 0) /* (T4) USB0_DRVVBUS */ + J721E_IOPAD(0xd0, PIN_OUTPUT, 7) /* (T5) SPI0_D1.GPIO0_55 */ >; }; +}; - vdd_sd_dv_pins_default: vdd-sd-dv-pins-default { +&main_pmx1 { + main_usbss0_pins_default: main-usbss0-pins-default { pinctrl-single,pins = < - J721E_IOPAD(0xd0, PIN_OUTPUT, 7) /* (T5) SPI0_D1.GPIO0_55 */ + J721E_IOPAD(0x04, PIN_OUTPUT, 0) /* (T4) USB0_DRVVBUS */ >; }; };
arch/arm64/boot/dts/ti/k3-j7200-main.dtsi +10 -1
@@ -295,7 +295,16 @@ main_pmx0: pinctrl@11c000 { compatible = "pinctrl-single"; /* Proxy 0 addressing */ - reg = <0x00 0x11c000 0x00 0x2b4>; + reg = <0x00 0x11c000 0x00 0x10c>; + #pinctrl-cells = <1>; + pinctrl-single,register-width = <32>; + pinctrl-single,function-mask = <0xffffffff>; + }; + + main_pmx1: pinctrl@11c11c { + compatible = "pinctrl-single"; + /* Proxy 0 addressing */ + reg = <0x00 0x11c11c 0x00 0xc>; #pinctrl-cells = <1>; pinctrl-single,register-width = <32>; pinctrl-single,function-mask = <0xffffffff>;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 259/530 ARM: dts: exynos: correct s5k6a3 reset polarity on Midas family
In reply to Greg Kroah-HartmanFrom: Dmitry Torokhov <[email protected]>
[ Upstream commit 3ba2d4bb9592bf7a6a3fe3dbe711ecfc3d004bab ]
According to s5k6a3 driver code, the reset line for the chip appears to be active low. This also matches the typical polarity of reset lines in general. Let's fix it up as having correct polarity in DTS is important when the driver will be switched over to gpiod API.
--- arch/arm/boot/dts/exynos4412-midas.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/boot/dts/exynos4412-midas.dtsi +1 -1
@@ -585,7 +585,7 @@ clocks = <&camera 1>; clock-names = "extclk"; samsung,camclk-out = <1>; - gpios = <&gpm1 6 GPIO_ACTIVE_HIGH>; + gpios = <&gpm1 6 GPIO_ACTIVE_LOW>; port { is_s5k6a3_ep: endpoint {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 260/530 ARM: Drop CMDLINE_* dependency on ATAGS
In reply to Greg Kroah-HartmanFrom: Geert Uytterhoeven <[email protected]>
[ Upstream commit 136f4b1ec7c962ee37a787e095fd37b058d72bd3 ]
On arm32, the configuration options to specify the kernel command line type depend on ATAGS. However, the actual CMDLINE cofiguration option does not depend on ATAGS, and the code that handles this is not specific to ATAGS (see drivers/of/fdt.c:early_init_dt_scan_chosen()).
Hence users who desire to override the kernel command line on arm32 must enable support for ATAGS, even on a pure-DT system. Other architectures (arm64, loongarch, microblaze, nios2, powerpc, and riscv) do not impose such a restriction.
Hence drop the dependency on ATAGS.
--- arch/arm/Kconfig | 1 - 1 file changed, 1 deletion(-)
arch/arm/Kconfig +0 -1
@@ -1741,7 +1741,6 @@ config CMDLINE choice prompt "Kernel command line type" if CMDLINE != "" default CMDLINE_FROM_BOOTLOADER - depends on ATAGS config CMDLINE_FROM_BOOTLOADER bool "Use bootloader kernel arguments if available"
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 261/530 ext4: dont run ext4lazyinit for read-only filesystems
In reply to Greg Kroah-HartmanFrom: Josh Triplett <[email protected]>
[ Upstream commit 426d15ad11419066f7042ffa8fbf1b5c21a1ecbe ]
On a read-only filesystem, we won't invoke the block allocator, so we don't need to prefetch the block bitmaps.
This avoids starting and running the ext4lazyinit thread at all on a system with no read-write ext4 filesystems (for instance, a container VM with read-only filesystems underneath an overlayfs).
--- fs/ext4/super.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
fs/ext4/super.c +3 -3
@@ -3587,9 +3587,9 @@ int ext4_register_li_request(struct super_block *sb, goto out; } -if (test_opt (sb,NO_PREFETCH_BLOCK_BITMAPS ) && - (first_not_zeroed == ngroups ||sb_rdonly (sb) || - !test_opt (sb,INIT_INODE_TABLE ))) +if (sb_rdonly (sb) || + (test_opt (sb,NO_PREFETCH_BLOCK_BITMAPS ) && + (first_not_zeroed == ngroups || !test_opt (sb,INIT_INODE_TABLE )))) goto out; elr =ext4_li_request_new (sb, first_not_zeroed);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 262/530 arm64: ftrace: fix module PLTs with mcount
In reply to Greg Kroah-HartmanFrom: Mark Rutland <[email protected]>
[ Upstream commit 8cfb08575c6d4585f1ce0deeb189e5c824776b04 ]
Li Huafei reports that mcount-based ftrace with module PLTs was broken by commit:
a6253579977e4c6f ("arm64: ftrace: consistently handle PLTs.")
When a module PLTs are used and a module is loaded sufficiently far away from the kernel, we'll create PLTs for any branches which are out-of-range. These are separate from the special ftrace trampoline PLTs, which the module PLT code doesn't directly manipulate.
When mcount is in use this is a problem, as each mcount callsite in a module will be initialized to point to a module PLT, but since commit a6253579977e4c6f ftrace_make_nop() will assume that the callsite has been initialized to point to the special ftrace trampoline PLT, and ftrace_find_callable_addr() rejects other cases.
This means that when ftrace tries to initialize a callsite via ftrace_make_nop(), the call to ftrace_find_callable_addr() will find that the _mcount stub is out-of-range and is not handled by the ftrace PLT, resulting in a splat:
| ftrace_test: loading out-of-tree module taints kernel. | ftrace: no module PLT for _mcount | ------------[ ftrace bug ]------------ | ftrace failed to modify | [<ffff800029180014>] 0xffff800029180014 | actual: 44:00:00:94 | Initializing ftrace call sites | ftrace record flags: 2000000 | (0) | expected tramp: ffff80000802eb3c | ------------[ cut here ]------------ | WARNING: CPU: 3 PID: 157 at kernel/trace/ftrace.c:2120 ftrace_bug+0x94/0x270 | Modules linked in: | CPU: 3 PID: 157 Comm: insmod Tainted: G O 6.0.0-rc6-00151-gcd722513a189-dirty #22 | Hardware name: linux,dummy-virt (DT) | pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) | pc : ftrace_bug+0x94/0x270 | lr : ftrace_bug+0x21c/0x270 | sp : ffff80000b2bbaf0 | x29: ffff80000b2bbaf0 x28: 0000000000000000 x27: ffff0000c4d38000 | x26: 0000000000000001 x25: ffff800009d7e000 x24: ffff0000c4d86e00 | x23: 0000000002000000 x22: ffff80000a62b000 x21: ffff8000098ebea8 | x20: ffff0000c4d38000 x19: ffff80000aa24158 x18: ffffffffffffffff | x17: 0000000000000000 x16: 0a0d2d2d2d2d2d2d x15: ffff800009aa9118 | x14: 0000000000000000 x13: 6333626532303830 x12: 3030303866666666 | x11: 203a706d61727420 x10: 6465746365707865 x9 : 3362653230383030 | x8 : c0000000ffffefff x7 : 0000000000017fe8 x6 : 000000000000bff4 | x5 : 0000000000057fa8 x4 : 0000000000000000 x3 : 0000000000000001 | x2 : ad2cb14bb5438900 x1 : 0000000000000000 x0 : 0000000000000022 | Call trace: | ftrace_bug+0x94/0x270 | ftrace_process_locs+0x308/0x430 | ftrace_module_init+0x44/0x60 | load_module+0x15b4/0x1ce8 | __do_sys_init_module+0x1ec/0x238 | __arm64_sys_init_module+0x24/0x30 | invoke_syscall+0x54/0x118 | el0_svc_common.constprop.4+0x84/0x100 | do_el0_svc+0x3c/0xd0 | el0_svc+0x1c/0x50 | el0t_64_sync_handler+0x90/0xb8 | el0t_64_sync+0x15c/0x160 | ---[ end trace 0000000000000000 ]--- | ---------test_init-----------
Fix this by reverting to the old behaviour of ignoring the old instruction when initialising an mcount callsite in a module, which was the behaviour prior to commit a6253579977e4c6f.
--- arch/arm64/kernel/ftrace.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-)
arch/arm64/kernel/ftrace.c +16 -1
@@ -217,11 +217,26 @@ int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec,unsigned long pc = rec->ip;u32 old =0 , new; + new =aarch64_insn_gen_nop (); + +/* +* When using mcount, callsites in modules may have been initalized to +* call an arbitrary module PLT (which redirects to the _mcount stub) +* rather than the ftrace PLT we'll use at runtime (which redirects to +* the ftrace trampoline). We can ignore the old PLT when initializing +* the callsite. +* +* Note: 'mod' is only set at module load time. +*/ +if (!IS_ENABLED (CONFIG_DYNAMIC_FTRACE_WITH_REGS ) && +IS_ENABLED (CONFIG_ARM64_MODULE_PLTS ) && mod) { +return aarch64_insn_patch_text_nosync ((void *)pc, new); + } +if (!ftrace_find_callable_addr (rec, mod, &addr))return -EINVAL ; old =aarch64_insn_gen_branch_imm (pc, addr,AARCH64_INSN_BRANCH_LINK ); - new =aarch64_insn_gen_nop ();return ftrace_modify_code (pc, old, new, true); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 263/530 ARM: dts: exynos: fix polarity of VBUS GPIO of Origen
In reply to Greg Kroah-HartmanFrom: Dmitry Torokhov <[email protected]>
[ Upstream commit a08137bd1e0a7ce951dce9ce4a83e39d379b6e1b ]
EHCI Oxynos (drivers/usb/host/ehci-exynos.c) drives VBUS GPIO high when trying to power up the bus, therefore the GPIO in DTS must be marked as "active high". This will be important when EHCI driver is converted to gpiod API that respects declared polarities.
--- arch/arm/boot/dts/exynos4412-origen.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/boot/dts/exynos4412-origen.dts +1 -1
@@ -95,7 +95,7 @@ }; &ehci { - samsung,vbus-gpio = <&gpx3 5 1>; + samsung,vbus-gpio = <&gpx3 5 GPIO_ACTIVE_HIGH>; status = "okay"; phys = <&exynos_usbphy 2>, <&exynos_usbphy 3>; phy-names = "hsic0", "hsic1";
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 264/530 iio: adc: at91-sama5d2_adc: fix AT91_SAMA5D2_MR_TRACKTIM_MAX
In reply to Greg Kroah-HartmanFrom: Claudiu Beznea <[email protected]>
[ Upstream commit bb73d5d9164c57c4bb916739a98e5cd8e0a5ed8c ]
All ADC HW versions handled by this driver (SAMA5D2, SAM9X60, SAMA7G5) have MR.TRACKTIM on 4 bits. Fix AT91_SAMA5D2_MR_TRACKTIM_MAX to reflect this.
--- drivers/iio/adc/at91-sama5d2_adc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/adc/at91-sama5d2_adc.c +1 -1
@@ -74,7 +74,7 @@#define AT91_SAMA5D2_MR_ANACH BIT(23)/* Tracking Time */ #define AT91_SAMA5D2_MR_TRACKTIM (v) ((v) << 24) -#define AT91_SAMA5D2_MR_TRACKTIM_MAX 0xff +#define AT91_SAMA5D2_MR_TRACKTIM_MAX 0xf/* Transfer Time */ #define AT91_SAMA5D2_MR_TRANSFER (v) ((v) << 28)#define AT91_SAMA5D2_MR_TRANSFER_MAX 0x3
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 265/530 iio: adc: at91-sama5d2_adc: check return status for pressure and touch
In reply to Greg Kroah-HartmanFrom: Claudiu Beznea <[email protected]>
[ Upstream commit d84ace944a3b24529798dbae1340dea098473155 ]
Check return status of at91_adc_read_position() and at91_adc_read_pressure() in at91_adc_read_info_raw().
--- drivers/iio/adc/at91-sama5d2_adc.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/iio/adc/at91-sama5d2_adc.c +6 -2
@@ -1331,8 +1331,10 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev, *val = tmp_val;mutex_unlock (&st->lock);iio_device_release_direct_mode (indio_dev); +if (ret >0 ) + ret =at91_adc_adjust_val_osr (st, val); -return at91_adc_adjust_val_osr (st, val); +return ret; }if (chan->type ==IIO_PRESSURE ) { ret =iio_device_claim_direct_mode (indio_dev);
@@ -1345,8 +1347,10 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev, *val = tmp_val;mutex_unlock (&st->lock);iio_device_release_direct_mode (indio_dev); +if (ret >0 ) + ret =at91_adc_adjust_val_osr (st, val); -return at91_adc_adjust_val_osr (st, val); +return ret; }/* in this case we have a voltage channel */
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 266/530 iio: adc: at91-sama5d2_adc: lock around oversampling and sample freq
In reply to Greg Kroah-HartmanFrom: Claudiu Beznea <[email protected]>
[ Upstream commit 9780a23ed5a0a0a63683e078f576719a98d4fb70 ]
.read_raw()/.write_raw() could be called asynchronously from user space or other in kernel drivers. Without locking on st->lock these could be called asynchronously while there is a conversion in progress. Read will be harmless but changing registers while conversion is in progress may lead to inconsistent results. Thus, to avoid this lock st->lock.
--- drivers/iio/adc/at91-sama5d2_adc.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
drivers/iio/adc/at91-sama5d2_adc.c +8 -4
@@ -1329,10 +1329,10 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev, ret =at91_adc_read_position (st, chan->channel, &tmp_val); *val = tmp_val; -mutex_unlock (&st->lock); -iio_device_release_direct_mode (indio_dev);if (ret >0 ) ret =at91_adc_adjust_val_osr (st, val); +mutex_unlock (&st->lock); +iio_device_release_direct_mode (indio_dev);return ret; }
@@ -1345,10 +1345,10 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev, ret =at91_adc_read_pressure (st, chan->channel, &tmp_val); *val = tmp_val; -mutex_unlock (&st->lock); -iio_device_release_direct_mode (indio_dev);if (ret >0 ) ret =at91_adc_adjust_val_osr (st, val); +mutex_unlock (&st->lock); +iio_device_release_direct_mode (indio_dev);return ret; }
@@ -1441,16 +1441,20 @@ static int at91_adc_write_raw(struct iio_dev *indio_dev,/* if no change, optimize out */ if (val == st->oversampling_ratio)return 0 ; +mutex_lock (&st->lock); st->oversampling_ratio = val;/* update ratio */ at91_adc_config_emr (st); +mutex_unlock (&st->lock);return 0 ;case IIO_CHAN_INFO_SAMP_FREQ :if (val < st->soc_info.min_sample_rate || val > st->soc_info.max_sample_rate)return -EINVAL ; +mutex_lock (&st->lock);at91_adc_setup_samp_freq (indio_dev, val); +mutex_unlock (&st->lock);return 0 ;default :return -EINVAL ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 267/530 iio: adc: at91-sama5d2_adc: disable/prepare buffer on suspend/resume
In reply to Greg Kroah-HartmanFrom: Claudiu Beznea <[email protected]>
[ Upstream commit 808175e21d9b7f866eda742e8970f27b78afe5db ]
In case triggered buffers are enabled while system is suspended they will not work anymore after resume. For this call at91_adc_buffer_postdisable() on suspend and at91_adc_buffer_prepare() on resume. On tests it has been seen that at91_adc_buffer_postdisable() call is not necessary but it has been kept because it also does the book keeping for DMA. On resume path there is no need to call at91_adc_configure_touch() as it is embedded in at91_adc_buffer_prepare().
--- drivers/iio/adc/at91-sama5d2_adc.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
drivers/iio/adc/at91-sama5d2_adc.c +7 -7
@@ -1903,6 +1903,9 @@ static __maybe_unused int at91_adc_suspend(struct device *dev)struct iio_dev *indio_dev =dev_get_drvdata (dev);struct at91_adc_state *st =iio_priv (indio_dev); +if (iio_buffer_enabled (indio_dev)) +at91_adc_buffer_postdisable (indio_dev); +/* * Do a sofware reset of the ADC before we go to suspend. * this will ensure that all pins are free from being muxed by the ADC
@@ -1946,14 +1949,11 @@ static __maybe_unused int at91_adc_resume(struct device *dev)if (!iio_buffer_enabled (indio_dev))return 0 ; -/* check if we are enabling triggered buffer or the touchscreen */ -if (at91_adc_current_chan_is_touch (indio_dev)) -return at91_adc_configure_touch (st, true); -else -return at91_adc_configure_trigger (st->trig, true); + ret =at91_adc_buffer_prepare (indio_dev); +if (ret) + goto vref_disable_resume; -/* not needed but more explicit */ -return 0 ; +return at91_adc_configure_trigger (st->trig, true); vref_disable_resume:regulator_disable (st->vref);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 268/530 iio: inkern: only release the device node when done with it
In reply to Greg Kroah-HartmanFrom: Nuno Sá <[email protected]>
[ Upstream commit 79c3e84874c7d14f04ad58313b64955a0d2e9437 ]
'of_node_put()' can potentially release the memory pointed to by 'iiospec.np' which would leave us with an invalid pointer (and we would still pass it in 'of_xlate()'). Note that it is not guaranteed for the of_node lifespan to be attached to the device (to which is attached) lifespan so that there is (even though very unlikely) the possibility for the node to be freed while the device is still around. Thus, as there are indeed some of_xlate users which do access the node, a race is indeed possible.
As such, we can only release the node after we are done with it.
--- drivers/iio/inkern.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/iio/inkern.c +4 -2
@@ -148,9 +148,10 @@ static int __of_iio_channel_get(struct iio_channel *channel, idev =bus_find_device (&iio_bus_type,NULL , iiospec.np, iio_dev_node_match); -of_node_put (iiospec.np); -if (idev ==NULL ) +if (idev ==NULL ) { +of_node_put (iiospec.np);return -EPROBE_DEFER ; + } indio_dev =dev_to_iio_dev (idev); channel->indio_dev = indio_dev;
@@ -158,6 +159,7 @@ static int __of_iio_channel_get(struct iio_channel *channel, index = indio_dev->info->of_xlate (indio_dev, &iiospec); else index =__of_iio_simple_xlate (indio_dev, &iiospec); +of_node_put (iiospec.np);if (index <0 ) goto err_put; channel->channel = &indio_dev->channels[index];
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 269/530 iio: inkern: fix return value in devm_of_iio_channel_get_by_name()
In reply to Greg Kroah-HartmanFrom: Nuno Sá <[email protected]>
[ Upstream commit 9e878dbc0e8322f8b2f5ab0093c1e89926362dbe ]
of_iio_channel_get_by_name() can either return NULL or an error pointer so that only doing IS_ERR() is not enough. Fix it by checking the NULL pointer case and return -ENODEV in that case. Note this is done like this so that users of the function (which only check for error pointers) do not need to be changed. This is not ideal since we are losing error codes and as such, in a follow up change, things will be unified so that of_iio_channel_get_by_name() only returns error codes.
--- drivers/iio/inkern.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/iio/inkern.c +2 -0
@@ -395,6 +395,8 @@ struct iio_channel *devm_of_iio_channel_get_by_name(struct device *dev, channel =of_iio_channel_get_by_name (np, channel_name);if (IS_ERR (channel))return channel; +if (!channel) +return ERR_PTR (-ENODEV ); ret =devm_add_action_or_reset (dev, devm_iio_channel_free, channel);if (ret)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 270/530 iio: ABI: Fix wrong format of differential capacitance channel ABI.
In reply to Greg Kroah-HartmanFrom: Jonathan Cameron <[email protected]>
[ Upstream commit 1efc41035f1841acf0af2bab153158e27ce94f10 ]
in_ only occurs once in these attributes.
--- Documentation/ABI/testing/sysfs-bus-iio | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
Documentation/ABI/testing/sysfs-bus-iio +1 -1
@@ -188,7 +188,7 @@ Description: Raw capacitance measurement from channel Y. Units after application of scale and offset are nanofarads. -What: /sys/.../iio:deviceX/in_capacitanceY-in_capacitanceZ_raw +What: /sys/.../iio:deviceX/in_capacitanceY-capacitanceZ_raw KernelVersion: 3.2 Contact: [email protected] Description:
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 271/530 iio: magnetometer: yas530: Change data type of hard_offsets to signed
In reply to Greg Kroah-HartmanFrom: Jakob Hauser <[email protected]>
[ Upstream commit e137fafc8985cf152a4bb6f18ae83ebb06816df1 ]
The "hard_offsets" are currently unsigned u8 but they should be signed as they can get negative. They are signed in function yas5xx_meaure_offsets() and in the Yamaha drivers [1][2].
[1] https://github.com/NovaFusion/android_kernel_samsung_golden/blob/cm-12.1/drivers/sensor/compass/yas.h#L156
[2] https://github.com/msm8916-mainline/android_kernel_qcom_msm8916/blob/GT-I9195I/drivers/iio/magnetometer/yas_mag_drv-yas532.c#L91
--- drivers/iio/magnetometer/yamaha-yas530.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/magnetometer/yamaha-yas530.c +1 -1
@@ -132,7 +132,7 @@ struct yas5xx {unsigned int version;char name[16 ];struct yas5xx_calibration calibration; -u8 hard_offsets[3 ]; +s8 hard_offsets[3 ];struct iio_mount_matrix orientation;struct regmap *map;struct regulator_bulk_data regs[2 ];
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 272/530 RDMA/mlx5: Dont compare mkey tags in DEVX indirect mkey
In reply to Greg Kroah-HartmanFrom: Aharon Landau <[email protected]>
[ Upstream commit 13ad1125b941a5f257d9d3ae70485773abd34792 ]
According to the ib spec:
If the CI supports the Base Memory Management Extensions defined in this specification, the L_Key format must consist of:
24 bit index in the most significant bits of the R_Key, and 8 bit key in the least significant bits of the R_Key
Through a successful Allocate L_Key verb invocation, the CI must let the consumer own the key portion of the returned R_Key
Therefore, when creating a mkey using DEVX, the consumer is allowed to change the key part. The kernel should compare only the index part of a R_Key to determine equality with another R_Key.
Adding capability in order not to break backward compatibility.
--- drivers/infiniband/hw/mlx5/main.c | 3 +++ drivers/infiniband/hw/mlx5/odp.c | 3 ++- include/uapi/rdma/mlx5-abi.h | 1 + 3 files changed, 6 insertions(+), 1 deletion(-)
drivers/infiniband/hw/mlx5/main.c +3 -0
@@ -1847,6 +1847,9 @@ static int set_ucontext_resp(struct ib_ucontext *uctx,if (MLX5_CAP_GEN (dev->mdev, drain_sigerr)) resp->comp_mask |=MLX5_IB_ALLOC_UCONTEXT_RESP_MASK_SQD2RTS ; + resp->comp_mask |= +MLX5_IB_ALLOC_UCONTEXT_RESP_MASK_MKEY_UPDATE_TAG ; +return 0 ; }
drivers/infiniband/hw/mlx5/odp.c +2 -1
@@ -792,7 +792,8 @@ static bool mkey_is_eq(struct mlx5_core_mkey *mmkey, u32 key) {if (!mmkey)return false; -if (mmkey->type ==MLX5_MKEY_MW ) +if (mmkey->type ==MLX5_MKEY_MW || + mmkey->type ==MLX5_MKEY_INDIRECT_DEVX )return mlx5_base_mkey (mmkey->key) ==mlx5_base_mkey (key);return mmkey->key == key; }
include/uapi/rdma/mlx5-abi.h +1 -0
@@ -104,6 +104,7 @@ enum mlx5_ib_alloc_ucontext_resp_mask {MLX5_IB_ALLOC_UCONTEXT_RESP_MASK_ECE =1UL <<2 ,MLX5_IB_ALLOC_UCONTEXT_RESP_MASK_SQD2RTS =1UL <<3 ,MLX5_IB_ALLOC_UCONTEXT_RESP_MASK_REAL_TIME_TS =1UL <<4 , + MLX5_IB_ALLOC_UCONTEXT_RESP_MASK_MKEY_UPDATE_TAG = 1UL << 5, }; enum mlx5_user_cmds_supp_uhw {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 273/530 usb: common: debug: Check non-standard control requests
In reply to Greg Kroah-HartmanFrom: Thinh Nguyen <[email protected]>
[ Upstream commit b6155eaf6b05e558218b44b88a6cad03f15a586c ]
Previously usb_decode_ctrl() only decodes standard control requests, but it was used for non-standard requests also. If it's non-standard or unknown standard bRequest, print the Setup data values.
--- drivers/usb/common/debug.c | 96 +++++++++++++++++++++++++------------- 1 file changed, 64 insertions(+), 32 deletions(-)
drivers/usb/common/debug.c +64 -32
@@ -207,30 +207,28 @@ static void usb_decode_set_isoch_delay(__u8 wValue, char *str, size_t size)snprintf (str, size,"Set Isochronous Delay(Delay = %d ns)" , wValue); } -/** -* usb_decode_ctrl - Returns human readable representation of control request. -* @str: buffer to return a human-readable representation of control request. -* This buffer should have about 200 bytes. -* @size: size of str buffer. -* @bRequestType: matches the USB bmRequestType field -* @bRequest: matches the USB bRequest field -* @wValue: matches the USB wValue field (CPU byte order) -* @wIndex: matches the USB wIndex field (CPU byte order) -* @wLength: matches the USB wLength field (CPU byte order) -* -* Function returns decoded, formatted and human-readable description of -* control request packet. -* -* The usage scenario for this is for tracepoints, so function as a return -* use the same value as in parameters. This approach allows to use this -* function in TP_printk -* -* Important: wValue, wIndex, wLength parameters before invoking this function -* should be processed by le16_to_cpu macro. -*/ -const char *usb_decode_ctrl (char *str,size_t size,__u8 bRequestType, -__u8 bRequest,__u16 wValue,__u16 wIndex, -__u16 wLength) +static void usb_decode_ctrl_generic (char *str,size_t size,__u8 bRequestType, +__u8 bRequest,__u16 wValue,__u16 wIndex, +__u16 wLength) +{ +u8 recip = bRequestType &USB_RECIP_MASK ; +u8 type = bRequestType &USB_TYPE_MASK ; + +snprintf (str, size, +"Type=%s Recipient=%s Dir=%s bRequest=%u wValue=%u wIndex=%u wLength=%u" , + (type ==USB_TYPE_STANDARD ) ?"Standard" : + (type ==USB_TYPE_VENDOR ) ?"Vendor" : + (type ==USB_TYPE_CLASS ) ?"Class" :"Unknown" , + (recip ==USB_RECIP_DEVICE ) ?"Device" : + (recip ==USB_RECIP_INTERFACE ) ?"Interface" : + (recip ==USB_RECIP_ENDPOINT ) ?"Endpoint" :"Unknown" , + (bRequestType &USB_DIR_IN ) ?"IN" :"OUT" , + bRequest, wValue, wIndex, wLength); +} + +static void usb_decode_ctrl_standard (char *str,size_t size,__u8 bRequestType, +__u8 bRequest,__u16 wValue,__u16 wIndex, +__u16 wLength) {switch (bRequest) {case USB_REQ_GET_STATUS :
@@ -271,14 +269,48 @@ const char *usb_decode_ctrl(char *str, size_t size, __u8 bRequestType,usb_decode_set_isoch_delay (wValue, str, size);break ;default : -snprintf (str, size,"%02x %02x %02x %02x %02x %02x %02x %02x" , - bRequestType, bRequest, - (u8)(cpu_to_le16 (wValue) &0xff ), - (u8)(cpu_to_le16 (wValue) >>8 ), - (u8)(cpu_to_le16 (wIndex) &0xff ), - (u8)(cpu_to_le16 (wIndex) >>8 ), - (u8)(cpu_to_le16 (wLength) &0xff ), - (u8)(cpu_to_le16 (wLength) >>8 )); +usb_decode_ctrl_generic (str, size, bRequestType, bRequest, + wValue, wIndex, wLength); +break ; + } +} + +/** +* usb_decode_ctrl - Returns human readable representation of control request. +* @str: buffer to return a human-readable representation of control request. +* This buffer should have about 200 bytes. +* @size: size of str buffer. +* @bRequestType: matches the USB bmRequestType field +* @bRequest: matches the USB bRequest field +* @wValue: matches the USB wValue field (CPU byte order) +* @wIndex: matches the USB wIndex field (CPU byte order) +* @wLength: matches the USB wLength field (CPU byte order) +* +* Function returns decoded, formatted and human-readable description of +* control request packet. +* +* The usage scenario for this is for tracepoints, so function as a return +* use the same value as in parameters. This approach allows to use this +* function in TP_printk +* +* Important: wValue, wIndex, wLength parameters before invoking this function +* should be processed by le16_to_cpu macro. +*/ +const char *usb_decode_ctrl (char *str,size_t size,__u8 bRequestType, +__u8 bRequest,__u16 wValue,__u16 wIndex, +__u16 wLength) +{ +switch (bRequestType &USB_TYPE_MASK ) { +case USB_TYPE_STANDARD : +usb_decode_ctrl_standard (str, size, bRequestType, bRequest, + wValue, wIndex, wLength); +break ; +case USB_TYPE_VENDOR : +case USB_TYPE_CLASS : +default : +usb_decode_ctrl_generic (str, size, bRequestType, bRequest, + wValue, wIndex, wLength); +break ; }return str;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 274/530 clk: meson: Hold reference returned by of_get_parent()
In reply to Greg Kroah-HartmanFrom: Liang He <[email protected]>
[ Upstream commit 89ab396d712f7c91fe94f55cff23460426f5fc81 ]
We should hold the reference returned by of_get_parent() and use it to call of_node_put() for refcount balance.
--- drivers/clk/meson/meson-aoclk.c | 5 ++++- drivers/clk/meson/meson-eeclk.c | 5 ++++- drivers/clk/meson/meson8b.c | 5 ++++- 3 files changed, 12 insertions(+), 3 deletions(-)
drivers/clk/meson/meson-aoclk.c +4 -1
@@ -38,6 +38,7 @@ int meson_aoclkc_probe(struct platform_device *pdev)struct meson_aoclk_reset_controller *rstc;struct meson_aoclk_data *data;struct device *dev = &pdev->dev; +struct device_node *np;struct regmap *regmap;int ret, clkid;
@@ -49,7 +50,9 @@ int meson_aoclkc_probe(struct platform_device *pdev)if (!rstc)return -ENOMEM ; - regmap =syscon_node_to_regmap (of_get_parent (dev->of_node)); + np =of_get_parent (dev->of_node); + regmap =syscon_node_to_regmap (np); +of_node_put (np);if (IS_ERR (regmap)) {dev_err (dev,"failed to get regmap\n" );return PTR_ERR (regmap);
drivers/clk/meson/meson-eeclk.c +4 -1
@@ -18,6 +18,7 @@ int meson_eeclkc_probe(struct platform_device *pdev) {const struct meson_eeclkc_data *data;struct device *dev = &pdev->dev; +struct device_node *np;struct regmap *map;int ret, i;
@@ -26,7 +27,9 @@ int meson_eeclkc_probe(struct platform_device *pdev)return -EINVAL ;/* Get the hhi system controller node */ - map =syscon_node_to_regmap (of_get_parent (dev->of_node)); + np =of_get_parent (dev->of_node); + map =syscon_node_to_regmap (np); +of_node_put (np);if (IS_ERR (map)) {dev_err (dev,"failed to get HHI regmap\n" );
drivers/clk/meson/meson8b.c +4 -1
@@ -3717,12 +3717,15 @@ static void __init meson8b_clkc_init_common(struct device_node *np, struct clk_hw_onecell_data *clk_hw_onecell_data) {struct meson8b_clk_reset *rstc; +struct device_node *parent_np;const char *notifier_clk_name;struct clk *notifier_clk;struct regmap *map;int i, ret; - map =syscon_node_to_regmap (of_get_parent (np)); + parent_np =of_get_parent (np); + map =syscon_node_to_regmap (parent_np); +of_node_put (parent_np);if (IS_ERR (map)) {pr_err ("failed to get HHI regmap - Trying obsolete regs\n" );return ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 275/530 clk: oxnas: Hold reference returned by of_get_parent()
In reply to Greg Kroah-HartmanFrom: Liang He <[email protected]>
[ Upstream commit 1d6aa08c54cd0e005210ab8e3b1e92ede70f8a4f ]
In oxnas_stdclk_probe(), we need to hold the reference returned by of_get_parent() and use it to call of_node_put() for refcount balance.
--- drivers/clk/clk-oxnas.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/clk/clk-oxnas.c +4 -2
@@ -207,7 +207,7 @@ static const struct of_device_id oxnas_stdclk_dt_ids[] = {static int oxnas_stdclk_probe (struct platform_device *pdev) { -struct device_node *np = pdev->dev.of_node; +struct device_node *np = pdev->dev.of_node, *parent_np;const struct oxnas_stdclk_data *data;const struct of_device_id *id;struct regmap *regmap;
@@ -219,7 +219,9 @@ static int oxnas_stdclk_probe(struct platform_device *pdev)return -ENODEV ; data = id->data; - regmap =syscon_node_to_regmap (of_get_parent (np)); + parent_np =of_get_parent (np); + regmap =syscon_node_to_regmap (parent_np); +of_node_put (parent_np);if (IS_ERR (regmap)) {dev_err (&pdev->dev,"failed to have parent regmap\n" );return PTR_ERR (regmap);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 276/530 clk: qoriq: Hold reference returned by of_get_parent()
In reply to Greg Kroah-HartmanFrom: Liang He <[email protected]>
[ Upstream commit a8ea4273bc26256ce3cce83164f0f51c5bf6e127 ]
In legacy_init_clockgen(), we need to hold the reference returned by of_get_parent() and use it to call of_node_put() for refcount balance.
Beside, in create_sysclk(), we need to call of_node_put() on 'sysclk' also for refcount balance.
--- drivers/clk/clk-qoriq.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
drivers/clk/clk-qoriq.c +8 -2
@@ -1063,8 +1063,13 @@ static void __init _clockgen_init(struct device_node *np, bool legacy);*/ static void __init legacy_init_clockgen (struct device_node *np) { -if (!clockgen.node) -_clockgen_init (of_get_parent (np), true); +if (!clockgen.node) { +struct device_node *parent_np; + + parent_np =of_get_parent (np); +_clockgen_init (parent_np, true); +of_node_put (parent_np); + } }/* Legacy node */
@@ -1159,6 +1164,7 @@ static struct clk * __init create_sysclk(const char *name) sysclk =of_get_child_by_name (clockgen.node,"sysclk" );if (sysclk) { clk =sysclk_from_fixed (sysclk, name); +of_node_put (sysclk);if (!IS_ERR (clk))return clk; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 277/530 clk: berlin: Add of_node_put() for of_get_parent()
In reply to Greg Kroah-HartmanFrom: Liang He <[email protected]>
[ Upstream commit 37c381b812dcbfde9c3f1f3d3e75fdfc1b40d5bc ]
In berlin2_clock_setup() and berlin2q_clock_setup(), we need to call of_node_put() for the reference returned by of_get_parent() which has increased the refcount. We should call *_put() in fail path or when it is not used anymore.
--- drivers/clk/berlin/bg2.c | 5 ++++- drivers/clk/berlin/bg2q.c | 6 +++++- 2 files changed, 9 insertions(+), 2 deletions(-)
drivers/clk/berlin/bg2.c +4 -1
@@ -500,12 +500,15 @@ static void __init berlin2_clock_setup(struct device_node *np)int n, ret; clk_data =kzalloc (struct_size (clk_data, hws,MAX_CLKS ),GFP_KERNEL ); -if (!clk_data) +if (!clk_data) { +of_node_put (parent_np);return ; + } clk_data->num =MAX_CLKS ; hws = clk_data->hws; gbase =of_iomap (parent_np,0 ); +of_node_put (parent_np);if (!gbase)return ;
drivers/clk/berlin/bg2q.c +5 -1
@@ -286,19 +286,23 @@ static void __init berlin2q_clock_setup(struct device_node *np)int n, ret; clk_data =kzalloc (struct_size (clk_data, hws,MAX_CLKS ),GFP_KERNEL ); -if (!clk_data) +if (!clk_data) { +of_node_put (parent_np);return ; + } clk_data->num =MAX_CLKS ; hws = clk_data->hws; gbase =of_iomap (parent_np,0 );if (!gbase) { +of_node_put (parent_np);pr_err ("%pOF: Unable to map global base\n" , np);return ; }/* BG2Q CPU PLL is not part of global registers */ cpupll_base =of_iomap (parent_np,1 ); +of_node_put (parent_np);if (!cpupll_base) {pr_err ("%pOF: Unable to map cpupll base\n" , np);iounmap (gbase);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 278/530 clk: sprd: Hold reference returned by of_get_parent()
In reply to Greg Kroah-HartmanFrom: Liang He <[email protected]>
[ Upstream commit 91e6455bf715fb1558a0bf8f645ec1c131254a3c ]
We should hold the reference returned by of_get_parent() and use it to call of_node_put() for refcount balance.
--- drivers/clk/sprd/common.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
drivers/clk/sprd/common.c +5 -4
@@ -41,7 +41,7 @@ int sprd_clk_regmap_init(struct platform_device *pdev, {void __iomem *base;struct device *dev = &pdev->dev; -struct device_node *node = dev->of_node; +struct device_node *node = dev->of_node, *np;struct regmap *regmap;if (of_find_property (node,"sprd,syscon" ,NULL )) {
@@ -50,9 +50,10 @@ int sprd_clk_regmap_init(struct platform_device *pdev,pr_err ("%s: failed to get syscon regmap\n" , __func__);return PTR_ERR (regmap); } - }else if (of_device_is_compatible (of_get_parent (dev->of_node), -"syscon" )) { - regmap =device_node_to_regmap (of_get_parent (dev->of_node)); + }else if (of_device_is_compatible (np =of_get_parent (node),"syscon" ) || + (of_node_put (np),0 )) { + regmap =device_node_to_regmap (np); +of_node_put (np);if (IS_ERR (regmap)) {dev_err (dev,"failed to get regmap from its parent.\n" );return PTR_ERR (regmap);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 279/530 clk: tegra: Fix refcount leak in tegra210_clock_init
In reply to Greg Kroah-HartmanFrom: Miaoqian Lin <[email protected]>
[ Upstream commit 56c78cb1f00a9dde8cd762131ce8f4c5eb046fbb ]
of_find_matching_node() returns a node pointer with refcount incremented, we should use of_node_put() on it when not need anymore. Add missing of_node_put() to avoid refcount leak.
--- drivers/clk/tegra/clk-tegra210.c | 1 + 1 file changed, 1 insertion(+)
drivers/clk/tegra/clk-tegra210.c +1 -0
@@ -3748,6 +3748,7 @@ static void __init tegra210_clock_init(struct device_node *np) } pmc_base =of_iomap (node,0 ); +of_node_put (node);if (!pmc_base) {pr_err ("Can't map pmc registers\n" );WARN_ON (1 );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 280/530 clk: tegra: Fix refcount leak in tegra114_clock_init
In reply to Greg Kroah-HartmanFrom: Miaoqian Lin <[email protected]>
[ Upstream commit db16a80c76ea395766913082b1e3f939dde29b2c ]
of_find_matching_node() returns a node pointer with refcount incremented, we should use of_node_put() on it when not need anymore. Add missing of_node_put() to avoid refcount leak.
--- drivers/clk/tegra/clk-tegra114.c | 1 + 1 file changed, 1 insertion(+)
drivers/clk/tegra/clk-tegra114.c +1 -0
@@ -1317,6 +1317,7 @@ static void __init tegra114_clock_init(struct device_node *np) } pmc_base =of_iomap (node,0 ); +of_node_put (node);if (!pmc_base) {pr_err ("Can't map pmc registers\n" );WARN_ON (1 );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 281/530 clk: tegra20: Fix refcount leak in tegra20_clock_init
In reply to Greg Kroah-HartmanFrom: Miaoqian Lin <[email protected]>
[ Upstream commit 4e343bafe03ff68a62f48f8235cf98f2c685468b ]
of_find_matching_node() returns a node pointer with refcount incremented, we should use of_node_put() on it when not need anymore. Add missing of_node_put() to avoid refcount leak.
--- drivers/clk/tegra/clk-tegra20.c | 1 + 1 file changed, 1 insertion(+)
drivers/clk/tegra/clk-tegra20.c +1 -0
@@ -1128,6 +1128,7 @@ static void __init tegra20_clock_init(struct device_node *np) } pmc_base =of_iomap (node,0 ); +of_node_put (node);if (!pmc_base) {pr_err ("Can't map pmc registers\n" );BUG ();
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 282/530 HSI: omap_ssi: Fix refcount leak in ssi_probe
In reply to Greg Kroah-HartmanFrom: Miaoqian Lin <[email protected]>
[ Upstream commit 9a2ea132df860177b33c9fd421b26c4e9a0a9396 ]
When returning or breaking early from a for_each_available_child_of_node() loop, we need to explicitly call of_node_put() on the child node to possibly release the node.
--- drivers/hsi/controllers/omap_ssi_core.c | 1 + 1 file changed, 1 insertion(+)
drivers/hsi/controllers/omap_ssi_core.c +1 -0
@@ -524,6 +524,7 @@ static int ssi_probe(struct platform_device *pd)if (!childpdev) { err = -ENODEV ;dev_err (&pd->dev,"failed to create ssi controller port\n" ); +of_node_put (child); goto out3; } }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 283/530 HSI: omap_ssi_port: Fix dma_map_sg error check
In reply to Greg Kroah-HartmanFrom: Jack Wang <[email protected]>
[ Upstream commit 551e325bbd3fb8b5a686ac1e6cf76e5641461cf2 ]
dma_map_sg return 0 on error, in case of error return -EIO to caller.
--- drivers/hsi/controllers/omap_ssi_port.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/hsi/controllers/omap_ssi_port.c +4 -4
@@ -230,10 +230,10 @@ static int ssi_start_dma(struct hsi_msg *msg, int lch)if (msg->ttype ==HSI_MSG_READ ) { err =dma_map_sg (&ssi->device, msg->sgt.sgl, msg->sgt.nents,DMA_FROM_DEVICE ); -if (err <0 ) { +if (!err) {dev_dbg (&ssi->device,"DMA map SG failed !\n" );pm_runtime_put_autosuspend (omap_port->pdev); -return err; +return -EIO ; } csdp = SSI_DST_BURST_4x32_BIT |SSI_DST_MEMORY_PORT | SSI_SRC_SINGLE_ACCESS0 | SSI_SRC_PERIPHERAL_PORT |
@@ -247,10 +247,10 @@ static int ssi_start_dma(struct hsi_msg *msg, int lch) }else { err =dma_map_sg (&ssi->device, msg->sgt.sgl, msg->sgt.nents,DMA_TO_DEVICE ); -if (err <0 ) { +if (!err) {dev_dbg (&ssi->device,"DMA map SG failed !\n" );pm_runtime_put_autosuspend (omap_port->pdev); -return err; +return -EIO ; } csdp = SSI_SRC_BURST_4x32_BIT |SSI_SRC_MEMORY_PORT | SSI_DST_SINGLE_ACCESS0 | SSI_DST_PERIPHERAL_PORT |
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 284/530 media: exynos4-is: fimc-is: Add of_node_put() when breaking out of loop
In reply to Greg Kroah-HartmanFrom: Liang He <[email protected]>
[ Upstream commit 211f8304fa21aaedc2c247f0c9d6c7f1aaa61ad7 ]
In fimc_is_register_subdevs(), we need to call of_node_put() for the reference 'i2c_bus' when breaking out of the for_each_compatible_node() which has increased the refcount.
--- drivers/media/platform/exynos4-is/fimc-is.c | 1 + 1 file changed, 1 insertion(+)
drivers/media/platform/exynos4-is/fimc-is.c +1 -0
@@ -213,6 +213,7 @@ static int fimc_is_register_subdevs(struct fimc_is *is)if (ret <0 || index >=FIMC_IS_SENSORS_NUM ) {of_node_put (child); +of_node_put (i2c_bus);return ret; } index++;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 285/530 tty: xilinx_uartps: Fix the ignore_status
In reply to Greg Kroah-HartmanFrom: Shubhrajyoti Datta <[email protected]>
[ Upstream commit b8a6c3b3d4654fba19881cc77da61eac29f57cae ]
Currently the ignore_status is not considered in the isr. Add a check to add the ignore_status.
--- drivers/tty/serial/xilinx_uartps.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/tty/serial/xilinx_uartps.c +2 -0
@@ -375,6 +375,8 @@ static irqreturn_t cdns_uart_isr(int irq, void *dev_id) isrstatus &= ~CDNS_UART_IXR_TXEMPTY ; } + isrstatus &= port->read_status_mask; + isrstatus &= ~port->ignore_status_mask;/* * Skip RX processing if RX is disabled as RXEMPTY will never be set * as read bytes will not be removed from the FIFO.
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 286/530 media: meson: vdec: add missing clk_disable_unprepare on error in vdec_hevc_start()
In reply to Greg Kroah-HartmanFrom: Xu Qiang <[email protected]>
[ Upstream commit 4029372233e13e281f8c387f279f9f064ced3810 ]
Add the missing clk_disable_unprepare() before return from vdec_hevc_start() in the error handling case.
--- drivers/staging/media/meson/vdec/vdec_hevc.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/staging/media/meson/vdec/vdec_hevc.c +5 -1
@@ -167,8 +167,12 @@ static int vdec_hevc_start(struct amvdec_session *sess)clk_set_rate (core->vdec_hevc_clk,666666666 ); ret =clk_prepare_enable (core->vdec_hevc_clk); -if (ret) +if (ret) { +if (core->platform->revision ==VDEC_REVISION_G12A || + core->platform->revision ==VDEC_REVISION_SM1 ) +clk_disable_unprepare (core->vdec_hevcf_clk);return ret; + }if (core->platform->revision ==VDEC_REVISION_SM1 ) regmap_update_bits(core->regmap_ao, AO_RTI_GEN_PWR_SLEEP0,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 287/530 media: uvcvideo: Fix memory leak in uvc_gpio_parse
In reply to Greg Kroah-HartmanFrom: José Expósito <[email protected]>
[ Upstream commit f0f078457f18f10696888f8d0e6aba9deb9cde92 ]
Previously the unit buffer was allocated before checking the IRQ for privacy GPIO. In case of error, the unit buffer was leaked.
Allocate the unit buffer after the IRQ to avoid it.
Addresses-Coverity-ID: 1474639 ("Resource leak")
--- drivers/media/usb/uvc/uvc_driver.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/media/usb/uvc/uvc_driver.c +4 -4
@@ -1534,10 +1534,6 @@ static int uvc_gpio_parse(struct uvc_device *dev)if (IS_ERR_OR_NULL (gpio_privacy))return PTR_ERR_OR_ZERO (gpio_privacy); - unit =uvc_alloc_entity (UVC_EXT_GPIO_UNIT ,UVC_EXT_GPIO_UNIT_ID ,0 ,1 ); -if (!unit) -return -ENOMEM ; - irq =gpiod_to_irq (gpio_privacy);if (irq <0 ) {if (irq !=EPROBE_DEFER )
@@ -1546,6 +1542,10 @@ static int uvc_gpio_parse(struct uvc_device *dev)return irq; } + unit =uvc_alloc_entity (UVC_EXT_GPIO_UNIT ,UVC_EXT_GPIO_UNIT_ID ,0 ,1 ); +if (!unit) +return -ENOMEM ; + unit->gpio.gpio_privacy = gpio_privacy; unit->gpio.irq = irq; unit->gpio.bControlSize =1 ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 288/530 media: uvcvideo: Use entity get_cur in uvc_ctrl_set
In reply to Greg Kroah-HartmanFrom: Yunke Cao <[email protected]>
[ Upstream commit 5f36851c36b30f713f588ed2b60aa7b4512e2c76 ]
Entity controls should get_cur using an entity-defined function instead of via a query. Fix this in uvc_ctrl_set.
--- drivers/media/usb/uvc/uvc_ctrl.c | 83 ++++++++++++++++++-------------- 1 file changed, 46 insertions(+), 37 deletions(-)
drivers/media/usb/uvc/uvc_ctrl.c +46 -37
@@ -988,36 +988,56 @@ static s32 __uvc_ctrl_get_value(struct uvc_control_mapping *mapping,return value; } -static int __uvc_ctrl_get (struct uvc_video_chain *chain, -struct uvc_control *ctrl,struct uvc_control_mapping *mapping, -s32 *value) +static int __uvc_ctrl_load_cur (struct uvc_video_chain *chain, +struct uvc_control *ctrl) { +u8 *data;int ret; -if ((ctrl->info.flags &UVC_CTRL_FLAG_GET_CUR ) ==0 ) -return -EACCES ; +if (ctrl->loaded) +return 0 ; -if (!ctrl->loaded) { -if (ctrl->entity->get_cur) { - ret = ctrl->entity->get_cur (chain->dev, - ctrl->entity, - ctrl->info.selector, -uvc_ctrl_data (ctrl,UVC_CTRL_DATA_CURRENT ), - ctrl->info.size); - }else { - ret =uvc_query_ctrl (chain->dev,UVC_GET_CUR , - ctrl->entity->id, - chain->dev->intfnum, - ctrl->info.selector, -uvc_ctrl_data (ctrl,UVC_CTRL_DATA_CURRENT ), - ctrl->info.size); - } -if (ret <0 ) -return ret; + data =uvc_ctrl_data (ctrl,UVC_CTRL_DATA_CURRENT ); +if ((ctrl->info.flags &UVC_CTRL_FLAG_GET_CUR ) ==0 ) { +memset (data,0 , ctrl->info.size); ctrl->loaded =1 ; + +return 0 ; } +if (ctrl->entity->get_cur) + ret = ctrl->entity->get_cur (chain->dev, ctrl->entity, + ctrl->info.selector, data, + ctrl->info.size); +else + ret =uvc_query_ctrl (chain->dev,UVC_GET_CUR , + ctrl->entity->id, chain->dev->intfnum, + ctrl->info.selector, data, + ctrl->info.size); + +if (ret <0 ) +return ret; + + ctrl->loaded =1 ; + +return ret; +} + +static int __uvc_ctrl_get (struct uvc_video_chain *chain, +struct uvc_control *ctrl, +struct uvc_control_mapping *mapping, +s32 *value) +{ +int ret; + +if ((ctrl->info.flags &UVC_CTRL_FLAG_GET_CUR ) ==0 ) +return -EACCES ; + + ret =__uvc_ctrl_load_cur (chain, ctrl); +if (ret <0 ) +return ret; + *value =__uvc_ctrl_get_value (mapping,uvc_ctrl_data (ctrl,UVC_CTRL_DATA_CURRENT ));
@@ -1667,21 +1687,10 @@ int uvc_ctrl_set(struct uvc_fh *handle,* needs to be loaded from the device to perform the read-modify-write * operation. */ -if (!ctrl->loaded && (ctrl->info.size *8 ) != mapping->size) { -if ((ctrl->info.flags &UVC_CTRL_FLAG_GET_CUR ) ==0 ) { -memset (uvc_ctrl_data (ctrl,UVC_CTRL_DATA_CURRENT ), -0 , ctrl->info.size); - }else { - ret =uvc_query_ctrl (chain->dev,UVC_GET_CUR , - ctrl->entity->id, chain->dev->intfnum, - ctrl->info.selector, -uvc_ctrl_data (ctrl,UVC_CTRL_DATA_CURRENT ), - ctrl->info.size); -if (ret <0 ) -return ret; - } - - ctrl->loaded =1 ; +if ((ctrl->info.size *8 ) != mapping->size) { + ret =__uvc_ctrl_load_cur (chain, ctrl); +if (ret <0 ) +return ret; }/* Backup the current value in case we need to rollback later. */
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 289/530 media: xilinx: vipp: Fix refcount leak in xvip_graph_dma_init
In reply to Greg Kroah-HartmanFrom: Miaoqian Lin <[email protected]>
[ Upstream commit 1c78f19c3a0ea312a8178a6bfd8934eb93e9b10a ]
of_get_child_by_name() returns a node pointer with refcount incremented, we should use of_node_put() on it when not need anymore. Add missing of_node_put() to avoid refcount leak.
--- drivers/media/platform/xilinx/xilinx-vipp.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
drivers/media/platform/xilinx/xilinx-vipp.c +5 -4
@@ -472,7 +472,7 @@ static int xvip_graph_dma_init(struct xvip_composite_device *xdev) {struct device_node *ports;struct device_node *port; -int ret; +int ret =0 ; ports =of_get_child_by_name (xdev->dev->of_node,"ports" );if (ports ==NULL ) {
@@ -482,13 +482,14 @@ static int xvip_graph_dma_init(struct xvip_composite_device *xdev)for_each_child_of_node (ports, port) { ret =xvip_graph_dma_init_one (xdev, port); -if (ret <0 ) { +if (ret) {of_node_put (port); -return ret; +break ; } } -return 0 ; +of_node_put (ports); +return ret; }static void xvip_graph_cleanup (struct xvip_composite_device *xdev)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 290/530 RDMA/rxe: Fix "kernel NULL pointer dereference" error
In reply to Greg Kroah-HartmanFrom: Zhu Yanjun <[email protected]>
[ Upstream commit a625ca30eff806395175ebad3ac1399014bdb280 ]
When rxe_queue_init in the function rxe_qp_init_req fails, both qp->req.task.func and qp->req.task.arg are not initialized.
Because of creation of qp fails, the function rxe_create_qp will call rxe_qp_do_cleanup to handle allocated resource.
Before calling __rxe_do_task, both qp->req.task.func and qp->req.task.arg should be checked.
--- drivers/infiniband/sw/rxe/rxe_qp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/infiniband/sw/rxe/rxe_qp.c +3 -1
@@ -793,7 +793,9 @@ void rxe_qp_destroy(struct rxe_qp *qp)rxe_cleanup_task (&qp->comp.task);/* flush out any receive wr's or pending requests */ -__rxe_do_task (&qp->req.task); +if (qp->req.task.func) +__rxe_do_task (&qp->req.task); +if (qp->sq.queue) {__rxe_do_task (&qp->comp.task);__rxe_do_task (&qp->req.task);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 291/530 RDMA/rxe: Fix the error caused by qp->sk
In reply to Greg Kroah-HartmanFrom: Zhu Yanjun <[email protected]>
[ Upstream commit 548ce2e66725dcba4e27d1e8ac468d5dd17fd509 ]
When sock_create_kern in the function rxe_qp_init_req fails, qp->sk is set to NULL.
Then the function rxe_create_qp will call rxe_qp_do_cleanup to handle allocated resource.
Before handling qp->sk, this variable should be checked.
--- drivers/infiniband/sw/rxe/rxe_qp.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/infiniband/sw/rxe/rxe_qp.c +4 -2
@@ -835,8 +835,10 @@ static void rxe_qp_do_cleanup(struct work_struct *work)free_rd_atomic_resources (qp); -kernel_sock_shutdown (qp->sk,SHUT_RDWR ); -sock_release (qp->sk); +if (qp->sk) { +kernel_sock_shutdown (qp->sk,SHUT_RDWR ); +sock_release (qp->sk); + } }/* called when the last reference to the qp is dropped */
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 292/530 misc: ocxl: fix possible refcount leak in afu_ioctl()
In reply to Greg Kroah-HartmanFrom: Hangyu Hua <[email protected]>
[ Upstream commit c3b69ba5114c860d730870c03ab4ee45276e5e35 ]
eventfd_ctx_put need to be called to put the refcount that gotten by eventfd_ctx_fdget when ocxl_irq_set_handler fails.
--- drivers/misc/ocxl/file.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/misc/ocxl/file.c +2 -0
@@ -259,6 +259,8 @@ static long afu_ioctl(struct file *file, unsigned int cmd,if (IS_ERR (ev_ctx))return PTR_ERR (ev_ctx); rc =ocxl_irq_set_handler (ctx, irq_id, irq_handler, irq_free, ev_ctx); +if (rc) +eventfd_ctx_put (ev_ctx);break ;case OCXL_IOCTL_GET_METADATA :
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 293/530 fpga: prevent integer overflow in dfl_feature_ioctl_set_irq()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit 939bc5453b8cbdde9f1e5110ce8309aedb1b501a ]
The "hdr.count * sizeof(s32)" multiplication can overflow on 32 bit systems leading to memory corruption. Use array_size() to fix that.
--- drivers/fpga/dfl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/fpga/dfl.c +1 -1
@@ -1864,7 +1864,7 @@ long dfl_feature_ioctl_set_irq(struct platform_device *pdev,return -EINVAL ; fds =memdup_user ((void __user *)(arg +sizeof (hdr)), - hdr.count *sizeof (s32)); +array_size (hdr.count,sizeof (s32)));if (IS_ERR (fds))return PTR_ERR (fds);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 294/530 dmaengine: hisilicon: Disable channels when unregister hisi_dma
In reply to Greg Kroah-HartmanFrom: Jie Hai <[email protected]>
[ Upstream commit e3bdaa04ada31f46d0586df83a2789b8913053c5 ]
When hisi_dma is unloaded or unbinded, all of channels should be disabled. This patch disables DMA channels when driver is unloaded or unbinded.
--- drivers/dma/hisi_dma.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-)
drivers/dma/hisi_dma.c +9 -5
@@ -180,7 +180,8 @@ static void hisi_dma_reset_qp_point(struct hisi_dma_dev *hdma_dev, u32 index)hisi_dma_chan_write (hdma_dev->base,HISI_DMA_CQ_HEAD_PTR , index,0 ); } -static void hisi_dma_reset_hw_chan (struct hisi_dma_chan *chan) +static void hisi_dma_reset_or_disable_hw_chan (struct hisi_dma_chan *chan, +bool disable) {struct hisi_dma_dev *hdma_dev = chan->hdma_dev;u32 index = chan->qp_num, tmp;
@@ -201,8 +202,11 @@ static void hisi_dma_reset_hw_chan(struct hisi_dma_chan *chan)hisi_dma_do_reset (hdma_dev, index);hisi_dma_reset_qp_point (hdma_dev, index);hisi_dma_pause_dma (hdma_dev, index, false); -hisi_dma_enable_dma (hdma_dev, index, true); -hisi_dma_unmask_irq (hdma_dev, index); + +if (!disable) { +hisi_dma_enable_dma (hdma_dev, index, true); +hisi_dma_unmask_irq (hdma_dev, index); + } ret = readl_relaxed_poll_timeout(hdma_dev->base + HISI_DMA_Q_FSM_STS + index * HISI_DMA_OFFSET, tmp,
@@ -218,7 +222,7 @@ static void hisi_dma_free_chan_resources(struct dma_chan *c)struct hisi_dma_chan *chan =to_hisi_dma_chan (c);struct hisi_dma_dev *hdma_dev = chan->hdma_dev; -hisi_dma_reset_hw_chan (chan); +hisi_dma_reset_or_disable_hw_chan (chan, false);vchan_free_chan_resources (&chan->vc);memset (chan->sq,0 ,sizeof (struct hisi_dma_sqe ) * hdma_dev->chan_depth);
@@ -394,7 +398,7 @@ static void hisi_dma_enable_qp(struct hisi_dma_dev *hdma_dev, u32 qp_index)static void hisi_dma_disable_qp (struct hisi_dma_dev *hdma_dev,u32 qp_index) { -hisi_dma_reset_hw_chan (&hdma_dev->chan[qp_index]); +hisi_dma_reset_or_disable_hw_chan (&hdma_dev->chan[qp_index], true); }static void hisi_dma_enable_qps (struct hisi_dma_dev *hdma_dev)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 295/530 dmaengine: hisilicon: Fix CQ head update
In reply to Greg Kroah-HartmanFrom: Jie Hai <[email protected]>
[ Upstream commit 94477a79cf80e8ab55b68f14bc579a12ddea1e0b ]
After completion of data transfer of one or multiple descriptors, the completion status and the current head pointer to submission queue are written into the CQ and interrupt can be generated to inform the software. In interrupt process CQ is read and cq_head is updated.
hisi_dma_irq updates cq_head only when the completion status is success. When an abnormal interrupt reports, cq_head will not update which will cause subsequent interrupt processes read the error CQ and never report the correct status.
This patch updates cq_head whenever CQ is accessed.
--- drivers/dma/hisi_dma.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-)
drivers/dma/hisi_dma.c +3 -5
@@ -436,12 +436,10 @@ static irqreturn_t hisi_dma_irq(int irq, void *data) desc = chan->desc; cqe = chan->cq + chan->cq_head;if (desc) { + chan->cq_head = (chan->cq_head +1 ) % hdma_dev->chan_depth; +hisi_dma_chan_write (hdma_dev->base,HISI_DMA_CQ_HEAD_PTR , + chan->qp_num, chan->cq_head);if (FIELD_GET (STATUS_MASK , cqe->w0) ==STATUS_SUCC ) { - chan->cq_head = (chan->cq_head +1 ) % - hdma_dev->chan_depth; -hisi_dma_chan_write (hdma_dev->base, -HISI_DMA_CQ_HEAD_PTR , chan->qp_num, - chan->cq_head);vchan_cookie_complete (&desc->vd); }else {dev_err (&hdma_dev->pdev->dev,"task error!\n" );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 296/530 dmaengine: hisilicon: Add multi-thread support for a DMA channel
In reply to Greg Kroah-HartmanFrom: Jie Hai <[email protected]>
[ Upstream commit 2cbb95883c990d0002a77e13d3278913ab26ad79 ]
When we get a DMA channel and try to use it in multiple threads it will cause oops and hanging the system.
% echo 100 > /sys/module/dmatest/parameters/threads_per_chan % echo 100 > /sys/module/dmatest/parameters/iterations % echo 1 > /sys/module/dmatest/parameters/run
[383493.327077] Unable to handle kernel paging request at virtual address dead000000000108 [383493.335103] Mem abort info: [383493.335103] ESR = 0x96000044 [383493.335105] EC = 0x25: DABT (current EL), IL = 32 bits [383493.335107] SET = 0, FnV = 0 [383493.335108] EA = 0, S1PTW = 0 [383493.335109] FSC = 0x04: level 0 translation fault [383493.335110] Data abort info: [383493.335111] ISV = 0, ISS = 0x00000044 [383493.364739] CM = 0, WnR = 1 [383493.367793] [dead000000000108] address between user and kernel address ranges [383493.375021] Internal error: Oops: 96000044 [#1] PREEMPT SMP [383493.437574] CPU: 63 PID: 27895 Comm: dma0chan0-copy2 Kdump: loaded Tainted: GO 5.17.0-rc4+ #2 [383493.457851] pstate: 204000c9 (nzCv daIF +PAN -UAO -TCO -DIT -SSBS BTYPE=--) [383493.465331] pc : vchan_tx_submit+0x64/0xa0 [383493.469957] lr : vchan_tx_submit+0x34/0xa0
This occurs because the transmission timed out, and that's due to data race. Each thread rewrite channels's descriptor as soon as device_issue_pending is called. It leads to the situation that the driver thinks that it uses the right descriptor in interrupt handler while channels's descriptor has been changed by other thread. The descriptor which in fact reported interrupt will not be handled any more, as well as its tx->callback. That's why timeout reports.
With current fixes channels' descriptor changes it's value only when it has been used. A new descriptor is acquired from vc->desc_issued queue that is already filled with descriptors that are ready to be sent. Threads have no direct access to DMA channel descriptor. In case of channel's descriptor is busy, try to submit to HW again when a descriptor is completed. In this case, vc->desc_issued may be empty when hisi_dma_start_transfer is called, so delete error reporting on this. Now it is just possible to queue a descriptor for further processing.
--- drivers/dma/hisi_dma.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
drivers/dma/hisi_dma.c +2 -4
@@ -271,7 +271,6 @@ static void hisi_dma_start_transfer(struct hisi_dma_chan *chan) vd =vchan_next_desc (&chan->vc);if (!vd) { -dev_err (&hdma_dev->pdev->dev,"no issued task!\n" ); chan->desc =NULL ;return ; }
@@ -303,7 +302,7 @@ static void hisi_dma_issue_pending(struct dma_chan *c)spin_lock_irqsave (&chan->vc.lock, flags); -if (vchan_issue_pending (&chan->vc)) +if (vchan_issue_pending (&chan->vc) && !chan->desc)hisi_dma_start_transfer (chan);spin_unlock_irqrestore (&chan->vc.lock, flags);
@@ -441,11 +440,10 @@ static irqreturn_t hisi_dma_irq(int irq, void *data) chan->qp_num, chan->cq_head);if (FIELD_GET (STATUS_MASK , cqe->w0) ==STATUS_SUCC ) {vchan_cookie_complete (&desc->vd); +hisi_dma_start_transfer (chan); }else {dev_err (&hdma_dev->pdev->dev,"task error!\n" ); } - - chan->desc =NULL ; }spin_unlock (&chan->vc.lock);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 297/530 dyndbg: fix static_branch manipulation
In reply to Greg Kroah-HartmanFrom: Jim Cromie <[email protected]>
[ Upstream commit ee879be38bc87f8cedc79ae2742958db6533ca59 ]
In https://lore.kernel.org/lkml/[email protected]/
Vincent's patch commented on, and worked around, a bug toggling static_branch's, when a 2nd PRINTK-ish flag was added. The bug results in a premature static_branch_disable when the 1st of 2 flags was disabled.
The cited commit computed newflags, but then in the JUMP_LABEL block, failed to use that result, instead using just one of the terms in it. Using newflags instead made the code work properly.
This is Vincents test-case, reduced. It needs the 2nd flag to demonstrate the bug, but it's explanatory here.
pt_test() {
echo 5 > /sys/module/dynamic_debug/verbose
site="module tcp" # just one callsite
echo " $site =_ " > /proc/dynamic_debug/control # clear it
# A B ~A ~B
for flg in +T +p "-T #broke here" -p; do
echo " $site $flg " > /proc/dynamic_debug/control
done;
# A B ~B ~A
for flg in +T +p "-p #broke here" -T; do
echo " $site $flg " > /proc/dynamic_debug/control
done
}pt_test
--- lib/dynamic_debug.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
lib/dynamic_debug.c +3 -2
@@ -207,10 +207,11 @@ static int ddebug_change(const struct ddebug_query *query,continue ;#ifdef CONFIG_JUMP_LABEL if (dp->flags & _DPRINTK_FLAGS_PRINT) { -if (!(modifiers->flags & _DPRINTK_FLAGS_PRINT)) +if (!(newflags & _DPRINTK_FLAGS_PRINT))static_branch_disable (&dp->key.dd_key_true); - }else if (modifiers->flags & _DPRINTK_FLAGS_PRINT) + }else if (newflags & _DPRINTK_FLAGS_PRINT) {static_branch_enable (&dp->key.dd_key_true); + }#endif dp->flags = newflags; v2pr_info("changed %s:%d [%s]%s =%s\n",
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 298/530 dyndbg: fix module.dyndbg handling
In reply to Greg Kroah-HartmanFrom: Jim Cromie <[email protected]>
[ Upstream commit 85d6b66d31c35158364058ee98fb69ab5bb6a6b1 ]
For CONFIG_DYNAMIC_DEBUG=N, the ddebug_dyndbg_module_param_cb() stub-fn is too permissive:
bash-5.1# modprobe drm JUNKdyndbg
bash-5.1# modprobe drm dyndbgJUNK
[ 42.933220] dyndbg param is supported only in CONFIG_DYNAMIC_DEBUG builds [ 42.937484] ACPI: bus type drm_connector registered
This caused no ill effects, because unknown parameters are either ignored by default with an "unknown parameter" warning, or ignored because dyndbg allows its no-effect use on non-dyndbg builds.
But since the code has an explicit feedback message, it should be issued accurately. Fix with strcmp for exact param-name match.
--- include/linux/dynamic_debug.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/dynamic_debug.h +1 -1
@@ -201,7 +201,7 @@ static inline int ddebug_remove_module(const char *mod)static inline int ddebug_dyndbg_module_param_cb (char *param,char *val,const char *modname) { -if (strstr (param,"dyndbg" )) { +if (!strcmp (param,"dyndbg" )) {/* avoid pr_warn(), which wants pr_fmt() fully defined */ printk (KERN_WARNING "dyndbg param is supported only in " "CONFIG_DYNAMIC_DEBUG builds\n" );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 299/530 dyndbg: let query-modname override actual module name
In reply to Greg Kroah-HartmanFrom: Jim Cromie <[email protected]>
[ Upstream commit e75ef56f74965f426dd819a41336b640ffdd8fbc ]
dyndbg's control-parser: ddebug_parse_query(), requires that search
terms: module, func, file, lineno, are used only once in a query; a thing cannot be named both foo and bar.
The cited commit added an overriding module modname, taken from the module loader, which is authoritative. So it set query.module 1st, which disallowed its use in the query-string.
But now, its useful to allow a module-load to enable classes across a whole (or part of) a subsystem at once.
# enable (dynamic-debug in) drm only modprobe drm dyndbg="class DRM_UT_CORE +p"
# get drm_helper too modprobe drm dyndbg="class DRM_UT_CORE module drm* +p"
# get everything that knows DRM_UT_CORE modprobe drm dyndbg="class DRM_UT_CORE module * +p"
# also for boot-args: drm.dyndbg="class DRM_UT_CORE module * +p"
So convert the override into a default, by filling it only when/after the query-string omitted the module.
NB: the query class FOO handling is forthcoming.
--- lib/dynamic_debug.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
lib/dynamic_debug.c +7 -4
@@ -380,10 +380,6 @@ static int ddebug_parse_query(char *words[], int nwords,return -EINVAL ; } -if (modname) -/* support $modname.dyndbg=<multiple queries> */ - query->module = modname; -for (i =0 ; i < nwords; i +=2 ) {char *keyword = words[i];char *arg = words[i+1 ];
@@ -424,6 +420,13 @@ static int ddebug_parse_query(char *words[], int nwords,if (rc)return rc; } +if (!query->module && modname) +/* +* support $modname.dyndbg=<multiple queries>, when +* not given in the query itself +*/ + query->module = modname; +vpr_info_dq (query,"parsed" );return 0 ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 300/530 dyndbg: drop EXPORTed dynamic_debug_exec_queries
In reply to Greg Kroah-HartmanFrom: Jim Cromie <[email protected]>
[ Upstream commit e26ef3af964acfea311403126acee8c56c89e26b ]
This exported fn is unused, and will not be needed. Lets dump it.
The export was added to let drm control pr_debugs, as part of using them to avoid drm_debug_enabled overheads. But its better to just implement the drm.debug bitmap interface, then its available for everyone.
--- include/linux/dynamic_debug.h | 9 --------- lib/dynamic_debug.c | 29 ----------------------------- 2 files changed, 38 deletions(-)
include/linux/dynamic_debug.h +0 -9
@@ -55,9 +55,6 @@ struct _ddebug {#if defined(CONFIG_DYNAMIC_DEBUG_CORE ) -/* exported for module authors to exercise >control */ -int dynamic_debug_exec_queries (const char *query,const char *modname); -int ddebug_add_module (struct _ddebug *tab,unsigned int n,const char *modname);extern int ddebug_remove_module (const char *mod_name);
@@ -221,12 +218,6 @@ static inline int ddebug_dyndbg_module_param_cb(char *param, char *val, rowsize, groupsize, buf, len, ascii); \ } while (0) -static inline int dynamic_debug_exec_queries(const char *query, const char *modname) -{ -pr_warn ("kernel not built with CONFIG_DYNAMIC_DEBUG_CORE\n" ); -return 0 ; -} -#endif /* !CONFIG_DYNAMIC_DEBUG_CORE */ #endif
lib/dynamic_debug.c +0 -29
@@ -552,35 +552,6 @@ static int ddebug_exec_queries(char *query, const char *modname)return nfound; } -/** -* dynamic_debug_exec_queries - select and change dynamic-debug prints -* @query: query-string described in admin-guide/dynamic-debug-howto -* @modname: string containing module name, usually &module.mod_name -* -* This uses the >/proc/dynamic_debug/control reader, allowing module -* authors to modify their dynamic-debug callsites. The modname is -* canonically struct module.mod_name, but can also be null or a -* module-wildcard, for example: "drm*". -*/ -int dynamic_debug_exec_queries (const char *query,const char *modname) -{ -int rc; -char *qry;/* writable copy of query */ - -if (!query) { -pr_err ("non-null query/command string expected\n" ); -return -EINVAL ; - } - qry =kstrndup (query,PAGE_SIZE ,GFP_KERNEL ); -if (!qry) -return -ENOMEM ; - - rc =ddebug_exec_queries (qry, modname); -kfree (qry); -return rc; -} -EXPORT_SYMBOL_GPL (dynamic_debug_exec_queries); -#define PREFIX_SIZE 64static int remaining (int wrote)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 301/530 clk: qcom: sm6115: Select QCOM_GDSC
In reply to Greg Kroah-HartmanFrom: Dang Huynh <[email protected]>
[ Upstream commit 50ee65dc512b9b5c4de354cf3b4dded34f46c571 ]
While working on the Fxtec Pro1X device, this error shows up with my own minimal configuration:
gcc-sm6115: probe of 1400000.clock-controller failed with error -38
The clock driver depends on CONFIG_QCOM_GDSC and after enabling that, the driver probes successfully.
--- drivers/clk/qcom/Kconfig | 1 + 1 file changed, 1 insertion(+)
drivers/clk/qcom/Kconfig +1 -0
@@ -550,6 +550,7 @@ config SM_DISPCC_8250 config SM_GCC_6115 tristate "SM6115 and SM4250 Global Clock Controller" + select QCOM_GDSC help Support for the global clock controller on SM6115 and SM4250 devices. Say Y if you want to use peripheral devices such as UART, SPI,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 302/530 mtd: devices: docg3: check the return value of devm_ioremap() in the probe
In reply to Greg Kroah-HartmanFrom: William Dean <[email protected]>
[ Upstream commit 26e784433e6c65735cd6d93a8db52531970d9a60 ]
The function devm_ioremap() in docg3_probe() can fail, so its return value should be checked.
--- drivers/mtd/devices/docg3.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/mtd/devices/docg3.c +6 -1
@@ -1974,9 +1974,14 @@ static int __init docg3_probe(struct platform_device *pdev)dev_err (dev,"No I/O memory resource defined\n" );return ret; } - base =devm_ioremap (dev, ress->start,DOC_IOSPACE_SIZE ); ret = -ENOMEM ; + base =devm_ioremap (dev, ress->start,DOC_IOSPACE_SIZE ); +if (!base) { +dev_err (dev,"devm_ioremap dev failed\n" ); +return ret; + } + cascade =devm_kcalloc (dev,DOC_MAX_NBFLOORS ,sizeof (*cascade),GFP_KERNEL );if (!cascade)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 303/530 phy: amlogic: phy-meson-axg-mipi-pcie-analog: Hold reference returned by of_get_parent()
In reply to Greg Kroah-HartmanFrom: Liang He <[email protected]>
[ Upstream commit c4c349be07aeec5f397a349046dc5fc0f2657691 ]
As the of_get_parent() will increase the refcount of the node->parent and the reference will be discarded, so we should hold the reference with which we can decrease the refcount when done.
--- drivers/phy/amlogic/phy-meson-axg-mipi-pcie-analog.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/phy/amlogic/phy-meson-axg-mipi-pcie-analog.c +4 -2
@@ -197,7 +197,7 @@ static int phy_axg_mipi_pcie_analog_probe(struct platform_device *pdev)struct phy_provider *phy;struct device *dev = &pdev->dev;struct phy_axg_mipi_pcie_analog_priv *priv; -struct device_node *np = dev->of_node; +struct device_node *np = dev->of_node, *parent_np;struct regmap *map;int ret;
@@ -206,7 +206,9 @@ static int phy_axg_mipi_pcie_analog_probe(struct platform_device *pdev)return -ENOMEM ;/* Get the hhi system controller node */ - map =syscon_node_to_regmap (of_get_parent (dev->of_node)); + parent_np =of_get_parent (dev->of_node); + map =syscon_node_to_regmap (parent_np); +of_node_put (parent_np);if (IS_ERR (map)) {dev_err (dev,"failed to get HHI regmap\n" );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 304/530 phy: phy-mtk-tphy: fix the phy type setting issue
In reply to Greg Kroah-HartmanFrom: Chunfeng Yun <[email protected]>
[ Upstream commit 931c05a8cb1be029ef2fbc1e4af313d4cb297c47 ]
The PHY type is not set if the index is non zero, prepare type value according to the index, like as mask value.
--- drivers/phy/mediatek/phy-mtk-tphy.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/phy/mediatek/phy-mtk-tphy.c +4 -3
@@ -1039,7 +1039,7 @@ static int phy_type_syscon_get(struct mtk_phy_instance *instance,static int phy_type_set (struct mtk_phy_instance *instance) {int type; -u32 mask; +u32 offset;if (!instance->type_sw)return 0 ;
@@ -1062,8 +1062,9 @@ static int phy_type_set(struct mtk_phy_instance *instance)return 0 ; } - mask =RG_PHY_SW_TYPE << (instance->type_sw_index *BITS_PER_BYTE ); -regmap_update_bits (instance->type_sw, instance->type_sw_reg, mask, type); + offset = instance->type_sw_index *BITS_PER_BYTE ; +regmap_update_bits (instance->type_sw, instance->type_sw_reg, +RG_PHY_SW_TYPE << offset, type << offset);return 0 ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 305/530 mtd: rawnand: intel: Read the chip-select line from the correct OF node
In reply to Greg Kroah-HartmanFrom: Martin Blumenstingl <[email protected]>
[ Upstream commit bfc618fcc3f167ad082053e81e9d664e724c6288 ]
The chip select has to be read from the flash node which is a child node of the NAND controller.
--- drivers/mtd/nand/raw/intel-nand-controller.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
drivers/mtd/nand/raw/intel-nand-controller.c +9 -2
@@ -16,6 +16,7 @@#include <linux/mtd/rawnand.h> #include <linux/mtd/nand.h> +#include <linux/of.h> #include <linux/platform_device.h> #include <linux/sched.h> #include <linux/slab.h>
@@ -580,6 +581,7 @@ static int ebu_nand_probe(struct platform_device *pdev) {struct device *dev = &pdev->dev;struct ebu_nand_controller *ebu_host; +struct device_node *chip_np;struct nand_chip *nand;struct mtd_info *mtd;struct resource *res;
@@ -604,7 +606,12 @@ static int ebu_nand_probe(struct platform_device *pdev)if (IS_ERR (ebu_host->hsnand))return PTR_ERR (ebu_host->hsnand); - ret =device_property_read_u32 (dev,"reg" , &cs); + chip_np =of_get_next_child (dev->of_node,NULL ); +if (!chip_np) +return dev_err_probe (dev, -EINVAL , +"Could not find child node for the NAND chip\n" ); + + ret =of_property_read_u32 (chip_np,"reg" , &cs);if (ret) {dev_err (dev,"failed to get chip select: %d\n" , ret);return ret;
@@ -660,7 +667,7 @@ static int ebu_nand_probe(struct platform_device *pdev)writel (ebu_host->cs[cs].addr_sel |EBU_ADDR_MASK (5 ) |EBU_ADDR_SEL_REGEN , ebu_host->ebu +EBU_ADDR_SEL (cs)); -nand_set_flash_node (&ebu_host->chip, dev->of_node); +nand_set_flash_node (&ebu_host->chip, chip_np); mtd =nand_to_mtd (&ebu_host->chip);if (!mtd->name) {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 306/530 mtd: rawnand: intel: Remove undocumented compatible string
In reply to Greg Kroah-HartmanFrom: Martin Blumenstingl <[email protected]>
[ Upstream commit 68c02ebaa34d41063ccbbc789a352537ddc3cd8a ]
The "intel,nand-controller" compatible string is not part of the dt-bindings. Remove it from the driver as it's not supposed to be used without any documentation for it.
--- drivers/mtd/nand/raw/intel-nand-controller.c | 1 - 1 file changed, 1 deletion(-)
drivers/mtd/nand/raw/intel-nand-controller.c +0 -1
@@ -723,7 +723,6 @@ static int ebu_nand_remove(struct platform_device *pdev) }static const struct of_device_id ebu_nand_match[] = { - { .compatible ="intel,nand-controller" }, { .compatible ="intel,lgm-ebunand" }, {} };
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 307/530 mtd: rawnand: fsl_elbc: Fix none ECC mode
In reply to Greg Kroah-HartmanFrom: Pali Rohár <[email protected]>
[ Upstream commit 049e43b9fd8fd2966940485da163d67e96ee3fea ]
Commit f6424c22aa36 ("mtd: rawnand: fsl_elbc: Make SW ECC work") added support for specifying ECC mode via DTS and skipping autodetection.
But it broke explicit specification of HW ECC mode in DTS as correct settings for HW ECC mode are applied only when NONE mode or nothing was specified in DTS file.
Also it started aliasing NONE mode to be same as when ECC mode was not specified and disallowed usage of ON_DIE mode.
Fix all these issues. Use autodetection of ECC mode only in case when mode was really not specified in DTS file by checking that ecc value is invalid. Set HW ECC settings either when HW ECC was specified in DTS or it was autodetected. And do not fail when ON_DIE mode is set.
--- drivers/mtd/nand/raw/fsl_elbc_nand.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-)
drivers/mtd/nand/raw/fsl_elbc_nand.c +16 -12
@@ -726,36 +726,40 @@ static int fsl_elbc_attach_chip(struct nand_chip *chip)struct fsl_lbc_regs __iomem *lbc = ctrl->regs;unsigned int al; -switch (chip->ecc.engine_type) {/* * if ECC was not chosen in DT, decide whether to use HW or SW ECC from * CS Base Register */ -case NAND_ECC_ENGINE_TYPE_NONE : +if (chip->ecc.engine_type ==NAND_ECC_ENGINE_TYPE_INVALID ) {/* If CS Base Register selects full hardware ECC then use it */ if ((in_be32 (&lbc->bank[priv->bank].br) &BR_DECC ) ==BR_DECC_CHK_GEN ) { - chip->ecc.read_page = fsl_elbc_read_page; - chip->ecc.write_page = fsl_elbc_write_page; - chip->ecc.write_subpage = fsl_elbc_write_subpage; - chip->ecc.engine_type =NAND_ECC_ENGINE_TYPE_ON_HOST ; -mtd_set_ooblayout (mtd, &fsl_elbc_ooblayout_ops); - chip->ecc.size =512 ; - chip->ecc.bytes =3 ; - chip->ecc.strength =1 ; }else {/* otherwise fall back to default software ECC */ chip->ecc.engine_type =NAND_ECC_ENGINE_TYPE_SOFT ; chip->ecc.algo =NAND_ECC_ALGO_HAMMING ; } + } + +switch (chip->ecc.engine_type) { +/* if HW ECC was chosen, setup ecc and oob layout */ +case NAND_ECC_ENGINE_TYPE_ON_HOST : + chip->ecc.read_page = fsl_elbc_read_page; + chip->ecc.write_page = fsl_elbc_write_page; + chip->ecc.write_subpage = fsl_elbc_write_subpage; +mtd_set_ooblayout (mtd, &fsl_elbc_ooblayout_ops); + chip->ecc.size =512 ; + chip->ecc.bytes =3 ; + chip->ecc.strength =1 ;break ; -/* if SW ECC was chosen in DT, we do not need to set anything here */ +/* if none or SW ECC was chosen, we do not need to set anything here */ +case NAND_ECC_ENGINE_TYPE_NONE :case NAND_ECC_ENGINE_TYPE_SOFT : +case NAND_ECC_ENGINE_TYPE_ON_DIE :break ; -/* should we also implement *_ECC_ENGINE_CONTROLLER to do as above? */ default :return -EINVAL ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 308/530 RDMA/irdma: Align AE id codes to correct flush code and event
In reply to Greg Kroah-HartmanFrom: Sindhu-Devale <[email protected]>
[ Upstream commit 7f51a961f8c6b84752a48e950074a8c4a0808d91 ]
A number of asynchronous event (AE) ids were not aligned to the correct flush_code and event_type. Fix these up so that the correct IBV error and event codes are returned to application.
Also, add handling for new AE ids like IRDMA_AE_INVALID_REQUEST to return the correct WC error code.
--- drivers/infiniband/hw/irdma/defs.h | 1 + drivers/infiniband/hw/irdma/hw.c | 51 +++++++++++++++++------------ drivers/infiniband/hw/irdma/type.h | 1 + drivers/infiniband/hw/irdma/user.h | 1 + drivers/infiniband/hw/irdma/utils.c | 3 ++ drivers/infiniband/hw/irdma/verbs.c | 2 ++ 6 files changed, 38 insertions(+), 21 deletions(-)
drivers/infiniband/hw/irdma/defs.h +1 -0
@@ -314,6 +314,7 @@ enum irdma_cqp_op_type {#define IRDMA_AE_IB_REMOTE_ACCESS_ERROR 0x020d#define IRDMA_AE_IB_REMOTE_OP_ERROR 0x020e#define IRDMA_AE_WQE_LSMM_TOO_LONG 0x0220 +#define IRDMA_AE_INVALID_REQUEST 0x0223#define IRDMA_AE_DDP_INVALID_MSN_GAP_IN_MSN 0x0301#define IRDMA_AE_DDP_UBE_DDP_MESSAGE_TOO_LONG_FOR_AVAILABLE_BUFFER 0x0303#define IRDMA_AE_DDP_UBE_INVALID_DDP_VERSION 0x0304
drivers/infiniband/hw/irdma/hw.c +30 -21
89 lines not on this page · raw message
drivers/infiniband/hw/irdma/type.h +1 -0
@@ -99,6 +99,7 @@ enum irdma_term_mpa_errors {enum irdma_qp_event_type {IRDMA_QP_EVENT_CATASTROPHIC ,IRDMA_QP_EVENT_ACCESS_ERR , +IRDMA_QP_EVENT_REQ_ERR , };enum irdma_hw_stats_index_32b {
drivers/infiniband/hw/irdma/user.h +1 -0
@@ -104,6 +104,7 @@ enum irdma_flush_opcode {FLUSH_FATAL_ERR ,FLUSH_RETRY_EXC_ERR ,FLUSH_MW_BIND_ERR , + FLUSH_REM_INV_REQ_ERR, }; enum irdma_cmpl_status {
drivers/infiniband/hw/irdma/utils.c +3 -0
@@ -2535,6 +2535,9 @@ void irdma_ib_qp_event(struct irdma_qp *iwqp, enum irdma_qp_event_type event)case IRDMA_QP_EVENT_ACCESS_ERR : ibevent.event =IB_EVENT_QP_ACCESS_ERR ;break ; +case IRDMA_QP_EVENT_REQ_ERR : + ibevent.event =IB_EVENT_QP_REQ_ERR ; +break ; } ibevent.device = iwqp->ibqp.device; ibevent.element.qp = &iwqp->ibqp;
drivers/infiniband/hw/irdma/verbs.c +2 -0
@@ -3359,6 +3359,8 @@ static enum ib_wc_status irdma_flush_err_to_ib_wc_status(enum irdma_flush_opcodereturn IB_WC_RETRY_EXC_ERR ;case FLUSH_MW_BIND_ERR :return IB_WC_MW_BIND_ERR ; +case FLUSH_REM_INV_REQ_ERR : +return IB_WC_REM_INV_REQ_ERR ;case FLUSH_FATAL_ERR :default :return IB_WC_FATAL_ERR ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 309/530 RDMA/srp: Fix srp_abort()
In reply to Greg Kroah-HartmanFrom: Bart Van Assche <[email protected]>
[ Upstream commit 6dbe4a8dead84de474483910b02ec9e6a10fc1a9 ]
Fix the code for converting a SCSI command pointer into an SRP request pointer.
--- drivers/infiniband/ulp/srp/ib_srp.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
drivers/infiniband/ulp/srp/ib_srp.c +1 -3
@@ -2783,7 +2783,7 @@ static int srp_send_tsk_mgmt(struct srp_rdma_ch *ch, u64 req_tag, u64 lun,static int srp_abort (struct scsi_cmnd *scmnd) {struct srp_target_port *target =host_to_target (scmnd->device->host); -struct srp_request *req = (struct srp_request *) scmnd->host_scribble; +struct srp_request *req =scsi_cmd_priv (scmnd);u32 tag;u16 ch_idx;struct srp_rdma_ch *ch;
@@ -2791,8 +2791,6 @@ static int srp_abort(struct scsi_cmnd *scmnd)shost_printk (KERN_ERR , target->scsi_host,"SRP abort called\n" ); -if (!req) -return SUCCESS ; tag =blk_mq_unique_tag (scsi_cmd_to_rq (scmnd)); ch_idx =blk_mq_unique_tag_to_hwq (tag);if (WARN_ON_ONCE (ch_idx >= target->ch_count))
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 310/530 RDMA/siw: Always consume all skbuf data in sk_data_ready() upcall.
In reply to Greg Kroah-HartmanFrom: Bernard Metzler <[email protected]>
[ Upstream commit 754209850df8367c954ac1de7671c7430b1f342c ]
For header and trailer/padding processing, siw did not consume new skb data until minimum amount present to fill current header or trailer structure, including potential payload padding. Not consuming any data during upcall may cause a receive stall, since tcp_read_sock() is not upcalling again if no new data arrive.
A NFSoRDMA client got stuck at RDMA Write reception of unaligned payload, if the current skb did contain only the expected 3 padding bytes, but not the 4 bytes CRC trailer. Expecting 4 more bytes already arrived in another skb, and not consuming those 3 bytes in the current upcall left the Write incomplete, waiting for the CRC forever.
--- drivers/infiniband/sw/siw/siw_qp_rx.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-)
drivers/infiniband/sw/siw/siw_qp_rx.c +15 -12
@@ -961,27 +961,28 @@ int siw_proc_terminate(struct siw_qp *qp)static int siw_get_trailer (struct siw_qp *qp,struct siw_rx_stream *srx) {struct sk_buff *skb = srx->skb; +int avail =min (srx->skb_new, srx->fpdu_part_rem);u8 *tbuf = (u8 *)&srx->trailer.crc - srx->pad;__wsum crc_in, crc_own =0 ;siw_dbg_qp (qp,"expected %d, available %d, pad %u\n" , srx->fpdu_part_rem, srx->skb_new, srx->pad); -if (srx->skb_new < srx->fpdu_part_rem) -return -EAGAIN ; - -skb_copy_bits (skb, srx->skb_offset, tbuf, srx->fpdu_part_rem); +skb_copy_bits (skb, srx->skb_offset, tbuf, avail); -if (srx->mpa_crc_hd && srx->pad) -crypto_shash_update (srx->mpa_crc_hd, tbuf, srx->pad); + srx->skb_new -= avail; + srx->skb_offset += avail; + srx->skb_copied += avail; + srx->fpdu_part_rem -= avail; - srx->skb_new -= srx->fpdu_part_rem; - srx->skb_offset += srx->fpdu_part_rem; - srx->skb_copied += srx->fpdu_part_rem; +if (srx->fpdu_part_rem) +return -EAGAIN ;if (!srx->mpa_crc_hd)return 0 ; +if (srx->pad) +crypto_shash_update (srx->mpa_crc_hd, tbuf, srx->pad);/* * CRC32 is computed, transmitted and received directly in NBO, * so there's never a reason to convert byte order.
@@ -1083,10 +1084,9 @@ static int siw_get_hdr(struct siw_rx_stream *srx)* completely received. */ if (iwarp_pktinfo[opcode].hdr_len >sizeof (struct iwarp_ctrl_tagged )) { - bytes = iwarp_pktinfo[opcode].hdr_len -MIN_DDP_HDR ; +int hdrlen = iwarp_pktinfo[opcode].hdr_len; -if (srx->skb_new < bytes) -return -EAGAIN ; + bytes =min_t (int, hdrlen -MIN_DDP_HDR , srx->skb_new);skb_copy_bits (skb, srx->skb_offset, (char *)c_hdr + srx->fpdu_part_rcvd, bytes);
@@ -1096,6 +1096,9 @@ static int siw_get_hdr(struct siw_rx_stream *srx) srx->skb_new -= bytes; srx->skb_offset += bytes; srx->skb_copied += bytes; + +if (srx->fpdu_part_rcvd < hdrlen) +return -EAGAIN ; }/*
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 311/530 RDMA/siw: Fix QP destroy to wait for all references dropped.
In reply to Greg Kroah-HartmanFrom: Bernard Metzler <[email protected]>
[ Upstream commit a3c278807a459e6f50afee6971cabe74cccfb490 ]
Delay QP destroy completion until all siw references to QP are dropped. The calling RDMA core will free QP structure after successful return from siw_qp_destroy() call, so siw must not hold any remaining reference to the QP upon return. A use-after-free was encountered in xfstest generic/460, while testing NFSoRDMA. Here, after a TCP connection drop by peer, the triggered siw_cm_work_handler got delayed until after QP destroy call, referencing a QP which has already freed.
--- drivers/infiniband/sw/siw/siw.h | 1 + drivers/infiniband/sw/siw/siw_qp.c | 2 +- drivers/infiniband/sw/siw/siw_verbs.c | 3 +++ 3 files changed, 5 insertions(+), 1 deletion(-)
drivers/infiniband/sw/siw/siw.h +1 -0
@@ -418,6 +418,7 @@ struct siw_qp {struct ib_qp base_qp;struct siw_device *sdev;struct kref ref; +struct completion qp_free;struct list_head devq;int tx_cpu;struct siw_qp_attrs attrs;
drivers/infiniband/sw/siw/siw_qp.c +1 -1
@@ -1342,6 +1342,6 @@ void siw_free_qp(struct kref *ref)vfree (qp->orq);siw_put_tx_cpu (qp->tx_cpu); - +complete (&qp->qp_free);atomic_dec (&sdev->num_qp); }
drivers/infiniband/sw/siw/siw_verbs.c +3 -0
@@ -478,6 +478,8 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,list_add_tail (&qp->devq, &sdev->qp_list);spin_unlock_irqrestore (&sdev->lock, flags); +init_completion (&qp->qp_free); +return 0 ; err_out_xa:
@@ -622,6 +624,7 @@ int siw_destroy_qp(struct ib_qp *base_qp, struct ib_udata *udata) qp->scq = qp->rcq =NULL ;siw_qp_put (qp); +wait_for_completion (&qp->qp_free);return 0 ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 312/530 ata: fix ata_id_sense_reporting_enabled() and ata_id_has_sense_reporting()
In reply to Greg Kroah-HartmanFrom: Niklas Cassel <[email protected]>
[ Upstream commit 690aa8c3ae308bc696ec8b1b357b995193927083 ]
ACS-5 section
7.13.6.41 Words 85..87, 120: Commands and feature sets supported or enabled states that:
If bit 15 of word 86 is set to one, bit 14 of word 119 is set to one, and bit 15 of word 119 is cleared to zero, then word 119 is valid.
If bit 15 of word 86 is set to one, bit 14 of word 120 is set to one, and bit 15 of word 120 is cleared to zero, then word 120 is valid.
(This text also exists in really old ACS standards, e.g. ACS-3.)
Currently, ata_id_sense_reporting_enabled() and ata_id_has_sense_reporting() both check bit 15 of word 86, but neither of them check that bit 14 of word 119 is set to one, or that bit 15 of word 119 is cleared to zero.
Additionally, make ata_id_sense_reporting_enabled() return false if !ata_id_has_sense_reporting(), similar to how e.g. ata_id_flush_ext_enabled() returns false if !ata_id_has_flush_ext().
--- include/linux/ata.h | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
include/linux/ata.h +9 -4
@@ -770,16 +770,21 @@ static inline bool ata_id_has_read_log_dma_ext(const u16 *id)static inline bool ata_id_has_sense_reporting (const u16 *id) { -if (!(id[ATA_ID_CFS_ENABLE_2 ] & (1 <<15 ))) +if (!(id[ATA_ID_CFS_ENABLE_2 ] &BIT (15 ))) +return false; +if ((id[ATA_ID_COMMAND_SET_3 ] & (BIT (15 ) |BIT (14 ))) !=BIT (14 ))return false; -return id[ATA_ID_COMMAND_SET_3 ] & (1 <<6 ); +return id[ATA_ID_COMMAND_SET_3 ] &BIT (6 ); }static inline bool ata_id_sense_reporting_enabled (const u16 *id) { -if (!(id[ATA_ID_CFS_ENABLE_2 ] & (1 <<15 ))) +if (!ata_id_has_sense_reporting (id)) +return false; +/* ata_id_has_sense_reporting() == true, word 86 must have bit 15 set */ +if ((id[ATA_ID_COMMAND_SET_4 ] & (BIT (15 ) |BIT (14 ))) !=BIT (14 ))return false; -return id[ATA_ID_COMMAND_SET_4 ] & (1 <<6 ); +return id[ATA_ID_COMMAND_SET_4 ] &BIT (6 ); }/**
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 313/530 ata: fix ata_id_has_devslp()
In reply to Greg Kroah-HartmanFrom: Niklas Cassel <[email protected]>
[ Upstream commit 9c6e09a434e1317e09b78b3b69cd384022ec9a03 ]
ACS-5 section
7.13.6.36 Word 78: Serial ATA features supported
states that:
If word 76 is not 0000h or FFFFh, word 78 reports the features supported by the device. If this word is not supported, the word shall be cleared to zero.
(This text also exists in really old ACS standards, e.g. ACS-3.)
Additionally, move the macro to the other ATA_ID_FEATURE_SUPP macros (which already have this check), thus making it more likely that the next ATA_ID_FEATURE_SUPP macro that is added will include this check.
--- include/linux/ata.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
include/linux/ata.h +4 -1
@@ -565,6 +565,10 @@ struct ata_bmdma_prd { ((((id)[ATA_ID_SATA_CAPABILITY ] !=0x0000 ) && \ ((id)[ATA_ID_SATA_CAPABILITY ] !=0xffff )) && \ ((id)[ATA_ID_FEATURE_SUPP] & (1 << 2))) +#define ata_id_has_devslp (id) \ + ((((id)[ATA_ID_SATA_CAPABILITY] != 0x0000) && \ + ((id)[ATA_ID_SATA_CAPABILITY] != 0xffff)) && \ + ((id)[ATA_ID_FEATURE_SUPP] & (1 << 8)))#define ata_id_iordy_disable (id) ((id)[ATA_ID_CAPABILITY] & (1 << 10))#define ata_id_has_iordy (id) ((id)[ATA_ID_CAPABILITY] & (1 << 11))#define ata_id_u32 (id,n) \
@@ -577,7 +581,6 @@ struct ata_bmdma_prd {#define ata_id_cdb_intr (id) (((id)[ATA_ID_CONFIG] & 0x60) == 0x20)#define ata_id_has_da (id) ((id)[ATA_ID_SATA_CAPABILITY_2] & (1 << 4)) -#define ata_id_has_devslp (id) ((id)[ATA_ID_FEATURE_SUPP] & (1 << 8))#define ata_id_has_ncq_autosense (id) \ ((id)[ATA_ID_FEATURE_SUPP] & (1 << 7))
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 314/530 ata: fix ata_id_has_ncq_autosense()
In reply to Greg Kroah-HartmanFrom: Niklas Cassel <[email protected]>
[ Upstream commit a5fb6bf853148974dbde092ec1bde553bea5e49f ]
ACS-5 section
7.13.6.36 Word 78: Serial ATA features supported
states that:
If word 76 is not 0000h or FFFFh, word 78 reports the features supported by the device. If this word is not supported, the word shall be cleared to zero.
(This text also exists in really old ACS standards, e.g. ACS-3.)
Additionally, move the macro to the other ATA_ID_FEATURE_SUPP macros (which already have this check), thus making it more likely that the next ATA_ID_FEATURE_SUPP macro that is added will include this check.
--- include/linux/ata.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
include/linux/ata.h +4 -2
@@ -569,6 +569,10 @@ struct ata_bmdma_prd { ((((id)[ATA_ID_SATA_CAPABILITY ] !=0x0000 ) && \ ((id)[ATA_ID_SATA_CAPABILITY ] !=0xffff )) && \ ((id)[ATA_ID_FEATURE_SUPP] & (1 << 8))) +#define ata_id_has_ncq_autosense (id) \ + ((((id)[ATA_ID_SATA_CAPABILITY] != 0x0000) && \ + ((id)[ATA_ID_SATA_CAPABILITY] != 0xffff)) && \ + ((id)[ATA_ID_FEATURE_SUPP] & (1 << 7)))#define ata_id_iordy_disable (id) ((id)[ATA_ID_CAPABILITY] & (1 << 10))#define ata_id_has_iordy (id) ((id)[ATA_ID_CAPABILITY] & (1 << 11))#define ata_id_u32 (id,n) \
@@ -581,8 +585,6 @@ struct ata_bmdma_prd {#define ata_id_cdb_intr (id) (((id)[ATA_ID_CONFIG] & 0x60) == 0x20)#define ata_id_has_da (id) ((id)[ATA_ID_SATA_CAPABILITY_2] & (1 << 4)) -#define ata_id_has_ncq_autosense (id) \ - ((id)[ATA_ID_FEATURE_SUPP] & (1 << 7))static inline bool ata_id_has_hipm (const u16 *id) {
Signature · 1 line
2.35.1