5.19.4-rc1 review
Subsystems (4)
Greg Kroah-Hartman
maintainerPATCH 150/365 tsnep: Fix tsnep_tx_unmap() error path usage
In reply to Greg Kroah-HartmanFrom: Gerhard Engleder <[email protected]>
commit b3bb8628bf64440065976c71e4ab09186c393597 upstream.
If tsnep_tx_map() fails, then tsnep_tx_unmap() shall start at the write index like tsnep_tx_map(). This is different to the normal operation. Thus, add an additional parameter to tsnep_tx_unmap() to enable start at different positions for successful TX and failed TX.
--- drivers/net/ethernet/engleder/tsnep_main.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/net/ethernet/engleder/tsnep_main.c +4 -4
@@ -340,14 +340,14 @@ static int tsnep_tx_map(struct sk_buff *skb, struct tsnep_tx *tx, int count)return 0 ; } -static void tsnep_tx_unmap (struct tsnep_tx *tx,int count) +static void tsnep_tx_unmap (struct tsnep_tx *tx,int index,int count) {struct device *dmadev = tx->adapter->dmadev;struct tsnep_tx_entry *entry;int i;for (i =0 ; i < count; i++) { - entry = &tx->entry[(tx->read + i) %TSNEP_RING_SIZE ]; + entry = &tx->entry[(index + i) %TSNEP_RING_SIZE ];if (entry->len) {if (i ==0 )
@@ -395,7 +395,7 @@ static netdev_tx_t tsnep_xmit_frame_ring(struct sk_buff *skb, retval =tsnep_tx_map (skb, tx, count);if (retval !=0 ) { -tsnep_tx_unmap (tx, count); +tsnep_tx_unmap (tx, tx->write, count);dev_kfree_skb_any (entry->skb); entry->skb =NULL ;
@@ -464,7 +464,7 @@ static bool tsnep_tx_poll(struct tsnep_tx *tx, int napi_budget)if (skb_shinfo (entry->skb)->nr_frags >0 ) count +=skb_shinfo (entry->skb)->nr_frags; -tsnep_tx_unmap (tx, count); +tsnep_tx_unmap (tx, tx->read, count); if ((skb_shinfo(entry->skb)->tx_flags & SKBTX_IN_PROGRESS) && (__le32_to_cpu(entry->desc_wb->properties) &
Signature · 1 line
2.37.2
Greg Kroah-Hartman
maintainerPATCH 151/365 atm: idt77252: fix use-after-free bugs caused by tst_timer
In reply to Greg Kroah-HartmanFrom: Duoming Zhou <[email protected]>
commit 3f4093e2bf4673f218c0bf17d8362337c400e77b upstream.
There are use-after-free bugs caused by tst_timer. The root cause is that there are no functions to stop tst_timer in idt77252_exit(). One of the possible race conditions is shown below:
(thread 1) | (thread 2)
| idt77252_init_one
| init_card
| fill_tst
| mod_timer(&card->tst_timer, ...)
idt77252_exit | (wait a time)
| tst_timer
|
| ...
kfree(card) // FREE |
| card->soft_tst[e] // USEThe idt77252_dev is deallocated in idt77252_exit() and used in timer handler.
This patch adds del_timer_sync() in idt77252_exit() in order that the timer handler could be stopped before the idt77252_dev is deallocated.
--- drivers/atm/idt77252.c | 1 + 1 file changed, 1 insertion(+)
drivers/atm/idt77252.c +1 -0
@@ -3752,6 +3752,7 @@ static void __exit idt77252_exit(void) card = idt77252_chain; dev = card->atmdev; idt77252_chain = card->next; +del_timer_sync (&card->tst_timer);if (dev->phy->stop) dev->phy->stop (dev);
Greg Kroah-Hartman
maintainerPATCH 152/365 fscache: dont leak cookie access refs if invalidation is in progress or failed
In reply to Greg Kroah-HartmanFrom: Jeff Layton <[email protected]>
commit fb24771faf72a2fd62b3b6287af3c610c3ec9cf1 upstream.
It's possible for a request to invalidate a fscache_cookie will come in while we're already processing an invalidation. If that happens we currently take an extra access reference that will leak. Only call __fscache_begin_cookie_access if the FSCACHE_COOKIE_DO_INVALIDATE bit was previously clear.
Also, ensure that we attempt to clear the bit when the cookie is "FAILED" and put the reference to avoid an access leak.
--- fs/fscache/cookie.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
fs/fscache/cookie.c +5 -2
@@ -739,6 +739,9 @@ static void fscache_cookie_state_machine(struct fscache_cookie *cookie) fallthrough;case FSCACHE_COOKIE_STATE_FAILED : +if (test_and_clear_bit (FSCACHE_COOKIE_DO_INVALIDATE , &cookie->flags)) +fscache_end_cookie_access (cookie, fscache_access_invalidate_cookie_end); +if (atomic_read (&cookie->n_accesses) !=0 )break ;if (test_bit (FSCACHE_COOKIE_DO_RELINQUISH , &cookie->flags)) {
@@ -1063,8 +1066,8 @@ void __fscache_invalidate(struct fscache_cookie *cookie,return ;case FSCACHE_COOKIE_STATE_LOOKING_UP : -__fscache_begin_cookie_access (cookie, fscache_access_invalidate_cookie); -set_bit (FSCACHE_COOKIE_DO_INVALIDATE , &cookie->flags); +if (!test_and_set_bit (FSCACHE_COOKIE_DO_INVALIDATE , &cookie->flags)) +__fscache_begin_cookie_access (cookie, fscache_access_invalidate_cookie); fallthrough;case FSCACHE_COOKIE_STATE_CREATING :spin_unlock (&cookie->lock);
Signature · 1 line
2.37.2
Greg Kroah-Hartman
maintainerPATCH 153/365 geneve: fix TOS inheriting for ipv4
In reply to Greg Kroah-HartmanFrom: Matthias May <[email protected]>
commit b4ab94d6adaa5cf842b68bd28f4b50bc774496bd upstream.
The current code retrieves the TOS field after the lookup on the ipv4 routing table. The routing process currently only allows routing based on the original 3 TOS bits, and not on the full 6 DSCP bits.
As a result the retrieved TOS is cut to the 3 bits. However for inheriting purposes the full 6 bits should be used.
Extract the full 6 bits before the route lookup and use that instead of the cut off 3 TOS bits.
--- drivers/net/geneve.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
drivers/net/geneve.c +8 -4
@@ -797,7 +797,8 @@ static struct rtable *geneve_get_v4_rt(sstruct geneve_sock *gs4, struct flowi4 *fl4, const struct ip_tunnel_info *info, - __be16 dport, __be16 sport) + __be16 dport, __be16 sport, + __u8 *full_tos) { bool use_cache = ip_tunnel_dst_cache_usable(skb, info);struct geneve_dev *geneve =netdev_priv (dev);
@@ -823,6 +824,8 @@ static struct rtable *geneve_get_v4_rt(s use_cache = false; } fl4->flowi4_tos =RT_TOS (tos); +if (full_tos) + *full_tos = tos; dst_cache = (struct dst_cache *)&info->dst_cache;if (use_cache) {
@@ -910,6 +913,7 @@ static int geneve_xmit_skb(struct sk_bufconst struct ip_tunnel_key *key = &info->key;struct rtable *rt;struct flowi4 fl4; +__u8 full_tos;__u8 tos, ttl;__be16 df =0 ;__be16 sport;
@@ -920,7 +924,7 @@ static int geneve_xmit_skb(struct sk_buf sport =udp_flow_src_port (geneve->net, skb,1 ,USHRT_MAX , true); rt =geneve_get_v4_rt (skb, dev, gs4, &fl4, info, - geneve->cfg.info.key.tp_dst, sport); + geneve->cfg.info.key.tp_dst, sport, &full_tos);if (IS_ERR (rt))return PTR_ERR (rt);
@@ -964,7 +968,7 @@ static int geneve_xmit_skb(struct sk_buf df = key->tun_flags &TUNNEL_DONT_FRAGMENT ?htons (IP_DF ) :0 ; }else { - tos =ip_tunnel_ecn_encap (fl4.flowi4_tos,ip_hdr (skb), skb); + tos =ip_tunnel_ecn_encap (full_tos,ip_hdr (skb), skb);if (geneve->cfg.ttl_inherit) ttl =ip_tunnel_get_ttl (ip_hdr (skb), skb);else
@@ -1148,7 +1152,7 @@ static int geneve_fill_metadata_dst(stru 1, USHRT_MAX, true); rt =geneve_get_v4_rt (skb, dev, gs4, &fl4, info, - geneve->cfg.info.key.tp_dst, sport); + geneve->cfg.info.key.tp_dst, sport,NULL );if (IS_ERR (rt))return PTR_ERR (rt);
Greg Kroah-Hartman
maintainerPATCH 154/365 nvme-fc: fix the fc_appid_store return value
In reply to Greg Kroah-HartmanFrom: Christoph Hellwig <[email protected]>
commit 9317d0014499182c77a03cd095e83bcfb0f53750 upstream.
"nvme-fc: fold t fc_update_appid into fc_appid_store" accidentally changed the userspace interface for the appid attribute, because the code that decrements "count" to remove a trailing '\n' in the parsing results in the decremented value being incorrectly be returned from the sysfs write. Fix this by keeping an orig_count variable for the full length of the write.
--- drivers/nvme/host/fc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/nvme/host/fc.c +2 -1
@@ -3880,6 +3880,7 @@ static int fc_parse_cgrpid(const char *buf, u64 *id)static ssize_t fc_appid_store (struct device *dev,struct device_attribute *attr,const char *buf,size_t count) { +size_t orig_count = count;u64 cgrp_id;int appid_len =0 ;int cgrpid_len =0 ;
@@ -3904,7 +3905,7 @@ static ssize_t fc_appid_store(struct device *dev, ret =blkcg_set_fc_appid (app_id, cgrp_id,sizeof (app_id));if (ret <0 )return ret; -return count; +return orig_count; } static DEVICE_ATTR(appid_store, 0200, NULL, fc_appid_store);#endif /* CONFIG_BLK_CGROUP_FC_APPID */
Signature · 1 line
2.37.2
Greg Kroah-Hartman
maintainerPATCH 155/365 perf probe: Fix an error handling path in parse_perf_probe_command()
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
commit 4bf6dcaa93bcd083a13c278a91418fe10e6d23a0 upstream.
If a memory allocation fail, we should branch to the error handling path in order to free some resources allocated a few lines above.
--- tools/perf/util/probe-event.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
tools/perf/util/probe-event.c +4 -2
@@ -1775,8 +1775,10 @@ int parse_perf_probe_command(const charif (!pev->event && pev->point.function && pev->point.line && !pev->point.lazy_line && !pev->point.offset) {if (asprintf (&pev->event,"%s_L%d" , pev->point.function, - pev->point.line) <0 ) -return -ENOMEM ; + pev->point.line) <0 ) { + ret = -ENOMEM ; + goto out; + } }/* Copy arguments and ensure return probe has no C argument */
Greg Kroah-Hartman
maintainerPATCH 156/365 i2c: qcom-geni: Fix GPI DMA buffer sync-back
In reply to Greg Kroah-HartmanFrom: Robin Reckmann <[email protected]>
commit 8689b80b22dbf1f5e993233370fe57f08731b14d upstream.
Fix i2c transfers using GPI DMA mode for all message types that do not set the I2C_M_DMA_SAFE flag (e.g. SMBus "read byte").
In this case a bounce buffer is returned by i2c_get_dma_safe_msg_buf(), and it has to synced back to the message after the transfer is done.
Add missing assignment of dma buffer in geni_i2c_gpi().
Set xferred in i2c_put_dma_safe_msg_buf() to true in case of no error to ensure the sync-back of this dma buffer to the message.
--- drivers/i2c/busses/i2c-qcom-geni.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/i2c/busses/i2c-qcom-geni.c +3 -2
@@ -484,12 +484,12 @@ static void geni_i2c_gpi_unmap(struct ge {if (tx_buf) {dma_unmap_single (gi2c->se.dev->parent, tx_addr, msg->len,DMA_TO_DEVICE ); -i2c_put_dma_safe_msg_buf (tx_buf, msg, false); +i2c_put_dma_safe_msg_buf (tx_buf, msg, !gi2c->err); }if (rx_buf) {dma_unmap_single (gi2c->se.dev->parent, rx_addr, msg->len,DMA_FROM_DEVICE ); -i2c_put_dma_safe_msg_buf (rx_buf, msg, false); +i2c_put_dma_safe_msg_buf (rx_buf, msg, !gi2c->err); } }
@@ -553,6 +553,7 @@ static int geni_i2c_gpi(struct geni_i2c_ desc->callback_param = gi2c;dmaengine_submit (desc); + *buf = dma_buf; *dma_addr_p = addr;return 0 ;
Greg Kroah-Hartman
maintainerPATCH 157/365 perf parse-events: Fix segfault when event parser gets an error
In reply to Greg Kroah-HartmanFrom: Adrian Hunter <[email protected]>
commit 2e828582b81f5bc76a4fe8e7812df259ab208302 upstream.
parse_events() is often called with parse_events_error set to NULL. Make parse_events_error__handle() not segfault in that case.
A subsequent patch changes to avoid passing NULL in the first place.
--- tools/perf/util/parse-events.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
tools/perf/util/parse-events.c +11 -3
@@ -2391,9 +2391,12 @@ void parse_events_error__exit(struct parvoid parse_events_error__handle (struct parse_events_error *err,int idx,char *str,char *help) { -if (WARN (!str,"WARNING: failed to provide error string\n" )) { -free (help); -return ; +if (WARN (!str,"WARNING: failed to provide error string\n" )) + goto out_free; +if (!err) { +/* Assume caller does not want message printed */ +pr_debug ("event syntax error: %s\n" , str); + goto out_free; }switch (err->num_errors) {case 0 :
@@ -2419,6 +2422,11 @@ void parse_events_error__handle(struct pbreak ; } err->num_errors++; +return ; + +out_free: +free (str); +free (help); }#define MAX_WIDTH 1000
Greg Kroah-Hartman
maintainerPATCH 158/365 perf tests: Fix Track with sched_switch test for hybrid case
In reply to Greg Kroah-HartmanFrom: Adrian Hunter <[email protected]>
commit 1da1d60774014137d776d0400fdf2f1779d8d4d5 upstream.
If cpu_core PMU event fails to parse, try also cpu_atom PMU event when parsing cycles event.
--- tools/perf/tests/switch-tracking.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-)
tools/perf/tests/switch-tracking.c +13 -5
@@ -324,6 +324,7 @@ out_free_nodes:static int test__switch_tracking (struct test_suite *test__maybe_unused ,int subtest__maybe_unused ) {const char *sched_switch ="sched:sched_switch" ; +const char *cycles ="cycles:u" ;struct switch_tracking switch_tracking = { .tids =NULL , };struct record_opts opts = { .mmap_pages =UINT_MAX ,
@@ -372,12 +373,19 @@ static int test__switch_tracking(struct cpu_clocks_evsel =evlist__last (evlist);/* Second event */ -if (perf_pmu__has_hybrid ()) - err =parse_events (evlist,"cpu_core/cycles/u" ,NULL ); -else - err =parse_events (evlist,"cycles:u" ,NULL ); +if (perf_pmu__has_hybrid ()) { + cycles ="cpu_core/cycles/u" ; + err =parse_events (evlist, cycles,NULL ); +if (err) { + cycles ="cpu_atom/cycles/u" ; +pr_debug ("Trying %s\n" , cycles); + err =parse_events (evlist, cycles,NULL ); + } + }else { + err =parse_events (evlist, cycles,NULL ); + }if (err) { -pr_debug ("Failed to parse event cycles:u\n" ); +pr_debug ("Failed to parse event %s\n" , cycles); goto out_err; }
Greg Kroah-Hartman
maintainerPATCH 159/365 dpaa2-eth: trace the allocated address instead of page struct
In reply to Greg Kroah-HartmanFrom: Chen Lin <[email protected]>
commit e34f49348f8b7a53205b6f77707a3a6a40cf420b upstream.
We should trace the allocated address instead of page struct.
--- drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c +2 -2
@@ -1660,8 +1660,8 @@ static int dpaa2_eth_add_bufs(struct dpa buf_array[i] = addr;/* tracing point */ -trace_dpaa2_eth_buf_seed (priv->net_dev, - page,DPAA2_ETH_RX_BUF_RAW_SIZE , +trace_dpaa2_eth_buf_seed (priv->net_dev,page_address (page), +DPAA2_ETH_RX_BUF_RAW_SIZE , addr, priv->rx_buf_size, bpid); }
Greg Kroah-Hartman
maintainerPATCH 160/365 fs/ntfs3: Fix using uninitialized value n when calling indx_read
In reply to Greg Kroah-HartmanFrom: Yan Lei <[email protected]>
commit ae5a4e46916fc307288227b64c1d062352eb93b7 upstream.
This value is checked in indx_read, so it must be initialized
--- fs/ntfs3/index.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/ntfs3/index.c +1 -1
@@ -1994,7 +1994,7 @@ static int indx_free_children(struct ntf const struct NTFS_DE *e, bool trim) { int err; -struct indx_node *n; +struct indx_node *n =NULL ;struct INDEX_HDR *hdr;CLST vbn =de_get_vbn (e);size_t i;
Greg Kroah-Hartman
maintainerPATCH 161/365 fs/ntfs3: Fix NULL deref in ntfs_update_mftmirr
In reply to Greg Kroah-HartmanFrom: Pavel Skripkin <[email protected]>
commit 321460ca3b55f48b3ba6008248264ab2bd6407d9 upstream.
If ntfs_fill_super() wasn't called then sbi->sb will be equal to NULL. Code should check this ptr before dereferencing. Syzbot hit this issue via passing wrong mount param as can be seen from log below
Fail log:
ntfs3: Unknown parameter 'iochvrset'
general protection fault, probably for non-canonical address 0xdffffc0000000003: 0000 [#1] PREEMPT SMP KASAN KASAN: null-ptr-deref in range [0x0000000000000018-0x000000000000001f] CPU: 1 PID: 3589 Comm: syz-executor210 Not tainted 5.18.0-rc3-syzkaller-00016-gb253435746d9 #0 ... Call Trace: <TASK> put_ntfs+0x1ed/0x2a0 fs/ntfs3/super.c:463 ntfs_fs_free+0x6a/0xe0 fs/ntfs3/super.c:1363 put_fs_context+0x119/0x7a0 fs/fs_context.c:469 do_new_mount+0x2b4/0xad0 fs/namespace.c:3044 do_mount fs/namespace.c:3383 [inline] __do_sys_mount fs/namespace.c:3591 [inline]
--- fs/ntfs3/fsntfs.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
fs/ntfs3/fsntfs.c +6 -1
@@ -831,10 +831,15 @@ int ntfs_update_mftmirr(struct ntfs_sb_i {int err;struct super_block *sb = sbi->sb; -u32 blocksize = sb->s_blocksize; +u32 blocksize;sector_t block1, block2;u32 bytes; +if (!sb) +return -EINVAL ; + + blocksize = sb->s_blocksize; +if (!(sbi->flags &NTFS_FLAGS_MFTMIRR ))return 0 ;
Greg Kroah-Hartman
maintainerPATCH 162/365 fs/ntfs3: Dont clear upper bits accidentally in log_replay()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
commit 926034353d3c67db1ffeab47dcb7f6bdac02a263 upstream.
The "vcn" variable is a 64 bit. The "log->clst_per_page" variable is a u32. This means that the mask accidentally clears out the high 32 bits when it was only supposed to clear some low bits. Fix this by adding a cast to u64.
--- fs/ntfs3/fslog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/ntfs3/fslog.c +1 -1
@@ -5057,7 +5057,7 @@ undo_action_next: goto add_allocated_vcns; vcn =le64_to_cpu (lrh->target_vcn); - vcn &= ~(log->clst_per_page -1 ); + vcn &= ~(u64)(log->clst_per_page -1 ); add_allocated_vcns: for (i = 0, vcn = le64_to_cpu(lrh->target_vcn),
Greg Kroah-Hartman
maintainerPATCH 163/365 fs/ntfs3: Fix double free on remount
In reply to Greg Kroah-HartmanFrom: Konstantin Komarov <[email protected]>
commit cd39981fb92adf0cc736112f87e3e61602baa415 upstream.
Pointer to options was freed twice on remount
Fixes xfstest generic/361
--- fs/ntfs3/super.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
fs/ntfs3/super.c +4 -4
@@ -30,6 +30,7 @@#include <linux/fs_context.h> #include <linux/fs_parser.h> #include <linux/log2.h> +#include <linux/minmax.h> #include <linux/module.h> #include <linux/nls.h> #include <linux/seq_file.h>
@@ -390,7 +391,7 @@ static int ntfs_fs_reconfigure(struct fsreturn -EINVAL ; } -memcpy (sbi->options, new_opts,sizeof (*new_opts)); +swap (sbi->options, fc->fs_private);return 0 ; }
@@ -900,6 +901,8 @@ static int ntfs_fill_super(struct super_ ref.high =0 ; sbi->sb = sb; + sbi->options = fc->fs_private; + fc->fs_private =NULL ; sb->s_flags |=SB_NODIRATIME ; sb->s_magic =0x7366746e ;// "ntfs" sb->s_op = &ntfs_sops;
@@ -1262,8 +1265,6 @@ load_root: goto put_inode_out; } - fc->fs_private =NULL ; -return 0 ; put_inode_out:
@@ -1416,7 +1417,6 @@ static int ntfs_init_fs_context(struct fmutex_init (&sbi->compress.mtx_lzx);#endif - sbi->options = opts; fc->s_fs_info = sbi; ok: fc->fs_private = opts;
Greg Kroah-Hartman
maintainerPATCH 164/365 fs/ntfs3: Do not change mode if ntfs_set_ea failed
In reply to Greg Kroah-HartmanFrom: Konstantin Komarov <[email protected]>
commit 460bbf2990b3fdc597601c2cf669a3371c069242 upstream.
ntfs_set_ea can fail with NOSPC, so we don't need to change mode in this situation.
Fixes xfstest generic/449
--- fs/ntfs3/xattr.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-)
fs/ntfs3/xattr.c +10 -10
@@ -547,28 +547,23 @@ static noinline int ntfs_set_acl_ex(stru {const char *name;size_t size, name_len; -void *value =NULL ; -int err =0 ; +void *value; +int err;int flags; +umode_t mode;if (S_ISLNK (inode->i_mode))return -EOPNOTSUPP ; + mode = inode->i_mode;switch (type) {case ACL_TYPE_ACCESS :/* Do not change i_mode if we are in init_acl */ if (acl && !init_acl) { -umode_t mode; - err =posix_acl_update_mode (mnt_userns, inode, &mode, &acl);if (err) goto out; - -if (inode->i_mode != mode) { - inode->i_mode = mode; -mark_inode_dirty (inode); - } } name =XATTR_NAME_POSIX_ACL_ACCESS ; name_len =sizeof (XATTR_NAME_POSIX_ACL_ACCESS ) -1 ;
@@ -604,8 +599,13 @@ static noinline int ntfs_set_acl_ex(stru err =ntfs_set_ea (inode, name, name_len, value, size, flags,0 );if (err == -ENODATA && !size) err =0 ;/* Removing non existed xattr. */ -if (!err) +if (!err) {set_cached_acl (inode, type, acl); +if (inode->i_mode != mode) { + inode->i_mode = mode; +mark_inode_dirty (inode); + } + } out:kfree (value);
Greg Kroah-Hartman
maintainerPATCH 165/365 fs/ntfs3: Fix missing i_op in ntfs_read_mft
In reply to Greg Kroah-HartmanFrom: Konstantin Komarov <[email protected]>
commit 37a530bfe56ca9a0d3129598803f2794c7428aae upstream.
There is null pointer dereference because i_op == NULL.
The bug happens because we don't initialize i_op for records in $Extend.
--- fs/ntfs3/inode.c | 1 + 1 file changed, 1 insertion(+)
fs/ntfs3/inode.c +1 -0
@@ -430,6 +430,7 @@ end_enum: }else if (fname && fname->home.low ==cpu_to_le32 (MFT_REC_EXTEND ) && fname->home.seq ==cpu_to_le16 (MFT_REC_EXTEND )) {/* Records in $Extend are not a files or general directories. */ + inode->i_op = &ntfs_file_inode_operations; }else { err = -EINVAL ; goto out;
Greg Kroah-Hartman
maintainerPATCH 166/365 nios2: page fault et.al. are *not* restartable syscalls...
In reply to Greg Kroah-HartmanFrom: Al Viro <[email protected]>
commit 8535c239ac674f7ead0f2652932d35c52c4123b2 upstream.
make sure that ->orig_r2 is negative for everything except the syscalls.
--- arch/nios2/include/asm/entry.h | 3 ++- arch/nios2/kernel/entry.S | 4 +--- 2 files changed, 3 insertions(+), 4 deletions(-)
arch/nios2/include/asm/entry.h +2 -1
@@ -50,7 +50,8 @@ stw r13, PT_R13(sp) stw r14, PT_R14(sp) stw r15, PT_R15(sp) - stw r2, PT_ORIG_R2(sp) + movi r24, -1 + stw r24, PT_ORIG_R2(sp) stw r7, PT_ORIG_R7(sp) stw ra, PT_RA(sp)
arch/nios2/kernel/entry.S +1 -3
@@ -185,6 +185,7 @@ ENTRY(handle_system_call) ldw r5, PT_R5(sp) local_restart: + stw r2, PT_ORIG_R2(sp) /* Check that the requested system call is within limits */ movui r1, __NR_syscalls bgeu r2, r1, ret_invsyscall
@@ -336,9 +337,6 @@ external_interrupt: /* skip if no interrupt is pending */ beq r12, r0, ret_from_interrupt - movi r24, -1 - stw r24, PT_ORIG_R2(sp) - /* * Process an external hardware interrupt. */
Greg Kroah-Hartman
maintainerPATCH 167/365 nios2: dont leave NULLs in sys_call_table[]
In reply to Greg Kroah-HartmanFrom: Al Viro <[email protected]>
commit 45ec746c65097c25e77d24eae8fee0def5b6cc5d upstream.
fill the gaps in there with sys_ni_syscall, as everyone does...
--- arch/nios2/kernel/entry.S | 1 - arch/nios2/kernel/syscall_table.c | 1 + 2 files changed, 1 insertion(+), 1 deletion(-)
arch/nios2/kernel/entry.S +0 -1
@@ -193,7 +193,6 @@ local_restart: movhi r11, %hiadj(sys_call_table) add r1, r1, r11 ldw r1, %lo(sys_call_table)(r1) - beq r1, r0, ret_invsyscall /* Check if we are being traced */ GET_THREAD_INFO r11
arch/nios2/kernel/syscall_table.c +1 -0
@@ -13,5 +13,6 @@#define __SYSCALL (nr, call) [nr] = (call),void *sys_call_table[__NR_syscalls] = { + [0 ... __NR_syscalls-1 ] = sys_ni_syscall, #include <asm/unistd.h> };
Greg Kroah-Hartman
maintainerPATCH 168/365 nios2: traced syscall does need to check the syscall number
In reply to Greg Kroah-HartmanFrom: Al Viro <[email protected]>
commit 25ba820ef36bdbaf9884adeac69b6e1821a7df76 upstream.
all checks done before letting the tracer modify the register state are worthless...
--- arch/nios2/kernel/entry.S | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
arch/nios2/kernel/entry.S +8 -3
@@ -255,9 +255,9 @@ traced_system_call: ldw r6, PT_R6(sp) ldw r7, PT_R7(sp) - /* Fetch the syscall function, we don't need to check the boundaries - * since this is already done. - */ + /* Fetch the syscall function. */ + movui r1, __NR_syscalls + bgeu r2, r1, traced_invsyscall slli r1, r2, 2 movhi r11,%hiadj(sys_call_table) add r1, r1, r11
@@ -287,6 +287,11 @@ end_translate_rc_and_ret2: RESTORE_SWITCH_STACK br ret_from_exception + /* If the syscall number was invalid return ENOSYS */ +traced_invsyscall: + movi r2, -ENOSYS + br translate_rc_and_ret2 + Luser_return: GET_THREAD_INFO r11 /* get thread_info pointer */ ldw r10, TI_FLAGS(r11) /* get thread_info->flags */
Greg Kroah-Hartman
maintainerPATCH 169/365 nios2: fix syscall restart checks
In reply to Greg Kroah-HartmanFrom: Al Viro <[email protected]>
commit 2d631bd58fe0ea3e3350212e23c9aba1fb606514 upstream.
sys_foo() returns -512 (aka -ERESTARTSYS) => do_signal() sees 512 in r2 and 1 in r1.
sys_foo() returns 512 => do_signal() sees 512 in r2 and 0 in r1.
The former is restart-worthy; the latter obviously isn't.
--- arch/nios2/kernel/signal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/nios2/kernel/signal.c +1 -1
@@ -242,7 +242,7 @@ static int do_signal(struct pt_regs *reg/* * If we were from a system call, check for system call restarting... */ -if (regs->orig_r2 >=0 ) { +if (regs->orig_r2 >=0 && regs->r1) { continue_addr = regs->ea; restart_addr = continue_addr -4 ; retval = regs->r2;
Greg Kroah-Hartman
maintainerPATCH 170/365 nios2: restarts apply only to the first sigframe we build...
In reply to Greg Kroah-HartmanFrom: Al Viro <[email protected]>
commit 411a76b7219555c55867466c82d70ce928d6c9e1 upstream.
--- arch/nios2/kernel/signal.c | 1 + 1 file changed, 1 insertion(+)
arch/nios2/kernel/signal.c +1 -0
@@ -264,6 +264,7 @@ static int do_signal(struct pt_regs *reg regs->ea = restart_addr;break ; } + regs->orig_r2 =-1 ; }if (get_signal (&ksig)) {
Greg Kroah-Hartman
maintainerPATCH 171/365 nios2: add force_successful_syscall_return()
In reply to Greg Kroah-HartmanFrom: Al Viro <[email protected]>
commit fd0c153daad135d0ec1a53c5dbe6936a724d6ae1 upstream.
If we use the ancient SysV syscall ABI, we'd better have tell the kernel how to claim that a negative return value is a success. Use ->orig_r2 for that - it's inaccessible via ptrace, so it's a fair game for changes and it's normally[*] non-negative on return from syscall. Set to -1; syscall is not going to be restart-worthy by definition, so we won't interfere with that use either.
[*] the only exception is rt_sigreturn(), where we skip the entire messing with r1/r2 anyway.
--- arch/nios2/include/asm/ptrace.h | 2 ++ arch/nios2/kernel/entry.S | 6 ++++++ 2 files changed, 8 insertions(+)
arch/nios2/include/asm/ptrace.h +2 -0
@@ -74,6 +74,8 @@ extern void show_regs(struct pt_regs *); ((struct pt_regs *)((unsigned long )current_thread_info () +THREAD_SIZE )\ - 1) +#define force_successful_syscall_return () (current_pt_regs()->orig_r2 = -1) +int do_syscall_trace_enter (void );void do_syscall_trace_exit (void );#endif /* __ASSEMBLY__ */
arch/nios2/kernel/entry.S +6 -0
@@ -213,6 +213,9 @@ local_restart: translate_rc_and_ret: movi r1, 0 bge r2, zero, 3f + ldw r1, PT_ORIG_R2(sp) + addi r1, r1, 1 + beq r1, zero, 3f sub r2, zero, r2 movi r1, 1 3:
@@ -276,6 +279,9 @@ traced_system_call: translate_rc_and_ret2: movi r1, 0 bge r2, zero, 4f + ldw r1, PT_ORIG_R2(sp) + addi r1, r1, 1 + beq r1, zero, 4f sub r2, zero, r2 movi r1, 1 4:
Greg Kroah-Hartman
maintainerPATCH 172/365 iavf: Fix adminq error handling
In reply to Greg Kroah-HartmanFrom: Przemyslaw Patynowski <[email protected]>
commit 419831617ed349992c84344dbd9e627f9e68f842 upstream.
iavf_alloc_asq_bufs/iavf_alloc_arq_bufs allocates with dma_alloc_coherent
memory for VF mailbox.
Free DMA regions for both ASQ and ARQ in case error happens during
configuration of ASQ/ARQ registers.
Without this change it is possible to see when unloading interface:
74626.583369: dma_debug_device_change: device driver has pending DMA allocations while released from device [count=32] One of leaked entries details: [device address=0x0000000b27ff9000] [size=4096 bytes] [mapped with DMA_BIDIRECTIONAL] [mapped as coherent]
--- drivers/net/ethernet/intel/iavf/iavf_adminq.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-)
drivers/net/ethernet/intel/iavf/iavf_adminq.c +13 -2
@@ -324,6 +324,7 @@ static enum iavf_status iavf_config_arq_static enum iavf_status iavf_init_asq (struct iavf_hw *hw) {enum iavf_status ret_code =0 ; +int i;if (hw->aq.asq.count >0 ) {/* queue already initialized */
@@ -354,12 +355,17 @@ static enum iavf_status iavf_init_asq(st/* initialize base registers */ ret_code =iavf_config_asq_regs (hw);if (ret_code) - goto init_adminq_free_rings; + goto init_free_asq_bufs;/* success! */ hw->aq.asq.count = hw->aq.num_asq_entries; goto init_adminq_exit; +init_free_asq_bufs: +for (i =0 ; i < hw->aq.num_asq_entries; i++) +iavf_free_dma_mem (hw, &hw->aq.asq.r.asq_bi[i]); +iavf_free_virt_mem (hw, &hw->aq.asq.dma_head); + init_adminq_free_rings:iavf_free_adminq_asq (hw);
@@ -383,6 +389,7 @@ init_adminq_exit:static enum iavf_status iavf_init_arq (struct iavf_hw *hw) {enum iavf_status ret_code =0 ; +int i;if (hw->aq.arq.count >0 ) {/* queue already initialized */
@@ -413,12 +420,16 @@ static enum iavf_status iavf_init_arq(st/* initialize base registers */ ret_code =iavf_config_arq_regs (hw);if (ret_code) - goto init_adminq_free_rings; + goto init_free_arq_bufs;/* success! */ hw->aq.arq.count = hw->aq.num_arq_entries; goto init_adminq_exit; +init_free_arq_bufs: +for (i =0 ; i < hw->aq.num_arq_entries; i++) +iavf_free_dma_mem (hw, &hw->aq.arq.r.arq_bi[i]); +iavf_free_virt_mem (hw, &hw->aq.arq.dma_head); init_adminq_free_rings:iavf_free_adminq_arq (hw);
Greg Kroah-Hartman
maintainerPATCH 173/365 iavf: Fix NULL pointer dereference in iavf_get_link_ksettings
In reply to Greg Kroah-HartmanFrom: Przemyslaw Patynowski <[email protected]>
commit 541a1af451b0cb3779e915d48d08efb17915207b upstream.
Fix possible NULL pointer dereference, due to freeing of adapter->vf_res in iavf_init_get_resources. Previous commit introduced a regression, where receiving IAVF_ERR_ADMIN_QUEUE_NO_WORK from iavf_get_vf_config would free adapter->vf_res. However, netdev is still registered, so ethtool_ops can be called. Calling iavf_get_link_ksettings with no vf_res, will result with:
[ 9385.242676] BUG: kernel NULL pointer dereference, address: 0000000000000008 [ 9385.242683] #PF: supervisor read access in kernel mode [ 9385.242686] #PF: error_code(0x0000) - not-present page [ 9385.242690] PGD 0 P4D 0 [ 9385.242696] Oops: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC PTI [ 9385.242701] CPU: 6 PID: 3217 Comm: pmdalinux Kdump: loaded Tainted: G S E 5.18.0-04958-ga54ce3703613-dirty #1 [ 9385.242708] Hardware name: Dell Inc. PowerEdge R730/0WCJNT, BIOS 2.11.0 11/02/2019 [ 9385.242710] RIP: 0010:iavf_get_link_ksettings+0x29/0xd0 [iavf] [ 9385.242745] Code: 00 0f 1f 44 00 00 b8 01 ef ff ff 48 c7 46 30 00 00 00 00 48 c7 46 38 00 00 00 00 c6 46 0b 00 66 89 46 08 48 8b 87 68 0e 00 00 <f6> 40 08 80 75 50 8b 87 5c 0e 00 00 83 f8 08 74 7a 76 1d 83 f8 20 [ 9385.242749] RSP: 0018:ffffc0560ec7fbd0 EFLAGS: 00010246 [ 9385.242755] RAX: 0000000000000000 RBX: ffffc0560ec7fc08 RCX: 0000000000000000 [ 9385.242759] RDX: ffffffffc0ad4550 RSI: ffffc0560ec7fc08 RDI: ffffa0fc66674000 [ 9385.242762] RBP: 00007ffd1fb2bf50 R08: b6a2d54b892363ee R09: ffffa101dc14fb00 [ 9385.242765] R10: 0000000000000000 R11: 0000000000000004 R12: ffffa0fc66674000 [ 9385.242768] R13: 0000000000000000 R14: ffffa0fc66674000 R15: 00000000ffffffa1 [ 9385.242771] FS: 00007f93711a2980(0000) GS:ffffa0fad72c0000(0000) knlGS:0000000000000000 [ 9385.242775] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 9385.242778] CR2: 0000000000000008 CR3: 0000000a8e61c003 CR4: 00000000003706e0 [ 9385.242781] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 9385.242784] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 9385.242787] Call Trace: [ 9385.242791] <TASK> [ 9385.242793] ethtool_get_settings+0x71/0x1a0 [ 9385.242814] __dev_ethtool+0x426/0x2f40 [ 9385.242823] ? slab_post_alloc_hook+0x4f/0x280 [ 9385.242836] ? kmem_cache_alloc_trace+0x15d/0x2f0 [ 9385.242841] ? dev_ethtool+0x59/0x170 [ 9385.242848] dev_ethtool+0xa7/0x170 [ 9385.242856] dev_ioctl+0xc3/0x520 [ 9385.242866] sock_do_ioctl+0xa0/0xe0 [ 9385.242877] sock_ioctl+0x22f/0x320 [ 9385.242885] __x64_sys_ioctl+0x84/0xc0 [ 9385.242896] do_syscall_64+0x3a/0x80 [ 9385.242904] entry_SYSCALL_64_after_hwframe+0x46/0xb0 [ 9385.242918] RIP: 0033:0x7f93702396db [ 9385.242923] Code: 73 01 c3 48 8b 0d ad 57 38 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa b8 10 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 7d 57 38 00 f7 d8 64 89 01 48 [ 9385.242927] RSP: 002b:00007ffd1fb2bf18 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 [ 9385.242932] RAX: ffffffffffffffda RBX: 000055671b1d2fe0 RCX: 00007f93702396db [ 9385.242935] RDX: 00007ffd1fb2bf20 RSI: 0000000000008946 RDI: 0000000000000007 [ 9385.242937] RBP: 00007ffd1fb2bf20 R08: 0000000000000003 R09: 0030763066307330 [ 9385.242940] R10: 0000000000000000 R11: 0000000000000246 R12: 00007ffd1fb2bf80 [ 9385.242942] R13: 0000000000000007 R14: 0000556719f6de90 R15: 00007ffd1fb2c1b0 [ 9385.242948] </TASK> [ 9385.242949] Modules linked in: iavf(E) xt_CHECKSUM xt_MASQUERADE xt_conntrack ipt_REJECT nft_compat nf_nat_tftp nft_objref nf_conntrack_tftp bridge stp llc nft_fib_inet nft_fib_ipv4 nft_fib_ipv6 nft_fib nft_reject_inet nf_reject_ipv4 nf_reject_ipv6 nft_reject nft_ct nft_chain_nat nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 ip_set nf_tables rfkill nfnetlink vfat fat irdma ib_uverbs ib_core intel_rapl_msr intel_rapl_common sb_edac x86_pkg_temp_thermal intel_powerclamp coretemp kvm_intel kvm iTCO_wdt iTCO_vendor_support ice irqbypass crct10dif_pclmul crc32_pclmul ghash_clmulni_intel rapl i40e pcspkr intel_cstate joydev mei_me intel_uncore mxm_wmi mei ipmi_ssif lpc_ich ipmi_si acpi_power_meter xfs libcrc32c mgag200 i2c_algo_bit drm_shmem_helper drm_kms_helper sd_mod t10_pi crc64_rocksoft crc64 syscopyarea sg sysfillrect sysimgblt fb_sys_fops drm ixgbe ahci libahci libata crc32c_intel mdio dca wmi dm_mirror dm_region_hash dm_log dm_mod ipmi_devintf ipmi_msghandler fuse [ 9385.243065] [last unloaded: iavf]
Dereference happens in if (ADV_LINK_SUPPORT(adapter)) statement
--- drivers/net/ethernet/intel/iavf/iavf_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/intel/iavf/iavf_main.c +1 -1
@@ -2281,7 +2281,7 @@ static void iavf_init_get_resources(stru err =iavf_get_vf_config (adapter);if (err == -EALREADY ) { err =iavf_send_vf_config_msg (adapter); - goto err_alloc; + goto err; }else if (err == -EINVAL ) {/* We only get -EINVAL if the device is in a very bad * state or if we've been disabled for previous bad
Greg Kroah-Hartman
maintainerPATCH 174/365 iavf: Fix reset error handling
In reply to Greg Kroah-HartmanFrom: Przemyslaw Patynowski <[email protected]>
commit 31071173771e079f7bc08dacd61e0db913262fbf upstream.
Do not call iavf_close in iavf_reset_task error handling. Doing so can lead to double call of napi_disable, which can lead to deadlock there. Removing VF would lead to iavf_remove task being stuck, because it requires crit_lock, which is held by iavf_close.
Call iavf_disable_vf if reset fail, so that driver will clean up remaining invalid resources.
During rapid VF resets, HW can fail to setup VF mailbox. Wrong error handling can lead to iavf_remove being stuck with:
[ 5218.999087] iavf 0000:82:01.0: Failed to init adminq: -53 ... [ 5267.189211] INFO: task repro.sh:11219 blocked for more than 30 seconds. [ 5267.189520] Tainted: G S E 5.18.0-04958-ga54ce3703613-dirty #1 [ 5267.189764] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. [ 5267.190062] task:repro.sh state:D stack: 0 pid:11219 ppid: 8162 flags:0x00000000 [ 5267.190347] Call Trace: [ 5267.190647] <TASK> [ 5267.190927] __schedule+0x460/0x9f0 [ 5267.191264] schedule+0x44/0xb0 [ 5267.191563] schedule_preempt_disabled+0x14/0x20 [ 5267.191890] __mutex_lock.isra.12+0x6e3/0xac0 [ 5267.192237] ? iavf_remove+0xf9/0x6c0 [iavf] [ 5267.192565] iavf_remove+0x12a/0x6c0 [iavf] [ 5267.192911] ? _raw_spin_unlock_irqrestore+0x1e/0x40 [ 5267.193285] pci_device_remove+0x36/0xb0 [ 5267.193619] device_release_driver_internal+0xc1/0x150 [ 5267.193974] pci_stop_bus_device+0x69/0x90 [ 5267.194361] pci_stop_and_remove_bus_device+0xe/0x20 [ 5267.194735] pci_iov_remove_virtfn+0xba/0x120 [ 5267.195130] sriov_disable+0x2f/0xe0 [ 5267.195506] ice_free_vfs+0x7d/0x2f0 [ice] [ 5267.196056] ? pci_get_device+0x4f/0x70 [ 5267.196496] ice_sriov_configure+0x78/0x1a0 [ice] [ 5267.196995] sriov_numvfs_store+0xfe/0x140 [ 5267.197466] kernfs_fop_write_iter+0x12e/0x1c0 [ 5267.197918] new_sync_write+0x10c/0x190 [ 5267.198404] vfs_write+0x24e/0x2d0 [ 5267.198886] ksys_write+0x5c/0xd0 [ 5267.199367] do_syscall_64+0x3a/0x80 [ 5267.199827] entry_SYSCALL_64_after_hwframe+0x46/0xb0 [ 5267.200317] RIP: 0033:0x7f5b381205c8 [ 5267.200814] RSP: 002b:00007fff8c7e8c78 EFLAGS: 00000246 ORIG_RAX: 0000000000000001 [ 5267.201981] RAX: ffffffffffffffda RBX: 0000000000000002 RCX: 00007f5b381205c8 [ 5267.202620] RDX: 0000000000000002 RSI: 00005569420ee900 RDI: 0000000000000001 [ 5267.203426] RBP: 00005569420ee900 R08: 000000000000000a R09: 00007f5b38180820 [ 5267.204327] R10: 000000000000000a R11: 0000000000000246 R12: 00007f5b383c06e0 [ 5267.205193] R13: 0000000000000002 R14: 00007f5b383bb880 R15: 0000000000000002 [ 5267.206041] </TASK> [ 5267.206970] Kernel panic - not syncing: hung_task: blocked tasks [ 5267.207809] CPU: 48 PID: 551 Comm: khungtaskd Kdump: loaded Tainted: G S E 5.18.0-04958-ga54ce3703613-dirty #1 [ 5267.208726] Hardware name: Dell Inc. PowerEdge R730/0WCJNT, BIOS 2.11.0 11/02/2019 [ 5267.209623] Call Trace: [ 5267.210569] <TASK> [ 5267.211480] dump_stack_lvl+0x33/0x42 [ 5267.212472] panic+0x107/0x294 [ 5267.213467] watchdog.cold.8+0xc/0xbb [ 5267.214413] ? proc_dohung_task_timeout_secs+0x30/0x30 [ 5267.215511] kthread+0xf4/0x120 [ 5267.216459] ? kthread_complete_and_exit+0x20/0x20 [ 5267.217505] ret_from_fork+0x22/0x30 [ 5267.218459] </TASK>
--- drivers/net/ethernet/intel/iavf/iavf_main.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
drivers/net/ethernet/intel/iavf/iavf_main.c +6 -3
@@ -2998,12 +2998,15 @@ continue_reset:return ; reset_err: +if (running) { +set_bit (__IAVF_VSI_DOWN, adapter->vsi.state); +iavf_free_traffic_irqs (adapter); + } +iavf_disable_vf (adapter); +mutex_unlock (&adapter->client_lock);mutex_unlock (&adapter->crit_lock); -if (running) -iavf_change_state (adapter, __IAVF_RUNNING);dev_err (&adapter->pdev->dev,"failed to allocate resources during reinit\n" ); -iavf_close (netdev); }/**
Greg Kroah-Hartman
maintainerPATCH 175/365 iavf: Fix deadlock in initialization
In reply to Greg Kroah-HartmanFrom: Ivan Vecera <[email protected]>
commit cbe9e51126305832cf407ee6bb556ce831488ffe upstream.
Fix deadlock that occurs when iavf interface is a part of failover configuration.
1. Mutex crit_lock is taken at the beginning of iavf_watchdog_task()
2. Function iavf_init_config_adapter() is called when adapter state is __IAVF_INIT_CONFIG_ADAPTER
3. iavf_init_config_adapter() calls register_netdevice() that emits NETDEV_REGISTER event
4. Notifier function failover_event() then calls net_failover_slave_register() that calls dev_open()
5. dev_open() calls iavf_open() that tries to take crit_lock in end-less loop
Stack trace:
...
[ 790.251876] usleep_range_state+0x5b/0x80 [ 790.252547] iavf_open+0x37/0x1d0 [iavf] [ 790.253139] __dev_open+0xcd/0x160 [ 790.253699] dev_open+0x47/0x90 [ 790.254323] net_failover_slave_register+0x122/0x220 [net_failover] [ 790.255213] failover_slave_register.part.7+0xd2/0x180 [failover] [ 790.256050] failover_event+0x122/0x1ab [failover] [ 790.256821] notifier_call_chain+0x47/0x70 [ 790.257510] register_netdevice+0x20f/0x550 [ 790.258263] iavf_watchdog_task+0x7c8/0xea0 [iavf] [ 790.259009] process_one_work+0x1a7/0x360 [ 790.259705] worker_thread+0x30/0x390
To fix the situation we should check the current adapter state after first unsuccessful mutex_trylock() and return with -EBUSY if it is __IAVF_INIT_CONFIG_ADAPTER.
--- drivers/net/ethernet/intel/iavf/iavf_main.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
drivers/net/ethernet/intel/iavf/iavf_main.c +10 -1
@@ -3989,8 +3989,17 @@ static int iavf_open(struct net_device *return -EIO ; } -while (!mutex_trylock (&adapter->crit_lock)) +while (!mutex_trylock (&adapter->crit_lock)) { +/* If we are in __IAVF_INIT_CONFIG_ADAPTER state the crit_lock +* is already taken and iavf_open is called from an upper +* device's notifier reacting on NETDEV_REGISTER event. +* We have to leave here to avoid dead lock. +*/ +if (adapter->state == __IAVF_INIT_CONFIG_ADAPTER) +return -EBUSY ; +usleep_range (500 ,1000 ); + }if (adapter->state != __IAVF_DOWN) { err = -EBUSY ;
Greg Kroah-Hartman
maintainerPATCH 176/365 ASoC: Intel: avs: Fix potential buffer overflow by snprintf()
In reply to Greg Kroah-HartmanFrom: Takashi Iwai <[email protected]>
commit ca3b7b9dc9bc1fa552f4697b7cccfa0258a44d00 upstream.
snprintf() returns the would-be-filled size when the string overflows the given buffer size, hence using this value may result in a buffer overflow (although it's unrealistic).
This patch replaces it with a safer version, scnprintf() for papering over such a potential issue.
--- sound/soc/intel/avs/pcm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
sound/soc/intel/avs/pcm.c +2 -2
@@ -636,8 +636,8 @@ static ssize_t topology_name_read(structchar buf[64 ];size_t len; - len =snprintf (buf,sizeof (buf),"%s/%s\n" , component->driver->topology_name_prefix, - mach->tplg_filename); + len =scnprintf (buf,sizeof (buf),"%s/%s\n" , component->driver->topology_name_prefix, + mach->tplg_filename);return simple_read_from_buffer (user_buf, count, ppos, buf, len); }
Greg Kroah-Hartman
maintainerPATCH 177/365 ASoC: SOF: debug: Fix potential buffer overflow by snprintf()
In reply to Greg Kroah-HartmanFrom: Takashi Iwai <[email protected]>
commit 1eb123ce985e6cf302ac6e3f19862d132d86fa8f upstream.
snprintf() returns the would-be-filled size when the string overflows the given buffer size, hence using this value may result in the buffer overflow (although it's unrealistic).
This patch replaces with a safer version, scnprintf() for papering over such a potential issue.
--- sound/soc/sof/debug.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
sound/soc/sof/debug.c +3 -3
@@ -252,9 +252,9 @@ static int memory_info_update(struct snd }for (i =0 , len =0 ; i < reply->num_elems; i++) { - ret =snprintf (buf + len, buff_size - len,"zone %d.%d used %#8x free %#8x\n" , - reply->elems[i].zone, reply->elems[i].id, - reply->elems[i].used, reply->elems[i].free); + ret =scnprintf (buf + len, buff_size - len,"zone %d.%d used %#8x free %#8x\n" , + reply->elems[i].zone, reply->elems[i].id, + reply->elems[i].used, reply->elems[i].free);if (ret <0 ) goto error; len += ret;
Greg Kroah-Hartman
maintainerPATCH 178/365 ASoC: SOF: Intel: hda: Fix potential buffer overflow by snprintf()
In reply to Greg Kroah-HartmanFrom: Takashi Iwai <[email protected]>
commit 94c1ceb043c1a002de9649bb630c8e8347645982 upstream.
snprintf() returns the would-be-filled size when the string overflows the given buffer size, hence using this value may result in the buffer overflow (although it's unrealistic).
This patch replaces with a safer version, scnprintf() for papering over such a potential issue.
--- sound/soc/sof/intel/hda.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/soc/sof/intel/hda.c +1 -1
@@ -467,7 +467,7 @@ static void hda_dsp_dump_ext_rom_status( chip =get_chip_info (sdev->pdata);for (i =0 ; i <HDA_EXT_ROM_STATUS_SIZE ; i++) { value =snd_sof_dsp_read (sdev,HDA_DSP_BAR , chip->rom_status_reg + i *0x4 ); - len +=snprintf (msg + len,sizeof (msg) - len," 0x%x" , value); + len +=scnprintf (msg + len,sizeof (msg) - len," 0x%x" , value); }dev_printk (level, sdev->dev,"extended rom status: %s" , msg);
Greg Kroah-Hartman
maintainerPATCH 179/365 ASoC: DPCM: Dont pick up BE without substream
In reply to Greg Kroah-HartmanFrom: Takashi Iwai <[email protected]>
commit 754590651ccbbcc74a7c20907be4bb15d642bde3 upstream.
When DPCM tries to add valid BE connections at dpcm_add_paths(), it doesn't check whether the picked BE actually supports for the given stream direction. Due to that, when an asymmetric BE stream is present, it picks up wrongly and this may result in a NULL dereference at a later point where the code assumes the existence of a corresponding BE substream.
This patch adds the check for the presence of the substream for the target BE for avoiding the problem above.
Note that we have already some fix for non-existing BE substream at commit 6246f283d5e0 ("ASoC: dpcm: skip missing substream while applying symmetry"). But the code path we've hit recently is rather happening before the previous fix. So this patch tries to fix at picking up a BE instead of parsing BE lists.
--- sound/soc/soc-pcm.c | 3 +++ 1 file changed, 3 insertions(+)
sound/soc/soc-pcm.c +3 -0
@@ -1318,6 +1318,9 @@ static struct snd_soc_pcm_runtime *dpcm_if (!be->dai_link->no_pcm)continue ; +if (!snd_soc_dpcm_get_substream (be, stream)) +continue ; +for_each_rtd_dais (be, i, dai) { w =snd_soc_dai_get_widget (dai, stream);
Greg Kroah-Hartman
maintainerPATCH 180/365 ASoC: tas2770: Set correct FSYNC polarity
In reply to Greg Kroah-HartmanFrom: Martin Povišer <[email protected]>
commit e9ac31f0a5d0e246b046c20348954519f91a297f upstream.
Fix setting of FSYNC polarity for DAI formats other than I2S. Also add support for polarity inversion.
--- sound/soc/codecs/tas2770.c | 20 +++++++++++++++++++- sound/soc/codecs/tas2770.h | 3 +++ 2 files changed, 22 insertions(+), 1 deletion(-)
sound/soc/codecs/tas2770.c +19 -1
@@ -337,7 +337,7 @@ static int tas2770_set_fmt(struct snd_sostruct snd_soc_component *component = dai->component;struct tas2770_priv *tas2770 =snd_soc_component_get_drvdata (component); -u8 tdm_rx_start_slot =0 , asi_cfg_1 =0 ; +u8 tdm_rx_start_slot =0 , invert_fpol =0 , fpol_preinv =0 , asi_cfg_1 =0 ;int ret;switch (fmt &SND_SOC_DAIFMT_MASTER_MASK ) {
@@ -349,9 +349,15 @@ static int tas2770_set_fmt(struct snd_so }switch (fmt &SND_SOC_DAIFMT_INV_MASK ) { +case SND_SOC_DAIFMT_NB_IF : + invert_fpol =1 ; + fallthrough;case SND_SOC_DAIFMT_NB_NF : asi_cfg_1 |=TAS2770_TDM_CFG_REG1_RX_RSING ;break ; +case SND_SOC_DAIFMT_IB_IF : + invert_fpol =1 ; + fallthrough;case SND_SOC_DAIFMT_IB_NF : asi_cfg_1 |=TAS2770_TDM_CFG_REG1_RX_FALING ;break ;
@@ -369,15 +375,19 @@ static int tas2770_set_fmt(struct snd_soswitch (fmt &SND_SOC_DAIFMT_FORMAT_MASK ) {case SND_SOC_DAIFMT_I2S : tdm_rx_start_slot =1 ; + fpol_preinv =0 ;break ;case SND_SOC_DAIFMT_DSP_A : tdm_rx_start_slot =0 ; + fpol_preinv =1 ;break ;case SND_SOC_DAIFMT_DSP_B : tdm_rx_start_slot =1 ; + fpol_preinv =1 ;break ;case SND_SOC_DAIFMT_LEFT_J : tdm_rx_start_slot =0 ; + fpol_preinv =1 ;break ;default : dev_err(tas2770->dev,
@@ -391,6 +401,14 @@ static int tas2770_set_fmt(struct snd_soif (ret <0 )return ret; + ret =snd_soc_component_update_bits (component,TAS2770_TDM_CFG_REG0 , +TAS2770_TDM_CFG_REG0_FPOL_MASK , + (fpol_preinv ^ invert_fpol) + ?TAS2770_TDM_CFG_REG0_FPOL_RSING + :TAS2770_TDM_CFG_REG0_FPOL_FALING ); +if (ret <0 ) +return ret; +return 0 ; }
sound/soc/codecs/tas2770.h +3 -0
@@ -41,6 +41,9 @@#define TAS2770_TDM_CFG_REG0_31_44_1_48KHZ 0x6#define TAS2770_TDM_CFG_REG0_31_88_2_96KHZ 0x8#define TAS2770_TDM_CFG_REG0_31_176_4_192KHZ 0xa +#define TAS2770_TDM_CFG_REG0_FPOL_MASK BIT(0) +#define TAS2770_TDM_CFG_REG0_FPOL_RSING 0 +#define TAS2770_TDM_CFG_REG0_FPOL_FALING 1/* TDM Configuration Reg1 */ #define TAS2770_TDM_CFG_REG1 TAS2770_REG(0X0, 0x0B)#define TAS2770_TDM_CFG_REG1_MASK GENMASK(5, 1)
Greg Kroah-Hartman
maintainerPATCH 181/365 ASoC: tas2770: Allow mono streams
In reply to Greg Kroah-HartmanFrom: Martin Povišer <[email protected]>
commit bf54d97a835dfe62d4d29e245e170c63d0089be7 upstream.
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.
--- sound/soc/codecs/tas2770.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/soc/codecs/tas2770.c +1 -1
@@ -507,7 +507,7 @@ static struct snd_soc_dai_driver tas2770 .id = 0, .playback = { .stream_name = "ASI1 Playback", - .channels_min = 2, + .channels_min = 1, .channels_max = 2, .rates = TAS2770_RATES, .formats = TAS2770_FORMATS,
Greg Kroah-Hartman
maintainerPATCH 182/365 ASoC: tas2770: Drop conflicting set_bias_level power setting
In reply to Greg Kroah-HartmanFrom: Martin Povišer <[email protected]>
commit 482c23fbc7e9bf5a7a74defd0735d5346215db58 upstream.
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.
--- sound/soc/codecs/tas2770.c | 33 --------------------------------- 1 file changed, 33 deletions(-)
sound/soc/codecs/tas2770.c +0 -33
@@ -46,38 +46,6 @@ static void tas2770_reset(struct tas2770usleep_range (1000 ,2000 ); } -static int tas2770_set_bias_level (struct snd_soc_component *component, -enum snd_soc_bias_level level) -{ -struct tas2770_priv *tas2770 = -snd_soc_component_get_drvdata (component); - -switch (level) { -case SND_SOC_BIAS_ON : -snd_soc_component_update_bits (component,TAS2770_PWR_CTRL , -TAS2770_PWR_CTRL_MASK , -TAS2770_PWR_CTRL_ACTIVE ); -break ; -case SND_SOC_BIAS_STANDBY : -case SND_SOC_BIAS_PREPARE : -snd_soc_component_update_bits (component,TAS2770_PWR_CTRL , -TAS2770_PWR_CTRL_MASK , -TAS2770_PWR_CTRL_MUTE ); -break ; -case SND_SOC_BIAS_OFF : -snd_soc_component_update_bits (component,TAS2770_PWR_CTRL , -TAS2770_PWR_CTRL_MASK , -TAS2770_PWR_CTRL_SHUTDOWN ); -break ; - -default : -dev_err (tas2770->dev,"wrong power level setting %d\n" , level); -return -EINVAL ; - } - -return 0 ; -} -#ifdef CONFIG_PM static int tas2770_codec_suspend (struct snd_soc_component *component) {
@@ -555,7 +523,6 @@ static const struct snd_soc_component_dr .probe = tas2770_codec_probe, .suspend = tas2770_codec_suspend, .resume = tas2770_codec_resume, - .set_bias_level = tas2770_set_bias_level, .controls = tas2770_snd_controls, .num_controls = ARRAY_SIZE(tas2770_snd_controls), .dapm_widgets = tas2770_dapm_widgets,
Greg Kroah-Hartman
maintainerPATCH 183/365 ASoC: tas2770: Fix handling of mute/unmute
In reply to Greg Kroah-HartmanFrom: Martin Povišer <[email protected]>
commit 1e5907bcb3a3b569be0a03ebe668bba2ed320a50 upstream.
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 can mute an ongoing stream by toggling a speaker pin control.
--- sound/soc/codecs/tas2770.c | 57 +++++++++++++++++++++++---------------------- sound/soc/codecs/tas2770.h | 2 + 2 files changed, 32 insertions(+), 27 deletions(-)
sound/soc/codecs/tas2770.c +30 -27
@@ -46,6 +46,26 @@ static void tas2770_reset(struct tas2770usleep_range (1000 ,2000 ); } +static int tas2770_update_pwr_ctrl (struct tas2770_priv *tas2770) +{ +struct snd_soc_component *component = tas2770->component; +unsigned int val; +int ret; + +if (tas2770->dac_powered) + val = tas2770->unmuted ? +TAS2770_PWR_CTRL_ACTIVE :TAS2770_PWR_CTRL_MUTE ; +else + val =TAS2770_PWR_CTRL_SHUTDOWN ; + + ret =snd_soc_component_update_bits (component,TAS2770_PWR_CTRL , +TAS2770_PWR_CTRL_MASK , val); +if (ret <0 ) +return ret; + +return 0 ; +} +#ifdef CONFIG_PM static int tas2770_codec_suspend (struct snd_soc_component *component) {
@@ -82,9 +102,7 @@ static int tas2770_codec_resume(struct sgpiod_set_value_cansleep (tas2770->sdz_gpio,1 );usleep_range (1000 ,2000 ); }else { - ret =snd_soc_component_update_bits (component,TAS2770_PWR_CTRL , -TAS2770_PWR_CTRL_MASK , -TAS2770_PWR_CTRL_ACTIVE ); + ret =tas2770_update_pwr_ctrl (tas2770);if (ret <0 )return ret; }
@@ -120,24 +138,19 @@ static int tas2770_dac_event(struct snd_switch (event) {case SND_SOC_DAPM_POST_PMU : - ret =snd_soc_component_update_bits (component,TAS2770_PWR_CTRL , -TAS2770_PWR_CTRL_MASK , -TAS2770_PWR_CTRL_MUTE ); + tas2770->dac_powered =1 ; + ret =tas2770_update_pwr_ctrl (tas2770);break ;case SND_SOC_DAPM_PRE_PMD : - ret =snd_soc_component_update_bits (component,TAS2770_PWR_CTRL , -TAS2770_PWR_CTRL_MASK , -TAS2770_PWR_CTRL_SHUTDOWN ); + tas2770->dac_powered =0 ; + ret =tas2770_update_pwr_ctrl (tas2770);break ;default :dev_err (tas2770->dev,"Not supported evevt\n" );return -EINVAL ; } -if (ret <0 ) -return ret; - -return 0 ; +return ret; } static const struct snd_kcontrol_new isense_switch =
@@ -171,21 +184,11 @@ static const struct snd_soc_dapm_route tstatic int tas2770_mute (struct snd_soc_dai *dai,int mute,int direction) {struct snd_soc_component *component = dai->component; -int ret; - -if (mute) - ret =snd_soc_component_update_bits (component,TAS2770_PWR_CTRL , -TAS2770_PWR_CTRL_MASK , -TAS2770_PWR_CTRL_MUTE ); -else - ret =snd_soc_component_update_bits (component,TAS2770_PWR_CTRL , -TAS2770_PWR_CTRL_MASK , -TAS2770_PWR_CTRL_ACTIVE ); - -if (ret <0 ) -return ret; +struct tas2770_priv *tas2770 = +snd_soc_component_get_drvdata (component); -return 0 ; + tas2770->unmuted = !mute; +return tas2770_update_pwr_ctrl (tas2770); }static int tas2770_set_bitwidth (struct tas2770_priv *tas2770,int bitwidth)
sound/soc/codecs/tas2770.h +2 -0
@@ -138,6 +138,8 @@ struct tas2770_priv {struct device *dev;int v_sense_slot;int i_sense_slot; +bool dac_powered; + bool unmuted; };#endif /* __TAS2770__ */
Greg Kroah-Hartman
maintainerPATCH 184/365 ASoC: codec: tlv320aic32x4: fix mono playback via I2S
In reply to Greg Kroah-HartmanFrom: Philipp Zabel <[email protected]>
commit b4b5f29a076e52181f63e45a2ad1bc88593072e3 upstream.
The two commits referenced below break mono playback via I2S DAI because they set BCLK to half the required speed. For PCM transport over I2S, the number of transmitted channels is always 2, even for mono playback.
--- sound/soc/codecs/tlv320aic32x4.c | 9 +++++++++ 1 file changed, 9 insertions(+)
sound/soc/codecs/tlv320aic32x4.c +9 -0
@@ -49,6 +49,8 @@ struct aic32x4_priv {struct aic32x4_setup_data *setup;struct device *dev;enum aic32x4_type type; + +unsigned int fmt; }; static int aic32x4_reset_adc(struct snd_soc_dapm_widget *w,
@@ -611,6 +613,7 @@ static int aic32x4_set_dai_sysclk(structstatic int aic32x4_set_dai_fmt (struct snd_soc_dai *codec_dai,unsigned int fmt) {struct snd_soc_component *component = codec_dai->component; +struct aic32x4_priv *aic32x4 =snd_soc_component_get_drvdata (component);u8 iface_reg_1 =0 ;u8 iface_reg_2 =0 ;u8 iface_reg_3 =0 ;
@@ -654,6 +657,8 @@ static int aic32x4_set_dai_fmt(struct snreturn -EINVAL ; } + aic32x4->fmt = fmt; +snd_soc_component_update_bits (component,AIC32X4_IFACE1 ,AIC32X4_IFACE1_DATATYPE_MASK |AIC32X4_IFACE1_MASTER_MASK , iface_reg_1);
@@ -758,6 +763,10 @@ static int aic32x4_setup_clocks(struct sreturn -EINVAL ; } +/* PCM over I2S is always 2-channel */ +if ((aic32x4->fmt &SND_SOC_DAIFMT_FORMAT_MASK ) ==SND_SOC_DAIFMT_I2S ) + channels =2 ; + madc =DIV_ROUND_UP ((32 * adc_resource_class), aosr); max_dosr = (AIC32X4_MAX_DOSR_FREQ / sample_rate / dosr_increment) * dosr_increment;
Greg Kroah-Hartman
maintainerPATCH 185/365 IB/iser: Fix login with authentication
In reply to Greg Kroah-HartmanFrom: Sergey Gorenko <[email protected]>
commit d6d142cb7f79bec6051c5ecf744b7a5309c5a0ee upstream.
The iSER Initiator uses two types of receive buffers:
- one big login buffer posted by iser_post_recvl();
- several small message buffers posted by iser_post_recvm().
The login buffer is used at the login phase and full feature phase in the discovery session. It may take a few requests and responses to complete the login phase. The message buffers are only used in the normal operational session at the full feature phase.
After the commit referred in the fixes line, the login operation fails if the authentication is enabled. That happens because the Initiator posts a small receive buffer after the first response from Target. So, the next send operation fails because Target's second response does not fit into the small receive buffer.
This commit adds additional checks to prevent posting small receive buffers until the full feature phase.
--- drivers/infiniband/ulp/iser/iser_initiator.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/infiniband/ulp/iser/iser_initiator.c +6 -1
@@ -537,6 +537,7 @@ void iser_login_rsp(struct ib_cq *cq, ststruct iscsi_hdr *hdr;char *data;int length; +bool full_feature_phase;if (unlikely (wc->status !=IB_WC_SUCCESS )) {iser_err_comp (wc,"login_rsp" );
@@ -550,6 +551,9 @@ void iser_login_rsp(struct ib_cq *cq, st hdr = desc->rsp +sizeof (struct iser_ctrl ); data = desc->rsp +ISER_HEADERS_LEN ; length = wc->byte_len -ISER_HEADERS_LEN ; + full_feature_phase = ((hdr->flags &ISCSI_FULL_FEATURE_PHASE ) == +ISCSI_FULL_FEATURE_PHASE ) && + (hdr->flags &ISCSI_FLAG_CMD_FINAL );iser_dbg ("op 0x%x itt 0x%x dlen %d\n" , hdr->opcode, hdr->itt, length);
@@ -560,7 +564,8 @@ void iser_login_rsp(struct ib_cq *cq, st desc->rsp_dma,ISER_RX_LOGIN_SIZE , DMA_FROM_DEVICE); -if (iser_conn->iscsi_conn->session->discovery_sess) +if (!full_feature_phase || + iser_conn->iscsi_conn->session->discovery_sess)return ;/* Post the first RX buffer that is skipped in iser_post_rx_bufs() */
Greg Kroah-Hartman
maintainerPATCH 186/365 RDMA/mlx5: Use the proper number of ports
In reply to Greg Kroah-HartmanFrom: Mark Bloch <[email protected]>
commit 4b83c3caf289b80acecc539c79f10a6937cc42dd upstream.
The cited commit allowed the driver to operate over HCAs that have 4 physical ports. Use the number of ports of the RDMA device in the for loop instead of using the struct size.
--- drivers/infiniband/hw/mlx5/main.c | 34 +++++++++++++++---------------- 1 file changed, 16 insertions(+), 18 deletions(-)
drivers/infiniband/hw/mlx5/main.c +16 -18
@@ -2738,26 +2738,24 @@ static int set_has_smi_cap(struct mlx5_ib_dev *dev)int err;int port; -for (port =1 ; port <=ARRAY_SIZE (dev->port_caps); port++) { - dev->port_caps[port -1 ].has_smi = false; -if (MLX5_CAP_GEN (dev->mdev, port_type) == -MLX5_CAP_PORT_TYPE_IB ) { -if (MLX5_CAP_GEN (dev->mdev, ib_virt)) { - err =mlx5_query_hca_vport_context (dev->mdev,0 , - port,0 , - &vport_ctx); -if (err) { -mlx5_ib_err (dev,"query_hca_vport_context for port=%d failed %d\n" , - port, err); -return err; - } - dev->port_caps[port -1 ].has_smi = - vport_ctx.has_smi; - }else { - dev->port_caps[port -1 ].has_smi = true; - } +if (MLX5_CAP_GEN (dev->mdev, port_type) !=MLX5_CAP_PORT_TYPE_IB ) +return 0 ; + +for (port =1 ; port <= dev->num_ports; port++) { +if (!MLX5_CAP_GEN (dev->mdev, ib_virt)) { + dev->port_caps[port -1 ].has_smi = true; +continue ; } + err =mlx5_query_hca_vport_context (dev->mdev,0 , port,0 , + &vport_ctx); +if (err) { +mlx5_ib_err (dev,"query_hca_vport_context for port=%d failed %d\n" , + port, err); +return err; + } + dev->port_caps[port -1 ].has_smi = vport_ctx.has_smi; } +return 0 ; }
Signature · 1 line
2.37.2
Greg Kroah-Hartman
maintainerPATCH 187/365 RDMA/cxgb4: fix accept failure due to increased cpl_t5_pass_accept_rpl size
In reply to Greg Kroah-HartmanFrom: Potnuri Bharat Teja <[email protected]>
commit ef0162298abf46b881e4a4d0c604d1a066228647 upstream.
Commit 'c2ed5611afd7' has increased the cpl_t5_pass_accept_rpl{} structure size by 8B to avoid roundup. cpl_t5_pass_accept_rpl{} is a HW specific structure and increasing its size will lead to unwanted adapter errors. Current commit reverts the cpl_t5_pass_accept_rpl{} back to its original and allocates zeroed skb buffer there by avoiding the memset for iss field. Reorder code to minimize chip type checks.
--- drivers/infiniband/hw/cxgb4/cm.c | 25 ++++++++------------- drivers/net/ethernet/chelsio/cxgb4/t4_msg.h | 2 +- 2 files changed, 10 insertions(+), 17 deletions(-)
drivers/infiniband/hw/cxgb4/cm.c +9 -16
@@ -2468,31 +2468,24 @@ static int accept_cr(struct c4iw_ep *ep, struct sk_buff *skb, opt2 |=CCTRL_ECN_V (1 ); } -skb_get (skb); - rpl =cplhdr (skb);if (!is_t4 (adapter_type)) { -BUILD_BUG_ON (sizeof (*rpl5) !=roundup (sizeof (*rpl5),16 )); -skb_trim (skb,sizeof (*rpl5)); - rpl5 = (void *)rpl; -INIT_TP_WR (rpl5, ep->hwtid); - }else { -skb_trim (skb,sizeof (*rpl)); -INIT_TP_WR (rpl, ep->hwtid); - } -OPCODE_TID (rpl) =cpu_to_be32 (MK_OPCODE_TID (CPL_PASS_ACCEPT_RPL , - ep->hwtid)); - -if (CHELSIO_CHIP_VERSION (adapter_type) >CHELSIO_T4 ) {u32 isn = (prandom_u32 () & ~7UL ) -1 ; + + skb =get_skb (skb,roundup (sizeof (*rpl5),16 ),GFP_KERNEL ); + rpl5 =__skb_put_zero (skb,roundup (sizeof (*rpl5),16 )); + rpl = (void *)rpl5; +INIT_TP_WR_CPL (rpl5,CPL_PASS_ACCEPT_RPL , ep->hwtid); opt2 |=T5_OPT_2_VALID_F ; opt2 |=CONG_CNTRL_V (CONG_ALG_TAHOE ); opt2 |=T5_ISS_F ; - rpl5 = (void *)rpl; -memset_after (rpl5,0 , iss);if (peer2peer) isn +=4 ; rpl5->iss =cpu_to_be32 (isn);pr_debug ("iss %u\n" ,be32_to_cpu (rpl5->iss)); + }else { + skb =get_skb (skb,sizeof (*rpl),GFP_KERNEL ); + rpl =__skb_put_zero (skb,sizeof (*rpl)); +INIT_TP_WR_CPL (rpl,CPL_PASS_ACCEPT_RPL , ep->hwtid); } rpl->opt0 =cpu_to_be64 (opt0);
drivers/net/ethernet/chelsio/cxgb4/t4_msg.h +1 -1
@@ -497,7 +497,7 @@ struct cpl_t5_pass_accept_rpl {__be32 opt2;__be64 opt0;__be32 iss; -__be32 rsvd[3 ]; +__be32 rsvd; };struct cpl_act_open_req {
Signature · 1 line
2.37.2
Greg Kroah-Hartman
maintainerPATCH 188/365 netfilter: nfnetlink: re-enable conntrack expectation events
In reply to Greg Kroah-HartmanFrom: Florian Westphal <[email protected]>
commit 0b2f3212b551a87fe936701fa0813032861a3308 upstream.
To avoid allocation of the conntrack extension area when possible, the default behaviour was changed to only allocate the event extension if a userspace program is subscribed to a notification group.
Problem is that while 'conntrack -E' does enable the event allocation behind the scenes, 'conntrack -E expect' does not: no expectation events are delivered unless user sets "net.netfilter.nf_conntrack_events" back to 1 (always on).
Fix the autodetection to also consider EXP type group.
We need to track the 6 event groups (3+3, new/update/destroy for events and for expectations each) independently, else we'd disable events again if an expectation group becomes empty while there is still an active event group.
--- include/net/netns/conntrack.h | 2 - net/netfilter/nfnetlink.c | 83 +++++++++++++++++++++++++++++++++++------- 2 files changed, 72 insertions(+), 13 deletions(-)
include/net/netns/conntrack.h +1 -1
@@ -95,7 +95,7 @@ struct nf_ip_net {struct netns_ct {#ifdef CONFIG_NF_CONNTRACK_EVENTS -bool ctnetlink_has_listener; +u8 ctnetlink_has_listener;bool ecache_dwork_pending;#endif u8 sysctl_log_invalid;/* Log invalid packets */
net/netfilter/nfnetlink.c +71 -12
111 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 189/365 netfilter: nf_tables: use READ_ONCE and WRITE_ONCE for shared generation id access
In reply to Greg Kroah-HartmanFrom: Pablo Neira Ayuso <[email protected]>
commit 3400278328285a8c2f121904496aff5e7b610a01 upstream.
The generation ID is bumped from the commit path while holding the mutex, however, netlink dump operations rely on RCU.
This patch also adds missing cb->base_eq initialization in nf_tables_dump_set().
--- net/netfilter/nf_tables_api.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-)
net/netfilter/nf_tables_api.c +13 -7
@@ -889,7 +889,7 @@ static int nf_tables_dump_tables(structrcu_read_lock (); nft_net =nft_pernet (net); - cb->seq = nft_net->base_seq; + cb->seq =READ_ONCE (nft_net->base_seq);list_for_each_entry_rcu (table, &nft_net->tables, list) {if (family !=NFPROTO_UNSPEC && family != table->family)
@@ -1705,7 +1705,7 @@ static int nf_tables_dump_chains(structrcu_read_lock (); nft_net =nft_pernet (net); - cb->seq = nft_net->base_seq; + cb->seq =READ_ONCE (nft_net->base_seq);list_for_each_entry_rcu (table, &nft_net->tables, list) {if (family !=NFPROTO_UNSPEC && family != table->family)
@@ -3149,7 +3149,7 @@ static int nf_tables_dump_rules(struct srcu_read_lock (); nft_net =nft_pernet (net); - cb->seq = nft_net->base_seq; + cb->seq =READ_ONCE (nft_net->base_seq);list_for_each_entry_rcu (table, &nft_net->tables, list) {if (family !=NFPROTO_UNSPEC && family != table->family)
@@ -4133,7 +4133,7 @@ static int nf_tables_dump_sets(struct skrcu_read_lock (); nft_net =nft_pernet (net); - cb->seq = nft_net->base_seq; + cb->seq =READ_ONCE (nft_net->base_seq);list_for_each_entry_rcu (table, &nft_net->tables, list) { if (ctx->family != NFPROTO_UNSPEC &&
@@ -5061,6 +5061,8 @@ static int nf_tables_dump_set(struct sk_rcu_read_lock (); nft_net =nft_pernet (net); + cb->seq =READ_ONCE (nft_net->base_seq); +list_for_each_entry_rcu (table, &nft_net->tables, list) {if (dump_ctx->ctx.family !=NFPROTO_UNSPEC && dump_ctx->ctx.family != table->family)
@@ -6887,7 +6889,7 @@ static int nf_tables_dump_obj(struct sk_rcu_read_lock (); nft_net =nft_pernet (net); - cb->seq = nft_net->base_seq; + cb->seq =READ_ONCE (nft_net->base_seq);list_for_each_entry_rcu (table, &nft_net->tables, list) {if (family !=NFPROTO_UNSPEC && family != table->family)
@@ -7819,7 +7821,7 @@ static int nf_tables_dump_flowtable(strurcu_read_lock (); nft_net =nft_pernet (net); - cb->seq = nft_net->base_seq; + cb->seq =READ_ONCE (nft_net->base_seq);list_for_each_entry_rcu (table, &nft_net->tables, list) {if (family !=NFPROTO_UNSPEC && family != table->family)
@@ -8752,6 +8754,7 @@ static int nf_tables_commit(struct net *struct nft_trans_elem *te;struct nft_chain *chain;struct nft_table *table; +unsigned int base_seq;LIST_HEAD (adl);int err;
@@ -8801,9 +8804,12 @@ static int nf_tables_commit(struct net ** Bump generation counter, invalidate any dump in progress. * Cannot fail after this point. */ -while (++nft_net->base_seq ==0 ) + base_seq =READ_ONCE (nft_net->base_seq); +while (++base_seq ==0 ) ; +WRITE_ONCE (nft_net->base_seq, base_seq); +/* step 3. Start new generation, rules_gen_X now in use. */ net->nft.gencursor =nft_gencursor_next (net);
Greg Kroah-Hartman
maintainerPATCH 190/365 fs/ntfs3: uninitialized variable in ntfs_set_acl_ex()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
commit d4073595d0c61463ec3a87411b19e2a90f76d3f8 upstream.
The goto out calls kfree(value) on an uninitialized pointer. Just return directly as the other error paths do.
--- fs/ntfs3/xattr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/ntfs3/xattr.c +1 -1
@@ -563,7 +563,7 @@ static noinline int ntfs_set_acl_ex(stru err =posix_acl_update_mode (mnt_userns, inode, &mode, &acl);if (err) - goto out; +return err; } name =XATTR_NAME_POSIX_ACL_ACCESS ; name_len =sizeof (XATTR_NAME_POSIX_ACL_ACCESS ) -1 ;
Greg Kroah-Hartman
maintainerPATCH 191/365 netfilter: nf_tables: disallow NFTA_SET_ELEM_KEY_END with NFT_SET_ELEM_INTERVAL_END flag
In reply to Greg Kroah-HartmanFrom: Pablo Neira Ayuso <[email protected]>
commit 4963674c2e71fc062f8f089f0f58ffbb5533060b upstream.
These are mutually exclusive, actually NFTA_SET_ELEM_KEY_END replaces the flag notation.
--- net/netfilter/nf_tables_api.c | 1 + 1 file changed, 1 insertion(+)
net/netfilter/nf_tables_api.c +1 -0
@@ -5855,6 +5855,7 @@ static int nft_add_set_elem(struct nft_c nla[NFTA_SET_ELEM_EXPIRATION ] || nla[NFTA_SET_ELEM_USERDATA ] || nla[NFTA_SET_ELEM_EXPR ] || + nla[NFTA_SET_ELEM_KEY_END ] || nla[NFTA_SET_ELEM_EXPRESSIONS])) return -EINVAL;
Greg Kroah-Hartman
maintainerPATCH 192/365 netfilter: nf_ct_sane: remove pseudo skb linearization
In reply to Greg Kroah-HartmanFrom: Florian Westphal <[email protected]>
commit a664375da76c6da8f83dc7997e43c568e1eb9a6a upstream.
For historical reason this code performs pseudo linearization of skbs via skb_header_pointer and a global 64k buffer.
With arrival of BIG TCP, packets generated by TCP stack can exceed 64kb.
Rewrite this to only extract the needed header data. This also allows to get rid of the locking.
--- net/netfilter/nf_conntrack_sane.c | 68 ++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 38 deletions(-)
net/netfilter/nf_conntrack_sane.c +30 -38
@@ -34,10 +34,6 @@ MODULE_AUTHOR("Michal Schmidt <mschmidt@MODULE_DESCRIPTION ("SANE connection tracking helper" );MODULE_ALIAS_NFCT_HELPER (HELPER_NAME ); -static char *sane_buffer; - -static DEFINE_SPINLOCK (nf_sane_lock); -#define MAX_PORTS 8static u_int16_t ports[MAX_PORTS ];static unsigned int ports_c;
@@ -67,14 +63,16 @@ static int help(struct sk_buff *skb,unsigned int dataoff, datalen;const struct tcphdr *th;struct tcphdr _tcph; -void *sb_ptr;int ret =NF_ACCEPT ;int dir =CTINFO2DIR (ctinfo);struct nf_ct_sane_master *ct_sane_info =nfct_help_data (ct);struct nf_conntrack_expect *exp;struct nf_conntrack_tuple *tuple; -struct sane_request *req;struct sane_reply_net_start *reply; +union { +struct sane_request req; +struct sane_reply_net_start repl; + } buf;/* Until there's been traffic both ways, don't look in packets. */ if (ctinfo != IP_CT_ESTABLISHED &&
@@ -92,59 +90,62 @@ static int help(struct sk_buff *skb,return NF_ACCEPT ; datalen = skb->len - dataoff; - -spin_lock_bh (&nf_sane_lock); - sb_ptr =skb_header_pointer (skb, dataoff, datalen, sane_buffer); -if (!sb_ptr) { -spin_unlock_bh (&nf_sane_lock); -return NF_ACCEPT ; - } -if (dir ==IP_CT_DIR_ORIGINAL ) { +const struct sane_request *req; +if (datalen !=sizeof (struct sane_request )) - goto out; +return NF_ACCEPT ; + + req =skb_header_pointer (skb, dataoff, datalen, &buf.req); +if (!req) +return NF_ACCEPT ; - req = sb_ptr;if (req->RPC_code !=htonl (SANE_NET_START )) {/* Not an interesting command */ - ct_sane_info->state =SANE_STATE_NORMAL ; - goto out; +WRITE_ONCE (ct_sane_info->state,SANE_STATE_NORMAL ); +return NF_ACCEPT ; }/* We're interested in the next reply */ - ct_sane_info->state =SANE_STATE_START_REQUESTED ; - goto out; +WRITE_ONCE (ct_sane_info->state,SANE_STATE_START_REQUESTED ); +return NF_ACCEPT ; } +/* IP_CT_DIR_REPLY */ +/* Is it a reply to an uninteresting command? */ -if (ct_sane_info->state !=SANE_STATE_START_REQUESTED ) - goto out; +if (READ_ONCE (ct_sane_info->state) !=SANE_STATE_START_REQUESTED ) +return NF_ACCEPT ;/* It's a reply to SANE_NET_START. */ - ct_sane_info->state =SANE_STATE_NORMAL ; +WRITE_ONCE (ct_sane_info->state,SANE_STATE_NORMAL );if (datalen <sizeof (struct sane_reply_net_start )) {pr_debug ("NET_START reply too short\n" ); - goto out; +return NF_ACCEPT ; } - reply = sb_ptr; + datalen =sizeof (struct sane_reply_net_start ); + + reply =skb_header_pointer (skb, dataoff, datalen, &buf.repl); +if (!reply) +return NF_ACCEPT ; +if (reply->status !=htonl (SANE_STATUS_SUCCESS )) {/* saned refused the command */ pr_debug ("unsuccessful SANE_STATUS = %u\n" ,ntohl (reply->status)); - goto out; +return NF_ACCEPT ; }/* Invalid saned reply? Ignore it. */ if (reply->zero !=0 ) - goto out; +return NF_ACCEPT ; exp =nf_ct_expect_alloc (ct);if (exp ==NULL ) {nf_ct_helper_log (skb, ct,"cannot alloc expectation" ); - ret =NF_DROP ; - goto out; +return NF_DROP ; } tuple = &ct->tuplehash[IP_CT_DIR_ORIGINAL ].tuple;
@@ -162,9 +163,6 @@ static int help(struct sk_buff *skb, }nf_ct_expect_put (exp); - -out: -spin_unlock_bh (&nf_sane_lock);return ret; }
@@ -178,7 +176,6 @@ static const struct nf_conntrack_expect_ static void __exit nf_conntrack_sane_fini(void) {nf_conntrack_helpers_unregister (sane, ports_c *2 ); -kfree (sane_buffer); }static int __init nf_conntrack_sane_init (void )
@@ -187,10 +184,6 @@ static int __init nf_conntrack_sane_initNF_CT_HELPER_BUILD_BUG_ON (sizeof (struct nf_ct_sane_master )); - sane_buffer =kmalloc (65536 ,GFP_KERNEL ); -if (!sane_buffer) -return -ENOMEM ; -if (ports_c ==0 ) ports[ports_c++] =SANE_PORT ;
@@ -210,7 +203,6 @@ static int __init nf_conntrack_sane_init ret =nf_conntrack_helpers_register (sane, ports_c *2 );if (ret <0 ) {pr_err ("failed to register helpers\n" ); -kfree (sane_buffer);return ret; }
Greg Kroah-Hartman
maintainerPATCH 193/365 netfilter: nf_ct_h323: cap packet size at 64k
In reply to Greg Kroah-HartmanFrom: Florian Westphal <[email protected]>
commit f3e124c36f70d5ffcdd4e8bdbe7bb28a98a715c0 upstream.
With BIG TCP, packets generated by tcp stack may exceed 64kb. Cap datalen at 64kb. The internal message format uses 16bit fields, so no embedded message can exceed 64k size.
Multiple h323 messages in a single superpacket may now result in a message to get treated as incomplete/truncated, but thats better than scribbling past h323_buffer.
Another alternative suitable for net tree would be a switch to skb_linearize().
--- net/netfilter/nf_conntrack_h323_main.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
net/netfilter/nf_conntrack_h323_main.c +9 -1
@@ -34,6 +34,8 @@#include <net/netfilter/nf_conntrack_zones.h> #include <linux/netfilter/nf_conntrack_h323.h> +#define H323_MAX_SIZE 65535 +/* Parameters */ static unsigned int default_rrq_ttl__read_mostly =300 ;module_param (default_rrq_ttl, uint,0600 );
@@ -142,6 +144,9 @@ static int get_tpkt_data(struct sk_buffif (tcpdatalen <=0 )/* No TCP data */ goto clear_out; +if (tcpdatalen >H323_MAX_SIZE ) + tcpdatalen =H323_MAX_SIZE ; +if (*data ==NULL ) {/* first TPKT */ /* Get first TPKT pointer */ tpkt = skb_header_pointer(skb, tcpdataoff, tcpdatalen,
@@ -1220,6 +1225,9 @@ static unsigned char *get_udp_data(strucif (dataoff >= skb->len)return NULL ; *datalen = skb->len - dataoff; +if (*datalen >H323_MAX_SIZE ) + *datalen =H323_MAX_SIZE ; +return skb_header_pointer (skb, dataoff, *datalen, h323_buffer); }
@@ -1821,7 +1829,7 @@ static int __init nf_conntrack_h323_initNF_CT_HELPER_BUILD_BUG_ON (sizeof (struct nf_ct_h323_master )); - h323_buffer =kmalloc (65536 ,GFP_KERNEL ); + h323_buffer =kmalloc (H323_MAX_SIZE +1 ,GFP_KERNEL );if (!h323_buffer)return -ENOMEM ; ret =h323_helper_init ();
Greg Kroah-Hartman
maintainerPATCH 194/365 netfilter: nf_ct_ftp: prefer skb_linearize
In reply to Greg Kroah-HartmanFrom: Florian Westphal <[email protected]>
commit c783a29c7e5934eabac2b760571489ad83bf4fd1 upstream.
This uses a pseudo-linearization scheme with a 64k global buffer, but BIG TCP arrival means IPv6 TCP stack can generate skbs that exceed this size.
Use skb_linearize. It should be possible to rewrite this to properly deal with segmented skbs (i.e., only do small chunk-wise accesses), but this is going to be a lot more intrusive than this because every helper function needs to get the sk_buff instead of a pointer to a raw data buffer.
In practice, provided we're really looking at FTP control channel packets, there should never be a case where we deal with huge packets.
--- net/netfilter/nf_conntrack_ftp.c | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-)
net/netfilter/nf_conntrack_ftp.c +6 -18
@@ -34,11 +34,6 @@ MODULE_DESCRIPTION("ftp connection tracking helper");MODULE_ALIAS ("ip_conntrack_ftp" );MODULE_ALIAS_NFCT_HELPER (HELPER_NAME ); -/* This is slow, but it's simple. --RR */ -static char *ftp_buffer; - -static DEFINE_SPINLOCK (nf_ftp_lock); -#define MAX_PORTS 8static u_int16_t ports[MAX_PORTS ];static unsigned int ports_c;
@@ -398,6 +393,9 @@ static int help(struct sk_buff *skb,return NF_ACCEPT ; } +if (unlikely (skb_linearize (skb))) +return NF_DROP ; + th =skb_header_pointer (skb, protoff,sizeof (_tcph), &_tcph);if (th ==NULL )return NF_ACCEPT ;
@@ -411,12 +409,8 @@ static int help(struct sk_buff *skb, } datalen = skb->len - dataoff; -spin_lock_bh (&nf_ftp_lock); - fb_ptr =skb_header_pointer (skb, dataoff, datalen, ftp_buffer); -if (!fb_ptr) { -spin_unlock_bh (&nf_ftp_lock); -return NF_ACCEPT ; - } +spin_lock_bh (&ct->lock); + fb_ptr = skb->data + dataoff; ends_in_nl = (fb_ptr[datalen -1 ] =='\n' ); seq =ntohl (th->seq) + datalen;
@@ -544,7 +538,7 @@ static int help(struct sk_buff *skb,if (ends_in_nl)update_nl_seq (ct, seq, ct_ftp_info, dir, skb); out: -spin_unlock_bh (&nf_ftp_lock); +spin_unlock_bh (&ct->lock);return ret; }
@@ -571,7 +565,6 @@ static const struct nf_conntrack_expect_policy ftp_exp_policy = { static void __exit nf_conntrack_ftp_fini(void) {nf_conntrack_helpers_unregister (ftp, ports_c *2 ); -kfree (ftp_buffer); }static int __init nf_conntrack_ftp_init (void )
@@ -580,10 +573,6 @@ static int __init nf_conntrack_ftp_init(void)NF_CT_HELPER_BUILD_BUG_ON (sizeof (struct nf_ct_ftp_master )); - ftp_buffer =kmalloc (65536 ,GFP_KERNEL ); -if (!ftp_buffer) -return -ENOMEM ; -if (ports_c ==0 ) ports[ports_c++] =FTP_PORT ;
@@ -603,7 +592,6 @@ static int __init nf_conntrack_ftp_init(void) ret =nf_conntrack_helpers_register (ftp, ports_c *2 );if (ret <0 ) {pr_err ("failed to register helpers\n" ); -kfree (ftp_buffer);return ret; }
Signature · 1 line
2.37.2
Greg Kroah-Hartman
maintainerPATCH 195/365 netfilter: nf_ct_irc: cap packet search space to 4k
In reply to Greg Kroah-HartmanFrom: Florian Westphal <[email protected]>
commit 976bf59c69cd2e2c17f0ab20a14c0e700cba0f15 upstream.
This uses a pseudo-linearization scheme with a 64k global buffer, but BIG TCP arrival means IPv6 TCP stack can generate skbs that exceed this size.
In practice, IRC commands are not expected to exceed 512 bytes, plus this is interactive protocol, so we should not see large packets in practice.
Given most IRC connections nowadays use TLS so this helper could also be removed in the near future.
--- net/netfilter/nf_conntrack_irc.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
net/netfilter/nf_conntrack_irc.c +9 -3
@@ -39,6 +39,7 @@ unsigned int (*nf_nat_irc_hook)(struct sk_buff *skb,EXPORT_SYMBOL_GPL (nf_nat_irc_hook);#define HELPER_NAME "irc" +#define MAX_SEARCH_SIZE 4095MODULE_AUTHOR ("Harald Welte <[email protected]>" );MODULE_DESCRIPTION ("IRC (DCC) connection tracking helper" );
@@ -121,6 +122,7 @@ static int help(struct sk_buff *skb, unsigned int protoff,int i, ret =NF_ACCEPT ;char *addr_beg_p, *addr_end_p;typeof (nf_nat_irc_hook) nf_nat_irc; +unsigned int datalen;/* If packet is coming from IRC server */ if (dir ==IP_CT_DIR_REPLY )
@@ -140,8 +142,12 @@ static int help(struct sk_buff *skb, unsigned int protoff,if (dataoff >= skb->len)return NF_ACCEPT ; + datalen = skb->len - dataoff; +if (datalen >MAX_SEARCH_SIZE ) + datalen =MAX_SEARCH_SIZE ; +spin_lock_bh (&irc_buffer_lock); - ib_ptr =skb_header_pointer (skb, dataoff, skb->len - dataoff, + ib_ptr =skb_header_pointer (skb, dataoff, datalen, irc_buffer);if (!ib_ptr) {spin_unlock_bh (&irc_buffer_lock);
@@ -149,7 +155,7 @@ static int help(struct sk_buff *skb, unsigned int protoff, } data = ib_ptr; - data_limit = ib_ptr + skb->len - dataoff; + data_limit = ib_ptr + datalen;/* strlen("\1DCC SENT t AAAAAAAA P\1\n")=24 * 5+MINMATCHLEN+strlen("t AAAAAAAA P\1\n")=14 */
@@ -251,7 +257,7 @@ static int __init nf_conntrack_irc_init(void) irc_exp_policy.max_expected = max_dcc_channels; irc_exp_policy.timeout = dcc_timeout; - irc_buffer =kmalloc (65536 ,GFP_KERNEL ); + irc_buffer =kmalloc (MAX_SEARCH_SIZE +1 ,GFP_KERNEL );if (!irc_buffer)return -ENOMEM ;
Signature · 1 line
2.37.2
Greg Kroah-Hartman
maintainerPATCH 196/365 netfilter: nf_tables: possible module reference underflow in error path
In reply to Greg Kroah-HartmanFrom: Pablo Neira Ayuso <[email protected]>
commit c485c35ff6783ccd12c160fcac6a0e504e83e0bf upstream.
dst->ops is set on when nft_expr_clone() fails, but module refcount has not been bumped yet, therefore nft_expr_destroy() leads to module reference underflow.
--- net/netfilter/nf_tables_api.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/netfilter/nf_tables_api.c +1 -1
@@ -5566,7 +5566,7 @@ int nft_set_elem_expr_clone(const struct err =nft_expr_clone (expr, set->exprs[i]);if (err <0 ) { -nft_expr_destroy (ctx, expr); +kfree (expr); goto err_expr; } expr_array[i] = expr;
Greg Kroah-Hartman
maintainerPATCH 197/365 netfilter: nf_tables: really skip inactive sets when allocating name
In reply to Greg Kroah-HartmanFrom: Pablo Neira Ayuso <[email protected]>
commit 271c5ca826e0c3c53e0eb4032f8eaedea1ee391c upstream.
While looping to build the bitmap of used anonymous set names, check the current set in the iteration, instead of the one that is being created.
--- net/netfilter/nf_tables_api.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/netfilter/nf_tables_api.c +1 -1
@@ -3907,7 +3907,7 @@ cont:list_for_each_entry (i, &ctx->table->sets, list) {int tmp; -if (!nft_is_active_next (ctx->net, set)) +if (!nft_is_active_next (ctx->net, i))continue ;if (!sscanf (i->name, name, &tmp))continue ;
Greg Kroah-Hartman
maintainerPATCH 198/365 netfilter: nf_tables: fix scheduling-while-atomic splat
In reply to Greg Kroah-HartmanFrom: Florian Westphal <[email protected]>
commit 2024439bd5ceb145eeeb428b2a59e9b905153ac3 upstream.
nf_tables_check_loops() can be called from rhashtable list walk so cond_resched() cannot be used here.
--- net/netfilter/nf_tables_api.c | 4 ---- 1 file changed, 4 deletions(-)
net/netfilter/nf_tables_api.c +0 -4
@@ -9372,13 +9372,9 @@ static int nf_tables_check_loops(const sbreak ; } } - -cond_resched (); }list_for_each_entry (set, &ctx->table->sets, list) { -cond_resched (); -if (!nft_is_active_next (ctx->net, set))continue ; if (!(set->flags & NFT_SET_MAP) ||
Greg Kroah-Hartman
maintainerPATCH 199/365 netfilter: nf_tables: validate NFTA_SET_ELEM_OBJREF based on NFT_SET_OBJECT flag
In reply to Greg Kroah-HartmanFrom: Pablo Neira Ayuso <[email protected]>
commit 5a2f3dc31811e93be15522d9eb13ed61460b76c8 upstream.
If the NFTA_SET_ELEM_OBJREF netlink attribute is present and NFT_SET_OBJECT flag is set on, report EINVAL.
Move existing sanity check earlier to validate that NFT_SET_OBJECT requires NFTA_SET_ELEM_OBJREF.
--- net/netfilter/nf_tables_api.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
net/netfilter/nf_tables_api.c +9 -4
@@ -5848,6 +5848,15 @@ static int nft_add_set_elem(struct nft_creturn -EINVAL ; } +if (set->flags &NFT_SET_OBJECT ) { +if (!nla[NFTA_SET_ELEM_OBJREF ] && + !(flags &NFT_SET_ELEM_INTERVAL_END )) +return -EINVAL ; + }else { +if (nla[NFTA_SET_ELEM_OBJREF ]) +return -EINVAL ; + } + if ((flags & NFT_SET_ELEM_INTERVAL_END) && (nla[NFTA_SET_ELEM_DATA] || nla[NFTA_SET_ELEM_OBJREF] ||
@@ -5986,10 +5995,6 @@ static int nft_add_set_elem(struct nft_c }if (nla[NFTA_SET_ELEM_OBJREF ] !=NULL ) { -if (!(set->flags &NFT_SET_OBJECT )) { - err = -EINVAL ; - goto err_parse_key_end; - } obj =nft_obj_lookup (ctx->net, ctx->table, nla[NFTA_SET_ELEM_OBJREF ], set->objtype, genmask);
Greg Kroah-Hartman
maintainerPATCH 200/365 netfilter: nf_tables: NFTA_SET_ELEM_KEY_END requires concat and interval flags
In reply to Greg Kroah-HartmanFrom: Pablo Neira Ayuso <[email protected]>
commit 88cccd908d51397f9754f89a937cd13fa59dee37 upstream.
If the NFT_SET_CONCAT|NFT_SET_INTERVAL flags are set on, then the netlink attribute NFTA_SET_ELEM_KEY_END must be specified. Otherwise, NFTA_SET_ELEM_KEY_END should not be present.
For catch-all element, NFTA_SET_ELEM_KEY_END should not be present. The NFT_SET_ELEM_INTERVAL_END is never used with this set flags combination.
--- net/netfilter/nf_tables_api.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+)
net/netfilter/nf_tables_api.c +24 -0
@@ -5798,6 +5798,24 @@ static void nft_setelem_remove(const str set->ops->remove (net, set, elem); } +static bool nft_setelem_valid_key_end (const struct nft_set *set, +struct nlattr **nla,u32 flags) +{ +if ((set->flags & (NFT_SET_CONCAT |NFT_SET_INTERVAL )) == + (NFT_SET_CONCAT |NFT_SET_INTERVAL )) { +if (flags &NFT_SET_ELEM_INTERVAL_END ) +return false; +if (!nla[NFTA_SET_ELEM_KEY_END ] && + !(flags &NFT_SET_ELEM_CATCHALL )) +return false; + }else { +if (nla[NFTA_SET_ELEM_KEY_END ]) +return false; + } + +return true; +} +static int nft_add_set_elem (struct nft_ctx *ctx,struct nft_set *set,const struct nlattr *attr,u32 nlmsg_flags) {
@@ -5857,6 +5875,9 @@ static int nft_add_set_elem(struct nft_creturn -EINVAL ; } +if (!nft_setelem_valid_key_end (set, nla, flags)) +return -EINVAL ; + if ((flags & NFT_SET_ELEM_INTERVAL_END) && (nla[NFTA_SET_ELEM_DATA] || nla[NFTA_SET_ELEM_OBJREF] ||
@@ -6281,6 +6302,9 @@ static int nft_del_setelem(struct nft_ctif (!nla[NFTA_SET_ELEM_KEY ] && !(flags &NFT_SET_ELEM_CATCHALL ))return -EINVAL ; +if (!nft_setelem_valid_key_end (set, nla, flags)) +return -EINVAL ; +nft_set_ext_prepare (&tmpl);if (flags !=0 ) {
Greg Kroah-Hartman
maintainerPATCH 201/365 netfilter: nf_tables: disallow NFT_SET_ELEM_CATCHALL and NFT_SET_ELEM_INTERVAL_END
In reply to Greg Kroah-HartmanFrom: Pablo Neira Ayuso <[email protected]>
commit fc0ae524b5fd2938c94d56da3f749f11eb3273d5 upstream.
These flags are mutually exclusive, report EINVAL in this case.
--- net/netfilter/nf_tables_api.c | 3 +++ 1 file changed, 3 insertions(+)
net/netfilter/nf_tables_api.c +3 -0
@@ -5198,6 +5198,9 @@ static int nft_setelem_parse_flags(constif (!(set->flags &NFT_SET_INTERVAL ) && *flags &NFT_SET_ELEM_INTERVAL_END )return -EINVAL ; +if ((*flags & (NFT_SET_ELEM_INTERVAL_END |NFT_SET_ELEM_CATCHALL )) == + (NFT_SET_ELEM_INTERVAL_END |NFT_SET_ELEM_CATCHALL )) +return -EINVAL ;return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 202/365 netfilter: nf_tables: check NFT_SET_CONCAT flag if field_count is specified
In reply to Greg Kroah-HartmanFrom: Pablo Neira Ayuso <[email protected]>
commit 1b6345d4160ecd3d04bd8cd75df90c67811e8cc9 upstream.
Since f3a2181e16f1 ("netfilter: nf_tables: Support for sets with multiple ranged fields"), it possible to combine intervals and concatenations. Later on, ef516e8625dd ("netfilter: nf_tables:
reintroduce the NFT_SET_CONCAT flag") provides the NFT_SET_CONCAT flag for userspace to report that the set stores a concatenation.
Make sure NFT_SET_CONCAT is set on if field_count is specified for consistency. Otherwise, if NFT_SET_CONCAT is specified with no field_count, bail out with EINVAL.
--- net/netfilter/nf_tables_api.c | 5 +++++ 1 file changed, 5 insertions(+)
net/netfilter/nf_tables_api.c +5 -0
@@ -4451,6 +4451,11 @@ static int nf_tables_newset(struct sk_bu err =nf_tables_set_desc_parse (&desc, nla[NFTA_SET_DESC ]);if (err <0 )return err; + +if (desc.field_count >1 && !(flags &NFT_SET_CONCAT )) +return -EINVAL ; + }else if (flags &NFT_SET_CONCAT ) { +return -EINVAL ; }if (nla[NFTA_SET_EXPR ] || nla[NFTA_SET_EXPRESSIONS ])
Greg Kroah-Hartman
maintainerPATCH 203/365 powerpc/pci: Fix get_phb_number() locking
In reply to Greg Kroah-HartmanFrom: Michael Ellerman <[email protected]>
commit 8d48562a2729742f767b0fdd994d6b2a56a49c63 upstream.
The recent change to get_phb_number() causes a DEBUG_ATOMIC_SLEEP warning on some systems:
BUG: sleeping function called from invalid context at kernel/locking/mutex.c:580
in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 1, name: swapper
preempt_count: 1, expected: 0
RCU nest depth: 0, expected: 0
1 lock held by swapper/1:
#0: c157efb0 (hose_spinlock){+.+.}-{2:2}, at: pcibios_alloc_controller+0x64/0x220
Preemption disabled at:
[<00000000>] 0x0
CPU: 0 PID: 1 Comm: swapper Not tainted 5.19.0-yocto-standard+ #1
Call Trace:
[d101dc90] [c073b264] dump_stack_lvl+0x50/0x8c (unreliable)
[d101dcb0] [c0093b70] __might_resched+0x258/0x2a8
[d101dcd0] [c0d3e634] __mutex_lock+0x6c/0x6ec
[d101dd50] [c0a84174] of_alias_get_id+0x50/0xf4
[d101dd80] [c002ec78] pcibios_alloc_controller+0x1b8/0x220
[d101ddd0] [c140c9dc] pmac_pci_init+0x198/0x784
[d101de50] [c140852c] discover_phbs+0x30/0x4c
[d101de60] [c0007fd4] do_one_initcall+0x94/0x344
[d101ded0] [c1403b40] kernel_init_freeable+0x1a8/0x22c
[d101df10] [c00086e0] kernel_init+0x34/0x160
[d101df30] [c001b334] ret_from_kernel_thread+0x5c/0x64This is because pcibios_alloc_controller() holds hose_spinlock but of_alias_get_id() takes of_mutex which can sleep.
The hose_spinlock protects the phb_bitmap, and also the hose_list, but it doesn't need to be held while get_phb_number() calls the OF routines, because those are only looking up information in the device tree.
So fix it by having get_phb_number() take the hose_spinlock itself, only where required, and then dropping the lock before returning. pcibios_alloc_controller() then needs to take the lock again before the list_add() but that's safe, the order of the list is not important.
--- arch/powerpc/kernel/pci-common.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-)
arch/powerpc/kernel/pci-common.c +10 -6
@@ -67,10 +67,6 @@ void __init set_pci_dma_ops(const struct pci_dma_ops = dma_ops; } -/* -* This function should run under locking protection, specifically -* hose_spinlock. -*/ static int get_phb_number (struct device_node *dn) {int ret, phb_id =-1 ;
@@ -107,15 +103,20 @@ static int get_phb_number(struct device_if (!ret) phb_id = (int )(prop & (MAX_PHBS -1 )); +spin_lock (&hose_spinlock); +/* We need to be sure to not use the same PHB number twice. */ if ((phb_id >=0 ) && !test_and_set_bit (phb_id, phb_bitmap)) -return phb_id; + goto out_unlock;/* If everything fails then fallback to dynamic PHB numbering. */ phb_id =find_first_zero_bit (phb_bitmap,MAX_PHBS );BUG_ON (phb_id >=MAX_PHBS );set_bit (phb_id, phb_bitmap); +out_unlock: +spin_unlock (&hose_spinlock); +return phb_id; }
@@ -126,10 +127,13 @@ struct pci_controller *pcibios_alloc_con phb =zalloc_maybe_bootmem (sizeof (struct pci_controller ),GFP_KERNEL );if (phb ==NULL )return NULL ; -spin_lock (&hose_spinlock); + phb->global_number =get_phb_number (dev); + +spin_lock (&hose_spinlock);list_add_tail (&phb->list_node, &hose_list);spin_unlock (&hose_spinlock); + phb->dn = dev; phb->is_dynamic =slab_is_available ();#ifdef CONFIG_PPC64
Greg Kroah-Hartman
maintainerPATCH 204/365 spi: meson-spicc: add local pow2 clock ops to preserve rate between messages
In reply to Greg Kroah-HartmanFrom: Neil Armstrong <[email protected]>
commit 09992025dacd258c823f50e82db09d7ef06cdac4 upstream.
At the end of a message, the HW gets a reset in meson_spicc_unprepare_transfer(), this resets the SPICC_CONREG register and notably the value set by the Common Clock Framework.
This is problematic because:
- the register value CCF can be different from the corresponding CCF cached rate
- CCF is allowed to change the clock rate whenever the HW state
This introduces:
- local pow2 clock ops checking the HW state before allowing a clock operation
- separation of legacy pow2 clock patch and new enhanced clock path
- SPICC_CONREG datarate value is now value kepts across messages
It has been checked that:
- SPICC_CONREG datarate value is kept across messages
- CCF is only allowed to change the SPICC_CONREG datarate value when busy
- SPICC_CONREG datarate value is correct for each transfer
This didn't appear before commit 3e0cf4d3fc29 ("spi: meson-spicc: add a linear clock divider support") because we recalculated and wrote the rate for each xfer.
--- drivers/spi/spi-meson-spicc.c | 129 ++++++++++++++++++++++++++++++++---------- 1 file changed, 101 insertions(+), 28 deletions(-)
drivers/spi/spi-meson-spicc.c +101 -28
@@ -156,6 +156,7 @@ struct meson_spicc_device {void __iomem *base;struct clk *core;struct clk *pclk; +struct clk_divider pow2_div;struct clk *clk;struct spi_message *message;struct spi_transfer *xfer;
@@ -168,6 +169,8 @@ struct meson_spicc_device {unsigned long xfer_remain; }; +#define pow2_clk_to_spicc (_div) container_of(_div, struct meson_spicc_device, pow2_div) +static void meson_spicc_oen_enable (struct meson_spicc_device *spicc) {u32 conf;
@@ -421,7 +424,7 @@ static int meson_spicc_prepare_message(s {struct meson_spicc_device *spicc =spi_master_get_devdata (master);struct spi_device *spi = message->spi; -u32 conf =0 ; +u32 conf =readl_relaxed (spicc->base +SPICC_CONREG ) &SPICC_DATARATE_MASK ;/* Store current message */ spicc->message = message;
@@ -458,8 +461,6 @@ static int meson_spicc_prepare_message(s/* Select CS */ conf |=FIELD_PREP (SPICC_CS_MASK , spi->chip_select); -/* Default Clock rate core/4 */ -/* Default 8bit word */ conf |=FIELD_PREP (SPICC_BITLENGTH_MASK ,8 -1 );
@@ -476,12 +477,16 @@ static int meson_spicc_prepare_message(sstatic int meson_spicc_unprepare_transfer (struct spi_master *master) {struct meson_spicc_device *spicc =spi_master_get_devdata (master); +u32 conf =readl_relaxed (spicc->base +SPICC_CONREG ) &SPICC_DATARATE_MASK ;/* Disable all IRQs */ writel (0 , spicc->base +SPICC_INTREG );device_reset_optional (&spicc->pdev->dev); +/* Set default configuration, keeping datarate field */ +writel_relaxed (conf, spicc->base +SPICC_CONREG ); +return 0 ; }
@@ -518,14 +523,60 @@ static void meson_spicc_cleanup(struct s* Clk path for G12A series: * pclk -> pow2 fixed div -> pow2 div -> mux -> out * pclk -> enh fixed div -> enh div -> mux -> out +* +* The pow2 divider is tied to the controller HW state, and the +* divider is only valid when the controller is initialized. +* +* A set of clock ops is added to make sure we don't read/set this +* clock rate while the controller is in an unknown state. */ -static int meson_spicc_clk_init (struct meson_spicc_device *spicc) +static unsigned long meson_spicc_pow2_recalc_rate (struct clk_hw *hw, +unsigned long parent_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) +return 0 ; + +return clk_divider_ops.recalc_rate (hw, parent_rate); +} + +static int meson_spicc_pow2_determine_rate (struct clk_hw *hw, +struct clk_rate_request *req) +{ +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) +return -EINVAL ; + +return clk_divider_ops.determine_rate (hw, req); +} + +static int meson_spicc_pow2_set_rate (struct clk_hw *hw,unsigned long rate, +unsigned long parent_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) +return -EINVAL ; + +return clk_divider_ops.set_rate (hw, rate, parent_rate); +} + +const struct clk_ops meson_spicc_pow2_clk_ops = { + .recalc_rate = meson_spicc_pow2_recalc_rate, + .determine_rate = meson_spicc_pow2_determine_rate, + .set_rate = meson_spicc_pow2_set_rate, +}; + +static int meson_spicc_pow2_clk_init (struct meson_spicc_device *spicc) {struct device *dev = &spicc->pdev->dev; -struct clk_fixed_factor *pow2_fixed_div, *enh_fixed_div; -struct clk_divider *pow2_div, *enh_div; -struct clk_mux *mux; +struct clk_fixed_factor *pow2_fixed_div;struct clk_init_data init;struct clk *clk;struct clk_parent_data parent_data[2 ];
@@ -560,31 +611,45 @@ static int meson_spicc_clk_init(struct mif (WARN_ON (IS_ERR (clk)))return PTR_ERR (clk); - pow2_div =devm_kzalloc (dev,sizeof (*pow2_div),GFP_KERNEL ); -if (!pow2_div) -return -ENOMEM ; -snprintf (name,sizeof (name),"%s#pow2_div" ,dev_name (dev)); init.name = name; - init.ops = &clk_divider_ops; - init.flags =CLK_SET_RATE_PARENT ; + init.ops = &meson_spicc_pow2_clk_ops; +/* +* Set NOCACHE here to make sure we read the actual HW value +* since we reset the HW after each transfer. +*/ + init.flags =CLK_SET_RATE_PARENT |CLK_GET_RATE_NOCACHE ; parent_data[0 ].hw = &pow2_fixed_div->hw; init.num_parents =1 ; - pow2_div->shift =16 , - pow2_div->width =3 , - pow2_div->flags =CLK_DIVIDER_POWER_OF_TWO , - pow2_div->reg = spicc->base +SPICC_CONREG ; - pow2_div->hw.init = &init; + spicc->pow2_div.shift =16 , + spicc->pow2_div.width =3 , + spicc->pow2_div.flags =CLK_DIVIDER_POWER_OF_TWO , + spicc->pow2_div.reg = spicc->base +SPICC_CONREG ; + spicc->pow2_div.hw.init = &init; - clk =devm_clk_register (dev, &pow2_div->hw); -if (WARN_ON (IS_ERR (clk))) -return PTR_ERR (clk); + spicc->clk =devm_clk_register (dev, &spicc->pow2_div.hw); +if (WARN_ON (IS_ERR (spicc->clk))) +return PTR_ERR (spicc->clk); -if (!spicc->data->has_enhance_clk_div) { - spicc->clk = clk; -return 0 ; - } +return 0 ; +} + +static int meson_spicc_enh_clk_init (struct meson_spicc_device *spicc) +{ +struct device *dev = &spicc->pdev->dev; +struct clk_fixed_factor *enh_fixed_div; +struct clk_divider *enh_div; +struct clk_mux *mux; +struct clk_init_data init; +struct clk *clk; +struct clk_parent_data parent_data[2 ]; +char name[64 ]; + +memset (&init,0 ,sizeof (init)); +memset (&parent_data,0 ,sizeof (parent_data)); + + init.parent_data = parent_data;/* algorithm for enh div: rate = freq / 2 / (N + 1) */
@@ -637,7 +702,7 @@ static int meson_spicc_clk_init(struct msnprintf (name,sizeof (name),"%s#sel" ,dev_name (dev)); init.name = name; init.ops = &clk_mux_ops; - parent_data[0 ].hw = &pow2_div->hw; + parent_data[0 ].hw = &spicc->pow2_div.hw; parent_data[1 ].hw = &enh_div->hw; init.num_parents =2 ; init.flags =CLK_SET_RATE_PARENT ;
@@ -754,12 +819,20 @@ static int meson_spicc_probe(struct platmeson_spicc_oen_enable (spicc); - ret =meson_spicc_clk_init (spicc); + ret =meson_spicc_pow2_clk_init (spicc);if (ret) { -dev_err (&pdev->dev,"clock registration failed\n" ); +dev_err (&pdev->dev,"pow2 clock registration failed\n" ); goto out_clk; } +if (spicc->data->has_enhance_clk_div) { + ret =meson_spicc_enh_clk_init (spicc); +if (ret) { +dev_err (&pdev->dev,"clock registration failed\n" ); + goto out_clk; + } + } + ret =devm_spi_register_master (&pdev->dev, master);if (ret) {dev_err (&pdev->dev,"spi master registration failed\n" );
Greg Kroah-Hartman
maintainerPATCH 205/365 net/sunrpc: fix potential memory leaks in rpc_sysfs_xprt_state_change()
In reply to Greg Kroah-HartmanFrom: Xin Xiong <[email protected]>
commit bfc48f1b0505ffcb03a6d749139b7577d6b81ae0 upstream.
The issue happens on some error handling paths. When the function fails to grab the object xprt, it simply returns 0, forgetting to decrease the reference count of another object xps, which is increased by rpc_sysfs_xprt_kobj_get_xprt_switch(), causing refcount leaks. Also, the function forgets to check whether xps is valid before using it, which may result in NULL-dereferencing issues.
Fix it by adding proper error handling code when either xprt or xps is NULL.
--- net/sunrpc/sysfs.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
net/sunrpc/sysfs.c +4 -2
@@ -291,8 +291,10 @@ static ssize_t rpc_sysfs_xprt_state_chanint offline =0 , online =0 , remove =0 ;struct rpc_xprt_switch *xps =rpc_sysfs_xprt_kobj_get_xprt_switch (kobj); -if (!xprt) -return 0 ; +if (!xprt || !xps) { + count =0 ; + goto out_put; + }if (!strncmp (buf,"offline" ,7 )) offline =1 ;
Greg Kroah-Hartman
maintainerPATCH 206/365 net: dsa: mv88e6060: prevent crash on an unused port
In reply to Greg Kroah-HartmanFrom: Sergei Antonov <[email protected]>
commit 246bbf2f977ea36aaf41f5d24370fef433250728 upstream.
If the port isn't a CPU port nor a user port, 'cpu_dp' is a null pointer and a crash happened on dereferencing it in mv88e6060_setup_port():
[ 9.575872] Unable to handle kernel NULL pointer dereference at virtual address 00000014 ... [ 9.942216] mv88e6060_setup from dsa_register_switch+0x814/0xe84 [ 9.948616] dsa_register_switch from mdio_probe+0x2c/0x54 [ 9.954433] mdio_probe from really_probe.part.0+0x98/0x2a0 [ 9.960375] really_probe.part.0 from driver_probe_device+0x30/0x10c [ 9.967029] driver_probe_device from __device_attach_driver+0xb8/0x13c [ 9.973946] __device_attach_driver from bus_for_each_drv+0x90/0xe0 [ 9.980509] bus_for_each_drv from __device_attach+0x110/0x184 [ 9.986632] __device_attach from bus_probe_device+0x8c/0x94 [ 9.992577] bus_probe_device from deferred_probe_work_func+0x78/0xa8 [ 9.999311] deferred_probe_work_func from process_one_work+0x290/0x73c [ 10.006292] process_one_work from worker_thread+0x30/0x4b8 [ 10.012155] worker_thread from kthread+0xd4/0x10c [ 10.017238] kthread from ret_from_fork+0x14/0x3c
--- drivers/net/dsa/mv88e6060.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/dsa/mv88e6060.c +3 -0
@@ -118,6 +118,9 @@ static int mv88e6060_setup_port(struct mint addr =REG_PORT (p);int ret; +if (dsa_is_unused_port (priv->ds, p)) +return 0 ; +/* Do not force flow control, disable Ingress and Egress * Header tagging, disable VLAN tunneling, and set the port * state to Forwarding. Additionally, if this is the CPU
Greg Kroah-Hartman
maintainerPATCH 207/365 net: qrtr: start MHI channel after endpoit creation
In reply to Greg Kroah-HartmanFrom: Maxim Kochetkov <[email protected]>
commit 68a838b84effb7b57ba7d50b1863fc6ae35a54ce upstream.
MHI channel may generates event/interrupt right after enabling. It may leads to 2 race conditions issues.
1)
Such event may be dropped by qcom_mhi_qrtr_dl_callback() at check:
if (!qdev || mhi_res->transaction_status) return;
Because dev_set_drvdata(&mhi_dev->dev, qdev) may be not performed at this moment. In this situation qrtr-ns will be unable to enumerate services in device.
---------------------------------------------------------------
2)
Such event may come at the moment after dev_set_drvdata() and before qrtr_endpoint_register(). In this case kernel will panic with accessing wrong pointer at qcom_mhi_qrtr_dl_callback():
rc = qrtr_endpoint_post(&qdev->ep, mhi_res->buf_addr, mhi_res->bytes_xferd);
Because endpoint is not created yet.
--------------------------------------------------------------
So move mhi_prepare_for_transfer_autoqueue after endpoint creation to fix it.
--- net/qrtr/mhi.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
net/qrtr/mhi.c +7 -5
@@ -78,11 +78,6 @@ static int qcom_mhi_qrtr_probe(struct mhstruct qrtr_mhi_dev *qdev;int rc; -/* start channels */ - rc =mhi_prepare_for_transfer_autoqueue (mhi_dev); -if (rc) -return rc; - qdev =devm_kzalloc (&mhi_dev->dev,sizeof (*qdev),GFP_KERNEL );if (!qdev)return -ENOMEM ;
@@ -96,6 +91,13 @@ static int qcom_mhi_qrtr_probe(struct mhif (rc)return rc; +/* start channels */ + rc =mhi_prepare_for_transfer_autoqueue (mhi_dev); +if (rc) { +qrtr_endpoint_unregister (&qdev->ep); +return rc; + } +dev_dbg (qdev->dev,"Qualcomm MHI QRTR driver probed\n" );return 0 ;
Greg Kroah-Hartman
maintainerPATCH 208/365 virtio_net: fix endian-ness for RSS
In reply to Greg Kroah-HartmanFrom: Michael S. Tsirkin <[email protected]>
commit 95bb633048fab742230eb2cdf20b8e2676240a54 upstream.
Using native endian-ness for device supplied fields is wrong on BE platforms. Sparse warns about this.
--- drivers/net/virtio_net.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/virtio_net.c +2 -2
@@ -1199,7 +1199,7 @@ static void virtio_skb_set_hash(const struct virtio_net_hdr_v1_hash *hdr_hash,if (!hdr_hash || !skb)return ; -switch ((int )hdr_hash->hash_report) { +switch (__le16_to_cpu (hdr_hash->hash_report)) {case VIRTIO_NET_HASH_REPORT_TCPv4:case VIRTIO_NET_HASH_REPORT_UDPv4:case VIRTIO_NET_HASH_REPORT_TCPv6:
@@ -1217,7 +1217,7 @@ static void virtio_skb_set_hash(const struct virtio_net_hdr_v1_hash *hdr_hash,default : rss_hash_type =PKT_HASH_TYPE_NONE ; } -skb_set_hash (skb, (unsigned int )hdr_hash->hash_value, rss_hash_type); +skb_set_hash (skb,__le32_to_cpu (hdr_hash->hash_value), rss_hash_type); } static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq,
Signature · 1 line
2.37.2
Greg Kroah-Hartman
maintainerPATCH 209/365 mlxsw: spectrum: Clear PTP configuration after unregistering the netdevice
In reply to Greg Kroah-HartmanFrom: Amit Cohen <[email protected]>
commit a159e986ad26d3f35c0157ac92760ba5e44e6785 upstream.
Currently as part of removing port, PTP API is called to clear the existing configuration and set the 'rx_filter' and 'tx_type' to zero. The clearing is done before unregistering the netdevice, which means that there is a window of time in which the user can reconfigure PTP in the port, and this configuration will not be cleared.
Reorder the operations, clear PTP configuration after unregistering the netdevice.
--- drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/mellanox/mlxsw/spectrum.c +1 -1
@@ -1822,9 +1822,9 @@ static void mlxsw_sp_port_remove(structcancel_delayed_work_sync (&mlxsw_sp_port->periodic_hw_stats.update_dw);cancel_delayed_work_sync (&mlxsw_sp_port->ptp.shaper_dw); -mlxsw_sp_port_ptp_clear (mlxsw_sp_port);mlxsw_core_port_clear (mlxsw_sp->core, local_port, mlxsw_sp);unregister_netdev (mlxsw_sp_port->dev);/* This calls ndo_stop */ +mlxsw_sp_port_ptp_clear (mlxsw_sp_port);mlxsw_sp_port_vlan_classification_set (mlxsw_sp_port, true, true); mlxsw_sp->ports[local_port] =NULL ;mlxsw_sp_port_vlan_flush (mlxsw_sp_port, true);
Greg Kroah-Hartman
maintainerPATCH 210/365 net: moxa: pass pdev instead of ndev to DMA functions
In reply to Greg Kroah-HartmanFrom: Sergei Antonov <[email protected]>
commit 3a12df22a8f68954a4ba48435c06b3d1791c87c4 upstream.
dma_map_single() calls fail in moxart_mac_setup_desc_ring() and moxart_mac_start_xmit() which leads to an incessant output of this:
[ 16.043925] moxart-ethernet 92000000.mac eth0: DMA mapping error [ 16.050957] moxart-ethernet 92000000.mac eth0: DMA mapping error [ 16.058229] moxart-ethernet 92000000.mac eth0: DMA mapping error
Passing pdev to DMA is a common approach among net drivers.
--- drivers/net/ethernet/moxa/moxart_ether.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-)
drivers/net/ethernet/moxa/moxart_ether.c +10 -10
@@ -77,7 +77,7 @@ static void moxart_mac_free_memory(strucint i;for (i =0 ; i <RX_DESC_NUM ; i++) -dma_unmap_single (&ndev->dev, priv->rx_mapping[i], +dma_unmap_single (&priv->pdev->dev, priv->rx_mapping[i], priv->rx_buf_size,DMA_FROM_DEVICE );if (priv->tx_desc_base)
@@ -147,11 +147,11 @@ static void moxart_mac_setup_desc_ring(s desc + RX_REG_OFFSET_DESC1); priv->rx_buf[i] = priv->rx_buf_base + priv->rx_buf_size * i; - priv->rx_mapping[i] =dma_map_single (&ndev->dev, + priv->rx_mapping[i] =dma_map_single (&priv->pdev->dev, priv->rx_buf[i], priv->rx_buf_size,DMA_FROM_DEVICE ); -if (dma_mapping_error (&ndev->dev, priv->rx_mapping[i])) +if (dma_mapping_error (&priv->pdev->dev, priv->rx_mapping[i]))netdev_err (ndev,"DMA mapping error\n" ); moxart_desc_write(priv->rx_mapping[i],
@@ -240,7 +240,7 @@ static int moxart_rx_poll(struct napi_stif (len >RX_BUF_SIZE ) len =RX_BUF_SIZE ; -dma_sync_single_for_cpu (&ndev->dev, +dma_sync_single_for_cpu (&priv->pdev->dev, priv->rx_mapping[rx_head], priv->rx_buf_size,DMA_FROM_DEVICE ); skb =netdev_alloc_skb_ip_align (ndev, len);
@@ -294,7 +294,7 @@ static void moxart_tx_finished(struct neunsigned int tx_tail = priv->tx_tail;while (tx_tail != tx_head) { -dma_unmap_single (&ndev->dev, priv->tx_mapping[tx_tail], +dma_unmap_single (&priv->pdev->dev, priv->tx_mapping[tx_tail], priv->tx_len[tx_tail],DMA_TO_DEVICE ); ndev->stats.tx_packets++;
@@ -358,9 +358,9 @@ static netdev_tx_t moxart_mac_start_xmit len = skb->len >TX_BUF_SIZE ?TX_BUF_SIZE : skb->len; - priv->tx_mapping[tx_head] =dma_map_single (&ndev->dev, skb->data, + priv->tx_mapping[tx_head] =dma_map_single (&priv->pdev->dev, skb->data, len,DMA_TO_DEVICE ); -if (dma_mapping_error (&ndev->dev, priv->tx_mapping[tx_head])) { +if (dma_mapping_error (&priv->pdev->dev, priv->tx_mapping[tx_head])) {netdev_err (ndev,"DMA mapping error\n" ); goto out_unlock; }
@@ -379,7 +379,7 @@ static netdev_tx_t moxart_mac_start_xmit len =ETH_ZLEN ; } -dma_sync_single_for_device (&ndev->dev, priv->tx_mapping[tx_head], +dma_sync_single_for_device (&priv->pdev->dev, priv->tx_mapping[tx_head], priv->tx_buf_size,DMA_TO_DEVICE ); txdes1 =TX_DESC1_LTS |TX_DESC1_FTS | (len &TX_DESC1_BUF_SIZE_MASK );
@@ -493,7 +493,7 @@ static int moxart_mac_probe(struct platf priv->tx_buf_size =TX_BUF_SIZE ; priv->rx_buf_size =RX_BUF_SIZE ; - priv->tx_desc_base =dma_alloc_coherent (&pdev->dev,TX_REG_DESC_SIZE * + priv->tx_desc_base =dma_alloc_coherent (p_dev,TX_REG_DESC_SIZE *TX_DESC_NUM , &priv->tx_base,GFP_DMA |GFP_KERNEL );if (!priv->tx_desc_base) {
@@ -501,7 +501,7 @@ static int moxart_mac_probe(struct platf goto init_fail; } - priv->rx_desc_base =dma_alloc_coherent (&pdev->dev,RX_REG_DESC_SIZE * + priv->rx_desc_base =dma_alloc_coherent (p_dev,RX_REG_DESC_SIZE *RX_DESC_NUM , &priv->rx_base,GFP_DMA |GFP_KERNEL );if (!priv->rx_desc_base) {
Greg Kroah-Hartman
maintainerPATCH 211/365 net: fix potential refcount leak in ndisc_router_discovery()
In reply to Greg Kroah-HartmanFrom: Xin Xiong <[email protected]>
commit 7396ba87f1edf549284869451665c7c4e74ecd4f upstream.
The issue happens on specific paths in the function. After both the object rt and neigh are grabbed successfully, when lifetime is nonzero but the metric needs change, the function just deletes the route and set rt to NULL. Then, it may try grabbing rt and neigh again if above conditions hold. The function simply overwrite neigh if succeeds or returns if fails, without decreasing the reference count of previous neigh. This may result in memory leaks.
Fix it by decrementing the reference count of neigh in place.
--- net/ipv6/ndisc.c | 3 +++ 1 file changed, 3 insertions(+)
net/ipv6/ndisc.c +3 -0
@@ -1358,6 +1358,9 @@ static void ndisc_router_discovery(strucif (!rt && lifetime) {ND_PRINTK (3 , info,"RA: adding default router\n" ); +if (neigh) +neigh_release (neigh); + rt =rt6_add_dflt_router (net, &ipv6_hdr (skb)->saddr, skb->dev, pref, defrtr_usr_metric);if (!rt) {
Greg Kroah-Hartman
maintainerPATCH 212/365 net: rtnetlink: fix module reference count leak issue in rtnetlink_rcv_msg
In reply to Greg Kroah-HartmanFrom: Zhengchao Shao <[email protected]>
commit 5b22f62724a0a09e00d301abf5b57b0c12be8a16 upstream.
When bulk delete command is received in the rtnetlink_rcv_msg function, if bulk delete is not supported, module_put is not called to release the reference counting. As a result, module reference count is leaked.
--- net/core/rtnetlink.c | 1 + 1 file changed, 1 insertion(+)
net/core/rtnetlink.c +1 -0
@@ -6070,6 +6070,7 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,if (kind ==RTNL_KIND_DEL && (nlh->nlmsg_flags &NLM_F_BULK ) && !(flags &RTNL_FLAG_BULK_DEL_SUPPORTED )) {NL_SET_ERR_MSG (extack,"Bulk delete is not supported" ); +module_put (owner); goto err_unlock; }
Signature · 1 line
2.37.2
Greg Kroah-Hartman
maintainerPATCH 213/365 net: sched: fix misuse of qcpu->backlog in gnet_stats_add_queue_cpu
In reply to Greg Kroah-HartmanFrom: Zhengchao Shao <[email protected]>
commit de64b6b6fb6f369840d171b7c5a9baf31b8b2630 upstream.
In the gnet_stats_add_queue_cpu function, the qstats->qlen statistics are incorrectly set to qcpu->backlog.
--- net/core/gen_stats.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/core/gen_stats.c +1 -1
@@ -345,7 +345,7 @@ static void gnet_stats_add_queue_cpu(strfor_each_possible_cpu (i) {const struct gnet_stats_queue *qcpu =per_cpu_ptr (q, i); - qstats->qlen += qcpu->backlog; + qstats->qlen += qcpu->qlen; qstats->backlog += qcpu->backlog; qstats->drops += qcpu->drops; qstats->requeues += qcpu->requeues;
Greg Kroah-Hartman
maintainerPATCH 214/365 net: dsa: microchip: ksz9477: fix fdb_dump last invalid entry
In reply to Greg Kroah-HartmanFrom: Arun Ramadoss <[email protected]>
commit 36c0d935015766bf20d621c18313f17691bda5e3 upstream.
In the ksz9477_fdb_dump function it reads the ALU control register and exit from the timeout loop if there is valid entry or search is complete. After exiting the loop, it reads the alu entry and report to the user space irrespective of entry is valid. It works till the valid entry. If the loop exited when search is complete, it reads the alu table. The table returns all ones and it is reported to user space. So bridge fdb show gives ff:ff:ff:ff:ff:ff as last entry for every port. To fix it, after exiting the loop the entry is reported only if it is valid one.
--- drivers/net/dsa/microchip/ksz9477.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/dsa/microchip/ksz9477.c +3 -0
@@ -658,6 +658,9 @@ static int ksz9477_port_fdb_dump(struct goto exit; } +if (!(ksz_data &ALU_VALID )) +continue ; +/* read ALU table */ ksz9477_read_table (dev, alu_table);
Greg Kroah-Hartman
maintainerPATCH 215/365 net: dsa: felix: fix ethtool 256-511 and 512-1023 TX packet counters
In reply to Greg Kroah-HartmanFrom: Vladimir Oltean <[email protected]>
commit 40d21c4565bce064c73a03b79a157a3493c518b9 upstream.
What the driver actually reports as 256-511 is in fact 512-1023, and the TX packets in the 256-511 bucket are not reported. Fix that.
--- drivers/net/dsa/ocelot/felix_vsc9959.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/dsa/ocelot/felix_vsc9959.c +2 -1
@@ -601,7 +601,8 @@ static const struct ocelot_stat_layout v { .offset = 0x87, .name = "tx_frames_below_65_octets", }, { .offset = 0x88, .name = "tx_frames_65_to_127_octets", }, { .offset = 0x89, .name = "tx_frames_128_255_octets", }, - { .offset = 0x8B, .name = "tx_frames_256_511_octets", }, + { .offset = 0x8A, .name = "tx_frames_256_511_octets", }, + { .offset = 0x8B, .name = "tx_frames_512_1023_octets", }, { .offset = 0x8C, .name = "tx_frames_1024_1526_octets", }, { .offset = 0x8D, .name = "tx_frames_over_1526_octets", }, { .offset = 0x8E, .name = "tx_yellow_prio_0", },
Greg Kroah-Hartman
maintainerPATCH 216/365 net: mscc: ocelot: fix incorrect ndo_get_stats64 packet counters
In reply to Greg Kroah-HartmanFrom: Vladimir Oltean <[email protected]>
commit 5152de7b79ab0be150f5966481b0c8f996192531 upstream.
Reading stats using the SYS_COUNT_* register definitions is only used by ocelot_get_stats64() from the ocelot switchdev driver, however, currently the bucket definitions are incorrect.
Separately, on both RX and TX, we have the following problems:
- a 256-1023 bucket which actually tracks the 256-511 packets
- the 1024-1526 bucket actually tracks the 512-1023 packets
- the 1527-max bucket actually tracks the 1024-1526 packets
=> nobody tracks the packets from the real 1527-max bucket
Additionally, the RX_PAUSE, RX_CONTROL, RX_LONGS and RX_CLASSIFIED_DROPS all track the wrong thing. However this doesn't seem to have any consequence, since ocelot_get_stats64() doesn't use these.
Even though this problem only manifests itself for the switchdev driver, we cannot split the fix for ocelot and for DSA, since it requires fixing the bucket definitions from enum ocelot_reg, which makes us necessarily adapt the structures from felix and seville as well.
--- drivers/net/dsa/ocelot/felix_vsc9959.c | 20 ++++++++++++-------- drivers/net/dsa/ocelot/seville_vsc9953.c | 16 +++++++++------- drivers/net/ethernet/mscc/ocelot_net.c | 6 ++++-- drivers/net/ethernet/mscc/vsc7514_regs.c | 24 +++++++++++++----------- include/soc/mscc/ocelot.h | 6 ++++-- 5 files changed, 42 insertions(+), 30 deletions(-)
drivers/net/dsa/ocelot/felix_vsc9959.c +12 -8
@@ -280,19 +280,23 @@ static const u32 vsc9959_sys_regmap[] =REG (SYS_COUNT_RX_64 ,0x000024 ),REG (SYS_COUNT_RX_65_127 ,0x000028 ),REG (SYS_COUNT_RX_128_255 ,0x00002c ), -REG (SYS_COUNT_RX_256_1023 ,0x000030 ), -REG (SYS_COUNT_RX_1024_1526 ,0x000034 ), -REG (SYS_COUNT_RX_1527_MAX ,0x000038 ), -REG (SYS_COUNT_RX_LONGS ,0x000044 ), +REG (SYS_COUNT_RX_256_511 ,0x000030 ), +REG (SYS_COUNT_RX_512_1023 ,0x000034 ), +REG (SYS_COUNT_RX_1024_1526 ,0x000038 ), +REG (SYS_COUNT_RX_1527_MAX ,0x00003c ), +REG (SYS_COUNT_RX_PAUSE ,0x000040 ), +REG (SYS_COUNT_RX_CONTROL ,0x000044 ), +REG (SYS_COUNT_RX_LONGS ,0x000048 ),REG (SYS_COUNT_TX_OCTETS ,0x000200 ),REG (SYS_COUNT_TX_COLLISION ,0x000210 ),REG (SYS_COUNT_TX_DROPS ,0x000214 ),REG (SYS_COUNT_TX_64 ,0x00021c ),REG (SYS_COUNT_TX_65_127 ,0x000220 ), -REG (SYS_COUNT_TX_128_511 ,0x000224 ), -REG (SYS_COUNT_TX_512_1023 ,0x000228 ), -REG (SYS_COUNT_TX_1024_1526 ,0x00022c ), -REG (SYS_COUNT_TX_1527_MAX ,0x000230 ), +REG (SYS_COUNT_TX_128_255 ,0x000224 ), +REG (SYS_COUNT_TX_256_511 ,0x000228 ), +REG (SYS_COUNT_TX_512_1023 ,0x00022c ), +REG (SYS_COUNT_TX_1024_1526 ,0x000230 ), +REG (SYS_COUNT_TX_1527_MAX ,0x000234 ),REG (SYS_COUNT_TX_AGING ,0x000278 ),REG (SYS_RESET_CFG ,0x000e00 ), REG(SYS_SR_ETYPE_CFG, 0x000e04),
drivers/net/dsa/ocelot/seville_vsc9953.c +9 -7
@@ -277,19 +277,21 @@ static const u32 vsc9953_sys_regmap[] =REG (SYS_COUNT_RX_64 ,0x000024 ),REG (SYS_COUNT_RX_65_127 ,0x000028 ),REG (SYS_COUNT_RX_128_255 ,0x00002c ), -REG (SYS_COUNT_RX_256_1023 ,0x000030 ), -REG (SYS_COUNT_RX_1024_1526 ,0x000034 ), -REG (SYS_COUNT_RX_1527_MAX ,0x000038 ), +REG (SYS_COUNT_RX_256_511 ,0x000030 ), +REG (SYS_COUNT_RX_512_1023 ,0x000034 ), +REG (SYS_COUNT_RX_1024_1526 ,0x000038 ), +REG (SYS_COUNT_RX_1527_MAX ,0x00003c ),REG (SYS_COUNT_RX_LONGS ,0x000048 ),REG (SYS_COUNT_TX_OCTETS ,0x000100 ),REG (SYS_COUNT_TX_COLLISION ,0x000110 ),REG (SYS_COUNT_TX_DROPS ,0x000114 ),REG (SYS_COUNT_TX_64 ,0x00011c ),REG (SYS_COUNT_TX_65_127 ,0x000120 ), -REG (SYS_COUNT_TX_128_511 ,0x000124 ), -REG (SYS_COUNT_TX_512_1023 ,0x000128 ), -REG (SYS_COUNT_TX_1024_1526 ,0x00012c ), -REG (SYS_COUNT_TX_1527_MAX ,0x000130 ), +REG (SYS_COUNT_TX_128_255 ,0x000124 ), +REG (SYS_COUNT_TX_256_511 ,0x000128 ), +REG (SYS_COUNT_TX_512_1023 ,0x00012c ), +REG (SYS_COUNT_TX_1024_1526 ,0x000130 ), +REG (SYS_COUNT_TX_1527_MAX ,0x000134 ),REG (SYS_COUNT_TX_AGING ,0x000178 ),REG (SYS_RESET_CFG ,0x000318 ), REG_RESERVED(SYS_SR_ETYPE_CFG),
drivers/net/ethernet/mscc/ocelot_net.c +4 -2
@@ -739,7 +739,8 @@ static void ocelot_get_stats64(struct neocelot_read (ocelot,SYS_COUNT_RX_64 ) +ocelot_read (ocelot,SYS_COUNT_RX_65_127 ) +ocelot_read (ocelot,SYS_COUNT_RX_128_255 ) + -ocelot_read (ocelot,SYS_COUNT_RX_256_1023 ) + +ocelot_read (ocelot,SYS_COUNT_RX_256_511 ) + +ocelot_read (ocelot,SYS_COUNT_RX_512_1023 ) +ocelot_read (ocelot,SYS_COUNT_RX_1024_1526 ) +ocelot_read (ocelot,SYS_COUNT_RX_1527_MAX ); stats->multicast =ocelot_read (ocelot,SYS_COUNT_RX_MULTICAST );
@@ -749,7 +750,8 @@ static void ocelot_get_stats64(struct ne stats->tx_bytes =ocelot_read (ocelot,SYS_COUNT_TX_OCTETS ); stats->tx_packets =ocelot_read (ocelot,SYS_COUNT_TX_64 ) +ocelot_read (ocelot,SYS_COUNT_TX_65_127 ) + -ocelot_read (ocelot,SYS_COUNT_TX_128_511 ) + +ocelot_read (ocelot,SYS_COUNT_TX_128_255 ) + +ocelot_read (ocelot,SYS_COUNT_TX_256_511 ) +ocelot_read (ocelot,SYS_COUNT_TX_512_1023 ) +ocelot_read (ocelot,SYS_COUNT_TX_1024_1526 ) +ocelot_read (ocelot,SYS_COUNT_TX_1527_MAX );
drivers/net/ethernet/mscc/vsc7514_regs.c +13 -11
@@ -180,13 +180,14 @@ const u32 vsc7514_sys_regmap[] = {REG (SYS_COUNT_RX_64 ,0x000024 ),REG (SYS_COUNT_RX_65_127 ,0x000028 ),REG (SYS_COUNT_RX_128_255 ,0x00002c ), -REG (SYS_COUNT_RX_256_1023 ,0x000030 ), -REG (SYS_COUNT_RX_1024_1526 ,0x000034 ), -REG (SYS_COUNT_RX_1527_MAX ,0x000038 ), -REG (SYS_COUNT_RX_PAUSE ,0x00003c ), -REG (SYS_COUNT_RX_CONTROL ,0x000040 ), -REG (SYS_COUNT_RX_LONGS ,0x000044 ), -REG (SYS_COUNT_RX_CLASSIFIED_DROPS ,0x000048 ), +REG (SYS_COUNT_RX_256_511 ,0x000030 ), +REG (SYS_COUNT_RX_512_1023 ,0x000034 ), +REG (SYS_COUNT_RX_1024_1526 ,0x000038 ), +REG (SYS_COUNT_RX_1527_MAX ,0x00003c ), +REG (SYS_COUNT_RX_PAUSE ,0x000040 ), +REG (SYS_COUNT_RX_CONTROL ,0x000044 ), +REG (SYS_COUNT_RX_LONGS ,0x000048 ), +REG (SYS_COUNT_RX_CLASSIFIED_DROPS ,0x00004c ),REG (SYS_COUNT_TX_OCTETS ,0x000100 ),REG (SYS_COUNT_TX_UNICAST ,0x000104 ), REG(SYS_COUNT_TX_MULTICAST, 0x000108),
@@ -196,10 +197,11 @@ const u32 vsc7514_sys_regmap[] = {REG (SYS_COUNT_TX_PAUSE ,0x000118 ),REG (SYS_COUNT_TX_64 ,0x00011c ),REG (SYS_COUNT_TX_65_127 ,0x000120 ), -REG (SYS_COUNT_TX_128_511 ,0x000124 ), -REG (SYS_COUNT_TX_512_1023 ,0x000128 ), -REG (SYS_COUNT_TX_1024_1526 ,0x00012c ), -REG (SYS_COUNT_TX_1527_MAX ,0x000130 ), +REG (SYS_COUNT_TX_128_255 ,0x000124 ), +REG (SYS_COUNT_TX_256_511 ,0x000128 ), +REG (SYS_COUNT_TX_512_1023 ,0x00012c ), +REG (SYS_COUNT_TX_1024_1526 ,0x000130 ), +REG (SYS_COUNT_TX_1527_MAX ,0x000134 ),REG (SYS_COUNT_TX_AGING ,0x000170 ),REG (SYS_RESET_CFG ,0x000508 ), REG(SYS_CMID, 0x00050c),
include/soc/mscc/ocelot.h +4 -2
@@ -335,7 +335,8 @@ enum ocelot_reg {SYS_COUNT_RX_64 ,SYS_COUNT_RX_65_127 ,SYS_COUNT_RX_128_255 , -SYS_COUNT_RX_256_1023 , +SYS_COUNT_RX_256_511 , +SYS_COUNT_RX_512_1023 ,SYS_COUNT_RX_1024_1526 ,SYS_COUNT_RX_1527_MAX , SYS_COUNT_RX_PAUSE,
@@ -351,7 +352,8 @@ enum ocelot_reg {SYS_COUNT_TX_PAUSE ,SYS_COUNT_TX_64 ,SYS_COUNT_TX_65_127 , -SYS_COUNT_TX_128_511 , +SYS_COUNT_TX_128_255 , +SYS_COUNT_TX_256_511 ,SYS_COUNT_TX_512_1023 ,SYS_COUNT_TX_1024_1526 , SYS_COUNT_TX_1527_MAX,
Greg Kroah-Hartman
maintainerPATCH 217/365 net: mscc: ocelot: fix address of SYS_COUNT_TX_AGING counter
In reply to Greg Kroah-HartmanFrom: Vladimir Oltean <[email protected]>
commit 173ca86618d751bd183456c9cdbb69952ba283c8 upstream.
This register, used as part of stats->tx_dropped in ocelot_get_stats64(), has a wrong address. At the address currently given, there is actually the c_tx_green_prio_6 counter.
--- drivers/net/ethernet/mscc/vsc7514_regs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/mscc/vsc7514_regs.c +1 -1
@@ -202,7 +202,7 @@ const u32 vsc7514_sys_regmap[] = {REG (SYS_COUNT_TX_512_1023 ,0x00012c ),REG (SYS_COUNT_TX_1024_1526 ,0x000130 ),REG (SYS_COUNT_TX_1527_MAX ,0x000134 ), -REG (SYS_COUNT_TX_AGING ,0x000170 ), +REG (SYS_COUNT_TX_AGING ,0x000178 ),REG (SYS_RESET_CFG ,0x000508 ),REG (SYS_CMID ,0x00050c ), REG(SYS_VLAN_ETYPE_CFG, 0x000510),
Greg Kroah-Hartman
maintainerPATCH 218/365 net: genl: fix error path memory leak in policy dumping
In reply to Greg Kroah-HartmanFrom: Jakub Kicinski <[email protected]>
commit 249801360db3dec4f73768c502192020bfddeacc upstream.
If construction of the array of policies fails when recording non-first policy we need to unwind.
netlink_policy_dump_add_policy() itself also needs fixing as it currently gives up on error without recording the allocated pointer in the pstate pointer.
--- net/netlink/genetlink.c | 6 +++++- net/netlink/policy.c | 14 ++++++++++++-- 2 files changed, 17 insertions(+), 3 deletions(-)
net/netlink/genetlink.c +5 -1
@@ -1174,13 +1174,17 @@ static int ctrl_dumppolicy_start(struct op.policy, op.maxattr);if (err) -return err; + goto err_free_state; } }if (!ctx->state)return -ENODATA ;return 0 ; + +err_free_state: +netlink_policy_dump_free (ctx->state); +return err; } static void *ctrl_dumppolicy_prep(struct sk_buff *skb,
net/netlink/policy.c +12 -2
@@ -144,7 +144,7 @@ int netlink_policy_dump_add_policy(struc err =add_policy (&state, policy, maxtype);if (err) -return err; + goto err_try_undo; for (policy_idx = 0; policy_idx < state->n_alloc && state->policies[policy_idx].policy;
@@ -164,7 +164,7 @@ int netlink_policy_dump_add_policy(struc policy[type].nested_policy, policy[type].len);if (err) -return err; + goto err_try_undo;break ;default :break ;
@@ -174,6 +174,16 @@ int netlink_policy_dump_add_policy(struc *pstate = state;return 0 ; + +err_try_undo: +/* Try to preserve reasonable unwind semantics - if we're starting from +* scratch clean up fully, otherwise record what we got and caller will. +*/ +if (!*pstate) +netlink_policy_dump_free (state); +else + *pstate = state; +return err; } static bool
Greg Kroah-Hartman
maintainerPATCH 219/365 net: dsa: dont warn in dsa_port_set_state_now() when driver doesnt support it
In reply to Greg Kroah-HartmanFrom: Vladimir Oltean <[email protected]>
commit 211987f3ac734000ea1548784b2a4539a974fbc8 upstream.
ds->ops->port_stp_state_set() is, like most DSA methods, optional, and if absent, the port is supposed to remain in the forwarding state (as standalone). Such is the case with the mv88e6060 driver, which does not offload the bridge layer. DSA warns that the STP state can't be changed to FORWARDING as part of dsa_port_enable_rt(), when in fact it should not.
The error message is also not up to modern standards, so take the opportunity to make it more descriptive.
--- net/dsa/port.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
net/dsa/port.c +5 -2
@@ -145,11 +145,14 @@ int dsa_port_set_state(struct dsa_port *static void dsa_port_set_state_now (struct dsa_port *dp,u8 state,bool do_fast_age) { +struct dsa_switch *ds = dp->ds;int err; err =dsa_port_set_state (dp, state, do_fast_age); -if (err) -pr_err ("DSA: failed to set STP state %u (%d)\n" , state, err); +if (err && err != -EOPNOTSUPP ) { +dev_err (ds->dev,"port %d failed to set STP state %u: %pe\n" , + dp->index, state,ERR_PTR (err)); + } } int dsa_port_set_mst_state(struct dsa_port *dp,
Greg Kroah-Hartman
maintainerPATCH 220/365 net: dsa: sja1105: fix buffer overflow in sja1105_setup_devlink_regions()
In reply to Greg Kroah-HartmanFrom: Rustam Subkhankulov <[email protected]>
commit fd8e899cdb5ecaf8e8ee73854a99e10807eef1de upstream.
If an error occurs in dsa_devlink_region_create(), then 'priv->regions' array will be accessed by negative index '-1'.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
--- drivers/net/dsa/sja1105/sja1105_devlink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/dsa/sja1105/sja1105_devlink.c +1 -1
@@ -93,7 +93,7 @@ static int sja1105_setup_devlink_regions region =dsa_devlink_region_create (ds, ops,1 , size);if (IS_ERR (region)) { -while (i-- >=0 ) +while (--i >=0 )dsa_devlink_region_destroy (priv->regions[i]);return PTR_ERR (region); }
Greg Kroah-Hartman
maintainerPATCH 221/365 ice: Fix VSI rebuild WARN_ON check for VF
In reply to Greg Kroah-HartmanFrom: Benjamin Mikailenko <[email protected]>
commit 7fe05e125d5f730bd2d0fc53985bee77b6c762f0 upstream.
In commit b03d519d3460 ("ice: store VF pointer instead of VF ID") WARN_ON checks were added to validate the vsi->vf pointer and catch programming errors. However, one check to vsi->vf was missed. This caused a call trace when resetting VFs.
Fix ice_vsi_rebuild by encompassing VF pointer in WARN_ON check.
--- drivers/net/ethernet/intel/ice/ice_lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/intel/ice/ice_lib.c +1 -1
@@ -3178,7 +3178,7 @@ int ice_vsi_rebuild(struct ice_vsi *vsi, pf = vsi->back; vtype = vsi->type; -if (WARN_ON (vtype ==ICE_VSI_VF ) && !vsi->vf) +if (WARN_ON (vtype ==ICE_VSI_VF && !vsi->vf))return -EINVAL ;ice_vsi_init_vlan_ops (vsi);
Greg Kroah-Hartman
maintainerPATCH 222/365 ice: Fix call trace with null VSI during VF reset
In reply to Greg Kroah-HartmanFrom: Michal Jaron <[email protected]>
commit cf90b74341eecc32ceef0c136954a1668e43b1e7 upstream.
During stress test with attaching and detaching VF from KVM and simultaneously changing VFs spoofcheck and trust there was a call trace in ice_reset_vf that VF's VSI is null.
[145237.352797] WARNING: CPU: 46 PID: 840629 at drivers/net/ethernet/intel/ice/ice_vf_lib.c:508 ice_reset_vf+0x3d6/0x410 [ice] [145237.352851] Modules linked in: ice(E) vfio_pci vfio_pci_core vfio_virqfd vfio_iommu_type1 vfio iavf dm_mod xt_CHECKSUM xt_MASQUERADE
xt_conntrack ipt_REJECT nf_reject_ipv4 nft_compat nft_chain_nat nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 nf_tables nfnetlink tun
bridge stp llc sunrpc intel_rapl_msr intel_rapl_common sb_edac x86_pkg_temp_thermal intel_powerclamp coretemp kvm_intel kvm iTCO_wdt iTCO_vendor_support irqbypass crct10dif_pclmul crc32_pclmul ghash_clmulni_intel rapl ipmi_si intel_cstate ipmi_devintf joydev intel_uncore m ei_me ipmi_msghandler i2c_i801 pcspkr mei lpc_ich ioatdma i2c_smbus acpi_pad acpi_power_meter ip_tables xfs libcrc32c i2c_algo_bit drm_sh mem_helper drm_kms_helper sd_mod t10_pi crc64_rocksoft syscopyarea crc64 sysfillrect sg sysimgblt fb_sys_fops drm i40e ixgbe ahci libahci
libata crc32c_intel mdio dca wmi fuse [last unloaded: ice]
[145237.352917] CPU: 46 PID: 840629 Comm: kworker/46:2 Tainted: G S W I E 5.19.0-rc6+ #24 [145237.352921] Hardware name: Intel Corporation S2600WTT/S2600WTT, BIOS SE5C610.86B.01.01.0008.021120151325 02/11/2015 [145237.352923] Workqueue: ice ice_service_task [ice] [145237.352948] RIP: 0010:ice_reset_vf+0x3d6/0x410 [ice] [145237.352984] Code: 30 ec f3 cc e9 28 fd ff ff 0f b7 4b 50 48 c7 c2 48 19 9c c0 4c 89 ee 48 c7 c7 30 fe 9e c0 e8 d1 21 9d cc 31 c0 e9 a 9 fe ff ff <0f> 0b b8 ea ff ff ff e9 c1 fc ff ff 0f 0b b8 fb ff ff ff e9 91 fe [145237.352987] RSP: 0018:ffffb453e257fdb8 EFLAGS: 00010246 [145237.352990] RAX: ffff8bd0040181c0 RBX: ffff8be68db8f800 RCX: 0000000000000000 [145237.352991] RDX: 000000000000ffff RSI: 0000000000000000 RDI: ffff8be68db8f800 [145237.352993] RBP: ffff8bd0040181c0 R08: 0000000000001000 R09: ffff8bcfd520e000 [145237.352995] R10: 0000000000000000 R11: 00008417b5ab0bc0 R12: 0000000000000005 [145237.352996] R13: ffff8bcee061c0d0 R14: ffff8bd004019640 R15: 0000000000000000 [145237.352998] FS: 0000000000000000(0000) GS:ffff8be5dfb00000(0000) knlGS:0000000000000000 [145237.353000] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [145237.353002] CR2: 00007fd81f651d68 CR3: 0000001a0fe10001 CR4: 00000000001726e0 [145237.353003] Call Trace: [145237.353008] <TASK> [145237.353011] ice_process_vflr_event+0x8d/0xb0 [ice] [145237.353049] ice_service_task+0x79f/0xef0 [ice] [145237.353074] process_one_work+0x1c8/0x390 [145237.353081] ? process_one_work+0x390/0x390 [145237.353084] worker_thread+0x30/0x360 [145237.353087] ? process_one_work+0x390/0x390 [145237.353090] kthread+0xe8/0x110 [145237.353094] ? kthread_complete_and_exit+0x20/0x20 [145237.353097] ret_from_fork+0x22/0x30 [145237.353103] </TASK>
Remove WARN_ON() from check if VSI is null in ice_reset_vf. Add "VF is already removed\n" in dev_dbg().
This WARN_ON() is unnecessary and causes call trace, despite that call trace, driver still works. There is no need for this warn because this piece of code is responsible for disabling VF's Tx/Rx queues when VF is disabled, but when VF is already removed there is no need to do reset or disable queues.
--- drivers/net/ethernet/intel/ice/ice_vf_lib.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/net/ethernet/intel/ice/ice_vf_lib.c +3 -1
@@ -505,8 +505,10 @@ int ice_reset_vf(struct ice_vf *vf, u32if (ice_is_vf_disabled (vf)) { vsi =ice_get_vf_vsi (vf); -if (WARN_ON (!vsi)) +if (!vsi) { +dev_dbg (dev,"VF is already removed\n" );return -EINVAL ; + }ice_vsi_stop_lan_tx_rings (vsi,ICE_NO_RESET , vf->vf_id);ice_vsi_stop_all_rx_rings (vsi); dev_dbg(dev, "VF is already disabled, there is no need for resetting it, telling VM, all is fine %d\n",
Greg Kroah-Hartman
maintainerPATCH 223/365 ice: Fix VF not able to send tagged traffic with no VLAN filters
In reply to Greg Kroah-HartmanFrom: Sylwester Dziedziuch <[email protected]>
commit 664d4646184ed986f8195df684cc4660563fb02a upstream.
VF was not able to send tagged traffic when it didn't have any VLAN interfaces and VLAN anti-spoofing was enabled. Fix this by allowing VFs with no VLAN filters to send tagged traffic. After VF adds a VLAN interface it will be able to send tagged traffic matching VLAN filters only.
Testing hints:
1. Spawn VF
2. Send tagged packet from a VF
3. The packet should be sent out and not dropped
4. Add a VLAN interface on VF
5. Send tagged packet on that VLAN interface
6. Packet should be sent out and not dropped
7. Send tagged packet with id different than VLAN interface
8. Packet should be dropped
--- drivers/net/ethernet/intel/ice/ice_vf_lib.c | 11 +++-- drivers/net/ethernet/intel/ice/ice_virtchnl.c | 57 ++++++++++++++++++++++---- 2 files changed, 57 insertions(+), 11 deletions(-)
drivers/net/ethernet/intel/ice/ice_vf_lib.c +7 -4
@@ -707,13 +707,16 @@ static int ice_cfg_mac_antispoof(structstatic int ice_vsi_ena_spoofchk (struct ice_vsi *vsi) {struct ice_vsi_vlan_ops *vlan_ops; -int err; +int err =0 ; vlan_ops =ice_get_compat_vsi_vlan_ops (vsi); - err = vlan_ops->ena_tx_filtering (vsi); -if (err) -return err; +/* Allow VF with VLAN 0 only to send all tagged traffic */ +if (vsi->type !=ICE_VSI_VF ||ice_vsi_has_non_zero_vlans (vsi)) { + err = vlan_ops->ena_tx_filtering (vsi); +if (err) +return err; + }return ice_cfg_mac_antispoof (vsi, true); }
drivers/net/ethernet/intel/ice/ice_virtchnl.c +50 -7
94 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 224/365 ice: Fix double VLAN error when entering promisc mode
In reply to Greg Kroah-HartmanFrom: Grzegorz Siwik <[email protected]>
commit ffa9ed86522f1c08d4face4e0a4ebf366037bf19 upstream.
Avoid enabling or disabling VLAN 0 when trying to set promiscuous VLAN mode if double VLAN mode is enabled. This fix is needed because the driver tries to add the VLAN 0 filter twice (once for inner and once for outer) when double VLAN mode is enabled. The filter program is rejected by the firmware when double VLAN is enabled, because the promiscuous filter only needs to be set once.
This issue was missed in the initial implementation of double VLAN mode.
--- drivers/net/ethernet/intel/ice/ice_switch.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/net/ethernet/intel/ice/ice_switch.c +7 -0
@@ -4414,6 +4414,13 @@ ice_set_vlan_vsi_promisc(struct ice_hw * goto free_fltr_list;list_for_each_entry (list_itr, &vsi_list_head, list_entry) { +/* Avoid enabling or disabling VLAN zero twice when in double +* VLAN mode +*/ +if (ice_is_dvm_ena (hw) && + list_itr->fltr_info.l_data.vlan.tpid ==0 ) +continue ; + vlan_id = list_itr->fltr_info.l_data.vlan.vlan_id;if (rm_vlan_promisc) status = ice_clear_vsi_promisc(hw, vsi_handle,
Greg Kroah-Hartman
maintainerPATCH 225/365 ice: Ignore EEXIST when setting promisc mode
In reply to Greg Kroah-HartmanFrom: Grzegorz Siwik <[email protected]>
commit 11e551a2efa4481bd4f616ab75374a2710b480e9 upstream.
Ignore EEXIST error when setting promiscuous mode. This fix is needed because the driver could set promiscuous mode when it still has not cleared properly.
Promiscuous mode could be set only once, so setting it second time will be rejected.
--- drivers/net/ethernet/intel/ice/ice_switch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/intel/ice/ice_switch.c +1 -1
@@ -4428,7 +4428,7 @@ ice_set_vlan_vsi_promisc(struct ice_hw *else status =ice_set_vsi_promisc (hw, vsi_handle, promisc_mask, vlan_id); -if (status) +if (status && status != -EEXIST )break ; }
Greg Kroah-Hartman
maintainerPATCH 226/365 ice: Fix clearing of promisc mode with bridge over bond
In reply to Greg Kroah-HartmanFrom: Grzegorz Siwik <[email protected]>
commit abddafd4585cc825d454da3cf308ad1226f6c554 upstream.
When at least two interfaces are bonded and a bridge is enabled on the bond, an error can occur when the bridge is removed and re-added. The reason for the error is because promiscuous mode was not fully cleared from the VLAN VSI in the hardware. With this change, promiscuous mode is properly removed when the bridge disconnects from bonding.
[ 1033.676359] bond1: link status definitely down for interface enp95s0f0, disabling it [ 1033.676366] bond1: making interface enp175s0f0 the new active one [ 1033.676369] device enp95s0f0 left promiscuous mode [ 1033.676522] device enp175s0f0 entered promiscuous mode [ 1033.676901] ice 0000:af:00.0 enp175s0f0: Error setting Multicast promiscuous mode on VSI 6 [ 1041.795662] ice 0000:af:00.0 enp175s0f0: Error setting Multicast promiscuous mode on VSI 6 [ 1041.944826] bond1: link status definitely down for interface enp175s0f0, disabling it [ 1041.944874] device enp175s0f0 left promiscuous mode [ 1041.944918] bond1: now running without any active interface!
--- drivers/net/ethernet/intel/ice/ice_lib.c | 6 +++++- drivers/net/ethernet/intel/ice/ice_main.c | 12 +++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-)
drivers/net/ethernet/intel/ice/ice_lib.c +5 -1
@@ -4078,7 +4078,11 @@ int ice_vsi_del_vlan_zero(struct ice_vsiif (err && err != -EEXIST )return err; -return 0 ; +/* when deleting the last VLAN filter, make sure to disable the VLAN +* promisc mode so the filter isn't left by accident +*/ +return ice_clear_vsi_promisc (&vsi->back->hw, vsi->idx, +ICE_MCAST_VLAN_PROMISC_BITS ,0 ); }/**
drivers/net/ethernet/intel/ice/ice_main.c +11 -1
@@ -267,8 +267,10 @@ static int ice_set_promisc(struct ice_vs status =ice_fltr_set_vsi_promisc (&vsi->back->hw, vsi->idx, promisc_m,0 ); } +if (status && status != -EEXIST ) +return status; -return status; +return 0 ; }/**
@@ -3572,6 +3574,14 @@ ice_vlan_rx_kill_vid(struct net_device *while (test_and_set_bit (ICE_CFG_BUSY , vsi->state))usleep_range (1000 ,2000 ); + ret =ice_clear_vsi_promisc (&vsi->back->hw, vsi->idx, +ICE_MCAST_VLAN_PROMISC_BITS , vid); +if (ret) { +netdev_err (netdev,"Error clearing multicast promiscuous mode on VSI %i\n" , + vsi->vsi_num); + vsi->current_netdev_flags |=IFF_ALLMULTI ; + } + vlan_ops =ice_get_compat_vsi_vlan_ops (vsi);/* Make sure VLAN delete is successful before updating VLAN
Greg Kroah-Hartman
maintainerPATCH 227/365 ice: Ignore error message when setting same promiscuous mode
In reply to Greg Kroah-HartmanFrom: Benjamin Mikailenko <[email protected]>
commit 79956b83ed4281c35561c39254558092d96a9ed1 upstream.
Commit 1273f89578f2 ("ice: Fix broken IFF_ALLMULTI handling") introduced new checks when setting/clearing promiscuous mode. But if the requested promiscuous mode setting already exists, an -EEXIST error message would be printed. This is incorrect because promiscuous mode is either on/off and shouldn't print an error when the requested configuration is already set.
This can happen when removing a bridge with two bonded interfaces and promiscuous most isn't fully cleared from VLAN VSI in hardware.
Fix this by ignoring cases where requested promiscuous mode exists.
--- drivers/net/ethernet/intel/ice/ice_fltr.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/net/ethernet/intel/ice/ice_fltr.c +4 -4
@@ -62,7 +62,7 @@ ice_fltr_set_vlan_vsi_promisc(struct iceint result; result =ice_set_vlan_vsi_promisc (hw, vsi->idx, promisc_mask, false); -if (result) +if (result && result != -EEXIST )dev_err (ice_pf_to_dev (pf),"Error setting promisc mode on VSI %i (rc=%d)\n" , vsi->vsi_num, result);
@@ -86,7 +86,7 @@ ice_fltr_clear_vlan_vsi_promisc(struct iint result; result =ice_set_vlan_vsi_promisc (hw, vsi->idx, promisc_mask, true); -if (result) +if (result && result != -EEXIST )dev_err (ice_pf_to_dev (pf),"Error clearing promisc mode on VSI %i (rc=%d)\n" , vsi->vsi_num, result);
@@ -109,7 +109,7 @@ ice_fltr_clear_vsi_promisc(struct ice_hwint result; result =ice_clear_vsi_promisc (hw, vsi_handle, promisc_mask, vid); -if (result) +if (result && result != -EEXIST )dev_err (ice_pf_to_dev (pf),"Error clearing promisc mode on VSI %i for VID %u (rc=%d)\n" ,ice_get_hw_vsi_num (hw, vsi_handle), vid, result);
@@ -132,7 +132,7 @@ ice_fltr_set_vsi_promisc(struct ice_hw *int result; result =ice_set_vsi_promisc (hw, vsi_handle, promisc_mask, vid); -if (result) +if (result && result != -EEXIST )dev_err (ice_pf_to_dev (pf),"Error setting promisc mode on VSI %i for VID %u (rc=%d)\n" ,ice_get_hw_vsi_num (hw, vsi_handle), vid, result);
Greg Kroah-Hartman
maintainerPATCH 228/365 modpost: fix module versioning when a symbol lacks valid CRC
In reply to Greg Kroah-HartmanFrom: Masahiro Yamada <[email protected]>
commit 5b8a9a8fd1f0c3d55d407cf759d54ca68798d9ad upstream.
Since commit 7b4537199a4a ("kbuild: link symbol CRCs at final link, removing CONFIG_MODULE_REL_CRCS"), module versioning is broken on some architectures. Loading a module fails with "disagrees about version of symbol module_layout".
On such architectures (e.g. ARCH=sparc build with sparc64_defconfig), modpost shows a warning, like follows:
WARNING: modpost: EXPORT symbol "_mcount" [vmlinux] version generation failed, symbol will not be versioned. Is "_mcount" prototyped in <asm/asm-prototypes.h>?
Previously, it was a harmless warning (CRC check was just skipped), but now wrong CRCs are used for comparison because invalid CRCs are just skipped.
$ sparc64-linux-gnu-nm -n vmlinux
[snip]
0000000000c2cea0 r __ksymtab__kstrtol
0000000000c2ceb8 r __ksymtab__kstrtoul
0000000000c2ced0 r __ksymtab__local_bh_enable
0000000000c2cee8 r __ksymtab__mcount
0000000000c2cf00 r __ksymtab__printk
0000000000c2cf18 r __ksymtab__raw_read_lock
0000000000c2cf30 r __ksymtab__raw_read_lock_bh
[snip]
0000000000c53b34 D __crc__kstrtol
0000000000c53b38 D __crc__kstrtoul
0000000000c53b3c D __crc__local_bh_enable
0000000000c53b40 D __crc__printk
0000000000c53b44 D __crc__raw_read_lock
0000000000c53b48 D __crc__raw_read_lock_bhPlease notice __crc__mcount is missing here.
When the module subsystem looks up a CRC that comes after, it results in reading out a wrong address. For example, when __crc__printk is needed, the module subsystem reads 0xc53b44 instead of 0xc53b40.
All CRC entries must be output for correct index accessing. Invalid CRCs will be unused, but are needed to keep the one-to-one mapping between __ksymtab_* and __crc_*.
The best is to fix all modpost warnings, but several warnings are still remaining on less popular architectures.
--- scripts/mod/modpost.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
scripts/mod/modpost.c +1 -3
@@ -2203,13 +2203,11 @@ static void add_exported_symbols(struct/* record CRCs for exported symbols */ buf_printf (buf,"\n" );list_for_each_entry (sym, &mod->exported_symbols, list) { -if (!sym->crc_valid) { +if (!sym->crc_valid)warn ("EXPORT symbol \"%s\" [%s%s] version generation failed, symbol will not be versioned.\n" "Is \"%s\" prototyped in <asm/asm-prototypes.h>?\n" , sym->name, mod->name, mod->is_vmlinux ?"" :".ko" , sym->name); -continue ; - }buf_printf (buf,"SYMBOL_CRC(%s, 0x%08x, \"%s\");\n" , sym->name, sym->crc, sym->is_gpl_only ?"_gpl" :"" );
Greg Kroah-Hartman
maintainerPATCH 229/365 i2c: imx: Make sure to unregister adapter on remove()
In reply to Greg Kroah-HartmanFrom: Uwe Kleine-König <[email protected]>
commit d98bdd3a5b50446d8e010be5b04ce81c4eabf728 upstream.
If for whatever reasons pm_runtime_resume_and_get() fails and .remove() is exited early, the i2c adapter stays around and the irq still calls its handler, while the driver data and the register mapping go away. So if later the i2c adapter is accessed or the irq triggers this results in havoc accessing freed memory and unmapped registers.
So unregister the software resources even if resume failed, and only skip the hardware access in that case.
--- drivers/i2c/busses/i2c-imx.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-)
drivers/i2c/busses/i2c-imx.c +11 -9
@@ -1572,9 +1572,7 @@ static int i2c_imx_remove(struct platforstruct imx_i2c_struct *i2c_imx =platform_get_drvdata (pdev);int irq, ret; - ret =pm_runtime_resume_and_get (&pdev->dev); -if (ret <0 ) -return ret; + ret =pm_runtime_get_sync (&pdev->dev);hrtimer_cancel (&i2c_imx->slave_timer);
@@ -1585,17 +1583,21 @@ static int i2c_imx_remove(struct platforif (i2c_imx->dma)i2c_imx_dma_free (i2c_imx); -/* setup chip registers to defaults */ -imx_i2c_write_reg (0 , i2c_imx,IMX_I2C_IADR ); -imx_i2c_write_reg (0 , i2c_imx,IMX_I2C_IFDR ); -imx_i2c_write_reg (0 , i2c_imx,IMX_I2C_I2CR ); -imx_i2c_write_reg (0 , i2c_imx,IMX_I2C_I2SR ); +if (ret ==0 ) { +/* setup chip registers to defaults */ +imx_i2c_write_reg (0 , i2c_imx,IMX_I2C_IADR ); +imx_i2c_write_reg (0 , i2c_imx,IMX_I2C_IFDR ); +imx_i2c_write_reg (0 , i2c_imx,IMX_I2C_I2CR ); +imx_i2c_write_reg (0 , i2c_imx,IMX_I2C_I2SR ); +clk_disable (i2c_imx->clk); + }clk_notifier_unregister (i2c_imx->clk, &i2c_imx->clk_change_nb); irq =platform_get_irq (pdev,0 );if (irq >=0 )free_irq (irq, i2c_imx); -clk_disable_unprepare (i2c_imx->clk); + +clk_unprepare (i2c_imx->clk);pm_runtime_put_noidle (&pdev->dev);pm_runtime_disable (&pdev->dev);
Greg Kroah-Hartman
maintainerPATCH 230/365 i40e: Fix tunnel checksum offload with fragmented traffic
In reply to Greg Kroah-HartmanFrom: Przemyslaw Patynowski <[email protected]>
commit 2c6482091f01ba104cf8ee549aa5c717e80d43ea upstream.
Fix checksum offload on VXLAN tunnels.
In case, when mpls protocol is not used, set l4 header to transport header of skb. This fixes case, when user tries to offload checksums of VXLAN tunneled traffic.
Steps for reproduction (requires link partner with tunnels):
ip l s enp130s0f0 up
ip a f enp130s0f0
ip a a 10.10.110.2/24 dev enp130s0f0
ip l s enp130s0f0 mtu 1600
ip link add vxlan12_sut type vxlan id 12 group 238.168.100.100 dev \
enp130s0f0 dstport 4789
ip l s vxlan12_sut up
ip a a 20.10.110.2/24 dev vxlan12_sut
iperf3 -c 20.10.110.1 #should connect
Without this patch, TX descriptor was using wrong data, due to l4 header pointing wrong address. NIC would then drop those packets internally, due to incorrect TX descriptor data, which increased GLV_TEPC register.
--- drivers/net/ethernet/intel/i40e/i40e_txrx.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
drivers/net/ethernet/intel/i40e/i40e_txrx.c +5 -3
@@ -3204,11 +3204,13 @@ static int i40e_tx_enable_csum(struct sk protocol =vlan_get_protocol (skb); -if (eth_p_mpls (protocol)) +if (eth_p_mpls (protocol)) { ip.hdr =skb_inner_network_header (skb); -else + l4.hdr =skb_checksum_start (skb); + }else { ip.hdr =skb_network_header (skb); - l4.hdr =skb_checksum_start (skb); + l4.hdr =skb_transport_header (skb); + }/* set the tx_flags to indicate the IP protocol type. this is * required so that checksum header computation below is accurate.
Greg Kroah-Hartman
maintainerPATCH 231/365 regulator: pca9450: Remove restrictions for regulator-name
In reply to Greg Kroah-HartmanFrom: Frieder Schrempf <[email protected]>
commit b0de7fa706506bf0591037908376351beda8c5d6 upstream.
The device bindings shouldn't put any constraints on the regulator-name property specified in the generic bindings. This allows using arbitrary and descriptive names for the regulators.
--- Documentation/devicetree/bindings/regulator/nxp,pca9450-regulator.yaml | 11 ---------- 1 file changed, 11 deletions(-)
Documentation/devicetree/bindings/regulator/nxp,pca9450-regulator.yaml +0 -11
@@ -47,12 +47,6 @@ properties: description: Properties for single LDO regulator. - properties: - regulator-name: - pattern: "^LDO[1-5]$" - description: - should be "LDO1", ..., "LDO5" - unevaluatedProperties: false "^BUCK[1-6]$":
@@ -62,11 +56,6 @@ properties: Properties for single BUCK regulator. properties: - regulator-name: - pattern: "^BUCK[1-6]$" - description: - should be "BUCK1", ..., "BUCK6" - nxp,dvs-run-voltage: $ref: "/schemas/types.yaml#/definitions/uint32" minimum: 600000
Greg Kroah-Hartman
maintainerPATCH 232/365 i40e: Fix to stop tx_timeout recovery if GLOBR fails
In reply to Greg Kroah-HartmanFrom: Alan Brady <[email protected]>
commit 57c942bc3bef0970f0b21f8e0998e76a900ea80d upstream.
When a tx_timeout fires, the PF attempts to recover by incrementally resetting. First we try a PFR, then CORER and finally a GLOBR. If the GLOBR fails, then we keep hitting the tx_timeout and incrementing the recovery level and issuing dmesgs, which is both annoying to the user and accomplishes nothing.
If the GLOBR fails, then we're pretty much totally hosed, and there's not much else we can do to recover, so this makes it such that we just kill the VSI and stop hitting the tx_timeout in such a case.
--- drivers/net/ethernet/intel/i40e/i40e_main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/net/ethernet/intel/i40e/i40e_main.c +3 -1
@@ -384,7 +384,9 @@ static void i40e_tx_timeout(struct net_dset_bit (__I40E_GLOBAL_RESET_REQUESTED, pf->state);break ;default : -netdev_err (netdev,"tx_timeout recovery unsuccessful\n" ); +netdev_err (netdev,"tx_timeout recovery unsuccessful, device is in non-recoverable state.\n" ); +set_bit (__I40E_DOWN_REQUESTED, pf->state); +set_bit (__I40E_VSI_DOWN_REQUESTED, vsi->state);break ; }
Greg Kroah-Hartman
maintainerPATCH 233/365 blk-mq: run queue no matter whether the request is the last request
In reply to Greg Kroah-HartmanFrom: Yufen Yu <[email protected]>
commit d3b38596875dbc709b4e721a5873f4663d8a9ea2 upstream.
We do test on a virtio scsi device (/dev/sda) and the default mq scheduler is 'none'. We found a IO hung as following:
blk_finish_plug
blk_mq_plug_issue_direct
scsi_mq_get_budget
//get budget_token fail and sdev->restarts=1
scsi_end_request
scsi_run_queue_async
//sdev->restart=0 and run queue
blk_mq_request_bypass_insert
//add request to hctx->dispatch list //continue to dispath plug list
blk_mq_dispatch_plug_list
blk_mq_try_issue_list_directly
//success issue all requests from plug listAfter .get_budget fail, scsi_mq_get_budget will increase 'restarts'. Normally, it will run hw queue when io complete and set 'restarts' as 0. But if we run queue before adding request to the dispatch list and blk_mq_dispatch_plug_list also success issue all requests, then on one will run queue, and the request will be stall in the dispatch list and cannot complete forever.
It is wrong to use last request of plug list to decide if run queue is needed since all the remained requests in plug list may be from other hctxs. To fix the bug, pass run_queue as true always to blk_mq_request_bypass_insert().
--- block/blk-mq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
block/blk-mq.c +1 -1
@@ -2568,7 +2568,7 @@ static void blk_mq_plug_issue_direct(strbreak ;case BLK_STS_RESOURCE :case BLK_STS_DEV_RESOURCE : -blk_mq_request_bypass_insert (rq, false, last); +blk_mq_request_bypass_insert (rq, false, true);blk_mq_commit_rqs (hctx, &queued, from_schedule);return ;default :
Greg Kroah-Hartman
maintainerPATCH 234/365 tools/rtla: Fix command symlinks
In reply to Greg Kroah-HartmanFrom: Ben Hutchings <[email protected]>
commit ff5a55dcdb343e3db9b9fb08795b78544b032773 upstream.
"ln -s" stores the next argument directly as the symlink target, so it needs to be a relative path. In this case, just "rtla".
--- tools/tracing/rtla/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
tools/tracing/rtla/Makefile +2 -2
@@ -108,9 +108,9 @@ install: doc_install $(INSTALL) rtla -m 755 $(DESTDIR)$(BINDIR) $(STRIP) $(DESTDIR)$(BINDIR)/rtla @test ! -f $(DESTDIR)$(BINDIR)/osnoise || rm $(DESTDIR)$(BINDIR)/osnoise - ln -s $(DESTDIR)$(BINDIR)/rtla $(DESTDIR)$(BINDIR)/osnoise + ln -s rtla $(DESTDIR)$(BINDIR)/osnoise @test ! -f $(DESTDIR)$(BINDIR)/timerlat || rm $(DESTDIR)$(BINDIR)/timerlat - ln -s $(DESTDIR)$(BINDIR)/rtla $(DESTDIR)$(BINDIR)/timerlat + ln -s rtla $(DESTDIR)$(BINDIR)/timerlat .PHONY: clean tarball clean: doc_clean
Signature · 1 line
2.37.2
Greg Kroah-Hartman
maintainerPATCH 235/365 fec: Fix timer capture timing in `fec_ptp_enable_pps()`
In reply to Greg Kroah-HartmanFrom: Csókás Bence <[email protected]>
commit 61d5e2a251fb20c2c5e998c3f1d52ed6d5360319 upstream.
Code reimplements functionality already in fec_ptp_read(), but misses check for FEC_QUIRK_BUG_CAPTURE. Replace with function call.
--- drivers/net/ethernet/freescale/fec_ptp.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-)
drivers/net/ethernet/freescale/fec_ptp.c +1 -5
@@ -135,11 +135,7 @@ static int fec_ptp_enable_pps(struct fec* NSEC_PER_SEC - ts.tv_nsec. Add the remaining nanoseconds * to current timer would be next second. */ - tempval =readl (fep->hwp +FEC_ATIME_CTRL ); - tempval |=FEC_T_CTRL_CAPTURE ; -writel (tempval, fep->hwp +FEC_ATIME_CTRL ); - - tempval =readl (fep->hwp +FEC_ATIME ); + tempval = fep->cc.read (&fep->cc);/* Convert the ptp local counter to 1588 timestamp */ ns =timecounter_cyc2time (&fep->tc, tempval); ts =ns_to_timespec64 (ns);
Greg Kroah-Hartman
maintainerPATCH 236/365 dt-bindings: display: sun4i: Add D1 TCONs to conditionals
In reply to Greg Kroah-HartmanFrom: Samuel Holland <[email protected]>
commit 2a29f80e155a9cf40ca8b6648bcdc8422db4c4e4 upstream.
When adding the D1 TCON bindings, I missed the conditional blocks that restrict the binding for TCON LCD vs TCON TV hardware. Add the D1 TCON variants to the appropriate blocks for DE2 TCON LCDs and TCON TVs.
--- .../devicetree/bindings/display/allwinner,sun4i-a10-tcon.yaml | 4 ++++ 1 file changed, 4 insertions(+)
Documentation/devicetree/bindings/display/allwinner,sun4i-a10-tcon.yaml +4 -0
@@ -233,6 +233,7 @@ allOf: - allwinner,sun8i-a83t-tcon-lcd - allwinner,sun8i-v3s-tcon - allwinner,sun9i-a80-tcon-lcd + - allwinner,sun20i-d1-tcon-lcd then: properties:
@@ -252,6 +253,7 @@ allOf: - allwinner,sun8i-a83t-tcon-tv - allwinner,sun8i-r40-tcon-tv - allwinner,sun9i-a80-tcon-tv + - allwinner,sun20i-d1-tcon-tv then: properties:
@@ -278,6 +280,7 @@ allOf: - allwinner,sun9i-a80-tcon-lcd - allwinner,sun4i-a10-tcon - allwinner,sun8i-a83t-tcon-lcd + - allwinner,sun20i-d1-tcon-lcd then: required:
@@ -294,6 +297,7 @@ allOf: - allwinner,sun8i-a23-tcon - allwinner,sun8i-a33-tcon - allwinner,sun8i-a83t-tcon-lcd + - allwinner,sun20i-d1-tcon-lcd then: properties:
Signature · 1 line
2.37.2
Greg Kroah-Hartman
maintainerPATCH 237/365 stmmac: intel: Add a missing clk_disable_unprepare() call in intel_eth_pci_remove()
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
commit 5c23d6b717e4e956376f3852b90f58e262946b50 upstream.
Commit 09f012e64e4b ("stmmac: intel: Fix clock handling on error and remove paths") removed this clk_disable_unprepare()
This was partly revert by commit ac322f86b56c ("net: stmmac: Fix clock handling on remove path") which removed this clk_disable_unprepare() because:
"
While unloading the dwmac-intel driver, clk_disable_unprepare() is being called twice in stmmac_dvr_remove() and intel_eth_pci_remove(). This causes kernel panic on the second call.
"
However later on, commit 5ec55823438e8 ("net: stmmac: add clocks management for gmac driver") has updated stmmac_dvr_remove() which do not call clk_disable_unprepare() anymore.
So this call should now be called from intel_eth_pci_remove().
--- drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c +1 -0
@@ -1104,6 +1104,7 @@ static void intel_eth_pci_remove(structstmmac_dvr_remove (&pdev->dev); +clk_disable_unprepare (priv->plat->stmmac_clk);clk_unregister_fixed_rate (priv->plat->stmmac_clk);pcim_iounmap_regions (pdev,BIT (0 ));
Greg Kroah-Hartman
maintainerPATCH 238/365 igb: Add lock to avoid data race
In reply to Greg Kroah-HartmanFrom: Lin Ma <[email protected]>
commit 6faee3d4ee8be0f0367d0c3d826afb3571b7a5e0 upstream.
The commit c23d92b80e0b ("igb: Teardown SR-IOV before unregister_netdev()") places the unregister_netdev() call after the igb_disable_sriov() call to avoid functionality issue.
However, it introduces several race conditions when detaching a device. For example, when .remove() is called, the below interleaving leads to use-after-free.
(FREE from device detaching) | (USE from netdev core)
igb_remove | igb_ndo_get_vf_config
igb_disable_sriov | vf >= adapter->vfs_allocated_count?
kfree(adapter->vf_data) |
adapter->vfs_allocated_count = 0 |
| memcpy(... adapter->vf_data[vf]Moreover, the igb_disable_sriov() also suffers from data race with the requests from VF driver.
(FREE from device detaching) | (USE from requests) igb_remove | igb_msix_other igb_disable_sriov | igb_msg_task kfree(adapter->vf_data) | vf < adapter->vfs_allocated_count adapter->vfs_allocated_count = 0 |
To this end, this commit first eliminates the data races from netdev core by using rtnl_lock (similar to commit 719479230893 ("dpaa2-eth: add MAC/PHY support through phylink")). And then adds a spinlock to eliminate races from driver requests. (similar to commit 1e53834ce541 ("ixgbe: Add locking to prevent panic when setting sriov_numvfs to zero")
--- drivers/net/ethernet/intel/igb/igb.h | 2 ++ drivers/net/ethernet/intel/igb/igb_main.c | 12 +++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-)
drivers/net/ethernet/intel/igb/igb.h +2 -0
@@ -664,6 +664,8 @@ struct igb_adapter {struct igb_mac_addr *mac_table;struct vf_mac_filter vf_macs;struct vf_mac_filter *vf_mac_list; +/* lock for VF resources */ +spinlock_t vfs_lock; };/* flags controlling PTP/1588 function */
drivers/net/ethernet/intel/igb/igb_main.c +11 -1
@@ -3637,6 +3637,7 @@ static int igb_disable_sriov(struct pci_struct net_device *netdev =pci_get_drvdata (pdev);struct igb_adapter *adapter =netdev_priv (netdev);struct e1000_hw *hw = &adapter->hw; +unsigned long flags;/* reclaim resources allocated to VFs */ if (adapter->vf_data) {
@@ -3649,12 +3650,13 @@ static int igb_disable_sriov(struct pci_pci_disable_sriov (pdev);msleep (500 ); } - +spin_lock_irqsave (&adapter->vfs_lock, flags);kfree (adapter->vf_mac_list); adapter->vf_mac_list =NULL ;kfree (adapter->vf_data); adapter->vf_data =NULL ; adapter->vfs_allocated_count =0 ; +spin_unlock_irqrestore (&adapter->vfs_lock, flags);wr32 (E1000_IOVCTL ,E1000_IOVCTL_REUSE_VFQ );wrfl ();msleep (100 );
@@ -3814,7 +3816,9 @@ static void igb_remove(struct pci_dev *pigb_release_hw_control (adapter);#ifdef CONFIG_PCI_IOV +rtnl_lock ();igb_disable_sriov (pdev); +rtnl_unlock ();#endif unregister_netdev (netdev);
@@ -3974,6 +3978,9 @@ static int igb_sw_init(struct igb_adaptespin_lock_init (&adapter->nfc_lock);spin_lock_init (&adapter->stats64_lock); + +/* init spinlock to avoid concurrency of VF resources */ +spin_lock_init (&adapter->vfs_lock);#ifdef CONFIG_PCI_IOV switch (hw->mac.type) {case e1000_82576:
@@ -7924,8 +7931,10 @@ unlock:static void igb_msg_task (struct igb_adapter *adapter) {struct e1000_hw *hw = &adapter->hw; +unsigned long flags;u32 vf; +spin_lock_irqsave (&adapter->vfs_lock, flags);for (vf =0 ; vf < adapter->vfs_allocated_count; vf++) {/* process any reset requests */ if (!igb_check_for_rst (hw, vf))
@@ -7939,6 +7948,7 @@ static void igb_msg_task(struct igb_adapif (!igb_check_for_ack (hw, vf))igb_rcv_ack_from_vf (adapter, vf); } +spin_unlock_irqrestore (&adapter->vfs_lock, flags); }/**
Greg Kroah-Hartman
maintainerPATCH 239/365 kbuild: fix the modules order between drivers and libs
In reply to Greg Kroah-HartmanFrom: Masahiro Yamada <[email protected]>
commit 113147510b48e764e624e3d0e6707a1e48bc05a9 upstream.
Commit b2c885549122 ("kbuild: update modules.order only when contained modules are updated") accidentally changed the modules order.
Prior to that commit, the modules order was determined based on vmlinux-dirs, which lists core-y/m, drivers-y/m, libs-y/m, in this order.
Now, subdir-modorder lists them in a different order: core-y/m, libs-y/m, drivers-y/m.
Presumably, there was no practical issue because the modules in drivers and libs are orthogonal, but there is no reason to have this distortion.
Get back to the original order.
--- Makefile | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
Makefile +2 -4
@@ -1112,13 +1112,11 @@ vmlinux-alldirs := $(sort $(vmlinux-dirs $(patsubst %/,%,$(filter %/, $(core-) \ $(drivers-) $(libs-)))) -subdir-modorder := $(addsuffix modules.order,$(filter %/, \ - $(core-y) $(core-m) $(libs-y) $(libs-m) \ - $(drivers-y) $(drivers-m))) - build-dirs := $(vmlinux-dirs) clean-dirs := $(vmlinux-alldirs) +subdir-modorder := $(addsuffix /modules.order, $(build-dirs)) + # Externally visible symbols (used by link-vmlinux.sh) KBUILD_VMLINUX_OBJS := $(head-y) $(patsubst %/,%/built-in.a, $(core-y)) KBUILD_VMLINUX_OBJS += $(addsuffix built-in.a, $(filter %/, $(libs-y)))
Greg Kroah-Hartman
maintainerPATCH 240/365 gcc-plugins: Undefine LATENT_ENTROPY_PLUGIN when plugin disabled for a file
In reply to Greg Kroah-HartmanFrom: Andrew Donnellan <[email protected]>
commit 012e8d2034f1bda8863435cd589636e618d6a659 upstream.
Commit 36d4b36b6959 ("lib/nodemask: inline next_node_in() and node_random()") refactored some code by moving node_random() from lib/nodemask.c to include/linux/nodemask.h, thus requiring nodemask.h to include random.h, which conditionally defines add_latent_entropy() depending on whether the macro LATENT_ENTROPY_PLUGIN is defined.
This broke the build on powerpc, where nodemask.h is indirectly included in arch/powerpc/kernel/prom_init.c, part of the early boot machinery that is excluded from the latent entropy plugin using DISABLE_LATENT_ENTROPY_PLUGIN. It turns out that while we add a gcc flag to disable the actual plugin, we don't undefine LATENT_ENTROPY_PLUGIN.
This leads to the following:
CC arch/powerpc/kernel/prom_init.o
In file included from ./include/linux/nodemask.h:97,
from ./include/linux/mmzone.h:17,
from ./include/linux/gfp.h:7,
from ./include/linux/xarray.h:15,
from ./include/linux/radix-tree.h:21,
from ./include/linux/idr.h:15,
from ./include/linux/kernfs.h:12,
from ./include/linux/sysfs.h:16,
from ./include/linux/kobject.h:20,
from ./include/linux/pci.h:35,
from arch/powerpc/kernel/prom_init.c:24:
./include/linux/random.h: In function 'add_latent_entropy':
./include/linux/random.h:25:46: error: 'latent_entropy' undeclared (first use in this function); did you mean 'add_latent_entropy'?
25 | add_device_randomness((const void *)&latent_entropy, sizeof(latent_entropy));
| ^~~~~~~~~~~~~~
| add_latent_entropy ./include/linux/random.h:25:46: note: each undeclared identifier is reported only once for each function it appears in make[2]: *** [scripts/Makefile.build:249: arch/powerpc/kernel/prom_init.o] Fehler 1
make[1]: *** [scripts/Makefile.build:465: arch/powerpc/kernel] Fehler 2
make: *** [Makefile:1855: arch/powerpc] Error 2
Change the DISABLE_LATENT_ENTROPY_PLUGIN flags to undefine LATENT_ENTROPY_PLUGIN for files where the plugin is disabled.
--- scripts/Makefile.gcc-plugins | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
scripts/Makefile.gcc-plugins +1 -1
@@ -4,7 +4,7 @@ gcc-plugin-$(CONFIG_GCC_PLUGIN_LATENT_EN gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_LATENT_ENTROPY) \ += -DLATENT_ENTROPY_PLUGIN ifdef CONFIG_GCC_PLUGIN_LATENT_ENTROPY - DISABLE_LATENT_ENTROPY_PLUGIN += -fplugin-arg-latent_entropy_plugin-disable + DISABLE_LATENT_ENTROPY_PLUGIN += -fplugin-arg-latent_entropy_plugin-disable -ULATENT_ENTROPY_PLUGIN endif export DISABLE_LATENT_ENTROPY_PLUGIN
Greg Kroah-Hartman
maintainerPATCH 241/365 can: j1939: j1939_sk_queue_activate_next_locked(): replace WARN_ON_ONCE with netdev_warn_once()
In reply to Greg Kroah-HartmanFrom: Fedor Pchelkin <[email protected]>
commit 8ef49f7f8244424adcf4a546dba4cbbeb0b09c09 upstream.
We should warn user-space that it is doing something wrong when trying to activate sessions with identical parameters but WARN_ON_ONCE macro can not be used here as it serves a different purpose.
So it would be good to replace it with netdev_warn_once() message.
Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
--- net/can/j1939/socket.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
net/can/j1939/socket.c +4 -1
@@ -178,7 +178,10 @@ activate_next:if (!first)return ; -if (WARN_ON_ONCE (j1939_session_activate (first))) { +if (j1939_session_activate (first)) { +netdev_warn_once (first->priv->ndev, +"%s: 0x%p: Identical session is already activated.\n" , + __func__, first); first->err = -EBUSY ; goto activate_next; }else {
Greg Kroah-Hartman
maintainerPATCH 242/365 drm/imx/dcss: get rid of HPD warning message
In reply to Greg Kroah-HartmanFrom: Laurentiu Palcu <[email protected]>
[ Upstream commit 30bdc36b8c776cd4fce5de2a96ff28b37f96942f ]
When DCSS + MIPI_DSI is used, and the last bridge in the chain supports HPD, we can see a "Hot plug detection already enabled" warning stack trace dump that's thrown when DCSS is initialized.
The problem appeared when HPD was enabled by default in the bridge_connector initialization, which made the drm_bridge_connector_enable_hpd() call, in DCSS init path, redundant. So, let's remove that call.
--- drivers/gpu/drm/imx/dcss/dcss-kms.c | 2 -- 1 file changed, 2 deletions(-)
drivers/gpu/drm/imx/dcss/dcss-kms.c +0 -2
@@ -142,8 +142,6 @@ struct dcss_kms_dev *dcss_kms_attach(struct dcss_dev *dcss)drm_kms_helper_poll_init (drm); -drm_bridge_connector_enable_hpd (kms->connector); - ret =drm_dev_register (drm,0 );if (ret) goto cleanup_crtc;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 243/365 drm/meson: Fix refcount bugs in meson_vpu_has_available_connectors()
In reply to Greg Kroah-HartmanFrom: Liang He <[email protected]>
[ Upstream commit 91b3c8dbe898df158fd2a84675f3a284ff6666f7 ]
In this function, there are two refcount leak bugs:
(1) when breaking out of for_each_endpoint_of_node(), we need call the of_node_put() for the 'ep';
(2) we should call of_node_put() for the reference returned by of_graph_get_remote_port() when it is not used anymore.
--- drivers/gpu/drm/meson/meson_drv.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/gpu/drm/meson/meson_drv.c +4 -1
@@ -115,8 +115,11 @@ static bool meson_vpu_has_available_connectors(struct device *dev)for_each_endpoint_of_node (dev->of_node, ep) {/* If the endpoint node exists, consider it enabled */ remote =of_graph_get_remote_port (ep); -if (remote) +if (remote) { +of_node_put (remote); +of_node_put (ep);return true; + } }return false;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 244/365 drm/i915/ttm: dont leak the ccs state
In reply to Greg Kroah-HartmanFrom: Matthew Auld <[email protected]>
[ Upstream commit 232d150fa15606e96c0e01e5c7a2d4e03f621787 ]
The kernel only manages the ccs state with lmem-only objects, however the kernel should still take care not to leak the CCS state from the previous user.
--- drivers/gpu/drm/i915/gt/intel_migrate.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-)
drivers/gpu/drm/i915/gt/intel_migrate.c +22 -1
@@ -708,7 +708,7 @@ intel_context_migrate_copy(struct intel_context *ce,u8 src_access, dst_access;struct i915_request *rq;int src_sz, dst_sz; -bool ccs_is_src; +bool ccs_is_src, overwrite_ccs;int err;GEM_BUG_ON (ce->vm != ce->engine->gt->migrate.context->vm);
@@ -749,6 +749,8 @@ intel_context_migrate_copy(struct intel_context *ce,get_ccs_sg_sgt (&it_ccs, bytes_to_cpy); } + overwrite_ccs =HAS_FLAT_CCS (i915) && !ccs_bytes_to_cpy && dst_is_lmem; + src_offset =0 ; dst_offset =CHUNK_SZ ;if (HAS_64K_PAGES (ce->engine->i915)) {
@@ -852,6 +854,25 @@ intel_context_migrate_copy(struct intel_context *ce,if (err) goto out_rq; ccs_bytes_to_cpy -= ccs_sz; + }else if (overwrite_ccs) { + err = rq->engine->emit_flush (rq,EMIT_INVALIDATE ); +if (err) + goto out_rq; + +/* +* While we can't always restore/manage the CCS state, +* we still need to ensure we don't leak the CCS state +* from the previous user, so make sure we overwrite it +* with something. +*/ + err =emit_copy_ccs (rq, dst_offset,INDIRECT_ACCESS , + dst_offset,DIRECT_ACCESS , len); +if (err) + goto out_rq; + + err = rq->engine->emit_flush (rq,EMIT_INVALIDATE ); +if (err) + goto out_rq; }/* Arbitration is re-enabled between requests. */
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 245/365 drm/amdgpu: Avoid another list of reset devices
In reply to Greg Kroah-HartmanFrom: Lijo Lazar <[email protected]>
[ Upstream commit 0a83bb35d8a6ff3d18c2772afe616780c23293a6 ]
A list of devices to be reset is already created in amdgpu_device_gpu_recover function. Creating another list with the same nodes is incorrect and not supported in list_head. Instead, pass the device list as part of reset context.
--- drivers/gpu/drm/amd/amdgpu/aldebaran.c | 45 +++++++--------------- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 2 + drivers/gpu/drm/amd/amdgpu/amdgpu_reset.h | 1 + 3 files changed, 17 insertions(+), 31 deletions(-)
drivers/gpu/drm/amd/amdgpu/aldebaran.c +14 -31
@@ -148,30 +148,22 @@ aldebaran_mode2_perform_reset(struct amdgpu_reset_control *reset_ctl, struct amdgpu_reset_context *reset_context) {struct amdgpu_device *adev = (struct amdgpu_device *)reset_ctl->handle; +struct list_head *reset_device_list = reset_context->reset_device_list;struct amdgpu_device *tmp_adev =NULL ; -struct list_head reset_device_list;int r =0 ;dev_dbg (adev->dev,"aldebaran perform hw reset\n" ); + +if (reset_device_list ==NULL ) +return -EINVAL ; +if (adev->ip_versions[MP1_HWIP ][0 ] ==IP_VERSION (13 ,0 ,2 ) && reset_context->hive ==NULL ) {/* Wrong context, return error */ return -EINVAL ; } -INIT_LIST_HEAD (&reset_device_list); -if (reset_context->hive) { -list_for_each_entry (tmp_adev, - &reset_context->hive->device_list, - gmc.xgmi.head) -list_add_tail (&tmp_adev->reset_list, - &reset_device_list); - }else { -list_add_tail (&reset_context->reset_req_dev->reset_list, - &reset_device_list); - } - - list_for_each_entry (tmp_adev, &reset_device_list, reset_list) { +list_for_each_entry (tmp_adev, reset_device_list, reset_list) {mutex_lock (&tmp_adev->reset_cntl->reset_lock); tmp_adev->reset_cntl->active_reset =AMD_RESET_METHOD_MODE2 ; }
@@ -179,7 +171,7 @@ aldebaran_mode2_perform_reset(struct amdgpu_reset_control *reset_ctl,* Mode2 reset doesn't need any sync between nodes in XGMI hive, instead launch * them together so that they can be completed asynchronously on multiple nodes */ - list_for_each_entry (tmp_adev, &reset_device_list, reset_list) { + list_for_each_entry(tmp_adev, reset_device_list, reset_list) { /* For XGMI run all resets in parallel to speed up the process */ if (tmp_adev->gmc.xgmi.num_physical_nodes > 1) { if (!queue_work(system_unbound_wq,
@@ -197,7 +189,7 @@ aldebaran_mode2_perform_reset(struct amdgpu_reset_control *reset_ctl,/* For XGMI wait for all resets to complete before proceed */ if (!r) { - list_for_each_entry (tmp_adev, &reset_device_list, reset_list) { +list_for_each_entry (tmp_adev, reset_device_list, reset_list) {if (tmp_adev->gmc.xgmi.num_physical_nodes >1 ) {flush_work (&tmp_adev->reset_cntl->reset_work); r = tmp_adev->asic_reset_res;
@@ -207,7 +199,7 @@ aldebaran_mode2_perform_reset(struct amdgpu_reset_control *reset_ctl, } } - list_for_each_entry (tmp_adev, &reset_device_list, reset_list) { +list_for_each_entry (tmp_adev, reset_device_list, reset_list) {mutex_unlock (&tmp_adev->reset_cntl->reset_lock); tmp_adev->reset_cntl->active_reset =AMD_RESET_METHOD_NONE ; }
@@ -339,10 +331,13 @@ static int aldebaran_mode2_restore_hwcontext(struct amdgpu_reset_control *reset_ctl, struct amdgpu_reset_context *reset_context) { + struct list_head *reset_device_list = reset_context->reset_device_list;struct amdgpu_device *tmp_adev =NULL ; -struct list_head reset_device_list;int r; +if (reset_device_list ==NULL ) +return -EINVAL ; +if (reset_context->reset_req_dev->ip_versions[MP1_HWIP ][0 ] ==IP_VERSION (13 ,0 ,2 ) && reset_context->hive ==NULL ) {
@@ -350,19 +345,7 @@ aldebaran_mode2_restore_hwcontext(struct amdgpu_reset_control *reset_ctl,return -EINVAL ; } -INIT_LIST_HEAD (&reset_device_list); -if (reset_context->hive) { -list_for_each_entry (tmp_adev, - &reset_context->hive->device_list, - gmc.xgmi.head) -list_add_tail (&tmp_adev->reset_list, - &reset_device_list); - }else { -list_add_tail (&reset_context->reset_req_dev->reset_list, - &reset_device_list); - } - - list_for_each_entry (tmp_adev, &reset_device_list, reset_list) { +list_for_each_entry (tmp_adev, reset_device_list, reset_list) {dev_info (tmp_adev->dev,"GPU reset succeeded, trying to resume\n" ); r =aldebaran_mode2_restore_ip (tmp_adev);
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +2 -0
@@ -4746,6 +4746,8 @@ int amdgpu_do_asic_reset(struct list_head *device_list_handle, tmp_adev = list_first_entry(device_list_handle, struct amdgpu_device, reset_list);amdgpu_reset_reg_dumps (tmp_adev); + + reset_context->reset_device_list = device_list_handle; r =amdgpu_reset_perform_reset (tmp_adev, reset_context);/* If reset handler not implemented, continue; otherwise return */ if (r == -ENOSYS )
drivers/gpu/drm/amd/amdgpu/amdgpu_reset.h +1 -0
@@ -37,6 +37,7 @@ struct amdgpu_reset_context {struct amdgpu_device *reset_req_dev;struct amdgpu_job *job;struct amdgpu_hive_info *hive; +struct list_head *reset_device_list;unsigned long flags; };
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 246/365 drm/bridge: lvds-codec: Fix error checking of drm_of_lvds_get_data_mapping()
In reply to Greg Kroah-HartmanFrom: Marek Vasut <[email protected]>
[ Upstream commit 2bba782002c5dab6ca8d608b778b386fb912adff ]
The drm_of_lvds_get_data_mapping() returns either negative value on error or MEDIA_BUS_FMT_* otherwise. The check for 'ret' would also catch the positive case of MEDIA_BUS_FMT_* and lead to probe failure every time 'data-mapping' DT property is specified.
--- drivers/gpu/drm/bridge/lvds-codec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/bridge/lvds-codec.c +1 -1
@@ -180,7 +180,7 @@ static int lvds_codec_probe(struct platform_device *pdev)of_node_put (bus_node);if (ret == -ENODEV ) {dev_warn (dev,"missing 'data-mapping' DT property\n" ); - }else if (ret) { + }else if (ret <0 ) {dev_err (dev,"invalid 'data-mapping' DT property\n" );return ret; }else {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 247/365 drm/sun4i: dsi: Prevent underflow when computing packet sizes
In reply to Greg Kroah-HartmanFrom: Samuel Holland <[email protected]>
[ Upstream commit 82a1356a933d8443139f8886f11b63c974a09a67 ]
Currently, the packet overhead is subtracted using unsigned arithmetic. With a short sync pulse, this could underflow and wrap around to near the maximal u16 value. Fix this by using signed subtraction. The call to max() will correctly handle any negative numbers that are produced.
Apply the same fix to the other timings, even though those subtractions are less likely to underflow.
--- drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c +5 -5
@@ -531,7 +531,7 @@ static void sun6i_dsi_setup_timings(struct sun6i_dsi *dsi, struct drm_display_mode *mode) {struct mipi_dsi_device *device = dsi->device; -unsigned int Bpp =mipi_dsi_pixel_format_to_bpp (device->format) /8 ; +int Bpp =mipi_dsi_pixel_format_to_bpp (device->format) /8 ;u16 hbp =0 , hfp =0 , hsa =0 , hblk =0 , vblk =0 ;u32 basic_ctl =0 ;size_t bytes;
@@ -555,7 +555,7 @@ static void sun6i_dsi_setup_timings(struct sun6i_dsi *dsi,* (4 bytes). Its minimal size is therefore 10 bytes */ #define HSA_PACKET_OVERHEAD 10 - hsa =max ((unsigned int )HSA_PACKET_OVERHEAD , + hsa =max (HSA_PACKET_OVERHEAD , (mode->hsync_end - mode->hsync_start) * Bpp -HSA_PACKET_OVERHEAD );/*
@@ -564,7 +564,7 @@ static void sun6i_dsi_setup_timings(struct sun6i_dsi *dsi,* therefore 6 bytes */ #define HBP_PACKET_OVERHEAD 6 - hbp =max ((unsigned int )HBP_PACKET_OVERHEAD , + hbp =max (HBP_PACKET_OVERHEAD , (mode->htotal - mode->hsync_end) * Bpp -HBP_PACKET_OVERHEAD );/*
@@ -574,7 +574,7 @@ static void sun6i_dsi_setup_timings(struct sun6i_dsi *dsi,* 16 bytes */ #define HFP_PACKET_OVERHEAD 16 - hfp =max ((unsigned int )HFP_PACKET_OVERHEAD , + hfp =max (HFP_PACKET_OVERHEAD , (mode->hsync_start - mode->hdisplay) * Bpp -HFP_PACKET_OVERHEAD );/*
@@ -583,7 +583,7 @@ static void sun6i_dsi_setup_timings(struct sun6i_dsi *dsi,* bytes). Its minimal size is therefore 10 bytes. */ #define HBLK_PACKET_OVERHEAD 10 - hblk =max ((unsigned int )HBLK_PACKET_OVERHEAD , + hblk =max (HBLK_PACKET_OVERHEAD , (mode->htotal - (mode->hsync_end - mode->hsync_start)) * Bpp -HBLK_PACKET_OVERHEAD );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 248/365 drm/amdgpu: Fix use-after-free on amdgpu_bo_list mutex
In reply to Greg Kroah-HartmanFrom: Maíra Canal <[email protected]>
[ Upstream commit bbca24d0a3c11193bafb9e174f89f52a379006e3 ]
If amdgpu_cs_vm_handling returns r != 0, then it will unlock the bo_list_mutex inside the function amdgpu_cs_vm_handling and again on amdgpu_cs_parser_fini. This problem results in the following use-after-free problem:
[ 220.280990] ------------[ cut here ]------------ [ 220.281000] refcount_t: underflow; use-after-free. [ 220.281019] WARNING: CPU: 1 PID: 3746 at lib/refcount.c:28 refcount_warn_saturate+0xba/0x110 [ 220.281029] ------------[ cut here ]------------ [ 220.281415] CPU: 1 PID: 3746 Comm: chrome:cs0 Tainted: G W L ------- --- 5.20.0-0.rc0.20220812git7ebfc85e2cd7.10.fc38.x86_64 #1 [ 220.281421] Hardware name: System manufacturer System Product Name/ROG STRIX X570-I GAMING, BIOS 4403 04/27/2022 [ 220.281426] RIP: 0010:refcount_warn_saturate+0xba/0x110 [ 220.281431] Code: 01 01 e8 79 4a 6f 00 0f 0b e9 42 47 a5 00 80 3d de 7e be 01 00 75 85 48 c7 c7 f8 98 8e 98 c6 05 ce 7e be 01 01 e8 56 4a 6f 00 <0f> 0b e9 1f 47 a5 00 80 3d b9 7e be 01 00 0f 85 5e ff ff ff 48 c7 [ 220.281437] RSP: 0018:ffffb4b0d18d7a80 EFLAGS: 00010282 [ 220.281443] RAX: 0000000000000026 RBX: 0000000000000003 RCX: 0000000000000000 [ 220.281448] RDX: 0000000000000001 RSI: ffffffff988d06dc RDI: 00000000ffffffff [ 220.281452] RBP: 00000000ffffffff R08: 0000000000000000 R09: ffffb4b0d18d7930 [ 220.281457] R10: 0000000000000003 R11: ffffa0672e2fffe8 R12: ffffa058ca360400 [ 220.281461] R13: ffffa05846c50a18 R14: 00000000fffffe00 R15: 0000000000000003 [ 220.281465] FS: 00007f82683e06c0(0000) GS:ffffa066e2e00000(0000) knlGS:0000000000000000 [ 220.281470] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 220.281475] CR2: 00003590005cc000 CR3: 00000001fca46000 CR4: 0000000000350ee0 [ 220.281480] Call Trace: [ 220.281485] <TASK> [ 220.281490] amdgpu_cs_ioctl+0x4e2/0x2070 [amdgpu] [ 220.281806] ? amdgpu_cs_find_mapping+0xe0/0xe0 [amdgpu] [ 220.282028] drm_ioctl_kernel+0xa4/0x150 [ 220.282043] drm_ioctl+0x21f/0x420 [ 220.282053] ? amdgpu_cs_find_mapping+0xe0/0xe0 [amdgpu] [ 220.282275] ? lock_release+0x14f/0x460 [ 220.282282] ? _raw_spin_unlock_irqrestore+0x30/0x60 [ 220.282290] ? _raw_spin_unlock_irqrestore+0x30/0x60 [ 220.282297] ? lockdep_hardirqs_on+0x7d/0x100 [ 220.282305] ? _raw_spin_unlock_irqrestore+0x40/0x60 [ 220.282317] amdgpu_drm_ioctl+0x4a/0x80 [amdgpu] [ 220.282534] __x64_sys_ioctl+0x90/0xd0 [ 220.282545] do_syscall_64+0x5b/0x80 [ 220.282551] ? futex_wake+0x6c/0x150 [ 220.282568] ? lock_is_held_type+0xe8/0x140 [ 220.282580] ? do_syscall_64+0x67/0x80 [ 220.282585] ? lockdep_hardirqs_on+0x7d/0x100 [ 220.282592] ? do_syscall_64+0x67/0x80 [ 220.282597] ? do_syscall_64+0x67/0x80 [ 220.282602] ? lockdep_hardirqs_on+0x7d/0x100 [ 220.282609] entry_SYSCALL_64_after_hwframe+0x63/0xcd [ 220.282616] RIP: 0033:0x7f8282a4f8bf [ 220.282639] Code: 00 48 89 44 24 18 31 c0 48 8d 44 24 60 c7 04 24 10 00 00 00 48 89 44 24 08 48 8d 44 24 20 48 89 44 24 10 b8 10 00 00 00 0f 05 <89> c2 3d 00 f0 ff ff 77 18 48 8b 44 24 18 64 48 2b 04 25 28 00 00 [ 220.282644] RSP: 002b:00007f82683df410 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 [ 220.282651] RAX: ffffffffffffffda RBX: 00007f82683df588 RCX: 00007f8282a4f8bf [ 220.282655] RDX: 00007f82683df4d0 RSI: 00000000c0186444 RDI: 0000000000000018 [ 220.282659] RBP: 00007f82683df4d0 R08: 00007f82683df5e0 R09: 00007f82683df4b0 [ 220.282663] R10: 00001d04000a0600 R11: 0000000000000246 R12: 00000000c0186444 [ 220.282667] R13: 0000000000000018 R14: 00007f82683df588 R15: 0000000000000003 [ 220.282689] </TASK> [ 220.282693] irq event stamp: 6232311 [ 220.282697] hardirqs last enabled at (6232319): [<ffffffff9718cd7e>] __up_console_sem+0x5e/0x70 [ 220.282704] hardirqs last disabled at (6232326): [<ffffffff9718cd63>] __up_console_sem+0x43/0x70 [ 220.282709] softirqs last enabled at (6232072): [<ffffffff970ff669>] __irq_exit_rcu+0xf9/0x170 [ 220.282716] softirqs last disabled at (6232061): [<ffffffff970ff669>] __irq_exit_rcu+0xf9/0x170 [ 220.282722] ---[ end trace 0000000000000000 ]---
Therefore, remove the mutex_unlock from the amdgpu_cs_vm_handling function, so that amdgpu_cs_submit and amdgpu_cs_parser_fini can handle the unlock.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +2 -6
@@ -837,16 +837,12 @@ static int amdgpu_cs_vm_handling(struct amdgpu_cs_parser *p)continue ; r =amdgpu_vm_bo_update (adev, bo_va, false); -if (r) { -mutex_unlock (&p->bo_list->bo_list_mutex); +if (r)return r; - } r =amdgpu_sync_fence (&p->job->sync, bo_va->last_pt_update); -if (r) { -mutex_unlock (&p->bo_list->bo_list_mutex); +if (r)return r; - } } r =amdgpu_vm_handle_moved (adev, vm);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 249/365 KVM: arm64: Treat PMCR_EL1.LC as RES1 on asymmetric systems
In reply to Greg Kroah-HartmanFrom: Oliver Upton <[email protected]>
[ Upstream commit f3c6efc72f3b20ec23566e768979802f0a398f04 ]
KVM does not support AArch32 on asymmetric systems. To that end, enforce AArch64-only behavior on PMCR_EL1.LC when on an asymmetric system.
--- arch/arm64/include/asm/kvm_host.h | 4 ++++ arch/arm64/kvm/arm.c | 3 +-- arch/arm64/kvm/sys_regs.c | 4 ++-- 3 files changed, 7 insertions(+), 4 deletions(-)
arch/arm64/include/asm/kvm_host.h +4 -0
@@ -838,6 +838,10 @@ bool kvm_arm_vcpu_is_finalized(struct kvm_vcpu *vcpu); (system_supports_mte () && \ test_bit(KVM_ARCH_FLAG_MTE_ENABLED, &(kvm)->arch.flags)) +#define kvm_supports_32bit_el0 () \ + (system_supports_32bit_el0() && \ + !static_branch_unlikely(&arm64_mismatched_32bit_el0)) +int kvm_trng_call (struct kvm_vcpu *vcpu);#ifdef CONFIG_KVM extern phys_addr_t hyp_mem_base;
arch/arm64/kvm/arm.c +1 -2
@@ -751,8 +751,7 @@ static bool vcpu_mode_is_bad_32bit(struct kvm_vcpu *vcpu)if (likely (!vcpu_mode_is_32bit (vcpu)))return false; -return !system_supports_32bit_el0 () || -static_branch_unlikely (&arm64_mismatched_32bit_el0); +return !kvm_supports_32bit_el0 (); }/**
arch/arm64/kvm/sys_regs.c +2 -2
@@ -692,7 +692,7 @@ static void reset_pmcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)*/ val = ((pmcr & ~ARMV8_PMU_PMCR_MASK ) | (ARMV8_PMU_PMCR_MASK &0xdecafbad )) & (~ARMV8_PMU_PMCR_E ); -if (!system_supports_32bit_el0 ()) +if (!kvm_supports_32bit_el0 ()) val |=ARMV8_PMU_PMCR_LC ;__vcpu_sys_reg (vcpu, r->reg) = val; }
@@ -741,7 +741,7 @@ static bool access_pmcr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, val =__vcpu_sys_reg (vcpu,PMCR_EL0 ); val &= ~ARMV8_PMU_PMCR_MASK ; val |= p->regval &ARMV8_PMU_PMCR_MASK ; -if (!system_supports_32bit_el0 ()) +if (!kvm_supports_32bit_el0 ()) val |=ARMV8_PMU_PMCR_LC ;__vcpu_sys_reg (vcpu,PMCR_EL0 ) = val;kvm_pmu_handle_pmcr (vcpu, val);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 250/365 KVM: arm64: Reject 32bit user PSTATE on asymmetric systems
In reply to Greg Kroah-HartmanFrom: Oliver Upton <[email protected]>
[ Upstream commit b10d86fb8e46cc812171728bcd326df2f34e9ed5 ]
KVM does not support AArch32 EL0 on asymmetric systems. To that end, prevent userspace from configuring a vCPU in such a state through setting PSTATE.
It is already ABI that KVM rejects such a write on a system where AArch32 EL0 is unsupported. Though the kernel's definition of a 32bit system changed in commit 2122a833316f ("arm64: Allow mismatched 32-bit EL0 support"), KVM's did not.
--- arch/arm64/kvm/guest.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/kvm/guest.c +1 -1
@@ -242,7 +242,7 @@ static int set_core_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)u64 mode = (*(u64 *)valp) &PSR_AA32_MODE_MASK ;switch (mode) {case PSR_AA32_MODE_USR : -if (!system_supports_32bit_el0 ()) +if (!kvm_supports_32bit_el0 ())return -EINVAL ;break ;case PSR_AA32_MODE_FIQ :
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 251/365 net: mscc: ocelot: turn stats_lock into a spinlock
In reply to Greg Kroah-HartmanFrom: Vladimir Oltean <[email protected]>
[ Upstream commit 22d842e3efe56402c33b5e6e303bb71ce9bf9334 ]
ocelot_get_stats64() currently runs unlocked and therefore may collide with ocelot_port_update_stats() which indirectly accesses the same counters. However, ocelot_get_stats64() runs in atomic context, and we cannot simply take the sleepable ocelot->stats_lock mutex. We need to convert it to an atomic spinlock first. Do that as a preparatory change.
--- drivers/net/dsa/ocelot/felix_vsc9959.c | 4 ++-- drivers/net/ethernet/mscc/ocelot.c | 11 +++++------ include/soc/mscc/ocelot.h | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-)
drivers/net/dsa/ocelot/felix_vsc9959.c +2 -2
@@ -2177,7 +2177,7 @@ static void vsc9959_psfp_sgi_table_del(struct ocelot *ocelot,static void vsc9959_psfp_counters_get (struct ocelot *ocelot,u32 index,struct felix_stream_filter_counters *counters) { -mutex_lock (&ocelot->stats_lock); +spin_lock (&ocelot->stats_lock); ocelot_rmw(ocelot, SYS_STAT_CFG_STAT_VIEW(index), SYS_STAT_CFG_STAT_VIEW_M,
@@ -2194,7 +2194,7 @@ static void vsc9959_psfp_counters_get(struct ocelot *ocelot, u32 index,SYS_STAT_CFG_STAT_CLEAR_SHOT (0x10 ), SYS_STAT_CFG); -mutex_unlock (&ocelot->stats_lock); +spin_unlock (&ocelot->stats_lock); } static int vsc9959_psfp_filter_add(struct ocelot *ocelot, int port,
drivers/net/ethernet/mscc/ocelot.c +5 -6
@@ -1906,13 +1906,13 @@ static void ocelot_check_stats_work(struct work_struct *work) stats_work);int i, err; -mutex_lock (&ocelot->stats_lock); +spin_lock (&ocelot->stats_lock);for (i =0 ; i < ocelot->num_phys_ports; i++) { err =ocelot_port_update_stats (ocelot, i);if (err)break ; } -mutex_unlock (&ocelot->stats_lock); +spin_unlock (&ocelot->stats_lock);if (err)dev_err (ocelot->dev,"Error %d updating ethtool stats\n" , err);
@@ -1925,7 +1925,7 @@ void ocelot_get_ethtool_stats(struct ocelot *ocelot, int port, u64 *data) {int i, err; -mutex_lock (&ocelot->stats_lock); +spin_lock (&ocelot->stats_lock);/* check and update now */ err =ocelot_port_update_stats (ocelot, port);
@@ -1934,7 +1934,7 @@ void ocelot_get_ethtool_stats(struct ocelot *ocelot, int port, u64 *data)for (i =0 ; i < ocelot->num_stats; i++) *data++ = ocelot->stats[port * ocelot->num_stats + i]; -mutex_unlock (&ocelot->stats_lock); +spin_unlock (&ocelot->stats_lock);if (err)dev_err (ocelot->dev,"Error %d updating ethtool stats\n" , err);
@@ -3363,7 +3363,7 @@ int ocelot_init(struct ocelot *ocelot)if (!ocelot->stats)return -ENOMEM ; -mutex_init (&ocelot->stats_lock); +spin_lock_init (&ocelot->stats_lock);mutex_init (&ocelot->ptp_lock);mutex_init (&ocelot->mact_lock);mutex_init (&ocelot->fwd_domain_lock);
@@ -3511,7 +3511,6 @@ void ocelot_deinit(struct ocelot *ocelot)cancel_delayed_work (&ocelot->stats_work);destroy_workqueue (ocelot->stats_queue);destroy_workqueue (ocelot->owq); -mutex_destroy (&ocelot->stats_lock); }EXPORT_SYMBOL (ocelot_deinit);
include/soc/mscc/ocelot.h +1 -1
@@ -752,7 +752,7 @@ struct ocelot {struct ocelot_psfp_list psfp;/* Workqueue to check statistics for overflow with its lock */ -struct mutex stats_lock; +spinlock_t stats_lock;u64 *stats;struct delayed_work stats_work;struct workqueue_struct *stats_queue;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 252/365 net: mscc: ocelot: fix race between ndo_get_stats64 and ocelot_check_stats_work
In reply to Greg Kroah-HartmanFrom: Vladimir Oltean <[email protected]>
[ Upstream commit 18d8e67df184081bc6ce6220a2dd965cfd3d7e6b ]
The 2 methods can run concurrently, and one will change the window of counters (SYS_STAT_CFG_STAT_VIEW) that the other sees. The fix is similar to what commit 7fbf6795d127 ("net: mscc: ocelot: fix mutex lock error during ethtool stats read") has done for ethtool -S.
--- drivers/net/ethernet/mscc/ocelot_net.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/net/ethernet/mscc/ocelot_net.c +4 -0
@@ -726,6 +726,8 @@ static void ocelot_get_stats64(struct net_device *dev,struct ocelot *ocelot = priv->port.ocelot;int port = priv->port.index; +spin_lock (&ocelot->stats_lock); +/* Configure the port to read the stats from */ ocelot_write (ocelot,SYS_STAT_CFG_STAT_VIEW (port),SYS_STAT_CFG );
@@ -758,6 +760,8 @@ static void ocelot_get_stats64(struct net_device *dev, stats->tx_dropped =ocelot_read (ocelot,SYS_COUNT_TX_DROPS ) +ocelot_read (ocelot,SYS_COUNT_TX_AGING ); stats->collisions =ocelot_read (ocelot,SYS_COUNT_TX_COLLISION ); + +spin_unlock (&ocelot->stats_lock); } static int ocelot_port_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 253/365 net: mscc: ocelot: make struct ocelot_stat_layout array indexable
In reply to Greg Kroah-HartmanFrom: Vladimir Oltean <[email protected]>
[ Upstream commit 9190460084ddd0e9235f55eab0fdd5456b5f2fd5 ]
The ocelot counters are 32-bit and require periodic reading, every 2 seconds, by ocelot_port_update_stats(), so that wraparounds are detected.
Currently, the counters reported by ocelot_get_stats64() come from the 32-bit hardware counters directly, rather than from the 64-bit accumulated ocelot->stats, and this is a problem for their integrity.
The strategy is to make ocelot_get_stats64() able to cherry-pick individual stats from ocelot->stats the way in which it currently reads them out from SYS_COUNT_* registers. But currently it can't, because ocelot->stats is an opaque u64 array that's used only to feed data into ethtool -S.
To solve that problem, we need to make ocelot->stats indexable, and associate each element with an element of struct ocelot_stat_layout used by ethtool -S.
This makes ocelot_stat_layout a fat (and possibly sparse) array, so we need to change the way in which we access it. We no longer need OCELOT_STAT_END as a sentinel, because we know the array's size (OCELOT_NUM_STATS). We just need to skip the array elements that were left unpopulated for the switch revision (ocelot, felix, seville).
--- drivers/net/dsa/ocelot/felix_vsc9959.c | 468 ++++++++++++++++----- drivers/net/dsa/ocelot/seville_vsc9953.c | 468 ++++++++++++++++----- drivers/net/ethernet/mscc/ocelot.c | 40 +- drivers/net/ethernet/mscc/ocelot_vsc7514.c | 468 ++++++++++++++++----- include/soc/mscc/ocelot.h | 105 ++++- 5 files changed, 1243 insertions(+), 306 deletions(-)
drivers/net/dsa/ocelot/felix_vsc9959.c +373 -95
@@ -550,101 +550,379 @@ static const struct reg_field vsc9959_regfields[REGFIELD_MAX] = { [SYS_PAUSE_CFG_PAUSE_ENA] = REG_FIELD_ID(SYS_PAUSE_CFG, 0, 1, 7, 4), }; -static const struct ocelot_stat_layout vsc9959_stats_layout[] = { - { .offset =0x00 , .name ="rx_octets" , }, - { .offset =0x01 , .name ="rx_unicast" , }, - { .offset =0x02 , .name ="rx_multicast" , }, - { .offset =0x03 , .name ="rx_broadcast" , }, - { .offset =0x04 , .name ="rx_shorts" , }, - { .offset =0x05 , .name ="rx_fragments" , }, - { .offset =0x06 , .name ="rx_jabbers" , }, - { .offset =0x07 , .name ="rx_crc_align_errs" , }, - { .offset =0x08 , .name ="rx_sym_errs" , }, - { .offset =0x09 , .name ="rx_frames_below_65_octets" , }, - { .offset =0x0A , .name ="rx_frames_65_to_127_octets" , }, - { .offset =0x0B , .name ="rx_frames_128_to_255_octets" , }, - { .offset =0x0C , .name ="rx_frames_256_to_511_octets" , }, - { .offset =0x0D , .name ="rx_frames_512_to_1023_octets" , }, - { .offset =0x0E , .name ="rx_frames_1024_to_1526_octets" , }, - { .offset =0x0F , .name ="rx_frames_over_1526_octets" , }, - { .offset =0x10 , .name ="rx_pause" , }, - { .offset =0x11 , .name ="rx_control" , }, - { .offset =0x12 , .name ="rx_longs" , }, - { .offset =0x13 , .name ="rx_classified_drops" , }, - { .offset =0x14 , .name ="rx_red_prio_0" , }, - { .offset =0x15 , .name ="rx_red_prio_1" , }, - { .offset =0x16 , .name ="rx_red_prio_2" , }, - { .offset =0x17 , .name ="rx_red_prio_3" , }, - { .offset =0x18 , .name ="rx_red_prio_4" , }, - { .offset =0x19 , .name ="rx_red_prio_5" , }, - { .offset =0x1A , .name ="rx_red_prio_6" , }, - { .offset =0x1B , .name ="rx_red_prio_7" , }, - { .offset =0x1C , .name ="rx_yellow_prio_0" , }, - { .offset =0x1D , .name ="rx_yellow_prio_1" , }, - { .offset =0x1E , .name ="rx_yellow_prio_2" , }, - { .offset =0x1F , .name ="rx_yellow_prio_3" , }, - { .offset =0x20 , .name ="rx_yellow_prio_4" , }, - { .offset =0x21 , .name ="rx_yellow_prio_5" , }, - { .offset =0x22 , .name ="rx_yellow_prio_6" , }, - { .offset =0x23 , .name ="rx_yellow_prio_7" , }, - { .offset =0x24 , .name ="rx_green_prio_0" , }, - { .offset =0x25 , .name ="rx_green_prio_1" , }, - { .offset =0x26 , .name ="rx_green_prio_2" , }, - { .offset =0x27 , .name ="rx_green_prio_3" , }, - { .offset =0x28 , .name ="rx_green_prio_4" , }, - { .offset =0x29 , .name ="rx_green_prio_5" , }, - { .offset =0x2A , .name ="rx_green_prio_6" , }, - { .offset =0x2B , .name ="rx_green_prio_7" , }, - { .offset =0x80 , .name ="tx_octets" , }, - { .offset =0x81 , .name ="tx_unicast" , }, - { .offset =0x82 , .name ="tx_multicast" , }, - { .offset =0x83 , .name ="tx_broadcast" , }, - { .offset =0x84 , .name ="tx_collision" , }, - { .offset =0x85 , .name ="tx_drops" , }, - { .offset =0x86 , .name ="tx_pause" , }, - { .offset =0x87 , .name ="tx_frames_below_65_octets" , }, - { .offset =0x88 , .name ="tx_frames_65_to_127_octets" , }, - { .offset =0x89 , .name ="tx_frames_128_255_octets" , }, - { .offset =0x8A , .name ="tx_frames_256_511_octets" , }, - { .offset =0x8B , .name ="tx_frames_512_1023_octets" , }, - { .offset =0x8C , .name ="tx_frames_1024_1526_octets" , }, - { .offset =0x8D , .name ="tx_frames_over_1526_octets" , }, - { .offset =0x8E , .name ="tx_yellow_prio_0" , }, - { .offset =0x8F , .name ="tx_yellow_prio_1" , }, - { .offset =0x90 , .name ="tx_yellow_prio_2" , }, - { .offset =0x91 , .name ="tx_yellow_prio_3" , }, - { .offset =0x92 , .name ="tx_yellow_prio_4" , }, - { .offset =0x93 , .name ="tx_yellow_prio_5" , }, - { .offset =0x94 , .name ="tx_yellow_prio_6" , }, - { .offset =0x95 , .name ="tx_yellow_prio_7" , }, - { .offset =0x96 , .name ="tx_green_prio_0" , }, - { .offset =0x97 , .name ="tx_green_prio_1" , }, - { .offset =0x98 , .name ="tx_green_prio_2" , }, - { .offset =0x99 , .name ="tx_green_prio_3" , }, - { .offset =0x9A , .name ="tx_green_prio_4" , }, - { .offset =0x9B , .name ="tx_green_prio_5" , }, - { .offset =0x9C , .name ="tx_green_prio_6" , }, - { .offset =0x9D , .name ="tx_green_prio_7" , }, - { .offset =0x9E , .name ="tx_aged" , }, - { .offset =0x100 , .name ="drop_local" , }, - { .offset =0x101 , .name ="drop_tail" , }, - { .offset =0x102 , .name ="drop_yellow_prio_0" , }, - { .offset =0x103 , .name ="drop_yellow_prio_1" , }, - { .offset =0x104 , .name ="drop_yellow_prio_2" , }, - { .offset =0x105 , .name ="drop_yellow_prio_3" , }, - { .offset =0x106 , .name ="drop_yellow_prio_4" , }, - { .offset =0x107 , .name ="drop_yellow_prio_5" , }, - { .offset =0x108 , .name ="drop_yellow_prio_6" , }, - { .offset =0x109 , .name ="drop_yellow_prio_7" , }, - { .offset =0x10A , .name ="drop_green_prio_0" , }, - { .offset =0x10B , .name ="drop_green_prio_1" , }, - { .offset =0x10C , .name ="drop_green_prio_2" , }, - { .offset =0x10D , .name ="drop_green_prio_3" , }, - { .offset =0x10E , .name ="drop_green_prio_4" , }, - { .offset =0x10F , .name ="drop_green_prio_5" , }, - { .offset =0x110 , .name ="drop_green_prio_6" , }, - { .offset =0x111 , .name ="drop_green_prio_7" , }, -OCELOT_STAT_END +static const struct ocelot_stat_layout vsc9959_stats_layout[OCELOT_NUM_STATS ] = { + [OCELOT_STAT_RX_OCTETS ] = { + .name ="rx_octets" , + .offset =0x00 , + }, + [OCELOT_STAT_RX_UNICAST ] = { + .name ="rx_unicast" , + .offset =0x01 , + }, + [OCELOT_STAT_RX_MULTICAST ] = { + .name ="rx_multicast" , + .offset =0x02 , + }, + [OCELOT_STAT_RX_BROADCAST ] = { + .name ="rx_broadcast" , + .offset =0x03 , + }, + [OCELOT_STAT_RX_SHORTS ] = { + .name ="rx_shorts" , + .offset =0x04 , + }, + [OCELOT_STAT_RX_FRAGMENTS ] = { + .name ="rx_fragments" , + .offset =0x05 , + }, + [OCELOT_STAT_RX_JABBERS ] = { + .name ="rx_jabbers" , + .offset =0x06 , + }, + [OCELOT_STAT_RX_CRC_ALIGN_ERRS ] = { + .name ="rx_crc_align_errs" , + .offset =0x07 , + }, + [OCELOT_STAT_RX_SYM_ERRS ] = { + .name ="rx_sym_errs" , + .offset =0x08 , + }, + [OCELOT_STAT_RX_64 ] = { + .name ="rx_frames_below_65_octets" , + .offset =0x09 , + }, + [OCELOT_STAT_RX_65_127 ] = { + .name ="rx_frames_65_to_127_octets" , + .offset =0x0A , + }, + [OCELOT_STAT_RX_128_255 ] = { + .name ="rx_frames_128_to_255_octets" , + .offset =0x0B , + }, + [OCELOT_STAT_RX_256_511 ] = { + .name ="rx_frames_256_to_511_octets" , + .offset =0x0C , + }, + [OCELOT_STAT_RX_512_1023 ] = { + .name ="rx_frames_512_to_1023_octets" , + .offset =0x0D , + }, + [OCELOT_STAT_RX_1024_1526 ] = { + .name ="rx_frames_1024_to_1526_octets" , + .offset =0x0E , + }, + [OCELOT_STAT_RX_1527_MAX ] = { + .name ="rx_frames_over_1526_octets" , + .offset =0x0F , + }, + [OCELOT_STAT_RX_PAUSE ] = { + .name ="rx_pause" , + .offset =0x10 , + }, + [OCELOT_STAT_RX_CONTROL ] = { + .name ="rx_control" , + .offset =0x11 , + }, + [OCELOT_STAT_RX_LONGS ] = { + .name ="rx_longs" , + .offset =0x12 , + }, + [OCELOT_STAT_RX_CLASSIFIED_DROPS ] = { + .name ="rx_classified_drops" , + .offset =0x13 , + }, + [OCELOT_STAT_RX_RED_PRIO_0 ] = { + .name ="rx_red_prio_0" , + .offset =0x14 , + }, + [OCELOT_STAT_RX_RED_PRIO_1 ] = { + .name ="rx_red_prio_1" , + .offset =0x15 , + }, + [OCELOT_STAT_RX_RED_PRIO_2 ] = { + .name ="rx_red_prio_2" , + .offset =0x16 , + }, + [OCELOT_STAT_RX_RED_PRIO_3 ] = { + .name ="rx_red_prio_3" , + .offset =0x17 , + }, + [OCELOT_STAT_RX_RED_PRIO_4 ] = { + .name ="rx_red_prio_4" , + .offset =0x18 , + }, + [OCELOT_STAT_RX_RED_PRIO_5 ] = { + .name ="rx_red_prio_5" , + .offset =0x19 , + }, + [OCELOT_STAT_RX_RED_PRIO_6 ] = { + .name ="rx_red_prio_6" , + .offset =0x1A , + }, + [OCELOT_STAT_RX_RED_PRIO_7 ] = { + .name ="rx_red_prio_7" , + .offset =0x1B , + }, + [OCELOT_STAT_RX_YELLOW_PRIO_0 ] = { + .name ="rx_yellow_prio_0" , + .offset =0x1C , + }, + [OCELOT_STAT_RX_YELLOW_PRIO_1 ] = { + .name ="rx_yellow_prio_1" , + .offset =0x1D , + }, + [OCELOT_STAT_RX_YELLOW_PRIO_2 ] = { + .name ="rx_yellow_prio_2" , + .offset =0x1E , + }, + [OCELOT_STAT_RX_YELLOW_PRIO_3 ] = { + .name ="rx_yellow_prio_3" , + .offset =0x1F , + }, + [OCELOT_STAT_RX_YELLOW_PRIO_4 ] = { + .name ="rx_yellow_prio_4" , + .offset =0x20 , + }, + [OCELOT_STAT_RX_YELLOW_PRIO_5 ] = { + .name ="rx_yellow_prio_5" , + .offset =0x21 , + }, + [OCELOT_STAT_RX_YELLOW_PRIO_6 ] = { + .name ="rx_yellow_prio_6" , + .offset =0x22 , + }, + [OCELOT_STAT_RX_YELLOW_PRIO_7 ] = { + .name ="rx_yellow_prio_7" , + .offset =0x23 , + }, + [OCELOT_STAT_RX_GREEN_PRIO_0 ] = { + .name ="rx_green_prio_0" , + .offset =0x24 , + }, + [OCELOT_STAT_RX_GREEN_PRIO_1 ] = { + .name ="rx_green_prio_1" , + .offset =0x25 , + }, + [OCELOT_STAT_RX_GREEN_PRIO_2 ] = { + .name ="rx_green_prio_2" , + .offset =0x26 , + }, + [OCELOT_STAT_RX_GREEN_PRIO_3 ] = { + .name ="rx_green_prio_3" , + .offset =0x27 , + }, + [OCELOT_STAT_RX_GREEN_PRIO_4 ] = { + .name ="rx_green_prio_4" , + .offset =0x28 , + }, + [OCELOT_STAT_RX_GREEN_PRIO_5 ] = { + .name ="rx_green_prio_5" , + .offset =0x29 , + }, + [OCELOT_STAT_RX_GREEN_PRIO_6 ] = { + .name ="rx_green_prio_6" , + .offset =0x2A , + }, + [OCELOT_STAT_RX_GREEN_PRIO_7 ] = { + .name ="rx_green_prio_7" , + .offset =0x2B , + }, + [OCELOT_STAT_TX_OCTETS ] = { + .name ="tx_octets" , + .offset =0x80 , + }, + [OCELOT_STAT_TX_UNICAST ] = { + .name ="tx_unicast" , + .offset =0x81 , + }, + [OCELOT_STAT_TX_MULTICAST ] = { + .name ="tx_multicast" , + .offset =0x82 , + }, + [OCELOT_STAT_TX_BROADCAST ] = { + .name ="tx_broadcast" , + .offset =0x83 , + }, + [OCELOT_STAT_TX_COLLISION ] = { + .name ="tx_collision" , + .offset =0x84 , + }, + [OCELOT_STAT_TX_DROPS ] = { + .name ="tx_drops" , + .offset =0x85 , + }, + [OCELOT_STAT_TX_PAUSE ] = { + .name ="tx_pause" , + .offset =0x86 , + }, + [OCELOT_STAT_TX_64 ] = { + .name ="tx_frames_below_65_octets" , + .offset =0x87 , + }, + [OCELOT_STAT_TX_65_127 ] = { + .name ="tx_frames_65_to_127_octets" , + .offset =0x88 , + }, + [OCELOT_STAT_TX_128_255 ] = { + .name ="tx_frames_128_255_octets" , + .offset =0x89 , + }, + [OCELOT_STAT_TX_256_511 ] = { + .name ="tx_frames_256_511_octets" , + .offset =0x8A , + }, + [OCELOT_STAT_TX_512_1023 ] = { + .name ="tx_frames_512_1023_octets" , + .offset =0x8B , + }, + [OCELOT_STAT_TX_1024_1526 ] = { + .name ="tx_frames_1024_1526_octets" , + .offset =0x8C , + }, + [OCELOT_STAT_TX_1527_MAX ] = { + .name ="tx_frames_over_1526_octets" , + .offset =0x8D , + }, + [OCELOT_STAT_TX_YELLOW_PRIO_0 ] = { + .name ="tx_yellow_prio_0" , + .offset =0x8E , + }, + [OCELOT_STAT_TX_YELLOW_PRIO_1 ] = { + .name ="tx_yellow_prio_1" , + .offset =0x8F , + }, + [OCELOT_STAT_TX_YELLOW_PRIO_2 ] = { + .name ="tx_yellow_prio_2" , + .offset =0x90 , + }, + [OCELOT_STAT_TX_YELLOW_PRIO_3 ] = { + .name ="tx_yellow_prio_3" , + .offset =0x91 , + }, + [OCELOT_STAT_TX_YELLOW_PRIO_4 ] = { + .name ="tx_yellow_prio_4" , + .offset =0x92 , + }, + [OCELOT_STAT_TX_YELLOW_PRIO_5 ] = { + .name ="tx_yellow_prio_5" , + .offset =0x93 , + }, + [OCELOT_STAT_TX_YELLOW_PRIO_6 ] = { + .name ="tx_yellow_prio_6" , + .offset =0x94 , + }, + [OCELOT_STAT_TX_YELLOW_PRIO_7 ] = { + .name ="tx_yellow_prio_7" , + .offset =0x95 , + }, + [OCELOT_STAT_TX_GREEN_PRIO_0 ] = { + .name ="tx_green_prio_0" , + .offset =0x96 , + }, + [OCELOT_STAT_TX_GREEN_PRIO_1 ] = { + .name ="tx_green_prio_1" , + .offset =0x97 , + }, + [OCELOT_STAT_TX_GREEN_PRIO_2 ] = { + .name ="tx_green_prio_2" , + .offset =0x98 , + }, + [OCELOT_STAT_TX_GREEN_PRIO_3 ] = { + .name ="tx_green_prio_3" , + .offset =0x99 , + }, + [OCELOT_STAT_TX_GREEN_PRIO_4 ] = { + .name ="tx_green_prio_4" , + .offset =0x9A , + }, + [OCELOT_STAT_TX_GREEN_PRIO_5 ] = { + .name ="tx_green_prio_5" , + .offset =0x9B , + }, + [OCELOT_STAT_TX_GREEN_PRIO_6 ] = { + .name ="tx_green_prio_6" , + .offset =0x9C , + }, + [OCELOT_STAT_TX_GREEN_PRIO_7 ] = { + .name ="tx_green_prio_7" , + .offset =0x9D , + }, + [OCELOT_STAT_TX_AGED ] = { + .name ="tx_aged" , + .offset =0x9E , + }, + [OCELOT_STAT_DROP_LOCAL ] = { + .name ="drop_local" , + .offset =0x100 , + }, + [OCELOT_STAT_DROP_TAIL ] = { + .name ="drop_tail" , + .offset =0x101 , + }, + [OCELOT_STAT_DROP_YELLOW_PRIO_0 ] = { + .name ="drop_yellow_prio_0" , + .offset =0x102 , + }, + [OCELOT_STAT_DROP_YELLOW_PRIO_1 ] = { + .name ="drop_yellow_prio_1" , + .offset =0x103 , + }, + [OCELOT_STAT_DROP_YELLOW_PRIO_2 ] = { + .name ="drop_yellow_prio_2" , + .offset =0x104 , + }, + [OCELOT_STAT_DROP_YELLOW_PRIO_3 ] = { + .name ="drop_yellow_prio_3" , + .offset =0x105 , + }, + [OCELOT_STAT_DROP_YELLOW_PRIO_4 ] = { + .name ="drop_yellow_prio_4" , + .offset =0x106 , + }, + [OCELOT_STAT_DROP_YELLOW_PRIO_5 ] = { + .name ="drop_yellow_prio_5" , + .offset =0x107 , + }, + [OCELOT_STAT_DROP_YELLOW_PRIO_6 ] = { + .name ="drop_yellow_prio_6" , + .offset =0x108 , + }, + [OCELOT_STAT_DROP_YELLOW_PRIO_7 ] = { + .name ="drop_yellow_prio_7" , + .offset =0x109 , + }, + [OCELOT_STAT_DROP_GREEN_PRIO_0 ] = { + .name ="drop_green_prio_0" , + .offset =0x10A , + }, + [OCELOT_STAT_DROP_GREEN_PRIO_1 ] = { + .name ="drop_green_prio_1" , + .offset =0x10B , + }, + [OCELOT_STAT_DROP_GREEN_PRIO_2 ] = { + .name ="drop_green_prio_2" , + .offset =0x10C , + }, + [OCELOT_STAT_DROP_GREEN_PRIO_3 ] = { + .name ="drop_green_prio_3" , + .offset =0x10D , + }, + [OCELOT_STAT_DROP_GREEN_PRIO_4 ] = { + .name ="drop_green_prio_4" , + .offset =0x10E , + }, + [OCELOT_STAT_DROP_GREEN_PRIO_5 ] = { + .name ="drop_green_prio_5" , + .offset =0x10F , + }, + [OCELOT_STAT_DROP_GREEN_PRIO_6 ] = { + .name ="drop_green_prio_6" , + .offset =0x110 , + }, + [OCELOT_STAT_DROP_GREEN_PRIO_7 ] = { + .name ="drop_green_prio_7" , + .offset =0x111 , + }, };static const struct vcap_field vsc9959_vcap_es0_keys[] = {
drivers/net/dsa/ocelot/seville_vsc9953.c +373 -95
474 lines not on this page · raw message
drivers/net/ethernet/mscc/ocelot.c +27 -13
@@ -1860,16 +1860,20 @@ void ocelot_get_strings(struct ocelot *ocelot, int port, u32 sset, u8 *data)if (sset !=ETH_SS_STATS )return ; -for (i =0 ; i < ocelot->num_stats; i++) +for (i =0 ; i <OCELOT_NUM_STATS ; i++) { +if (ocelot->stats_layout[i].name[0 ] =='\0' ) +continue ; +memcpy (data + i *ETH_GSTRING_LEN , ocelot->stats_layout[i].name,ETH_GSTRING_LEN ); + } }EXPORT_SYMBOL (ocelot_get_strings);/* Caller must hold &ocelot->stats_lock */ static int ocelot_port_update_stats (struct ocelot *ocelot,int port) { -unsigned int idx = port * ocelot->num_stats; +unsigned int idx = port *OCELOT_NUM_STATS ;struct ocelot_stats_region *region;int err, j;
@@ -1930,9 +1934,15 @@ void ocelot_get_ethtool_stats(struct ocelot *ocelot, int port, u64 *data)/* check and update now */ err =ocelot_port_update_stats (ocelot, port); -/* Copy all counters */ -for (i =0 ; i < ocelot->num_stats; i++) - *data++ = ocelot->stats[port * ocelot->num_stats + i]; +/* Copy all supported counters */ +for (i =0 ; i <OCELOT_NUM_STATS ; i++) { +int index = port *OCELOT_NUM_STATS + i; + +if (ocelot->stats_layout[i].name[0 ] =='\0' ) +continue ; + + *data++ = ocelot->stats[index]; + }spin_unlock (&ocelot->stats_lock);
@@ -1943,10 +1953,16 @@ EXPORT_SYMBOL(ocelot_get_ethtool_stats);int ocelot_get_sset_count (struct ocelot *ocelot,int port,int sset) { +int i, num_stats =0 ; +if (sset !=ETH_SS_STATS )return -EOPNOTSUPP ; -return ocelot->num_stats; +for (i =0 ; i <OCELOT_NUM_STATS ; i++) +if (ocelot->stats_layout[i].name[0 ] !='\0' ) + num_stats++; + +return num_stats; }EXPORT_SYMBOL (ocelot_get_sset_count);
@@ -1958,7 +1974,10 @@ static int ocelot_prepare_stats_regions(struct ocelot *ocelot)INIT_LIST_HEAD (&ocelot->stats_regions); -for (i =0 ; i < ocelot->num_stats; i++) { +for (i =0 ; i <OCELOT_NUM_STATS ; i++) { +if (ocelot->stats_layout[i].name[0 ] =='\0' ) +continue ; +if (region && ocelot->stats_layout[i].offset == last +1 ) { region->count++; }else {
@@ -3340,7 +3359,6 @@ static void ocelot_detect_features(struct ocelot *ocelot)int ocelot_init (struct ocelot *ocelot) { -const struct ocelot_stat_layout *stat;char queue_name[32 ];int i, ret;u32 port;
@@ -3353,12 +3371,8 @@ int ocelot_init(struct ocelot *ocelot) } } - ocelot->num_stats =0 ; -for_each_stat (ocelot, stat) - ocelot->num_stats++; - ocelot->stats =devm_kcalloc (ocelot->dev, - ocelot->num_phys_ports * ocelot->num_stats, + ocelot->num_phys_ports *OCELOT_NUM_STATS ,sizeof (u64),GFP_KERNEL );if (!ocelot->stats)return -ENOMEM ;
drivers/net/ethernet/mscc/ocelot_vsc7514.c +373 -95
474 lines not on this page · raw message
include/soc/mscc/ocelot.h +97 -8
128 lines not on this page · raw message
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 254/365 net: mscc: ocelot: report ndo_get_stats64 from the wraparound-resistant ocelot->stats
In reply to Greg Kroah-HartmanFrom: Vladimir Oltean <[email protected]>
[ Upstream commit e780e3193e889fd8358b862f7cd18ec5a4901caf ]
Rather than reading the stats64 counters directly from the 32-bit hardware, it's better to rely on the output produced by the periodic ocelot_port_update_stats().
It would be even better to call ocelot_port_update_stats() right from ocelot_get_stats64() to make sure we report the current values rather than the ones from 2 seconds ago. But we need to export ocelot_port_update_stats() from the switch lib towards the switchdev driver for that, and future work will largely undo that.
There are more ocelot-based drivers waiting to be introduced, an example of which is the SPI-controlled VSC7512. In that driver's case, it will be impossible to call ocelot_port_update_stats() from ndo_get_stats64 context, since the latter is atomic, and reading the stats over SPI is sleepable. So the compromise taken here, which will also hold going forward, is to report 64-bit counters to stats64, which are not 100% up to date.
--- drivers/net/ethernet/mscc/ocelot_net.c | 53 +++++++++++++------------- 1 file changed, 26 insertions(+), 27 deletions(-)
drivers/net/ethernet/mscc/ocelot_net.c +26 -27
@@ -725,41 +725,40 @@ static void ocelot_get_stats64(struct net_device *dev,struct ocelot_port_private *priv =netdev_priv (dev);struct ocelot *ocelot = priv->port.ocelot;int port = priv->port.index; +u64 *s;spin_lock (&ocelot->stats_lock); -/* Configure the port to read the stats from */ -ocelot_write (ocelot,SYS_STAT_CFG_STAT_VIEW (port), -SYS_STAT_CFG ); + s = &ocelot->stats[port *OCELOT_NUM_STATS ];/* Get Rx stats */ - stats->rx_bytes =ocelot_read (ocelot,SYS_COUNT_RX_OCTETS ); - stats->rx_packets =ocelot_read (ocelot,SYS_COUNT_RX_SHORTS ) + -ocelot_read (ocelot,SYS_COUNT_RX_FRAGMENTS ) + -ocelot_read (ocelot,SYS_COUNT_RX_JABBERS ) + -ocelot_read (ocelot,SYS_COUNT_RX_LONGS ) + -ocelot_read (ocelot,SYS_COUNT_RX_64 ) + -ocelot_read (ocelot,SYS_COUNT_RX_65_127 ) + -ocelot_read (ocelot,SYS_COUNT_RX_128_255 ) + -ocelot_read (ocelot,SYS_COUNT_RX_256_511 ) + -ocelot_read (ocelot,SYS_COUNT_RX_512_1023 ) + -ocelot_read (ocelot,SYS_COUNT_RX_1024_1526 ) + -ocelot_read (ocelot,SYS_COUNT_RX_1527_MAX ); - stats->multicast =ocelot_read (ocelot,SYS_COUNT_RX_MULTICAST ); + stats->rx_bytes = s[OCELOT_STAT_RX_OCTETS ]; + stats->rx_packets = s[OCELOT_STAT_RX_SHORTS ] + + s[OCELOT_STAT_RX_FRAGMENTS ] + + s[OCELOT_STAT_RX_JABBERS ] + + s[OCELOT_STAT_RX_LONGS ] + + s[OCELOT_STAT_RX_64 ] + + s[OCELOT_STAT_RX_65_127 ] + + s[OCELOT_STAT_RX_128_255 ] + + s[OCELOT_STAT_RX_256_511 ] + + s[OCELOT_STAT_RX_512_1023 ] + + s[OCELOT_STAT_RX_1024_1526 ] + + s[OCELOT_STAT_RX_1527_MAX ]; + stats->multicast = s[OCELOT_STAT_RX_MULTICAST ]; stats->rx_dropped = dev->stats.rx_dropped;/* Get Tx stats */ - stats->tx_bytes =ocelot_read (ocelot,SYS_COUNT_TX_OCTETS ); - stats->tx_packets =ocelot_read (ocelot,SYS_COUNT_TX_64 ) + -ocelot_read (ocelot,SYS_COUNT_TX_65_127 ) + -ocelot_read (ocelot,SYS_COUNT_TX_128_255 ) + -ocelot_read (ocelot,SYS_COUNT_TX_256_511 ) + -ocelot_read (ocelot,SYS_COUNT_TX_512_1023 ) + -ocelot_read (ocelot,SYS_COUNT_TX_1024_1526 ) + -ocelot_read (ocelot,SYS_COUNT_TX_1527_MAX ); - stats->tx_dropped =ocelot_read (ocelot,SYS_COUNT_TX_DROPS ) + -ocelot_read (ocelot,SYS_COUNT_TX_AGING ); - stats->collisions =ocelot_read (ocelot,SYS_COUNT_TX_COLLISION ); + stats->tx_bytes = s[OCELOT_STAT_TX_OCTETS ]; + stats->tx_packets = s[OCELOT_STAT_TX_64 ] + + s[OCELOT_STAT_TX_65_127 ] + + s[OCELOT_STAT_TX_128_255 ] + + s[OCELOT_STAT_TX_256_511 ] + + s[OCELOT_STAT_TX_512_1023 ] + + s[OCELOT_STAT_TX_1024_1526 ] + + s[OCELOT_STAT_TX_1527_MAX ]; + stats->tx_dropped = s[OCELOT_STAT_TX_DROPS ] + + s[OCELOT_STAT_TX_AGED ]; + stats->collisions = s[OCELOT_STAT_TX_COLLISION ];spin_unlock (&ocelot->stats_lock); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 255/365 x86/ibt, objtool: Add IBT_NOSEAL()
In reply to Greg Kroah-HartmanFrom: Josh Poimboeuf <[email protected]>
[ Upstream commit e27e5bea956ce4d3eb15112de5fa5a3b77c2f488 ]
Add a macro which prevents a function from getting sealed if there are no compile-time references to it.
Message-Id: <20220818213927.e44fmxkoq4yj6ybn@treble>
--- arch/x86/include/asm/ibt.h | 11 +++++++++++ tools/objtool/check.c | 3 ++- 2 files changed, 13 insertions(+), 1 deletion(-)
arch/x86/include/asm/ibt.h +11 -0
@@ -31,6 +31,16 @@#define __noendbr __attribute__((nocf_check)) +/* +* Create a dummy function pointer reference to prevent objtool from marking +* the function as needing to be "sealed" (i.e. ENDBR converted to NOP by +* apply_ibt_endbr()). +*/ +#define IBT_NOSEAL (fname) \ + ".pushsection .discard.ibt_endbr_noseal\n\t" \ + _ASM_PTR fname "\n\t" \ + ".popsection\n\t" + static inline __attribute_const__ u32 gen_endbr(void) {u32 endbr;
@@ -84,6 +94,7 @@ extern __noendbr void ibt_restore(u64 save);#ifndef __ASSEMBLY__#define ASM_ENDBR +#define IBT_NOSEAL (name)#define __noendbr
tools/objtool/check.c +2 -1
@@ -4096,7 +4096,8 @@ static int validate_ibt(struct objtool_file *file)* These sections can reference text addresses, but not with * the intent to indirect branch to them. */ - if (!strncmp(sec->name, ".discard", 8) || + if ((!strncmp(sec->name, ".discard", 8) && + strcmp(sec->name, ".discard.ibt_endbr_noseal")) || !strncmp(sec->name, ".debug", 6) || !strcmp(sec->name, ".altinstructions") || !strcmp(sec->name, ".ibt_endbr_seal") ||
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 256/365 x86/kvm: Fix "missing ENDBR" BUG for fastop functions
In reply to Greg Kroah-HartmanFrom: Josh Poimboeuf <[email protected]>
[ Upstream commit 3d9606b0e0f3aed4dfb61d0853ebf432fead7bba ]
The following BUG was reported:
traps: Missing ENDBR: andw_ax_dx+0x0/0x10 [kvm]
------------[ cut here ]------------
kernel BUG at arch/x86/kernel/traps.c:253!
invalid opcode: 0000 [#1] PREEMPT SMP NOPTI
<TASK>
asm_exc_control_protection+0x2b/0x30
RIP: 0010:andw_ax_dx+0x0/0x10 [kvm]
Code: c3 cc cc cc cc 0f 1f 44 00 00 66 0f 1f 00 48 19 d0 c3 cc cc cc
cc 0f 1f 40 00 f3 0f 1e fa 20 d0 c3 cc cc cc cc 0f 1f 44 00 00
<66> 0f 1f 00 66 21 d0 c3 cc cc cc cc 0f 1f 40 00 66 0f 1f 00 21
d0
? andb_al_dl+0x10/0x10 [kvm]
? fastop+0x5d/0xa0 [kvm]
x86_emulate_insn+0x822/0x1060 [kvm]
x86_emulate_instruction+0x46f/0x750 [kvm]
complete_emulated_mmio+0x216/0x2c0 [kvm]
kvm_arch_vcpu_ioctl_run+0x604/0x650 [kvm]
kvm_vcpu_ioctl+0x2f4/0x6b0 [kvm]
? wake_up_q+0xa0/0xa0The BUG occurred because the ENDBR in the andw_ax_dx() fastop function had been incorrectly "sealed" (converted to a NOP) by apply_ibt_endbr().
Objtool marked it to be sealed because KVM has no compile-time references to the function. Instead KVM calculates its address at runtime.
Prevent objtool from annotating fastop functions as sealable by creating throwaway dummy compile-time references to the functions.
Message-Id: <0d4116f90e9d0c1b754bb90c585e6f0415a1c508.1660837839.git.jpoimboe@kernel.org>
--- arch/x86/kvm/emulate.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
arch/x86/kvm/emulate.c +2 -1
@@ -316,7 +316,8 @@ static int fastop(struct x86_emulate_ctxt *ctxt, fastop_t fop); ".align " __stringify(FASTOP_SIZE) " \n\t" \".type " name", @function \n\t" \ name":\n\t" \ - ASM_ENDBR +ASM_ENDBR \ + IBT_NOSEAL(name)#define FOP_FUNC (name) \ __FOP_FUNC(#name)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 257/365 thunderbolt: Change downstream routers TMU rate in both TMU uni/bidir mode
In reply to Greg Kroah-HartmanFrom: Gil Fine <[email protected]>
[ Upstream commit 5fd6b9a5cbe63fea4c490fee8af34144a139a266 ]
In case of uni-directional time sync, TMU handshake is initiated by upstream router. In case of bi-directional time sync, TMU handshake is initiated by downstream router. In order to handle correctly the case of uni-directional mode, we avoid changing the upstream router's rate to off, because it might have another downstream router plugged that is set to uni-directional mode (and we don't want to change its mode). Instead, we always change downstream router's rate.
--- drivers/thunderbolt/tmu.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
drivers/thunderbolt/tmu.c +7 -6
@@ -359,13 +359,14 @@ int tb_switch_tmu_disable(struct tb_switch *sw)* In case of uni-directional time sync, TMU handshake is * initiated by upstream router. In case of bi-directional * time sync, TMU handshake is initiated by downstream router. -* Therefore, we change the rate to off in the respective -* router. +* We change downstream router's rate to off for both uni/bidir +* cases although it is needed only for the bi-directional mode. +* We avoid changing upstream router's mode since it might +* have another downstream router plugged, that is set to +* uni-directional mode and we don't want to change it's TMU +* mode. */ -if (unidirectional) -tb_switch_tmu_rate_write (parent,TB_SWITCH_TMU_RATE_OFF ); -else -tb_switch_tmu_rate_write (sw,TB_SWITCH_TMU_RATE_OFF ); +tb_switch_tmu_rate_write (sw,TB_SWITCH_TMU_RATE_OFF );tb_port_tmu_time_sync_disable (up); ret =tb_port_tmu_time_sync_disable (down);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 258/365 HID: multitouch: new device class fix Lenovo X12 trackpad sticky
In reply to Greg Kroah-HartmanFrom: Tao Jin <[email protected]>
[ Upstream commit 54eed5c7b938dc4ef6b14d4ee048bbdafdbce352 ]
The trackpad of the given device sends continuous report of pointers status as per wxn8 spec. However, the spec did not clarify when the fingers are lifted so fast that between the interval of two report frames fingers on pad reduced from >=2 to 0. The second last report contains >=2 fingers with tip state 1 and the last report contains only 1 finger with tip state 0. Although this can happen unfrequently, a
quick fix will be improve the consistency to 100%. A quick fix is to
disable MT_QUIRK_ALWAYS_VALID and enable MT_QUIRK_NOT_SEEN_MEANS_UP.
Test for hid-tools is added in [1]
In addition to this, I2C device 04CA:00B1 may also need similar class but with MT_QUIRK_FORCE_MULTI_INPUT disabled (but it does not harm to
enable it on non-multi-input device either). The respective owner has
been notified and a patch may coming soon after test.
[1]: https://gitlab.freedesktop.org/libevdev/hid-tools/-/merge_requests/130
--- drivers/hid/hid-multitouch.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
drivers/hid/hid-multitouch.c +12 -1
@@ -194,6 +194,7 @@ static void mt_post_parse(struct mt_device *td, struct mt_application *app);#define MT_CLS_WIN_8_FORCE_MULTI_INPUT 0x0015#define MT_CLS_WIN_8_DISABLE_WAKEUP 0x0016#define MT_CLS_WIN_8_NO_STICKY_FINGERS 0x0017 +#define MT_CLS_WIN_8_FORCE_MULTI_INPUT_NSMU 0x0018/* vendor specific classes */ #define MT_CLS_3M 0x0101
@@ -286,6 +287,15 @@ static const struct mt_class mt_classes[] = {MT_QUIRK_WIN8_PTP_BUTTONS | MT_QUIRK_FORCE_MULTI_INPUT, .export_all_inputs = true }, + { .name = MT_CLS_WIN_8_FORCE_MULTI_INPUT_NSMU, + .quirks =MT_QUIRK_IGNORE_DUPLICATES | +MT_QUIRK_HOVERING | +MT_QUIRK_CONTACT_CNT_ACCURATE | +MT_QUIRK_STICKY_FINGERS | +MT_QUIRK_WIN8_PTP_BUTTONS | +MT_QUIRK_FORCE_MULTI_INPUT | + MT_QUIRK_NOT_SEEN_MEANS_UP, + .export_all_inputs = true }, { .name = MT_CLS_WIN_8_DISABLE_WAKEUP, .quirks =MT_QUIRK_ALWAYS_VALID | MT_QUIRK_IGNORE_DUPLICATES |
@@ -783,6 +793,7 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi,case HID_DG_CONFIDENCE :if ((cls->name ==MT_CLS_WIN_8 || cls->name ==MT_CLS_WIN_8_FORCE_MULTI_INPUT || + cls->name ==MT_CLS_WIN_8_FORCE_MULTI_INPUT_NSMU || cls->name ==MT_CLS_WIN_8_DISABLE_WAKEUP ) && (field->application ==HID_DG_TOUCHPAD || field->application ==HID_DG_TOUCHSCREEN ))
@@ -2035,7 +2046,7 @@ static const struct hid_device_id mt_devices[] = { USB_DEVICE_ID_LENOVO_X1_TAB3) },/* Lenovo X12 TAB Gen 1 */ - { .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT, + { .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT_NSMU,HID_DEVICE (BUS_USB ,HID_GROUP_MULTITOUCH_WIN_8 ,USB_VENDOR_ID_LENOVO , USB_DEVICE_ID_LENOVO_X12_TAB) },
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 259/365 PCI: Add ACS quirk for Broadcom BCM5750x NICs
In reply to Greg Kroah-HartmanFrom: Pavan Chebbi <[email protected]>
[ Upstream commit afd306a65cedb9589564bdb23a0c368abc4215fd ]
The Broadcom BCM5750x NICs may be multi-function devices. They do not advertise ACS capability. Peer-to-peer transactions are not possible between the individual functions, so it is safe to treat them as fully isolated.
Add an ACS quirk for these devices so the functions can be in independent IOMMU groups and attached individually to userspace applications using VFIO.
--- drivers/pci/quirks.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/pci/quirks.c +3 -0
@@ -4924,6 +4924,9 @@ static const struct pci_dev_acs_enabled { { PCI_VENDOR_ID_AMPERE, 0xE00C, pci_quirk_xgene_acs },/* Broadcom multi-function device */ { PCI_VENDOR_ID_BROADCOM, 0x16D7, pci_quirk_mf_endpoint_acs }, + { PCI_VENDOR_ID_BROADCOM, 0x1750, pci_quirk_mf_endpoint_acs }, + { PCI_VENDOR_ID_BROADCOM, 0x1751, pci_quirk_mf_endpoint_acs }, + { PCI_VENDOR_ID_BROADCOM, 0x1752, pci_quirk_mf_endpoint_acs }, { PCI_VENDOR_ID_BROADCOM, 0xD714, pci_quirk_brcm_acs },/* Amazon Annapurna Labs */ { PCI_VENDOR_ID_AMAZON_ANNAPURNA_LABS, 0x0031, pci_quirk_al_acs },
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 260/365 platform/chrome: cros_ec_proto: dont show MKBP version if unsupported
In reply to Greg Kroah-HartmanFrom: Tzung-Bi Shih <[email protected]>
[ Upstream commit b36f0643ff14a2fb281b105418e4e73c9d7c11d0 ]
It wrongly showed the following message when it doesn't support MKBP:
"MKBP support version 4294967295".
Fix it.
--- drivers/platform/chrome/cros_ec_proto.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/platform/chrome/cros_ec_proto.c +4 -4
@@ -509,13 +509,13 @@ int cros_ec_query_all(struct cros_ec_device *ec_dev) ret =cros_ec_get_host_command_version_mask (ec_dev,EC_CMD_GET_NEXT_EVENT , &ver_mask); -if (ret <0 || ver_mask ==0 ) +if (ret <0 || ver_mask ==0 ) { ec_dev->mkbp_event_supported =0 ; -else + }else { ec_dev->mkbp_event_supported =fls (ver_mask); -dev_dbg (ec_dev->dev,"MKBP support version %u\n" , - ec_dev->mkbp_event_supported -1 ); +dev_dbg (ec_dev->dev,"MKBP support version %u\n" , ec_dev->mkbp_event_supported -1 ); + }/* Probe if host sleep v1 is supported for S0ix failure detection. */ ret = cros_ec_get_host_command_version_mask(ec_dev,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 261/365 staging: r8188eu: add error handling of rtw_read8
In reply to Greg Kroah-HartmanFrom: Pavel Skripkin <[email protected]>
[ Upstream commit 857fe9e5efc09833fe1110e99d8baba954a86abb ]
rtw_read8() reads data from device via USB API which may fail. In case of any failure previous code returned stack data to callers, which is wrong.
Fix it by changing rtw_read8() prototype and prevent caller from touching random stack data
--- drivers/staging/r8188eu/core/rtw_efuse.c | 13 +- drivers/staging/r8188eu/core/rtw_fw.c | 56 ++++-- drivers/staging/r8188eu/core/rtw_led.c | 16 +- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 48 ++++- drivers/staging/r8188eu/core/rtw_wlan_util.c | 20 +- drivers/staging/r8188eu/hal/HalPhyRf_8188e.c | 18 +- drivers/staging/r8188eu/hal/HalPwrSeqCmd.c | 9 +- drivers/staging/r8188eu/hal/hal_com.c | 27 ++- drivers/staging/r8188eu/hal/rtl8188e_cmd.c | 37 +++- drivers/staging/r8188eu/hal/rtl8188e_dm.c | 6 +- .../staging/r8188eu/hal/rtl8188e_hal_init.c | 69 +++++-- drivers/staging/r8188eu/hal/rtl8188e_phycfg.c | 10 +- drivers/staging/r8188eu/hal/usb_halinit.c | 171 +++++++++++++++--- drivers/staging/r8188eu/hal/usb_ops_linux.c | 7 +- drivers/staging/r8188eu/include/rtw_io.h | 2 +- drivers/staging/r8188eu/os_dep/ioctl_linux.c | 11 +- 16 files changed, 418 insertions(+), 102 deletions(-)
drivers/staging/r8188eu/core/rtw_efuse.c +11 -2
@@ -28,14 +28,21 @@ ReadEFuseByte(u32 value32;u8 readbyte;u16 retry; +int res;/* Write Address */ rtw_write8 (Adapter,EFUSE_CTRL +1 , (_offset &0xff )); - readbyte =rtw_read8 (Adapter,EFUSE_CTRL +2 ); + res =rtw_read8 (Adapter,EFUSE_CTRL +2 , &readbyte); +if (res) +return ; +rtw_write8 (Adapter,EFUSE_CTRL +2 , ((_offset >>8 ) &0x03 ) | (readbyte &0xfc ));/* Write bit 32 0 */ - readbyte =rtw_read8 (Adapter,EFUSE_CTRL +3 ); + res =rtw_read8 (Adapter,EFUSE_CTRL +3 , &readbyte); +if (res) +return ; +rtw_write8 (Adapter,EFUSE_CTRL +3 , (readbyte &0x7f ));/* Check bit 32 read-ready */
@@ -54,6 +61,8 @@ ReadEFuseByte( value32 =rtw_read32 (Adapter,EFUSE_CTRL ); *pbuf = (u8)(value32 &0xff ); + +/* FIXME: return an error to caller */ }/*-----------------------------------------------------------------------------
drivers/staging/r8188eu/core/rtw_fw.c +43 -13
107 lines not on this page · raw message
drivers/staging/r8188eu/core/rtw_led.c +13 -3
@@ -35,11 +35,15 @@ static void ResetLedStatus(struct LED_871x *pLed)static void SwLedOn (struct adapter *padapter,struct LED_871x *pLed) {u8 LedCfg; +int res;if (padapter->bSurpriseRemoved || padapter->bDriverStopped)return ; - LedCfg =rtw_read8 (padapter,REG_LEDCFG2 ); + res =rtw_read8 (padapter,REG_LEDCFG2 , &LedCfg); +if (res) +return ; +rtw_write8 (padapter,REG_LEDCFG2 , (LedCfg &0xf0 ) |BIT (5 ) |BIT (6 ));/* SW control led0 on. */ pLed->bLedOn = true; }
@@ -47,15 +51,21 @@ static void SwLedOn(struct adapter *padapter, struct LED_871x *pLed)static void SwLedOff (struct adapter *padapter,struct LED_871x *pLed) {u8 LedCfg; +int res;if (padapter->bSurpriseRemoved || padapter->bDriverStopped) goto exit; - LedCfg =rtw_read8 (padapter,REG_LEDCFG2 );/* 0x4E */ + res =rtw_read8 (padapter,REG_LEDCFG2 , &LedCfg);/* 0x4E */ +if (res) + goto exit; LedCfg &=0x90 ;/* Set to software control. */ rtw_write8 (padapter,REG_LEDCFG2 , (LedCfg |BIT (3 ))); - LedCfg =rtw_read8 (padapter,REG_MAC_PINMUX_CFG ); + res =rtw_read8 (padapter,REG_MAC_PINMUX_CFG , &LedCfg); +if (res) + goto exit; + LedCfg &=0xFE ;rtw_write8 (padapter,REG_MAC_PINMUX_CFG , LedCfg); exit:
drivers/staging/r8188eu/core/rtw_mlme_ext.c +40 -8
108 lines not on this page · raw message
drivers/staging/r8188eu/core/rtw_wlan_util.c +17 -3
@@ -279,8 +279,13 @@ void Restore_DM_Func_Flag(struct adapter *padapter)void Set_MSR (struct adapter *padapter,u8 type) {u8 val8; +int res; - val8 =rtw_read8 (padapter,MSR ) &0x0c ; + res =rtw_read8 (padapter,MSR , &val8); +if (res) +return ; + + val8 &=0x0c ; val8 |= type;rtw_write8 (padapter,MSR , val8); }
@@ -505,7 +510,11 @@ int WMM_param_handler(struct adapter *padapter, struct ndis_802_11_var_ie *pIE)static void set_acm_ctrl (struct adapter *adapter,u8 acm_mask) { -u8 acmctrl =rtw_read8 (adapter,REG_ACMHWCTRL ); +u8 acmctrl; +int res =rtw_read8 (adapter,REG_ACMHWCTRL , &acmctrl); + +if (res) +return ;if (acm_mask >1 ) acmctrl = acmctrl |0x1 ;
@@ -765,6 +774,7 @@ void HT_info_handler(struct adapter *padapter, struct ndis_802_11_var_ie *pIE)static void set_min_ampdu_spacing (struct adapter *adapter,u8 spacing) {u8 sec_spacing; +int res;if (spacing <=7 ) {switch (adapter->securitypriv.dot11PrivacyAlgrthm) {
@@ -786,8 +796,12 @@ static void set_min_ampdu_spacing(struct adapter *adapter, u8 spacing)if (spacing < sec_spacing) spacing = sec_spacing; + res =rtw_read8 (adapter,REG_AMPDU_MIN_SPACE , &sec_spacing); +if (res) +return ; +rtw_write8 (adapter,REG_AMPDU_MIN_SPACE , - (rtw_read8 (adapter,REG_AMPDU_MIN_SPACE ) &0xf8 ) | spacing); + (sec_spacing &0xf8 ) | spacing); } }
drivers/staging/r8188eu/hal/HalPhyRf_8188e.c +15 -3
@@ -463,6 +463,7 @@ void _PHY_SaveADDARegisters(struct adapter *adapt, u32 *ADDAReg, u32 *ADDABackup } } +/* FIXME: return an error to caller */ static void _PHY_SaveMACRegisters( struct adapter *adapt, u32 *MACReg,
@@ -470,9 +471,17 @@ static void _PHY_SaveMACRegisters( ) {u32 i; +int res; -for (i =0 ; i < (IQK_MAC_REG_NUM -1 ); i++) - MACBackup[i] =rtw_read8 (adapt, MACReg[i]); +for (i =0 ; i < (IQK_MAC_REG_NUM -1 ); i++) { +u8 reg; + + res =rtw_read8 (adapt, MACReg[i], ®); +if (res) +return ; + + MACBackup[i] = reg; + } MACBackup[i] =rtw_read32 (adapt, MACReg[i]); }
@@ -739,9 +748,12 @@ static void phy_LCCalibrate_8188E(struct adapter *adapt) {u8 tmpreg;u32 RF_Amode =0 , LC_Cal; +int res;/* Check continuous TX and Packet TX */ - tmpreg =rtw_read8 (adapt,0xd03 ); + res =rtw_read8 (adapt,0xd03 , &tmpreg); +if (res) +return ;if ((tmpreg &0x70 ) !=0 )/* Deal with contisuous TX case */ rtw_write8 (adapt,0xd03 , tmpreg &0x8F );/* disable all continuous TX */
drivers/staging/r8188eu/hal/HalPwrSeqCmd.c +7 -2
@@ -12,6 +12,7 @@ u8 HalPwrSeqCmdParsing(struct adapter *padapter, struct wl_pwr_cfg pwrseqcmd[])u32 offset =0 ;u32 poll_count =0 ;/* polling autoload done. */ u32 max_poll_count =5000 ; +int res; do { pwrcfgcmd = pwrseqcmd[aryidx];
@@ -21,7 +22,9 @@ u8 HalPwrSeqCmdParsing(struct adapter *padapter, struct wl_pwr_cfg pwrseqcmd[]) offset =GET_PWR_CFG_OFFSET (pwrcfgcmd);/* Read the value from system register */ - value =rtw_read8 (padapter, offset); + res =rtw_read8 (padapter, offset, &value); +if (res) +return false; value &= ~(GET_PWR_CFG_MASK (pwrcfgcmd)); value |= (GET_PWR_CFG_VALUE (pwrcfgcmd) &GET_PWR_CFG_MASK (pwrcfgcmd));
@@ -33,7 +36,9 @@ u8 HalPwrSeqCmdParsing(struct adapter *padapter, struct wl_pwr_cfg pwrseqcmd[]) poll_bit = false; offset =GET_PWR_CFG_OFFSET (pwrcfgcmd); do { - value = rtw_read8(padapter, offset); + res = rtw_read8(padapter, offset, &value); + if (res) + return false; value &= GET_PWR_CFG_MASK(pwrcfgcmd); if (value == (GET_PWR_CFG_VALUE(pwrcfgcmd) & GET_PWR_CFG_MASK(pwrcfgcmd)))
drivers/staging/r8188eu/hal/hal_com.c +21 -6
@@ -303,7 +303,9 @@ s32 c2h_evt_read(struct adapter *adapter, u8 *buf)if (!buf) goto exit; - trigger =rtw_read8 (adapter,REG_C2HEVT_CLEAR ); + ret =rtw_read8 (adapter,REG_C2HEVT_CLEAR , &trigger); +if (ret) +return _FAIL;if (trigger ==C2H_EVT_HOST_CLOSE ) goto exit;/* Not ready */
@@ -314,13 +316,26 @@ s32 c2h_evt_read(struct adapter *adapter, u8 *buf)memset (c2h_evt,0 ,16 ); - *buf =rtw_read8 (adapter,REG_C2HEVT_MSG_NORMAL ); - *(buf +1 ) =rtw_read8 (adapter,REG_C2HEVT_MSG_NORMAL +1 ); + ret =rtw_read8 (adapter,REG_C2HEVT_MSG_NORMAL , buf); +if (ret) { + ret = _FAIL; + goto clear_evt; + } + ret =rtw_read8 (adapter,REG_C2HEVT_MSG_NORMAL +1 , buf +1 ); +if (ret) { + ret = _FAIL; + goto clear_evt; + }/* Read the content */ -for (i =0 ; i < c2h_evt->plen; i++) - c2h_evt->payload[i] =rtw_read8 (adapter,REG_C2HEVT_MSG_NORMAL + -sizeof (*c2h_evt) + i); +for (i =0 ; i < c2h_evt->plen; i++) { + ret =rtw_read8 (adapter,REG_C2HEVT_MSG_NORMAL + +sizeof (*c2h_evt) + i, c2h_evt->payload + i); +if (ret) { + ret = _FAIL; + goto clear_evt; + } + } ret = _SUCCESS;
drivers/staging/r8188eu/hal/rtl8188e_cmd.c +31 -6
@@ -18,13 +18,18 @@static u8 _is_fw_read_cmd_down (struct adapter *adapt,u8 msgbox_num) { -u8 read_down = false; +u8 read_down = false, reg;int retry_cnts =100 ; +int res;u8 valid;do { - valid =rtw_read8 (adapt,REG_HMETFR ) &BIT (msgbox_num); + res =rtw_read8 (adapt,REG_HMETFR , ®); +if (res) +continue ; + + valid = reg &BIT (msgbox_num);if (0 == valid) read_down = true; }while ((!read_down) && (retry_cnts--));
@@ -533,6 +538,8 @@ void rtl8188e_set_FwJoinBssReport_cmd(struct adapter *adapt, u8 mstatus)bool bcn_valid = false;u8 DLBcnCount =0 ;u32 poll =0 ; +u8 reg; +int res;if (mstatus ==1 ) {/* We should set AID, correct TSF, HW seq enable before set JoinBssReport to Fw in 88/92C. */
@@ -547,8 +554,17 @@ void rtl8188e_set_FwJoinBssReport_cmd(struct adapter *adapt, u8 mstatus)/* Disable Hw protection for a time which revserd for Hw sending beacon. */ /* Fix download reserved page packet fail that access collision with the protection time. */ /* 2010.05.11. Added by tynli. */ -rtw_write8 (adapt,REG_BCN_CTRL ,rtw_read8 (adapt,REG_BCN_CTRL ) & (~BIT (3 ))); -rtw_write8 (adapt,REG_BCN_CTRL ,rtw_read8 (adapt,REG_BCN_CTRL ) |BIT (4 )); + res =rtw_read8 (adapt,REG_BCN_CTRL , ®); +if (res) +return ; + +rtw_write8 (adapt,REG_BCN_CTRL , reg & (~BIT (3 ))); + + res =rtw_read8 (adapt,REG_BCN_CTRL , ®); +if (res) +return ; + +rtw_write8 (adapt,REG_BCN_CTRL , reg |BIT (4 ));if (haldata->RegFwHwTxQCtrl &BIT (6 )) bSendBeacon = true;
@@ -581,8 +597,17 @@ void rtl8188e_set_FwJoinBssReport_cmd(struct adapter *adapt, u8 mstatus)/* */ /* Enable Bcn */ -rtw_write8 (adapt,REG_BCN_CTRL ,rtw_read8 (adapt,REG_BCN_CTRL ) |BIT (3 )); -rtw_write8 (adapt,REG_BCN_CTRL ,rtw_read8 (adapt,REG_BCN_CTRL ) & (~BIT (4 ))); + res =rtw_read8 (adapt,REG_BCN_CTRL , ®); +if (res) +return ; + +rtw_write8 (adapt,REG_BCN_CTRL , reg |BIT (3 )); + + res =rtw_read8 (adapt,REG_BCN_CTRL , ®); +if (res) +return ; + +rtw_write8 (adapt,REG_BCN_CTRL , reg & (~BIT (4 )));/* To make sure that if there exists an adapter which would like to send beacon. */ /* If exists, the origianl value of 0x422[6] will be 1, we should check this to */
drivers/staging/r8188eu/hal/rtl8188e_dm.c +5 -1
@@ -12,8 +12,12 @@static void dm_InitGPIOSetting (struct adapter *Adapter) {u8 tmp1byte; +int res; + + res =rtw_read8 (Adapter,REG_GPIO_MUXCFG , &tmp1byte); +if (res) +return ; - tmp1byte =rtw_read8 (Adapter,REG_GPIO_MUXCFG ); tmp1byte &= (GPIOSEL_GPIO | ~GPIOSEL_ENBT );rtw_write8 (Adapter,REG_GPIO_MUXCFG , tmp1byte);
drivers/staging/r8188eu/hal/rtl8188e_hal_init.c +55 -14
120 lines not on this page · raw message
drivers/staging/r8188eu/hal/rtl8188e_phycfg.c +8 -2
@@ -594,6 +594,7 @@ _PHY_SetBWMode92C(struct hal_data_8188e *pHalData = &Adapter->haldata;u8 regBwOpMode;u8 regRRSR_RSC; +int res;if (Adapter->bDriverStopped)return ;
@@ -602,8 +603,13 @@ _PHY_SetBWMode92C(/* 3<1>Set MAC register */ /* 3 */ - regBwOpMode =rtw_read8 (Adapter,REG_BWOPMODE ); - regRRSR_RSC =rtw_read8 (Adapter,REG_RRSR +2 ); + res =rtw_read8 (Adapter,REG_BWOPMODE , ®BwOpMode); +if (res) +return ; + + res =rtw_read8 (Adapter,REG_RRSR +2 , ®RRSR_RSC); +if (res) +return ;switch (pHalData->CurrentChannelBW) {case HT_CHANNEL_WIDTH_20 :
drivers/staging/r8188eu/hal/usb_halinit.c +141 -30
339 lines not on this page · raw message
drivers/staging/r8188eu/hal/usb_ops_linux.c +2 -5
@@ -94,16 +94,13 @@ static int usb_write(struct intf_hdl *intf, u16 value, void *data, u8 size)return status; } -u8 rtw_read8 (struct adapter *adapter,u32 addr) +int __must_check rtw_read8 (struct adapter *adapter,u32 addr,u8 *data) {struct io_priv *io_priv = &adapter->iopriv;struct intf_hdl *intf = &io_priv->intf;u16 value = addr &0xffff ; -u8 data; -usb_read (intf, value, &data,1 ); - -return data; +return usb_read (intf, value, data,1 ); }u16 rtw_read16 (struct adapter *adapter,u32 addr)
drivers/staging/r8188eu/include/rtw_io.h +1 -1
@@ -220,7 +220,7 @@ void unregister_intf_hdl(struct intf_hdl *pintfhdl);void _rtw_attrib_read (struct adapter *adapter,u32 addr,u32 cnt,u8 *pmem);void _rtw_attrib_write (struct adapter *adapter,u32 addr,u32 cnt,u8 *pmem); -u8 rtw_read8 (struct adapter *adapter,u32 addr); +int __must_check rtw_read8 (struct adapter *adapter,u32 addr,u8 *data);u16 rtw_read16 (struct adapter *adapter,u32 addr);u32 rtw_read32 (struct adapter *adapter,u32 addr);void _rtw_read_mem (struct adapter *adapter,u32 addr,u32 cnt,u8 *pmem);
drivers/staging/r8188eu/os_dep/ioctl_linux.c +8 -3
@@ -3178,6 +3178,7 @@ static void rtw_set_dynamic_functions(struct adapter *adapter, u8 dm_func) {struct hal_data_8188e *haldata = &adapter->haldata;struct odm_dm_struct *odmpriv = &haldata->odmpriv; +int res;switch (dm_func) {case 0 :
@@ -3193,7 +3194,9 @@ static void rtw_set_dynamic_functions(struct adapter *adapter, u8 dm_func)if (!(odmpriv->SupportAbility &DYNAMIC_BB_DIG )) {struct rtw_dig *digtable = &odmpriv->DM_DigTable; - digtable->CurIGValue =rtw_read8 (adapter,0xc50 ); + res =rtw_read8 (adapter,0xc50 , &digtable->CurIGValue); + (void )res; +/* FIXME: return an error to caller */ } odmpriv->SupportAbility =DYNAMIC_ALL_FUNC_ENABLE ;break ;
@@ -3329,8 +3332,9 @@ static int rtw_dbg_port(struct net_device *dev,u16 reg = arg;u16 start_value =0 ;u32 write_num = extra_arg; -int i; +int i, res;struct xmit_frame *xmit_frame; +u8 val8; xmit_frame =rtw_IOL_accquire_xmit_frame (padapter);if (!xmit_frame) {
@@ -3343,7 +3347,8 @@ static int rtw_dbg_port(struct net_device *dev,if (rtl8188e_IOL_exec_cmds_sync (padapter, xmit_frame,5000 ,0 ) != _SUCCESS) ret = -EPERM ; -rtw_read8 (padapter, reg); +/* FIXME: is this read necessary? */ + res =rtw_read8 (padapter, reg, &val8); }break ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 262/365 staging: r8188eu: add error handling of rtw_read16
In reply to Greg Kroah-HartmanFrom: Pavel Skripkin <[email protected]>
[ Upstream commit fed9e604eeb6150847d9757f6b056c12912d468b ]
rtw_read16() reads data from device via USB API which may fail. In case of any failure previous code returned stack data to callers, which is wrong.
Fix it by changing rtw_read16() prototype and prevent caller from touching random stack data
--- .../staging/r8188eu/hal/rtl8188e_hal_init.c | 29 +++++++++++++++---- drivers/staging/r8188eu/hal/rtl8188e_phycfg.c | 8 +++-- drivers/staging/r8188eu/hal/usb_halinit.c | 27 ++++++++++++++--- drivers/staging/r8188eu/hal/usb_ops_linux.c | 13 ++++++--- drivers/staging/r8188eu/include/rtw_io.h | 2 +- drivers/staging/r8188eu/os_dep/ioctl_linux.c | 9 ++++-- drivers/staging/r8188eu/os_dep/os_intfs.c | 6 +++- 7 files changed, 73 insertions(+), 21 deletions(-)
drivers/staging/r8188eu/hal/rtl8188e_hal_init.c +23 -6
@@ -200,7 +200,8 @@ efuse_phymap_to_logical(u8 *phymap, u16 _offset, u16 _size_byte, u8 *pbuf)kfree (eFuseWord); } -static void efuse_read_phymap_from_txpktbuf( +/* FIXME: add error handling in callers */ +static int efuse_read_phymap_from_txpktbuf( struct adapter *adapter, int bcnhead, /* beacon head, where FW store len(2-byte) and efuse physical map. */ u8 *content, /* buffer to store efuse physical map */
@@ -219,7 +220,7 @@ static void efuse_read_phymap_from_txpktbuf(if (bcnhead <0 ) {/* if not valid */ res =rtw_read8 (adapter,REG_TDECTRL +1 , ®);if (res) -return ; +return res; bcnhead = reg; }
@@ -249,11 +250,15 @@ static void efuse_read_phymap_from_txpktbuf( hi32 =cpu_to_le32 (rtw_read32 (adapter,REG_PKTBUF_DBG_DATA_H ));if (i ==0 ) { +u16 reg; +/* Although lenc is only used in a debug statement, * do not remove it as the rtw_read16() call consumes * 2 bytes from the EEPROM source. */ -rtw_read16 (adapter,REG_PKTBUF_DBG_DATA_L ); + res =rtw_read16 (adapter,REG_PKTBUF_DBG_DATA_L , ®); +if (res) +return res; len =le32_to_cpu (lo32) &0x0000ffff ;
@@ -280,6 +285,8 @@ static void efuse_read_phymap_from_txpktbuf( }rtw_write8 (adapter,REG_PKT_BUFF_ACCESS_CTRL ,DISABLE_TRXPKT_BUF_ACCESS ); *size = count; + +return 0 ; }static s32 iol_read_efuse (struct adapter *padapter,u8 txpktbuf_bndy,u16 offset,u16 size_byte,u8 *logical_map)
@@ -355,25 +362,35 @@ int rtl8188e_IOL_exec_cmds_sync(struct adapter *adapter, struct xmit_frame *xmitvoid rtl8188e_EfusePowerSwitch (struct adapter *pAdapter,u8 PwrState) {u16 tmpV16; +int res;if (PwrState) {rtw_write8 (pAdapter,REG_EFUSE_ACCESS ,EFUSE_ACCESS_ON );/* 1.2V Power: From VDDON with Power Cut(0x0000h[15]), defualt valid */ - tmpV16 =rtw_read16 (pAdapter,REG_SYS_ISO_CTRL ); + res =rtw_read16 (pAdapter,REG_SYS_ISO_CTRL , &tmpV16); +if (res) +return ; +if (!(tmpV16 &PWC_EV12V )) { tmpV16 |=PWC_EV12V ;rtw_write16 (pAdapter,REG_SYS_ISO_CTRL , tmpV16); }/* Reset: 0x0000h[28], default valid */ - tmpV16 =rtw_read16 (pAdapter,REG_SYS_FUNC_EN ); + res =rtw_read16 (pAdapter,REG_SYS_FUNC_EN , &tmpV16); +if (res) +return ; +if (!(tmpV16 &FEN_ELDR )) { tmpV16 |=FEN_ELDR ;rtw_write16 (pAdapter,REG_SYS_FUNC_EN , tmpV16); }/* Clock: Gated(0x0008h[5]) 8M(0x0008h[1]) clock from ANA, default valid */ - tmpV16 =rtw_read16 (pAdapter,REG_SYS_CLKR ); + res =rtw_read16 (pAdapter,REG_SYS_CLKR , &tmpV16); +if (res) +return ; +if ((!(tmpV16 &LOADER_CLK_EN )) || (!(tmpV16 &ANA8M ))) { tmpV16 |= (LOADER_CLK_EN |ANA8M );rtw_write16 (pAdapter,REG_SYS_CLKR , tmpV16);
drivers/staging/r8188eu/hal/rtl8188e_phycfg.c +6 -2
@@ -484,13 +484,17 @@ PHY_BBConfig8188E( {int rtStatus = _SUCCESS;struct hal_data_8188e *pHalData = &Adapter->haldata; -u32 RegVal; +u16 RegVal;u8 CrystalCap; +int res;phy_InitBBRFRegisterDefinition (Adapter);/* Enable BB and RF */ - RegVal =rtw_read16 (Adapter,REG_SYS_FUNC_EN ); + res =rtw_read16 (Adapter,REG_SYS_FUNC_EN , &RegVal); +if (res) +return _FAIL; +rtw_write16 (Adapter,REG_SYS_FUNC_EN , (u16)(RegVal |BIT (13 ) |BIT (0 ) |BIT (1 )));/* 20090923 Joseph: Advised by Steven and Jenyu. Power sequence before init RF. */
drivers/staging/r8188eu/hal/usb_halinit.c +23 -4
@@ -52,6 +52,8 @@ void rtl8188eu_interface_configure(struct adapter *adapt)u32 rtl8188eu_InitPowerOn (struct adapter *adapt) {u16 value16; +int res; +/* HW Power on sequence */ struct hal_data_8188e *haldata = &adapt->haldata;if (haldata->bMacPwrCtrlOn)
@@ -65,7 +67,10 @@ u32 rtl8188eu_InitPowerOn(struct adapter *adapt)rtw_write16 (adapt,REG_CR ,0x00 );/* suggseted by zhouzhou, by page, 20111230 */ /* Enable MAC DMA/WMAC/SCHEDULE/SEC block */ - value16 =rtw_read16 (adapt,REG_CR ); + res =rtw_read16 (adapt,REG_CR , &value16); +if (res) +return _FAIL; + value16 |= (HCI_TXDMA_EN |HCI_RXDMA_EN |TXDMA_EN |RXDMA_EN |PROTOCOL_EN |SCHEDULE_EN |ENSEC |CALTMR_EN );/* for SDIO - Set CR bit10 to enable 32k calibration. Suggested by SD1 Gimmy. Added by tynli. 2011.08.31. */
@@ -166,7 +171,14 @@ static void _InitNormalChipRegPriority(struct adapter *Adapter, u16 beQ, u16 bkQ, u16 viQ, u16 voQ, u16 mgtQ, u16 hiQ) { - u16 value16 = (rtw_read16(Adapter, REG_TRXDMA_CTRL) & 0x7); + u16 value16; +int res; + + res =rtw_read16 (Adapter,REG_TRXDMA_CTRL , &value16); +if (res) +return ; + + value16 &=0x7 ; value16 |=_TXDMA_BEQ_MAP (beQ) |_TXDMA_BKQ_MAP (bkQ) | _TXDMA_VIQ_MAP(viQ) | _TXDMA_VOQ_MAP(voQ) |
@@ -640,7 +652,10 @@ u32 rtl8188eu_hal_init(struct adapter *Adapter)/* Hw bug which Hw initials RxFF boundary size to a value which is larger than the real Rx buffer size in 88E. */ /* */ /* Enable MACTXEN/MACRXEN block */ - value16 =rtw_read16 (Adapter,REG_CR ); + res =rtw_read16 (Adapter,REG_CR , &value16); +if (res) +return _FAIL; + value16 |= (MACTXEN |MACRXEN );rtw_write8 (Adapter,REG_CR , value16);
@@ -713,7 +728,11 @@ u32 rtl8188eu_hal_init(struct adapter *Adapter)rtw_write16 (Adapter,REG_TX_RPT_TIME ,0x3DF0 );/* enable tx DMA to drop the redundate data of packet */ -rtw_write16 (Adapter,REG_TXDMA_OFFSET_CHK , (rtw_read16 (Adapter,REG_TXDMA_OFFSET_CHK ) |DROP_DATA_EN )); + res =rtw_read16 (Adapter,REG_TXDMA_OFFSET_CHK , &value16); +if (res) +return _FAIL; + +rtw_write16 (Adapter,REG_TXDMA_OFFSET_CHK , (value16 |DROP_DATA_EN ));/* 2010/08/26 MH Merge from 8192CE. */ if (pwrctrlpriv->rf_pwrstate == rf_on) {
drivers/staging/r8188eu/hal/usb_ops_linux.c +9 -4
@@ -103,16 +103,21 @@ int __must_check rtw_read8(struct adapter *adapter, u32 addr, u8 *data)return usb_read (intf, value, data,1 ); } -u16 rtw_read16 (struct adapter *adapter,u32 addr) +int __must_check rtw_read16 (struct adapter *adapter,u32 addr,u16 *data) {struct io_priv *io_priv = &adapter->iopriv;struct intf_hdl *intf = &io_priv->intf;u16 value = addr &0xffff ; -__le16 data; +__le16 le_data; +int res; -usb_read (intf, value, &data,2 ); + res =usb_read (intf, value, &le_data,2 ); +if (res) +return res; -return le16_to_cpu (data); + *data =le16_to_cpu (le_data); + +return 0 ; }u32 rtw_read32 (struct adapter *adapter,u32 addr)
drivers/staging/r8188eu/include/rtw_io.h +1 -1
@@ -221,7 +221,7 @@ void _rtw_attrib_read(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);void _rtw_attrib_write (struct adapter *adapter,u32 addr,u32 cnt,u8 *pmem);int __must_check rtw_read8 (struct adapter *adapter,u32 addr,u8 *data); -u16 rtw_read16 (struct adapter *adapter,u32 addr); +int __must_check rtw_read16 (struct adapter *adapter,u32 addr,u16 *data);u32 rtw_read32 (struct adapter *adapter,u32 addr);void _rtw_read_mem (struct adapter *adapter,u32 addr,u32 cnt,u8 *pmem);u32 rtw_read_port (struct adapter *adapter,u8 *pmem);
drivers/staging/r8188eu/os_dep/ioctl_linux.c +6 -3
@@ -3349,6 +3349,7 @@ static int rtw_dbg_port(struct net_device *dev,/* FIXME: is this read necessary? */ res =rtw_read8 (padapter, reg, &val8); + (void )res; }break ;
@@ -3357,8 +3358,8 @@ static int rtw_dbg_port(struct net_device *dev,u16 reg = arg;u16 start_value =200 ;u32 write_num = extra_arg; - -int i; +u16 val16; +int i, res;struct xmit_frame *xmit_frame; xmit_frame =rtw_IOL_accquire_xmit_frame (padapter);
@@ -3372,7 +3373,9 @@ static int rtw_dbg_port(struct net_device *dev,if (rtl8188e_IOL_exec_cmds_sync (padapter, xmit_frame,5000 ,0 ) != _SUCCESS) ret = -EPERM ; -rtw_read16 (padapter, reg); +/* FIXME: is this read necessary? */ + res =rtw_read16 (padapter, reg, &val16); + (void )res; }break ;case 0x08 :/* continuous write dword test */
drivers/staging/r8188eu/os_dep/os_intfs.c +5 -1
@@ -740,12 +740,16 @@ static void rtw_fifo_cleanup(struct adapter *adapter) {struct pwrctrl_priv *pwrpriv = &adapter->pwrctrlpriv;u8 trycnt =100 ; +int res;/* pause tx */ rtw_write8 (adapter,REG_TXPAUSE ,0xff );/* keep sn */ - adapter->xmitpriv.nqos_ssn =rtw_read16 (adapter,REG_NQOS_SEQ ); +/* FIXME: return an error to caller */ + res =rtw_read16 (adapter,REG_NQOS_SEQ , &adapter->xmitpriv.nqos_ssn); +if (res) +return ;if (!pwrpriv->bkeepfwalive) {/* RX DMA stop */
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 263/365 staging: r8188eu: add error handling of rtw_read32
In reply to Greg Kroah-HartmanFrom: Pavel Skripkin <[email protected]>
[ Upstream commit b9c5e272062708680d47df433bfbfe5299ad1a63 ]
rtw_read32() reads data from device via USB API which may fail. In case of any failure previous code returned stack data to callers, which is wrong.
Fix it by changing rtw_read32() prototype and prevent caller from touching random stack data
--- drivers/staging/r8188eu/core/rtw_cmd.c | 15 +++++- drivers/staging/r8188eu/core/rtw_efuse.c | 20 ++++--- drivers/staging/r8188eu/core/rtw_fw.c | 16 ++++-- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 14 ++++- drivers/staging/r8188eu/core/rtw_pwrctrl.c | 9 +++- .../r8188eu/hal/Hal8188ERateAdaptive.c | 21 ++++++-- drivers/staging/r8188eu/hal/HalPhyRf_8188e.c | 3 +- .../staging/r8188eu/hal/rtl8188e_hal_init.c | 40 +++++++++----- drivers/staging/r8188eu/hal/rtl8188e_phycfg.c | 12 ++++- drivers/staging/r8188eu/hal/usb_halinit.c | 53 ++++++++++++++++--- drivers/staging/r8188eu/hal/usb_ops_linux.c | 13 +++-- drivers/staging/r8188eu/include/rtw_io.h | 2 +- drivers/staging/r8188eu/os_dep/ioctl_linux.c | 27 ++++++++-- drivers/staging/r8188eu/os_dep/os_intfs.c | 13 ++++- 14 files changed, 202 insertions(+), 56 deletions(-)
drivers/staging/r8188eu/core/rtw_cmd.c +13 -2
@@ -898,8 +898,12 @@ static void traffic_status_watchdog(struct adapter *padapter)static void rtl8188e_sreset_xmit_status_check (struct adapter *padapter) {u32 txdma_status; +int res; + + res =rtw_read32 (padapter,REG_TXDMA_STATUS , &txdma_status); +if (res) +return ; - txdma_status =rtw_read32 (padapter,REG_TXDMA_STATUS );if (txdma_status !=0x00 )rtw_write32 (padapter,REG_TXDMA_STATUS , txdma_status);/* total xmit irp = 4 */
@@ -1177,7 +1181,14 @@ u8 rtw_ps_cmd(struct adapter *padapter)static bool rtw_is_hi_queue_empty (struct adapter *adapter) { -return (rtw_read32 (adapter,REG_HGQ_INFORMATION ) &0x0000ff00 ) ==0 ; +int res; +u32 reg; + + res =rtw_read32 (adapter,REG_HGQ_INFORMATION , ®); +if (res) +return false; + +return (reg &0x0000ff00 ) ==0 ; }static void rtw_chk_hi_queue_hdl (struct adapter *padapter)
drivers/staging/r8188eu/core/rtw_efuse.c +14 -6
@@ -46,11 +46,17 @@ ReadEFuseByte(rtw_write8 (Adapter,EFUSE_CTRL +3 , (readbyte &0x7f ));/* Check bit 32 read-ready */ - retry =0 ; - value32 =rtw_read32 (Adapter,EFUSE_CTRL ); -while (!(((value32 >>24 ) &0xff ) &0x80 ) && (retry <10000 )) { - value32 =rtw_read32 (Adapter,EFUSE_CTRL ); - retry++; + res =rtw_read32 (Adapter,EFUSE_CTRL , &value32); +if (res) +return ; + +for (retry =0 ; retry <10000 ; retry++) { + res =rtw_read32 (Adapter,EFUSE_CTRL , &value32); +if (res) +continue ; + +if (((value32 >>24 ) &0xff ) &0x80 ) +break ; }/* 20100205 Joseph: Add delay suggested by SD1 Victor. */
@@ -58,7 +64,9 @@ ReadEFuseByte(/* Designer says that there shall be some delay after ready bit is set, or the */ /* result will always stay on last data we read. */ udelay (50 ); - value32 =rtw_read32 (Adapter,EFUSE_CTRL ); + res =rtw_read32 (Adapter,EFUSE_CTRL , &value32); +if (res) +return ; *pbuf = (u8)(value32 &0xff );
drivers/staging/r8188eu/core/rtw_fw.c +12 -4
@@ -194,10 +194,14 @@ static int fw_free_to_go(struct adapter *padapter) {u32 counter =0 ;u32 value32; +int res;/* polling CheckSum report */ do { - value32 =rtw_read32 (padapter,REG_MCUFWDL ); + res =rtw_read32 (padapter,REG_MCUFWDL , &value32); +if (res) +continue ; +if (value32 &FWDL_CHKSUM_RPT )break ; }while (counter++ <POLLING_READY_TIMEOUT_COUNT );
@@ -205,7 +209,10 @@ static int fw_free_to_go(struct adapter *padapter)if (counter >=POLLING_READY_TIMEOUT_COUNT )return _FAIL; - value32 =rtw_read32 (padapter,REG_MCUFWDL ); + res =rtw_read32 (padapter,REG_MCUFWDL , &value32); +if (res) +return _FAIL; + value32 |=MCUFWDL_RDY ; value32 &= ~WINTINI_RDY ;rtw_write32 (padapter,REG_MCUFWDL , value32);
@@ -215,9 +222,10 @@ static int fw_free_to_go(struct adapter *padapter)/* polling for FW ready */ counter =0 ;do { - value32 =rtw_read32 (padapter,REG_MCUFWDL ); -if (value32 &WINTINI_RDY ) + res =rtw_read32 (padapter,REG_MCUFWDL , &value32); +if (!res && value32 &WINTINI_RDY )return _SUCCESS; +udelay (5 ); }while (counter++ <POLLING_READY_TIMEOUT_COUNT );
drivers/staging/r8188eu/core/rtw_mlme_ext.c +12 -2
@@ -6017,6 +6017,7 @@ static void mlme_join(struct adapter *adapter, int type) {struct mlme_priv *mlmepriv = &adapter->mlmepriv;u8 retry_limit =0x30 , reg; +u32 reg32;int res;switch (type) {
@@ -6025,8 +6026,12 @@ static void mlme_join(struct adapter *adapter, int type)/* enable to rx data frame, accept all data frame */ rtw_write16 (adapter,REG_RXFLTMAP2 ,0xFFFF ); + res =rtw_read32 (adapter,REG_RCR , ®32); +if (res) +return ; +rtw_write32 (adapter,REG_RCR , -rtw_read32 (adapter,REG_RCR ) |RCR_CBSSID_DATA |RCR_CBSSID_BCN ); + reg32 |RCR_CBSSID_DATA |RCR_CBSSID_BCN );if (check_fwstate (mlmepriv,WIFI_STATION_STATE )) { retry_limit =48 ;
@@ -6839,9 +6844,14 @@ static u8 chk_ap_is_alive(struct sta_info *psta)static int rtl8188e_sreset_linked_status_check (struct adapter *padapter) { -u32 rx_dma_status =rtw_read32 (padapter,REG_RXDMA_STATUS ); +u32 rx_dma_status; +int res;u8 reg; + res =rtw_read32 (padapter,REG_RXDMA_STATUS , &rx_dma_status); +if (res) +return res; +if (rx_dma_status !=0x00 )rtw_write32 (padapter,REG_RXDMA_STATUS , rx_dma_status);
drivers/staging/r8188eu/core/rtw_pwrctrl.c +8 -1
@@ -229,6 +229,9 @@ void rtw_set_ps_mode(struct adapter *padapter, u8 ps_mode, u8 smart_ps, u8 bcn_astatic bool lps_rf_on (struct adapter *adapter) { +int res; +u32 reg; +/* When we halt NIC, we should check if FW LPS is leave. */ if (adapter->pwrctrlpriv.rf_pwrstate == rf_off) {/* If it is in HW/SW Radio OFF or IPS state, we do not check Fw LPS Leave, */
@@ -236,7 +239,11 @@ static bool lps_rf_on(struct adapter *adapter)return true; } -if (rtw_read32 (adapter,REG_RCR ) &0x00070000 ) + res =rtw_read32 (adapter,REG_RCR , ®); +if (res) +return false; + +if (reg &0x00070000 )return false;return true;
drivers/staging/r8188eu/hal/Hal8188ERateAdaptive.c +17 -4
@@ -279,6 +279,7 @@ static int odm_ARFBRefresh_8188E(struct odm_dm_struct *dm_odm, struct odm_ra_inf {/* Wilson 2011/10/26 */ u32 MaskFromReg;s8 i; +int res;switch (pRaInfo->RateID) {case RATR_INX_WIRELESS_NGB :
@@ -303,19 +304,31 @@ static int odm_ARFBRefresh_8188E(struct odm_dm_struct *dm_odm, struct odm_ra_inf pRaInfo->RAUseRate = (pRaInfo->RateMask) &0x0000000d ;break ;case 12 : - MaskFromReg =rtw_read32 (dm_odm->Adapter,REG_ARFR0 ); + res =rtw_read32 (dm_odm->Adapter,REG_ARFR0 , &MaskFromReg); +if (res) +return res; + pRaInfo->RAUseRate = (pRaInfo->RateMask) & MaskFromReg;break ;case 13 : - MaskFromReg =rtw_read32 (dm_odm->Adapter,REG_ARFR1 ); + res =rtw_read32 (dm_odm->Adapter,REG_ARFR1 , &MaskFromReg); +if (res) +return res; + pRaInfo->RAUseRate = (pRaInfo->RateMask) & MaskFromReg;break ;case 14 : - MaskFromReg =rtw_read32 (dm_odm->Adapter,REG_ARFR2 ); + res =rtw_read32 (dm_odm->Adapter,REG_ARFR2 , &MaskFromReg); +if (res) +return res; + pRaInfo->RAUseRate = (pRaInfo->RateMask) & MaskFromReg;break ;case 15 : - MaskFromReg =rtw_read32 (dm_odm->Adapter,REG_ARFR3 ); + res =rtw_read32 (dm_odm->Adapter,REG_ARFR3 , &MaskFromReg); +if (res) +return res; + pRaInfo->RAUseRate = (pRaInfo->RateMask) & MaskFromReg;break ;default :
drivers/staging/r8188eu/hal/HalPhyRf_8188e.c +2 -1
@@ -483,7 +483,8 @@ static void _PHY_SaveMACRegisters( MACBackup[i] = reg; } - MACBackup[i] =rtw_read32 (adapt, MACReg[i]); + res =rtw_read32 (adapt, MACReg[i], MACBackup + i); + (void )res; }static void reload_adda_reg (struct adapter *adapt,u32 *ADDAReg,u32 *ADDABackup,u32 RegiesterNum)
drivers/staging/r8188eu/hal/rtl8188e_hal_init.c +26 -14
@@ -216,6 +216,7 @@ static int efuse_read_phymap_from_txpktbuf(u16 limit = *size;u8 reg;u8 *pos = content; +u32 reg32;if (bcnhead <0 ) {/* if not valid */ res =rtw_read8 (adapter,REG_TDECTRL +1 , ®);
@@ -246,8 +247,17 @@ static int efuse_read_phymap_from_txpktbuf( }while (time_before (jiffies, timeout));/* data from EEPROM needs to be in LE */ - lo32 =cpu_to_le32 (rtw_read32 (adapter,REG_PKTBUF_DBG_DATA_L )); - hi32 =cpu_to_le32 (rtw_read32 (adapter,REG_PKTBUF_DBG_DATA_H )); + res =rtw_read32 (adapter,REG_PKTBUF_DBG_DATA_L , ®32); +if (res) +return res; + + lo32 =cpu_to_le32 (reg32); + + res =rtw_read32 (adapter,REG_PKTBUF_DBG_DATA_H , ®32); +if (res) +return res; + + hi32 =cpu_to_le32 (reg32);if (i ==0 ) {u16 reg;
@@ -548,8 +558,12 @@ void rtl8188e_read_chip_version(struct adapter *padapter)u32 value32;struct HAL_VERSION ChipVersion;struct hal_data_8188e *pHalData = &padapter->haldata; +int res; + + res =rtw_read32 (padapter,REG_SYS_CFG , &value32); +if (res) +return ; - value32 =rtw_read32 (padapter,REG_SYS_CFG ); ChipVersion.ChipType = ((value32 &RTL_ID ) ?TEST_CHIP :NORMAL_CHIP ); ChipVersion.VendorType = ((value32 &VENDOR_ID ) ?CHIP_VENDOR_UMC :CHIP_VENDOR_TSMC );
@@ -596,26 +610,24 @@ void hal_notch_filter_8188e(struct adapter *adapter, bool enable)/* */ static s32 _LLTWrite (struct adapter *padapter,u32 address,u32 data) { -s32 status = _SUCCESS; -s32 count =0 ; +s32 count;u32 value =_LLT_INIT_ADDR (address) |_LLT_INIT_DATA (data) |_LLT_OP (_LLT_WRITE_ACCESS);u16 LLTReg =REG_LLT_INIT ; +int res;rtw_write32 (padapter, LLTReg, value);/* polling */ -do { - value =rtw_read32 (padapter, LLTReg); -if (_LLT_NO_ACTIVE ==_LLT_OP_VALUE (value)) -break ; +for (count =0 ; count <=POLLING_LLT_THRESHOLD ; count++) { + res =rtw_read32 (padapter, LLTReg, &value); +if (res) +continue ; -if (count >POLLING_LLT_THRESHOLD ) { - status = _FAIL; +if (_LLT_NO_ACTIVE ==_LLT_OP_VALUE (value))break ; - } - }while (count++); + } -return status; +return count >POLLING_LLT_THRESHOLD ? _FAIL : _SUCCESS; }s32 InitLLTTable (struct adapter *padapter,u8 txpktbuf_bndy)
drivers/staging/r8188eu/hal/rtl8188e_phycfg.c +10 -2
@@ -56,8 +56,12 @@ rtl8188e_PHY_QueryBBReg( ) {u32 ReturnValue =0 , OriginalValue, BitShift; +int res; + + res =rtw_read32 (Adapter, RegAddr, &OriginalValue); +if (res) +return 0 ; - OriginalValue =rtw_read32 (Adapter, RegAddr); BitShift =phy_CalculateBitShift (BitMask); ReturnValue = (OriginalValue & BitMask) >> BitShift;return ReturnValue;
@@ -84,9 +88,13 @@ rtl8188e_PHY_QueryBBReg(void rtl8188e_PHY_SetBBReg (struct adapter *Adapter,u32 RegAddr,u32 BitMask,u32 Data) {u32 OriginalValue, BitShift; +int res;if (BitMask != bMaskDWord) {/* if not "double word" write */ - OriginalValue =rtw_read32 (Adapter, RegAddr); + res =rtw_read32 (Adapter, RegAddr, &OriginalValue); +if (res) +return ; + BitShift =phy_CalculateBitShift (BitMask); Data = ((OriginalValue & (~BitMask)) | (Data << BitShift)); }
drivers/staging/r8188eu/hal/usb_halinit.c +45 -8
124 lines not on this page · raw message
drivers/staging/r8188eu/hal/usb_ops_linux.c +9 -4
@@ -120,16 +120,21 @@ int __must_check rtw_read16(struct adapter *adapter, u32 addr, u16 *data)return 0 ; } -u32 rtw_read32 (struct adapter *adapter,u32 addr) +int __must_check rtw_read32 (struct adapter *adapter,u32 addr,u32 *data) {struct io_priv *io_priv = &adapter->iopriv;struct intf_hdl *intf = &io_priv->intf;u16 value = addr &0xffff ; -__le32 data; +__le32 le_data; +int res; -usb_read (intf, value, &data,4 ); + res =usb_read (intf, value, &le_data,4 ); +if (res) +return res; -return le32_to_cpu (data); + *data =le32_to_cpu (le_data); + +return 0 ; }int rtw_write8 (struct adapter *adapter,u32 addr,u8 val)
drivers/staging/r8188eu/include/rtw_io.h +1 -1
@@ -222,7 +222,7 @@ void _rtw_attrib_write(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);int __must_check rtw_read8 (struct adapter *adapter,u32 addr,u8 *data);int __must_check rtw_read16 (struct adapter *adapter,u32 addr,u16 *data); -u32 rtw_read32 (struct adapter *adapter,u32 addr); +int __must_check rtw_read32 (struct adapter *adapter,u32 addr,u32 *data);void _rtw_read_mem (struct adapter *adapter,u32 addr,u32 cnt,u8 *pmem);u32 rtw_read_port (struct adapter *adapter,u8 *pmem);void rtw_read_port_cancel (struct adapter *adapter);
drivers/staging/r8188eu/os_dep/ioctl_linux.c +22 -5
@@ -3126,18 +3126,29 @@ static int rtw_rereg_nd_name(struct net_device *dev,static void mac_reg_dump (struct adapter *padapter) {int i, j =1 ; +u32 reg; +int res; +pr_info ("\n ======= MAC REG =======\n" );for (i =0x0 ; i <0x300 ; i +=4 ) {if (j %4 ==1 )pr_info ("0x%02x" , i); -pr_info (" 0x%08x " ,rtw_read32 (padapter, i)); + + res =rtw_read32 (padapter, i, ®); +if (!res) +pr_info (" 0x%08x " , reg); +if ((j++) %4 ==0 )pr_info ("\n" ); }for (i =0x400 ; i <0x800 ; i +=4 ) {if (j %4 ==1 )pr_info ("0x%02x" , i); -pr_info (" 0x%08x " ,rtw_read32 (padapter, i)); + + res =rtw_read32 (padapter, i, ®); +if (!res) +pr_info (" 0x%08x " , reg); +if ((j++) %4 ==0 )pr_info ("\n" ); }
@@ -3145,13 +3156,18 @@ static void mac_reg_dump(struct adapter *padapter)static void bb_reg_dump (struct adapter *padapter) { -int i, j =1 ; +int i, j =1 , res; +u32 reg; +pr_info ("\n ======= BB REG =======\n" );for (i =0x800 ; i <0x1000 ; i +=4 ) {if (j %4 ==1 )pr_info ("0x%02x" , i); -pr_info (" 0x%08x " ,rtw_read32 (padapter, i)); + res =rtw_read32 (padapter, i, ®); +if (!res) +pr_info (" 0x%08x " , reg); +if ((j++) %4 ==0 )pr_info ("\n" ); }
@@ -3398,7 +3414,8 @@ static int rtw_dbg_port(struct net_device *dev,if (rtl8188e_IOL_exec_cmds_sync (padapter, xmit_frame,5000 ,0 ) != _SUCCESS) ret = -EPERM ; -rtw_read32 (padapter, reg); +/* FIXME: is this read necessary? */ + ret =rtw_read32 (padapter, reg, &write_num); }break ; }
drivers/staging/r8188eu/os_dep/os_intfs.c +11 -2
@@ -741,6 +741,7 @@ static void rtw_fifo_cleanup(struct adapter *adapter)struct pwrctrl_priv *pwrpriv = &adapter->pwrctrlpriv;u8 trycnt =100 ;int res; +u32 reg;/* pause tx */ rtw_write8 (adapter,REG_TXPAUSE ,0xff );
@@ -753,10 +754,18 @@ static void rtw_fifo_cleanup(struct adapter *adapter)if (!pwrpriv->bkeepfwalive) {/* RX DMA stop */ + res =rtw_read32 (adapter,REG_RXPKT_NUM , ®); +if (res) +return ; +rtw_write32 (adapter,REG_RXPKT_NUM , - (rtw_read32 (adapter,REG_RXPKT_NUM ) |RW_RELEASE_EN )); + (reg |RW_RELEASE_EN ));do { -if (!(rtw_read32 (adapter,REG_RXPKT_NUM ) &RXDMA_IDLE )) + res =rtw_read32 (adapter,REG_RXPKT_NUM , ®); +if (res) +continue ; + +if (!(reg &RXDMA_IDLE ))break ; }while (trycnt--);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 264/365 usb: cdns3 fix use-after-free at workaround 2
In reply to Greg Kroah-HartmanFrom: Frank Li <[email protected]>
[ Upstream commit 7d602f30149a117eea260208b1661bc404c21dfd ]
BUG: KFENCE: use-after-free read in __list_del_entry_valid+0x10/0xac
cdns3_wa2_remove_old_request()
{
...
kfree(priv_req->request.buf);
cdns3_gadget_ep_free_request(&priv_ep->endpoint, &priv_req->request);
list_del_init(&priv_req->list);
^^^ use after free
...
}cdns3_gadget_ep_free_request() free the space pointed by priv_req, but priv_req is used in the following list_del_init().
This patch move list_del_init() before cdns3_gadget_ep_free_request().
--- drivers/usb/cdns3/cdns3-gadget.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/cdns3/cdns3-gadget.c +1 -1
@@ -625,9 +625,9 @@ static void cdns3_wa2_remove_old_request(struct cdns3_endpoint *priv_ep)trace_cdns3_wa2 (priv_ep,"removes eldest request" );kfree (priv_req->request.buf); +list_del_init (&priv_req->list);cdns3_gadget_ep_free_request (&priv_ep->endpoint, &priv_req->request); -list_del_init (&priv_req->list); --priv_ep->wa2_counter;if (!chain)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 265/365 usb: gadget: uvc: calculate the number of request depending on framesize
In reply to Greg Kroah-HartmanFrom: Michael Grzeschik <[email protected]>
[ Upstream commit 87d76b5f1d8eeb49efa16e2018e188864cbb9401 ]
The current limitation of possible number of requests being handled is dependent on the gadget speed. It makes more sense to depend on the typical frame size when calculating the number of requests. This patch is changing this and is using the previous limits as boundaries for reasonable minimum and maximum number of requests.
For a 1080p jpeg encoded video stream with a maximum imagesize of e.g. 800kB with a maxburst of 8 and an multiplier of 1 the resulting number of requests is calculated to 49.
800768 1
nreqs = ------ * -------------- ~= 49
2 (1024 * 8 * 1)--- drivers/usb/gadget/function/uvc_queue.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-)
drivers/usb/gadget/function/uvc_queue.c +12 -5
@@ -44,7 +44,8 @@ static int uvc_queue_setup(struct vb2_queue *vq, {struct uvc_video_queue *queue =vb2_get_drv_priv (vq); struct uvc_video *video = container_of(queue, struct uvc_video, queue); -struct usb_composite_dev *cdev = video->uvc->func.config->cdev; +unsigned int req_size; +unsigned int nreq;if (*nbuffers >UVC_MAX_VIDEO_BUFFERS ) *nbuffers =UVC_MAX_VIDEO_BUFFERS ;
@@ -53,10 +54,16 @@ static int uvc_queue_setup(struct vb2_queue *vq, sizes[0 ] = video->imagesize; -if (cdev->gadget->speed <USB_SPEED_SUPER ) - video->uvc_num_requests =4 ; -else - video->uvc_num_requests =64 ; + req_size = video->ep->maxpacket + * max_t(unsigned int, video->ep->maxburst, 1) + * (video->ep->mult); + +/* We divide by two, to increase the chance to run +* into fewer requests for smaller framesizes. +*/ + nreq =DIV_ROUND_UP (DIV_ROUND_UP (sizes[0 ],2 ), req_size); + nreq =clamp (nreq,4U ,64U ); + video->uvc_num_requests = nreq;return 0 ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 266/365 usb: gadget: uvc: call uvc uvcg_warn on completed status instead of uvcg_info
In reply to Greg Kroah-HartmanFrom: Michael Grzeschik <[email protected]>
[ Upstream commit a725d0f6dfc5d3739d6499f30ec865305ba3544d ]
Likewise to the uvcvideo hostside driver, this patch is changing the usb_request message of an non zero completion handler call from dev_info to dev_warn.
--- drivers/usb/gadget/function/uvc_video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/gadget/function/uvc_video.c +1 -1
@@ -261,7 +261,7 @@ uvc_video_complete(struct usb_ep *ep, struct usb_request *req)break ;default : -uvcg_info (&video->uvc->func, +uvcg_warn (&video->uvc->func,"VS request completed with status %d.\n" , req->status);uvcg_queue_cancel (queue,0 );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 267/365 PCI: aardvark: Fix reporting Slot capabilities on emulated bridge
In reply to Greg Kroah-HartmanFrom: Pali Rohár <[email protected]>
[ Upstream commit bcdb6fd4f3e9ac1097698c8d8f56b70853b49873 ]
Slot capabilities are currently not reported because emulated bridge does not report the PCI_EXP_FLAGS_SLOT flag.
Set PCI_EXP_FLAGS_SLOT to let the kernel know that PCI_EXP_SLT* registers are supported.
Move setting of PCI_EXP_SLTCTL register from "dynamic" pcie_conf_read function to static buffer as it is only statically filled the PCI_EXP_SLTSTA_PDS flag and dynamic read callback is not needed for this register.
Set Presence State Bit to 1 since there is no support for unplugging the card and there is currently no platform able to detect presence of a card - in such a case the bit needs to be set to 1.
Finally correctly set Physical Slot Number to 1 since there is only one port and zero value is reserved for ports within the same silicon as Root Port which is not our case for Aardvark HW.
--- drivers/pci/controller/pci-aardvark.c | 33 +++++++++++++++++++-------- 1 file changed, 24 insertions(+), 9 deletions(-)
drivers/pci/controller/pci-aardvark.c +24 -9
@@ -8,6 +8,7 @@* Author: Hezi Shahmoon <[email protected]> */ +#include <linux/bitfield.h> #include <linux/delay.h> #include <linux/gpio/consumer.h> #include <linux/interrupt.h>
@@ -857,14 +858,11 @@ advk_pci_bridge_emul_pcie_conf_read(struct pci_bridge_emul *bridge,switch (reg) { -case PCI_EXP_SLTCTL : - *value =PCI_EXP_SLTSTA_PDS <<16 ; -return PCI_BRIDGE_EMUL_HANDLED ; -/* -* PCI_EXP_RTCTL and PCI_EXP_RTSTA are also supported, but do not need -* to be handled here, because their values are stored in emulated -* config space buffer, and we read them from there when needed. +* PCI_EXP_SLTCAP, PCI_EXP_SLTCTL, PCI_EXP_RTCTL and PCI_EXP_RTSTA are +* also supported, but do not need to be handled here, because their +* values are stored in emulated config space buffer, and we read them +* from there when needed. */ case PCI_EXP_LNKCAP : {
@@ -977,8 +975,25 @@ static int advk_sw_pci_bridge_init(struct advk_pcie *pcie)/* Support interrupt A for MSI feature */ bridge->conf.intpin =PCI_INTERRUPT_INTA ; -/* Aardvark HW provides PCIe Capability structure in version 2 */ - bridge->pcie_conf.cap =cpu_to_le16 (2 ); +/* +* Aardvark HW provides PCIe Capability structure in version 2 and +* indicate slot support, which is emulated. +*/ + bridge->pcie_conf.cap =cpu_to_le16 (2 |PCI_EXP_FLAGS_SLOT ); + +/* +* Set Presence Detect State bit permanently since there is no support +* for unplugging the card nor detecting whether it is plugged. (If a +* platform exists in the future that supports it, via a GPIO for +* example, it should be implemented via this bit.) +* +* Set physical slot number to 1 since there is only one port and zero +* value is reserved for ports within the same silicon as Root Port +* which is not our case. +*/ + bridge->pcie_conf.slotcap =cpu_to_le32 (FIELD_PREP (PCI_EXP_SLTCAP_PSN , +1 )); + bridge->pcie_conf.slotsta =cpu_to_le16 (PCI_EXP_SLTSTA_PDS );/* Indicates supports for Completion Retry Status */ bridge->pcie_conf.rootcap =cpu_to_le16 (PCI_EXP_RTCAP_CRSVIS );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 268/365 scsi: ufs: core: Add UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS
In reply to Greg Kroah-HartmanFrom: Yoshihiro Shimoda <[email protected]>
[ Upstream commit 6554400d6f66b9494a0c0f07712ab0a9d307eb01 ]
Add UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS for host controllers which do not support 64-bit addressing.
--- drivers/ufs/core/ufshcd.c | 2 ++ include/ufs/ufshcd.h | 6 ++++++ 2 files changed, 8 insertions(+)
drivers/ufs/core/ufshcd.c +2 -0
@@ -2227,6 +2227,8 @@ static inline int ufshcd_hba_capabilities(struct ufs_hba *hba)int err; hba->capabilities =ufshcd_readl (hba,REG_CONTROLLER_CAPABILITIES ); +if (hba->quirks &UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS ) + hba->capabilities &= ~MASK_64_ADDRESSING_SUPPORT ;/* nutrs and nutmrs are 0 based values */ hba->nutrs = (hba->capabilities &MASK_TRANSFER_REQUESTS_SLOTS ) +1 ;
include/ufs/ufshcd.h +6 -0
@@ -577,6 +577,12 @@ enum ufshcd_quirks {* support physical host configuration. */ UFSHCD_QUIRK_SKIP_PH_CONFIGURATION =1 <<16 , + +/* +* This quirk needs to be enabled if the host controller has +* 64-bit addressing supported capability but it doesn't work. +*/ + UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS = 1 << 17, }; enum ufshcd_caps {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 269/365 scsi: ufs: core: Add UFSHCD_QUIRK_HIBERN_FASTAUTO
In reply to Greg Kroah-HartmanFrom: Yoshihiro Shimoda <[email protected]>
[ Upstream commit 2f11bbc2c7f37e3a6151ac548b1c0679cc90ea83 ]
Add UFSHCD_QUIRK_HIBERN_FASTAUTO quirk for host controllers which supports auto-hibernate the capability but only FASTAUTO mode.
--- drivers/ufs/core/ufshcd.c | 9 +++++++-- include/ufs/ufshcd.h | 6 ++++++ 2 files changed, 13 insertions(+), 2 deletions(-)
drivers/ufs/core/ufshcd.c +7 -2
@@ -4292,8 +4292,13 @@ static int ufshcd_get_max_pwr_mode(struct ufs_hba *hba)if (hba->max_pwr_info.is_valid)return 0 ; - pwr_info->pwr_tx =FAST_MODE ; - pwr_info->pwr_rx =FAST_MODE ; +if (hba->quirks &UFSHCD_QUIRK_HIBERN_FASTAUTO ) { + pwr_info->pwr_tx =FASTAUTO_MODE ; + pwr_info->pwr_rx =FASTAUTO_MODE ; + }else { + pwr_info->pwr_tx =FAST_MODE ; + pwr_info->pwr_rx =FAST_MODE ; + } pwr_info->hs_rate =PA_HS_MODE_B ;/* Get the connected lane count */
include/ufs/ufshcd.h +6 -0
@@ -583,6 +583,12 @@ enum ufshcd_quirks {* 64-bit addressing supported capability but it doesn't work. */ UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS =1 <<17 , + +/* +* This quirk needs to be enabled if the host controller has +* auto-hibernate capability but it's FASTAUTO only. +*/ + UFSHCD_QUIRK_HIBERN_FASTAUTO = 1 << 18, }; enum ufshcd_caps {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 270/365 irqchip/tegra: Fix overflow implicit truncation warnings
In reply to Greg Kroah-HartmanFrom: Sai Prakash Ranjan <[email protected]>
[ Upstream commit 443685992bda9bb4f8b17fc02c9f6c60e62b1461 ]
Fix -Woverflow warnings for tegra irqchip driver which is a result of moving arm64 custom MMIO accessor macros to asm-generic function implementations giving a bonus type-checking now and uncovering these overflow warnings.
drivers/irqchip/irq-tegra.c: In function ‘tegra_ictlr_suspend’:drivers/irqchip/irq-tegra.c:151:18: warning: large integer implicitly truncated to unsigned type [-Woverflow]
writel_relaxed(~0ul, ictlr + ICTLR_COP_IER_CLR);
^--- drivers/irqchip/irq-tegra.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/irqchip/irq-tegra.c +5 -5
@@ -148,10 +148,10 @@ static int tegra_ictlr_suspend(void) lic->cop_iep[i] =readl_relaxed (ictlr +ICTLR_COP_IEP_CLASS );/* Disable COP interrupts */ -writel_relaxed (~0ul , ictlr +ICTLR_COP_IER_CLR ); +writel_relaxed (GENMASK (31 ,0 ), ictlr +ICTLR_COP_IER_CLR );/* Disable CPU interrupts */ -writel_relaxed (~0ul , ictlr +ICTLR_CPU_IER_CLR ); +writel_relaxed (GENMASK (31 ,0 ), ictlr +ICTLR_CPU_IER_CLR );/* Enable the wakeup sources of ictlr */ writel_relaxed (lic->ictlr_wake_mask[i], ictlr +ICTLR_CPU_IER_SET );
@@ -172,12 +172,12 @@ static void tegra_ictlr_resume(void)writel_relaxed (lic->cpu_iep[i], ictlr +ICTLR_CPU_IEP_CLASS ); -writel_relaxed (~0ul , ictlr +ICTLR_CPU_IER_CLR ); +writel_relaxed (GENMASK (31 ,0 ), ictlr +ICTLR_CPU_IER_CLR );writel_relaxed (lic->cpu_ier[i], ictlr +ICTLR_CPU_IER_SET );writel_relaxed (lic->cop_iep[i], ictlr +ICTLR_COP_IEP_CLASS ); -writel_relaxed (~0ul , ictlr +ICTLR_COP_IER_CLR ); +writel_relaxed (GENMASK (31 ,0 ), ictlr +ICTLR_COP_IER_CLR );writel_relaxed (lic->cop_ier[i], ictlr +ICTLR_COP_IER_SET ); }
@@ -312,7 +312,7 @@ static int __init tegra_ictlr_init(struct device_node *node, lic->base[i] = base;/* Disable all interrupts */ -writel_relaxed (~0UL , base +ICTLR_CPU_IER_CLR ); +writel_relaxed (GENMASK (31 ,0 ), base +ICTLR_CPU_IER_CLR );/* All interrupts target IRQ */ writel_relaxed (0 , base +ICTLR_CPU_IEP_CLASS );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 271/365 drm/meson: Fix overflow implicit truncation warnings
In reply to Greg Kroah-HartmanFrom: Sai Prakash Ranjan <[email protected]>
[ Upstream commit 98692f52c588225034cbff458622c2c06dfcb544 ]
Fix -Woverflow warnings for drm/meson driver which is a result of moving arm64 custom MMIO accessor macros to asm-generic function implementations giving a bonus type-checking now and uncovering these overflow warnings.
drivers/gpu/drm/meson/meson_viu.c: In function ‘meson_viu_init’:drivers/gpu/drm/meson/meson_registers.h:1826:48: error: large integer implicitly truncated to unsigned type [-Werror=overflow]
#define VIU_OSD_BLEND_REORDER(dest, src) ((src) << (dest * 4))
^
drivers/gpu/drm/meson/meson_viu.c:472:18: note: in expansion of macro ‘VIU_OSD_BLEND_REORDER’
writel_relaxed(VIU_OSD_BLEND_REORDER(0, 1) |
^~~~~~~~~~~~~~~~~~~~~--- drivers/gpu/drm/meson/meson_viu.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-)
drivers/gpu/drm/meson/meson_viu.c +11 -11
@@ -469,17 +469,17 @@ void meson_viu_init(struct meson_drm *priv) priv->io_base + _REG(VD2_IF0_LUMA_FIFO_SIZE));if (meson_vpu_is_compatible (priv,VPU_COMPATIBLE_G12A )) { -writel_relaxed (VIU_OSD_BLEND_REORDER (0 ,1 ) | -VIU_OSD_BLEND_REORDER (1 ,0 ) | -VIU_OSD_BLEND_REORDER (2 ,0 ) | -VIU_OSD_BLEND_REORDER (3 ,0 ) | -VIU_OSD_BLEND_DIN_EN (1 ) | -VIU_OSD_BLEND1_DIN3_BYPASS_TO_DOUT1 | -VIU_OSD_BLEND1_DOUT_BYPASS_TO_BLEND2 | -VIU_OSD_BLEND_DIN0_BYPASS_TO_DOUT0 | -VIU_OSD_BLEND_BLEN2_PREMULT_EN (1 ) | -VIU_OSD_BLEND_HOLD_LINES (4 ), - priv->io_base +_REG (VIU_OSD_BLEND_CTRL )); +u32 val = (u32 )VIU_OSD_BLEND_REORDER (0 ,1 ) | + (u32 )VIU_OSD_BLEND_REORDER (1 ,0 ) | + (u32 )VIU_OSD_BLEND_REORDER (2 ,0 ) | + (u32 )VIU_OSD_BLEND_REORDER (3 ,0 ) | + (u32 )VIU_OSD_BLEND_DIN_EN (1 ) | + (u32 )VIU_OSD_BLEND1_DIN3_BYPASS_TO_DOUT1 | + (u32 )VIU_OSD_BLEND1_DOUT_BYPASS_TO_BLEND2 | + (u32 )VIU_OSD_BLEND_DIN0_BYPASS_TO_DOUT0 | + (u32 )VIU_OSD_BLEND_BLEN2_PREMULT_EN (1 ) | + (u32 )VIU_OSD_BLEND_HOLD_LINES (4 ); +writel_relaxed (val, priv->io_base +_REG (VIU_OSD_BLEND_CTRL ));writel_relaxed (OSD_BLEND_PATH_SEL_ENABLE , priv->io_base +_REG (OSD1_BLEND_SRC_CTRL ));
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 272/365 clk: ti: Stop using legacy clkctrl names for omap4 and 5
In reply to Greg Kroah-HartmanFrom: Tony Lindgren <[email protected]>
[ Upstream commit 255584b138343d4a28c6d25bd82d04b09460d672 ]
With the addition of clock-output-names, we can now unify the internal clock naming for omap4 and 5 to follow the other TI SoCs.
We are still using legacy clkctrl names for omap4 and 5 based on the clock manager name which is wrong. Instead, we want to use the clkctrl clock based naming.
We must now also drop the legacy TI_CLK_CLKCTRL_COMPAT quirk for the clkctrl clock.
This change will allow further devicetree warning cleanup as already done for am3/4 and dra7.
--- drivers/clk/ti/clk-44xx.c | 210 +++++++++++++++++++------------------- drivers/clk/ti/clk-54xx.c | 160 ++++++++++++++--------------- drivers/clk/ti/clkctrl.c | 4 - 3 files changed, 185 insertions(+), 189 deletions(-)
drivers/clk/ti/clk-44xx.c +105 -105
@@ -56,7 +56,7 @@ static const struct omap_clkctrl_bit_data omap4_aess_bit_data[] __initconst = { };static const char *const omap4_func_dmic_abe_gfclk_parents[]__initconst = { -"abe_cm:clk:0018:26" , +"abe-clkctrl:0018:26" ,"pad_clks_ck" ,"slimbus_clk" ,NULL ,
@@ -76,7 +76,7 @@ static const struct omap_clkctrl_bit_data omap4_dmic_bit_data[] __initconst = { };static const char *const omap4_func_mcasp_abe_gfclk_parents[]__initconst = { -"abe_cm:clk:0020:26" , +"abe-clkctrl:0020:26" ,"pad_clks_ck" ,"slimbus_clk" ,NULL ,
@@ -89,7 +89,7 @@ static const struct omap_clkctrl_bit_data omap4_mcasp_bit_data[] __initconst = { };static const char *const omap4_func_mcbsp1_gfclk_parents[]__initconst = { -"abe_cm:clk:0028:26" , +"abe-clkctrl:0028:26" ,"pad_clks_ck" ,"slimbus_clk" ,NULL ,
@@ -102,7 +102,7 @@ static const struct omap_clkctrl_bit_data omap4_mcbsp1_bit_data[] __initconst = };static const char *const omap4_func_mcbsp2_gfclk_parents[]__initconst = { -"abe_cm:clk:0030:26" , +"abe-clkctrl:0030:26" ,"pad_clks_ck" ,"slimbus_clk" ,NULL ,
@@ -115,7 +115,7 @@ static const struct omap_clkctrl_bit_data omap4_mcbsp2_bit_data[] __initconst = };static const char *const omap4_func_mcbsp3_gfclk_parents[]__initconst = { -"abe_cm:clk:0038:26" , +"abe-clkctrl:0038:26" ,"pad_clks_ck" ,"slimbus_clk" ,NULL ,
@@ -183,18 +183,18 @@ static const struct omap_clkctrl_bit_data omap4_timer8_bit_data[] __initconst =static const struct omap_clkctrl_reg_data omap4_abe_clkctrl_regs[]__initconst = { {OMAP4_L4_ABE_CLKCTRL ,NULL ,0 ,"ocp_abe_iclk" }, - {OMAP4_AESS_CLKCTRL , omap4_aess_bit_data,CLKF_SW_SUP ,"abe_cm:clk:0008:24" }, + {OMAP4_AESS_CLKCTRL , omap4_aess_bit_data,CLKF_SW_SUP ,"abe-clkctrl:0008:24" }, {OMAP4_MCPDM_CLKCTRL ,NULL ,CLKF_SW_SUP ,"pad_clks_ck" }, - {OMAP4_DMIC_CLKCTRL , omap4_dmic_bit_data,CLKF_SW_SUP ,"abe_cm:clk:0018:24" }, - {OMAP4_MCASP_CLKCTRL , omap4_mcasp_bit_data,CLKF_SW_SUP ,"abe_cm:clk:0020:24" }, - {OMAP4_MCBSP1_CLKCTRL , omap4_mcbsp1_bit_data,CLKF_SW_SUP ,"abe_cm:clk:0028:24" }, - {OMAP4_MCBSP2_CLKCTRL , omap4_mcbsp2_bit_data,CLKF_SW_SUP ,"abe_cm:clk:0030:24" }, - {OMAP4_MCBSP3_CLKCTRL , omap4_mcbsp3_bit_data,CLKF_SW_SUP ,"abe_cm:clk:0038:24" }, - {OMAP4_SLIMBUS1_CLKCTRL , omap4_slimbus1_bit_data,CLKF_SW_SUP ,"abe_cm:clk:0040:8" }, - {OMAP4_TIMER5_CLKCTRL , omap4_timer5_bit_data,CLKF_SW_SUP ,"abe_cm:clk:0048:24" }, - {OMAP4_TIMER6_CLKCTRL , omap4_timer6_bit_data,CLKF_SW_SUP ,"abe_cm:clk:0050:24" }, - {OMAP4_TIMER7_CLKCTRL , omap4_timer7_bit_data,CLKF_SW_SUP ,"abe_cm:clk:0058:24" }, - {OMAP4_TIMER8_CLKCTRL , omap4_timer8_bit_data,CLKF_SW_SUP ,"abe_cm:clk:0060:24" }, + {OMAP4_DMIC_CLKCTRL , omap4_dmic_bit_data,CLKF_SW_SUP ,"abe-clkctrl:0018:24" }, + {OMAP4_MCASP_CLKCTRL , omap4_mcasp_bit_data,CLKF_SW_SUP ,"abe-clkctrl:0020:24" }, + {OMAP4_MCBSP1_CLKCTRL , omap4_mcbsp1_bit_data,CLKF_SW_SUP ,"abe-clkctrl:0028:24" }, + {OMAP4_MCBSP2_CLKCTRL , omap4_mcbsp2_bit_data,CLKF_SW_SUP ,"abe-clkctrl:0030:24" }, + {OMAP4_MCBSP3_CLKCTRL , omap4_mcbsp3_bit_data,CLKF_SW_SUP ,"abe-clkctrl:0038:24" }, + {OMAP4_SLIMBUS1_CLKCTRL , omap4_slimbus1_bit_data,CLKF_SW_SUP ,"abe-clkctrl:0040:8" }, + {OMAP4_TIMER5_CLKCTRL , omap4_timer5_bit_data,CLKF_SW_SUP ,"abe-clkctrl:0048:24" }, + {OMAP4_TIMER6_CLKCTRL , omap4_timer6_bit_data,CLKF_SW_SUP ,"abe-clkctrl:0050:24" }, + {OMAP4_TIMER7_CLKCTRL , omap4_timer7_bit_data,CLKF_SW_SUP ,"abe-clkctrl:0058:24" }, + {OMAP4_TIMER8_CLKCTRL , omap4_timer8_bit_data,CLKF_SW_SUP ,"abe-clkctrl:0060:24" }, {OMAP4_WD_TIMER3_CLKCTRL ,NULL ,CLKF_SW_SUP ,"sys_32k_ck" }, {0 }, };
@@ -287,7 +287,7 @@ static const struct omap_clkctrl_bit_data omap4_fdif_bit_data[] __initconst = {static const struct omap_clkctrl_reg_data omap4_iss_clkctrl_regs[]__initconst = { {OMAP4_ISS_CLKCTRL , omap4_iss_bit_data,CLKF_SW_SUP ,"ducati_clk_mux_ck" }, - {OMAP4_FDIF_CLKCTRL , omap4_fdif_bit_data,CLKF_SW_SUP ,"iss_cm:clk:0008:24" }, + {OMAP4_FDIF_CLKCTRL , omap4_fdif_bit_data,CLKF_SW_SUP ,"iss-clkctrl:0008:24" }, {0 }, };
@@ -320,7 +320,7 @@ static const struct omap_clkctrl_bit_data omap4_dss_core_bit_data[] __initconst };static const struct omap_clkctrl_reg_data omap4_l3_dss_clkctrl_regs[]__initconst = { - {OMAP4_DSS_CORE_CLKCTRL , omap4_dss_core_bit_data,CLKF_SW_SUP ,"l3_dss_cm:clk:0000:8" }, + {OMAP4_DSS_CORE_CLKCTRL , omap4_dss_core_bit_data,CLKF_SW_SUP ,"l3-dss-clkctrl:0000:8" }, {0 }, };
@@ -336,7 +336,7 @@ static const struct omap_clkctrl_bit_data omap4_gpu_bit_data[] __initconst = { };static const struct omap_clkctrl_reg_data omap4_l3_gfx_clkctrl_regs[]__initconst = { - {OMAP4_GPU_CLKCTRL , omap4_gpu_bit_data,CLKF_SW_SUP ,"l3_gfx_cm:clk:0000:24" }, + {OMAP4_GPU_CLKCTRL , omap4_gpu_bit_data,CLKF_SW_SUP ,"l3-gfx-clkctrl:0000:24" }, {0 }, };
@@ -372,12 +372,12 @@ static const struct omap_clkctrl_bit_data omap4_hsi_bit_data[] __initconst = { };static const char *const omap4_usb_host_hs_utmi_p1_clk_parents[]__initconst = { -"l3_init_cm:clk:0038:24" , +"l3-init-clkctrl:0038:24" ,NULL , };static const char *const omap4_usb_host_hs_utmi_p2_clk_parents[]__initconst = { -"l3_init_cm:clk:0038:25" , +"l3-init-clkctrl:0038:25" ,NULL , };
@@ -418,7 +418,7 @@ static const struct omap_clkctrl_bit_data omap4_usb_host_hs_bit_data[] __initcon };static const char *const omap4_usb_otg_hs_xclk_parents[]__initconst = { -"l3_init_cm:clk:0040:24" , +"l3-init-clkctrl:0040:24" ,NULL , };
@@ -452,14 +452,14 @@ static const struct omap_clkctrl_bit_data omap4_ocp2scp_usb_phy_bit_data[] __ini };static const struct omap_clkctrl_reg_data omap4_l3_init_clkctrl_regs[]__initconst = { - {OMAP4_MMC1_CLKCTRL , omap4_mmc1_bit_data,CLKF_SW_SUP ,"l3_init_cm:clk:0008:24" }, - {OMAP4_MMC2_CLKCTRL , omap4_mmc2_bit_data,CLKF_SW_SUP ,"l3_init_cm:clk:0010:24" }, - {OMAP4_HSI_CLKCTRL , omap4_hsi_bit_data,CLKF_HW_SUP ,"l3_init_cm:clk:0018:24" }, + {OMAP4_MMC1_CLKCTRL , omap4_mmc1_bit_data,CLKF_SW_SUP ,"l3-init-clkctrl:0008:24" }, + {OMAP4_MMC2_CLKCTRL , omap4_mmc2_bit_data,CLKF_SW_SUP ,"l3-init-clkctrl:0010:24" }, + {OMAP4_HSI_CLKCTRL , omap4_hsi_bit_data,CLKF_HW_SUP ,"l3-init-clkctrl:0018:24" }, {OMAP4_USB_HOST_HS_CLKCTRL , omap4_usb_host_hs_bit_data,CLKF_SW_SUP ,"init_60m_fclk" }, {OMAP4_USB_OTG_HS_CLKCTRL , omap4_usb_otg_hs_bit_data,CLKF_HW_SUP ,"l3_div_ck" }, {OMAP4_USB_TLL_HS_CLKCTRL , omap4_usb_tll_hs_bit_data,CLKF_HW_SUP ,"l4_div_ck" }, {OMAP4_USB_HOST_FS_CLKCTRL ,NULL ,CLKF_SW_SUP ,"func_48mc_fclk" }, - {OMAP4_OCP2SCP_USB_PHY_CLKCTRL , omap4_ocp2scp_usb_phy_bit_data,CLKF_HW_SUP ,"l3_init_cm:clk:00c0:8" }, + {OMAP4_OCP2SCP_USB_PHY_CLKCTRL , omap4_ocp2scp_usb_phy_bit_data,CLKF_HW_SUP ,"l3-init-clkctrl:00c0:8" }, {0 }, };
@@ -530,7 +530,7 @@ static const struct omap_clkctrl_bit_data omap4_gpio6_bit_data[] __initconst = { };static const char *const omap4_per_mcbsp4_gfclk_parents[]__initconst = { -"l4_per_cm:clk:00c0:26" , +"l4-per-clkctrl:00c0:26" ,"pad_clks_ck" ,NULL , };
@@ -570,12 +570,12 @@ static const struct omap_clkctrl_bit_data omap4_slimbus2_bit_data[] __initconst };static const struct omap_clkctrl_reg_data omap4_l4_per_clkctrl_regs[]__initconst = { - {OMAP4_TIMER10_CLKCTRL , omap4_timer10_bit_data,CLKF_SW_SUP ,"l4_per_cm:clk:0008:24" }, - {OMAP4_TIMER11_CLKCTRL , omap4_timer11_bit_data,CLKF_SW_SUP ,"l4_per_cm:clk:0010:24" }, - {OMAP4_TIMER2_CLKCTRL , omap4_timer2_bit_data,CLKF_SW_SUP ,"l4_per_cm:clk:0018:24" }, - {OMAP4_TIMER3_CLKCTRL , omap4_timer3_bit_data,CLKF_SW_SUP ,"l4_per_cm:clk:0020:24" }, - {OMAP4_TIMER4_CLKCTRL , omap4_timer4_bit_data,CLKF_SW_SUP ,"l4_per_cm:clk:0028:24" }, - {OMAP4_TIMER9_CLKCTRL , omap4_timer9_bit_data,CLKF_SW_SUP ,"l4_per_cm:clk:0030:24" }, + {OMAP4_TIMER10_CLKCTRL , omap4_timer10_bit_data,CLKF_SW_SUP ,"l4-per-clkctrl:0008:24" }, + {OMAP4_TIMER11_CLKCTRL , omap4_timer11_bit_data,CLKF_SW_SUP ,"l4-per-clkctrl:0010:24" }, + {OMAP4_TIMER2_CLKCTRL , omap4_timer2_bit_data,CLKF_SW_SUP ,"l4-per-clkctrl:0018:24" }, + {OMAP4_TIMER3_CLKCTRL , omap4_timer3_bit_data,CLKF_SW_SUP ,"l4-per-clkctrl:0020:24" }, + {OMAP4_TIMER4_CLKCTRL , omap4_timer4_bit_data,CLKF_SW_SUP ,"l4-per-clkctrl:0028:24" }, + {OMAP4_TIMER9_CLKCTRL , omap4_timer9_bit_data,CLKF_SW_SUP ,"l4-per-clkctrl:0030:24" }, {OMAP4_ELM_CLKCTRL ,NULL ,0 ,"l4_div_ck" }, {OMAP4_GPIO2_CLKCTRL , omap4_gpio2_bit_data,CLKF_HW_SUP ,"l4_div_ck" }, {OMAP4_GPIO3_CLKCTRL , omap4_gpio3_bit_data,CLKF_HW_SUP ,"l4_div_ck" },
@@ -588,14 +588,14 @@ static const struct omap_clkctrl_reg_data omap4_l4_per_clkctrl_regs[] __initcons { OMAP4_I2C3_CLKCTRL, NULL, CLKF_SW_SUP, "func_96m_fclk" }, { OMAP4_I2C4_CLKCTRL, NULL, CLKF_SW_SUP, "func_96m_fclk" }, { OMAP4_L4_PER_CLKCTRL, NULL, 0, "l4_div_ck" }, - { OMAP4_MCBSP4_CLKCTRL, omap4_mcbsp4_bit_data, CLKF_SW_SUP, "l4_per_cm:clk:00c0:24" }, + { OMAP4_MCBSP4_CLKCTRL, omap4_mcbsp4_bit_data, CLKF_SW_SUP, "l4-per-clkctrl:00c0:24" }, { OMAP4_MCSPI1_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" }, { OMAP4_MCSPI2_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" }, { OMAP4_MCSPI3_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" }, { OMAP4_MCSPI4_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" }, { OMAP4_MMC3_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" }, { OMAP4_MMC4_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" }, - { OMAP4_SLIMBUS2_CLKCTRL, omap4_slimbus2_bit_data, CLKF_SW_SUP, "l4_per_cm:clk:0118:8" }, + { OMAP4_SLIMBUS2_CLKCTRL, omap4_slimbus2_bit_data, CLKF_SW_SUP, "l4-per-clkctrl:0118:8" }, { OMAP4_UART1_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" }, { OMAP4_UART2_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" }, { OMAP4_UART3_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" },
@@ -630,7 +630,7 @@ static const struct omap_clkctrl_reg_data omap4_l4_wkup_clkctrl_regs[] __initcon { OMAP4_L4_WKUP_CLKCTRL, NULL, 0, "l4_wkup_clk_mux_ck" }, { OMAP4_WD_TIMER2_CLKCTRL, NULL, CLKF_SW_SUP, "sys_32k_ck" }, { OMAP4_GPIO1_CLKCTRL, omap4_gpio1_bit_data, CLKF_HW_SUP, "l4_wkup_clk_mux_ck" }, - { OMAP4_TIMER1_CLKCTRL, omap4_timer1_bit_data, CLKF_SW_SUP, "l4_wkup_cm:clk:0020:24" }, + { OMAP4_TIMER1_CLKCTRL, omap4_timer1_bit_data, CLKF_SW_SUP, "l4-wkup-clkctrl:0020:24" }, { OMAP4_COUNTER_32K_CLKCTRL, NULL, 0, "sys_32k_ck" }, { OMAP4_KBD_CLKCTRL, NULL, CLKF_SW_SUP, "sys_32k_ck" }, { 0 },
@@ -644,7 +644,7 @@ static const char * const omap4_pmd_stm_clock_mux_ck_parents[] __initconst = { };static const char *const omap4_trace_clk_div_div_ck_parents[]__initconst = { -"emu_sys_cm:clk:0000:22" , +"emu-sys-clkctrl:0000:22" ,NULL , };
@@ -662,7 +662,7 @@ static const struct omap_clkctrl_div_data omap4_trace_clk_div_div_ck_data __init };static const char *const omap4_stm_clk_div_ck_parents[]__initconst = { -"emu_sys_cm:clk:0000:20" , +"emu-sys-clkctrl:0000:20" ,NULL , };
@@ -716,73 +716,73 @@ static struct ti_dt_clk omap44xx_clks[] = {* hwmod support. Once hwmod is removed, these can be removed * also. */ -DT_CLK (NULL ,"aess_fclk" ,"abe_cm:0008:24" ), -DT_CLK (NULL ,"cm2_dm10_mux" ,"l4_per_cm:0008:24" ), -DT_CLK (NULL ,"cm2_dm11_mux" ,"l4_per_cm:0010:24" ), -DT_CLK (NULL ,"cm2_dm2_mux" ,"l4_per_cm:0018:24" ), -DT_CLK (NULL ,"cm2_dm3_mux" ,"l4_per_cm:0020:24" ), -DT_CLK (NULL ,"cm2_dm4_mux" ,"l4_per_cm:0028:24" ), -DT_CLK (NULL ,"cm2_dm9_mux" ,"l4_per_cm:0030:24" ), -DT_CLK (NULL ,"dmic_sync_mux_ck" ,"abe_cm:0018:26" ), -DT_CLK (NULL ,"dmt1_clk_mux" ,"l4_wkup_cm:0020:24" ), -DT_CLK (NULL ,"dss_48mhz_clk" ,"l3_dss_cm:0000:9" ), -DT_CLK (NULL ,"dss_dss_clk" ,"l3_dss_cm:0000:8" ), -DT_CLK (NULL ,"dss_sys_clk" ,"l3_dss_cm:0000:10" ), -DT_CLK (NULL ,"dss_tv_clk" ,"l3_dss_cm:0000:11" ), -DT_CLK (NULL ,"fdif_fck" ,"iss_cm:0008:24" ), -DT_CLK (NULL ,"func_dmic_abe_gfclk" ,"abe_cm:0018:24" ), -DT_CLK (NULL ,"func_mcasp_abe_gfclk" ,"abe_cm:0020:24" ), -DT_CLK (NULL ,"func_mcbsp1_gfclk" ,"abe_cm:0028:24" ), -DT_CLK (NULL ,"func_mcbsp2_gfclk" ,"abe_cm:0030:24" ), -DT_CLK (NULL ,"func_mcbsp3_gfclk" ,"abe_cm:0038:24" ), -DT_CLK (NULL ,"gpio1_dbclk" ,"l4_wkup_cm:0018:8" ), -DT_CLK (NULL ,"gpio2_dbclk" ,"l4_per_cm:0040:8" ), -DT_CLK (NULL ,"gpio3_dbclk" ,"l4_per_cm:0048:8" ), -DT_CLK (NULL ,"gpio4_dbclk" ,"l4_per_cm:0050:8" ), -DT_CLK (NULL ,"gpio5_dbclk" ,"l4_per_cm:0058:8" ), -DT_CLK (NULL ,"gpio6_dbclk" ,"l4_per_cm:0060:8" ), -DT_CLK (NULL ,"hsi_fck" ,"l3_init_cm:0018:24" ), -DT_CLK (NULL ,"hsmmc1_fclk" ,"l3_init_cm:0008:24" ), -DT_CLK (NULL ,"hsmmc2_fclk" ,"l3_init_cm:0010:24" ), -DT_CLK (NULL ,"iss_ctrlclk" ,"iss_cm:0000:8" ), -DT_CLK (NULL ,"mcasp_sync_mux_ck" ,"abe_cm:0020:26" ), -DT_CLK (NULL ,"mcbsp1_sync_mux_ck" ,"abe_cm:0028:26" ), -DT_CLK (NULL ,"mcbsp2_sync_mux_ck" ,"abe_cm:0030:26" ), -DT_CLK (NULL ,"mcbsp3_sync_mux_ck" ,"abe_cm:0038:26" ), -DT_CLK (NULL ,"mcbsp4_sync_mux_ck" ,"l4_per_cm:00c0:26" ), -DT_CLK (NULL ,"ocp2scp_usb_phy_phy_48m" ,"l3_init_cm:00c0:8" ), -DT_CLK (NULL ,"otg_60m_gfclk" ,"l3_init_cm:0040:24" ), -DT_CLK (NULL ,"per_mcbsp4_gfclk" ,"l4_per_cm:00c0:24" ), -DT_CLK (NULL ,"pmd_stm_clock_mux_ck" ,"emu_sys_cm:0000:20" ), -DT_CLK (NULL ,"pmd_trace_clk_mux_ck" ,"emu_sys_cm:0000:22" ), -DT_CLK (NULL ,"sgx_clk_mux" ,"l3_gfx_cm:0000:24" ), -DT_CLK (NULL ,"slimbus1_fclk_0" ,"abe_cm:0040:8" ), -DT_CLK (NULL ,"slimbus1_fclk_1" ,"abe_cm:0040:9" ), -DT_CLK (NULL ,"slimbus1_fclk_2" ,"abe_cm:0040:10" ), -DT_CLK (NULL ,"slimbus1_slimbus_clk" ,"abe_cm:0040:11" ), -DT_CLK (NULL ,"slimbus2_fclk_0" ,"l4_per_cm:0118:8" ), -DT_CLK (NULL ,"slimbus2_fclk_1" ,"l4_per_cm:0118:9" ), -DT_CLK (NULL ,"slimbus2_slimbus_clk" ,"l4_per_cm:0118:10" ), -DT_CLK (NULL ,"stm_clk_div_ck" ,"emu_sys_cm:0000:27" ), -DT_CLK (NULL ,"timer5_sync_mux" ,"abe_cm:0048:24" ), -DT_CLK (NULL ,"timer6_sync_mux" ,"abe_cm:0050:24" ), -DT_CLK (NULL ,"timer7_sync_mux" ,"abe_cm:0058:24" ), -DT_CLK (NULL ,"timer8_sync_mux" ,"abe_cm:0060:24" ), -DT_CLK (NULL ,"trace_clk_div_div_ck" ,"emu_sys_cm:0000:24" ), -DT_CLK (NULL ,"usb_host_hs_func48mclk" ,"l3_init_cm:0038:15" ), -DT_CLK (NULL ,"usb_host_hs_hsic480m_p1_clk" ,"l3_init_cm:0038:13" ), -DT_CLK (NULL ,"usb_host_hs_hsic480m_p2_clk" ,"l3_init_cm:0038:14" ), -DT_CLK (NULL ,"usb_host_hs_hsic60m_p1_clk" ,"l3_init_cm:0038:11" ), -DT_CLK (NULL ,"usb_host_hs_hsic60m_p2_clk" ,"l3_init_cm:0038:12" ), -DT_CLK (NULL ,"usb_host_hs_utmi_p1_clk" ,"l3_init_cm:0038:8" ), -DT_CLK (NULL ,"usb_host_hs_utmi_p2_clk" ,"l3_init_cm:0038:9" ), -DT_CLK (NULL ,"usb_host_hs_utmi_p3_clk" ,"l3_init_cm:0038:10" ), -DT_CLK (NULL ,"usb_otg_hs_xclk" ,"l3_init_cm:0040:8" ), -DT_CLK (NULL ,"usb_tll_hs_usb_ch0_clk" ,"l3_init_cm:0048:8" ), -DT_CLK (NULL ,"usb_tll_hs_usb_ch1_clk" ,"l3_init_cm:0048:9" ), -DT_CLK (NULL ,"usb_tll_hs_usb_ch2_clk" ,"l3_init_cm:0048:10" ), -DT_CLK (NULL ,"utmi_p1_gfclk" ,"l3_init_cm:0038:24" ), -DT_CLK (NULL ,"utmi_p2_gfclk" ,"l3_init_cm:0038:25" ), +DT_CLK (NULL ,"aess_fclk" ,"abe-clkctrl:0008:24" ), +DT_CLK (NULL ,"cm2_dm10_mux" ,"l4-per-clkctrl:0008:24" ), +DT_CLK (NULL ,"cm2_dm11_mux" ,"l4-per-clkctrl:0010:24" ), +DT_CLK (NULL ,"cm2_dm2_mux" ,"l4-per-clkctrl:0018:24" ), +DT_CLK (NULL ,"cm2_dm3_mux" ,"l4-per-clkctrl:0020:24" ), +DT_CLK (NULL ,"cm2_dm4_mux" ,"l4-per-clkctrl:0028:24" ), +DT_CLK (NULL ,"cm2_dm9_mux" ,"l4-per-clkctrl:0030:24" ), +DT_CLK (NULL ,"dmic_sync_mux_ck" ,"abe-clkctrl:0018:26" ), +DT_CLK (NULL ,"dmt1_clk_mux" ,"l4-wkup-clkctrl:0020:24" ), +DT_CLK (NULL ,"dss_48mhz_clk" ,"l3-dss-clkctrl:0000:9" ), +DT_CLK (NULL ,"dss_dss_clk" ,"l3-dss-clkctrl:0000:8" ), +DT_CLK (NULL ,"dss_sys_clk" ,"l3-dss-clkctrl:0000:10" ), +DT_CLK (NULL ,"dss_tv_clk" ,"l3-dss-clkctrl:0000:11" ), +DT_CLK (NULL ,"fdif_fck" ,"iss-clkctrl:0008:24" ), +DT_CLK (NULL ,"func_dmic_abe_gfclk" ,"abe-clkctrl:0018:24" ), +DT_CLK (NULL ,"func_mcasp_abe_gfclk" ,"abe-clkctrl:0020:24" ), +DT_CLK (NULL ,"func_mcbsp1_gfclk" ,"abe-clkctrl:0028:24" ), +DT_CLK (NULL ,"func_mcbsp2_gfclk" ,"abe-clkctrl:0030:24" ), +DT_CLK (NULL ,"func_mcbsp3_gfclk" ,"abe-clkctrl:0038:24" ), +DT_CLK (NULL ,"gpio1_dbclk" ,"l4-wkup-clkctrl:0018:8" ), +DT_CLK (NULL ,"gpio2_dbclk" ,"l4-per-clkctrl:0040:8" ), +DT_CLK (NULL ,"gpio3_dbclk" ,"l4-per-clkctrl:0048:8" ), +DT_CLK (NULL ,"gpio4_dbclk" ,"l4-per-clkctrl:0050:8" ), +DT_CLK (NULL ,"gpio5_dbclk" ,"l4-per-clkctrl:0058:8" ), +DT_CLK (NULL ,"gpio6_dbclk" ,"l4-per-clkctrl:0060:8" ), +DT_CLK (NULL ,"hsi_fck" ,"l3-init-clkctrl:0018:24" ), +DT_CLK (NULL ,"hsmmc1_fclk" ,"l3-init-clkctrl:0008:24" ), +DT_CLK (NULL ,"hsmmc2_fclk" ,"l3-init-clkctrl:0010:24" ), +DT_CLK (NULL ,"iss_ctrlclk" ,"iss-clkctrl:0000:8" ), +DT_CLK (NULL ,"mcasp_sync_mux_ck" ,"abe-clkctrl:0020:26" ), +DT_CLK (NULL ,"mcbsp1_sync_mux_ck" ,"abe-clkctrl:0028:26" ), +DT_CLK (NULL ,"mcbsp2_sync_mux_ck" ,"abe-clkctrl:0030:26" ), +DT_CLK (NULL ,"mcbsp3_sync_mux_ck" ,"abe-clkctrl:0038:26" ), +DT_CLK (NULL ,"mcbsp4_sync_mux_ck" ,"l4-per-clkctrl:00c0:26" ), +DT_CLK (NULL ,"ocp2scp_usb_phy_phy_48m" ,"l3-init-clkctrl:00c0:8" ), +DT_CLK (NULL ,"otg_60m_gfclk" ,"l3-init-clkctrl:0040:24" ), +DT_CLK (NULL ,"per_mcbsp4_gfclk" ,"l4-per-clkctrl:00c0:24" ), +DT_CLK (NULL ,"pmd_stm_clock_mux_ck" ,"emu-sys-clkctrl:0000:20" ), +DT_CLK (NULL ,"pmd_trace_clk_mux_ck" ,"emu-sys-clkctrl:0000:22" ), +DT_CLK (NULL ,"sgx_clk_mux" ,"l3-gfx-clkctrl:0000:24" ), +DT_CLK (NULL ,"slimbus1_fclk_0" ,"abe-clkctrl:0040:8" ), +DT_CLK (NULL ,"slimbus1_fclk_1" ,"abe-clkctrl:0040:9" ), +DT_CLK (NULL ,"slimbus1_fclk_2" ,"abe-clkctrl:0040:10" ), +DT_CLK (NULL ,"slimbus1_slimbus_clk" ,"abe-clkctrl:0040:11" ), +DT_CLK (NULL ,"slimbus2_fclk_0" ,"l4-per-clkctrl:0118:8" ), +DT_CLK (NULL ,"slimbus2_fclk_1" ,"l4-per-clkctrl:0118:9" ), +DT_CLK (NULL ,"slimbus2_slimbus_clk" ,"l4-per-clkctrl:0118:10" ), +DT_CLK (NULL ,"stm_clk_div_ck" ,"emu-sys-clkctrl:0000:27" ), +DT_CLK (NULL ,"timer5_sync_mux" ,"abe-clkctrl:0048:24" ), +DT_CLK (NULL ,"timer6_sync_mux" ,"abe-clkctrl:0050:24" ), +DT_CLK (NULL ,"timer7_sync_mux" ,"abe-clkctrl:0058:24" ), +DT_CLK (NULL ,"timer8_sync_mux" ,"abe-clkctrl:0060:24" ), +DT_CLK (NULL ,"trace_clk_div_div_ck" ,"emu-sys-clkctrl:0000:24" ), +DT_CLK (NULL ,"usb_host_hs_func48mclk" ,"l3-init-clkctrl:0038:15" ), +DT_CLK (NULL ,"usb_host_hs_hsic480m_p1_clk" ,"l3-init-clkctrl:0038:13" ), +DT_CLK (NULL ,"usb_host_hs_hsic480m_p2_clk" ,"l3-init-clkctrl:0038:14" ), +DT_CLK (NULL ,"usb_host_hs_hsic60m_p1_clk" ,"l3-init-clkctrl:0038:11" ), +DT_CLK (NULL ,"usb_host_hs_hsic60m_p2_clk" ,"l3-init-clkctrl:0038:12" ), +DT_CLK (NULL ,"usb_host_hs_utmi_p1_clk" ,"l3-init-clkctrl:0038:8" ), +DT_CLK (NULL ,"usb_host_hs_utmi_p2_clk" ,"l3-init-clkctrl:0038:9" ), +DT_CLK (NULL ,"usb_host_hs_utmi_p3_clk" ,"l3_init-clkctrl:0038:10" ), +DT_CLK (NULL ,"usb_otg_hs_xclk" ,"l3-init-clkctrl:0040:8" ), +DT_CLK (NULL ,"usb_tll_hs_usb_ch0_clk" ,"l3-init-clkctrl:0048:8" ), +DT_CLK (NULL ,"usb_tll_hs_usb_ch1_clk" ,"l3-init-clkctrl:0048:9" ), +DT_CLK (NULL ,"usb_tll_hs_usb_ch2_clk" ,"l3-init-clkctrl:0048:10" ), +DT_CLK (NULL ,"utmi_p1_gfclk" ,"l3-init-clkctrl:0038:24" ), +DT_CLK (NULL ,"utmi_p2_gfclk" ,"l3-init-clkctrl:0038:25" ), { .node_name = NULL }, };
drivers/clk/ti/clk-54xx.c +80 -80
249 lines not on this page · raw message
drivers/clk/ti/clkctrl.c +0 -4
@@ -528,10 +528,6 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node)char *c;u16 soc_mask =0 ; -if (!(ti_clk_get_features ()->flags &TI_CLK_CLKCTRL_COMPAT ) && -of_node_name_eq (node,"clk" )) - ti_clk_features.flags |=TI_CLK_CLKCTRL_COMPAT ; - addrp =of_get_address (node,0 ,NULL ,NULL ); addr = (u32 )of_translate_address (node, addrp);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 273/365 scsi: ufs: ufs-mediatek: Fix the timing of configuring device regulators
In reply to Greg Kroah-HartmanFrom: Po-Wen Kao <[email protected]>
[ Upstream commit 3fd23b8dfb54d9b74eba6dfdd3225db3ac116785 ]
Currently the LPM configurations of device regulators may not work since VCC is not disabled yet while ufs_mtk_vreg_set_lpm() is executed.
Fix this by changing the timing of invoking ufs_mtk_vreg_set_lpm().
--- drivers/ufs/host/ufs-mediatek.c | 58 ++++++++++++++++++++++++++++++--- 1 file changed, 53 insertions(+), 5 deletions(-)
drivers/ufs/host/ufs-mediatek.c +53 -5
@@ -1026,7 +1026,6 @@ static int ufs_mtk_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op,* ufshcd_suspend() re-enabling regulators while vreg is still * in low-power mode. */ -ufs_mtk_vreg_set_lpm (hba, true); err =ufs_mtk_mphy_power_on (hba, false);if (err) goto fail;
@@ -1050,12 +1049,13 @@ static int ufs_mtk_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op) {int err; +if (hba->ufshcd_state !=UFSHCD_STATE_OPERATIONAL ) +ufs_mtk_vreg_set_lpm (hba, false); + err =ufs_mtk_mphy_power_on (hba, true);if (err) goto fail; -ufs_mtk_vreg_set_lpm (hba, false); -if (ufshcd_is_link_hibern8 (hba)) { err =ufs_mtk_link_set_hpm (hba);if (err)
@@ -1220,9 +1220,57 @@ static int ufs_mtk_remove(struct platform_device *pdev)return 0 ; } +int ufs_mtk_system_suspend (struct device *dev) +{ +struct ufs_hba *hba =dev_get_drvdata (dev); +int ret; + + ret =ufshcd_system_suspend (dev); +if (ret) +return ret; + +ufs_mtk_vreg_set_lpm (hba, true); + +return 0 ; +} + +int ufs_mtk_system_resume (struct device *dev) +{ +struct ufs_hba *hba =dev_get_drvdata (dev); + +ufs_mtk_vreg_set_lpm (hba, false); + +return ufshcd_system_resume (dev); +} + +int ufs_mtk_runtime_suspend (struct device *dev) +{ +struct ufs_hba *hba =dev_get_drvdata (dev); +int ret =0 ; + + ret =ufshcd_runtime_suspend (dev); +if (ret) +return ret; + +ufs_mtk_vreg_set_lpm (hba, true); + +return 0 ; +} + +int ufs_mtk_runtime_resume (struct device *dev) +{ +struct ufs_hba *hba =dev_get_drvdata (dev); + +ufs_mtk_vreg_set_lpm (hba, false); + +return ufshcd_runtime_resume (dev); +} +static const struct dev_pm_ops ufs_mtk_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(ufshcd_system_suspend, ufshcd_system_resume) -SET_RUNTIME_PM_OPS (ufshcd_runtime_suspend, ufshcd_runtime_resume,NULL ) + SET_SYSTEM_SLEEP_PM_OPS(ufs_mtk_system_suspend, + ufs_mtk_system_resume) +SET_RUNTIME_PM_OPS (ufs_mtk_runtime_suspend, + ufs_mtk_runtime_resume,NULL ) .prepare = ufshcd_suspend_prepare, .complete = ufshcd_resume_complete, };
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 274/365 usb: typec: mux: Add CONFIG guards for functions
In reply to Greg Kroah-HartmanFrom: Prashant Malani <[email protected]>
[ Upstream commit a37599ebfb656c2af4ca119de556eba29b6926d6 ]
There are some drivers that can use the Type C mux API, but don't have to. Introduce CONFIG guards for the mux functions so that drivers can include the header file and not run into compilation errors on systems which don't have CONFIG_TYPEC enabled. When CONFIG_TYPEC is not enabled, the Type C mux functions will be stub versions of the original calls.
--- include/linux/usb/typec_mux.h | 44 ++++++++++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 6 deletions(-)
include/linux/usb/typec_mux.h +38 -6
@@ -58,17 +58,13 @@ struct typec_mux_desc {void *drvdata; }; +#if IS_ENABLED (CONFIG_TYPEC ) +struct typec_mux *fwnode_typec_mux_get (struct fwnode_handle *fwnode,const struct typec_altmode_desc *desc);void typec_mux_put (struct typec_mux *mux);int typec_mux_set (struct typec_mux *mux,struct typec_mux_state *state); -static inline struct typec_mux * -typec_mux_get (struct device *dev,const struct typec_altmode_desc *desc) -{ -return fwnode_typec_mux_get (dev_fwnode (dev), desc); -} -struct typec_mux_dev *typec_mux_register (struct device *parent,const struct typec_mux_desc *desc);void typec_mux_unregister (struct typec_mux_dev *mux);
@@ -76,4 +72,40 @@ void typec_mux_unregister(struct typec_mux_dev *mux);void typec_mux_set_drvdata (struct typec_mux_dev *mux,void *data);void *typec_mux_get_drvdata (struct typec_mux_dev *mux); +#else + +static inline struct typec_mux *fwnode_typec_mux_get (struct fwnode_handle *fwnode, +const struct typec_altmode_desc *desc) +{ +return NULL ; +} + +static inline void typec_mux_put (struct typec_mux *mux) {} + +static inline int typec_mux_set (struct typec_mux *mux,struct typec_mux_state *state) +{ +return 0 ; +} + +static inline struct typec_mux_dev * +typec_mux_register (struct device *parent,const struct typec_mux_desc *desc) +{ +return ERR_PTR (-EOPNOTSUPP ); +} +static inline void typec_mux_unregister (struct typec_mux_dev *mux) {} + +static inline void typec_mux_set_drvdata (struct typec_mux_dev *mux,void *data) {} +static inline void *typec_mux_get_drvdata (struct typec_mux_dev *mux) +{ +return ERR_PTR (-EOPNOTSUPP ); +} + +#endif /* CONFIG_TYPEC */ + +static inline struct typec_mux * +typec_mux_get (struct device *dev,const struct typec_altmode_desc *desc) +{ +return fwnode_typec_mux_get (dev_fwnode (dev), desc); +} +#endif /* __USB_TYPEC_MUX */
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 275/365 usb: host: ohci-ppc-of: Fix refcount leak bug
In reply to Greg Kroah-HartmanFrom: Liang He <[email protected]>
[ Upstream commit 40a959d7042bb7711e404ad2318b30e9f92c6b9b ]
In ohci_hcd_ppc_of_probe(), of_find_compatible_node() will return a node pointer with refcount incremented. We should use of_node_put() when it is not used anymore.
--- drivers/usb/host/ohci-ppc-of.c | 1 + 1 file changed, 1 insertion(+)
drivers/usb/host/ohci-ppc-of.c +1 -0
@@ -166,6 +166,7 @@ static int ohci_hcd_ppc_of_probe(struct platform_device *op)release_mem_region (res.start,0x4 ); }else pr_debug ("%s: cannot get ehci offset from fdt\n" , __FILE__); +of_node_put (np); }irq_dispose_mapping (irq);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 276/365 usb: renesas: Fix refcount leak bug
In reply to Greg Kroah-HartmanFrom: Liang He <[email protected]>
[ Upstream commit 9d6d5303c39b8bc182475b22f45504106a07f086 ]
In usbhs_rza1_hardware_init(), of_find_node_by_name() will return a node pointer with refcount incremented. We should use of_node_put() when it is not used anymore.
--- drivers/usb/renesas_usbhs/rza.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/usb/renesas_usbhs/rza.c +4 -0
@@ -23,6 +23,10 @@ static int usbhs_rza1_hardware_init(struct platform_device *pdev) extal_clk =of_find_node_by_name (NULL ,"extal" );of_property_read_u32 (usb_x1_clk,"clock-frequency" , &freq_usb);of_property_read_u32 (extal_clk,"clock-frequency" , &freq_extal); + +of_node_put (usb_x1_clk); +of_node_put (extal_clk); +if (freq_usb ==0 ) {if (freq_extal ==12000000 ) {/* Select 12MHz XTAL */
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 277/365 scsi: iscsi: Fix HW conn removal use after free
In reply to Greg Kroah-HartmanFrom: Mike Christie <[email protected]>
[ Upstream commit c577ab7ba5f3bf9062db8a58b6e89d4fe370447e ]
If qla4xxx doesn't remove the connection before the session, the iSCSI class tries to remove the connection for it. We were doing a iscsi_put_conn() in the iter function which is not needed and will result in a use after free because iscsi_remove_conn() will free the connection.
--- drivers/scsi/scsi_transport_iscsi.c | 2 -- 1 file changed, 2 deletions(-)
drivers/scsi/scsi_transport_iscsi.c +0 -2
@@ -2143,8 +2143,6 @@ static int iscsi_iter_destroy_conn_fn(struct device *dev, void *data)return 0 ;iscsi_remove_conn (iscsi_dev_to_conn (dev)); -iscsi_put_conn (iscsi_dev_to_conn (dev)); -return 0 ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 278/365 usb: dwc2: gadget: remove D+ pull-up while no vbus with usb-role-switch
In reply to Greg Kroah-HartmanFrom: Amelie Delaunay <[email protected]>
[ Upstream commit db638c6500abaffb8f7770b2a69c40d003d54ae1 ]
When using usb-role-switch, D+ pull-up is set as soon as DTCL_SFTDISCON is cleared, whatever the vbus valid signal state is. The pull-up should not be set when vbus isn't present (this is determined by the drd controller).
This patch ensures that B-Session (so Peripheral role + vbus valid signal) is valid before clearing the DCTL_SFTDISCON bit when role switch is used. Keep original behavior when usb-role-switch isn't used.
--- drivers/usb/dwc2/gadget.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/usb/dwc2/gadget.c +2 -1
@@ -3594,7 +3594,8 @@ void dwc2_hsotg_core_disconnect(struct dwc2_hsotg *hsotg)void dwc2_hsotg_core_connect (struct dwc2_hsotg *hsotg) {/* remove the soft-disconnect and let's go */ -dwc2_clear_bit (hsotg,DCTL ,DCTL_SFTDISCON ); +if (!hsotg->role_sw || (dwc2_readl (hsotg,GOTGCTL ) &GOTGCTL_BSESVLD )) +dwc2_clear_bit (hsotg,DCTL ,DCTL_SFTDISCON ); }/**
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 279/365 vboxguest: Do not use devm for irq
In reply to Greg Kroah-HartmanFrom: Pascal Terjan <[email protected]>
[ Upstream commit 6169525b76764acb81918aa387ac168fb9a55575 ]
When relying on devm it doesn't get freed early enough which causes the following warning when unloading the module:
[249348.837181] remove_proc_entry: removing non-empty directory 'irq/20', leaking at least 'vboxguest' [249348.837219] WARNING: CPU: 0 PID: 6708 at fs/proc/generic.c:715 remove_proc_entry+0x119/0x140
[249348.837379] Call Trace: [249348.837385] unregister_irq_proc+0xbd/0xe0 [249348.837392] free_desc+0x23/0x60 [249348.837396] irq_free_descs+0x4a/0x70 [249348.837401] irq_domain_free_irqs+0x160/0x1a0 [249348.837452] mp_unmap_irq+0x5c/0x60 [249348.837458] acpi_unregister_gsi_ioapic+0x29/0x40 [249348.837463] acpi_unregister_gsi+0x17/0x30 [249348.837467] acpi_pci_irq_disable+0xbf/0xe0 [249348.837473] pcibios_disable_device+0x20/0x30 [249348.837478] pci_disable_device+0xef/0x120 [249348.837482] vbg_pci_remove+0x6c/0x70 [vboxguest]
--- drivers/virt/vboxguest/vboxguest_linux.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
drivers/virt/vboxguest/vboxguest_linux.c +6 -3
@@ -356,8 +356,8 @@ static int vbg_pci_probe(struct pci_dev *pci, const struct pci_device_id *id) goto err_vbg_core_exit; } - ret =devm_request_irq (dev, pci->irq, vbg_core_isr,IRQF_SHARED , -DEVICE_NAME , gdev); + ret =request_irq (pci->irq, vbg_core_isr,IRQF_SHARED ,DEVICE_NAME , + gdev);if (ret) {vbg_err ("vboxguest: Error requesting irq: %d\n" , ret); goto err_vbg_core_exit;
@@ -367,7 +367,7 @@ static int vbg_pci_probe(struct pci_dev *pci, const struct pci_device_id *id)if (ret) {vbg_err ("vboxguest: Error misc_register %s failed: %d\n" ,DEVICE_NAME , ret); - goto err_vbg_core_exit; + goto err_free_irq; } ret =misc_register (&gdev->misc_device_user);
@@ -403,6 +403,8 @@ static int vbg_pci_probe(struct pci_dev *pci, const struct pci_device_id *id)misc_deregister (&gdev->misc_device_user); err_unregister_misc_device:misc_deregister (&gdev->misc_device); +err_free_irq: +free_irq (pci->irq, gdev); err_vbg_core_exit:vbg_core_exit (gdev); err_disable_pcidev:
@@ -419,6 +421,7 @@ static void vbg_pci_remove(struct pci_dev *pci) vbg_gdev =NULL ;mutex_unlock (&vbg_gdev_mutex); +free_irq (pci->irq, gdev);device_remove_file (gdev->dev, &dev_attr_host_features);device_remove_file (gdev->dev, &dev_attr_host_version);misc_deregister (&gdev->misc_device_user);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 280/365 clk: qcom: ipq8074: dont disable gcc_sleep_clk_src
In reply to Greg Kroah-HartmanFrom: Robert Marko <[email protected]>
[ Upstream commit 1bf7305e79aab095196131bdc87a97796e0e3fac ]
Once the usb sleep clocks are disabled, clock framework is trying to disable the sleep clock source also.
However, it seems that it cannot be disabled and trying to do so produces:
[ 245.436390] ------------[ cut here ]------------ [ 245.441233] gcc_sleep_clk_src status stuck at 'on' [ 245.441254] WARNING: CPU: 2 PID: 223 at clk_branch_wait+0x130/0x140 [ 245.450435] Modules linked in: xhci_plat_hcd xhci_hcd dwc3 dwc3_qcom leds_gpio [ 245.456601] CPU: 2 PID: 223 Comm: sh Not tainted 5.18.0-rc4 #215 [ 245.463889] Hardware name: Xiaomi AX9000 (DT) [ 245.470050] pstate: 204000c5 (nzCv daIF +PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 245.474307] pc : clk_branch_wait+0x130/0x140 [ 245.481073] lr : clk_branch_wait+0x130/0x140 [ 245.485588] sp : ffffffc009f2bad0 [ 245.489838] x29: ffffffc009f2bad0 x28: ffffff8003e6c800 x27: 0000000000000000 [ 245.493057] x26: 0000000000000000 x25: 0000000000000000 x24: ffffff800226ef20 [ 245.500175] x23: ffffffc0089ff550 x22: 0000000000000000 x21: ffffffc008476ad0 [ 245.507294] x20: 0000000000000000 x19: ffffffc00965ac70 x18: fffffffffffc51a7 [ 245.514413] x17: 68702e3030303837 x16: 3a6d726f6674616c x15: ffffffc089f2b777 [ 245.521531] x14: ffffffc0095c9d18 x13: 0000000000000129 x12: 0000000000000129 [ 245.528649] x11: 00000000ffffffea x10: ffffffc009621d18 x9 : 0000000000000001 [ 245.535767] x8 : 0000000000000001 x7 : 0000000000017fe8 x6 : 0000000000000001 [ 245.542885] x5 : ffffff803fdca6d8 x4 : 0000000000000000 x3 : 0000000000000027 [ 245.550002] x2 : 0000000000000027 x1 : 0000000000000023 x0 : 0000000000000026 [ 245.557122] Call trace: [ 245.564229] clk_branch_wait+0x130/0x140 [ 245.566490] clk_branch2_disable+0x2c/0x40 [ 245.570656] clk_core_disable+0x60/0xb0 [ 245.574561] clk_core_disable+0x68/0xb0 [ 245.578293] clk_disable+0x30/0x50 [ 245.582113] dwc3_qcom_remove+0x60/0xc0 [dwc3_qcom] [ 245.585588] platform_remove+0x28/0x60 [ 245.590361] device_remove+0x4c/0x80 [ 245.594179] device_release_driver_internal+0x1dc/0x230 [ 245.597914] device_driver_detach+0x18/0x30 [ 245.602861] unbind_store+0xec/0x110 [ 245.607027] drv_attr_store+0x24/0x40 [ 245.610847] sysfs_kf_write+0x44/0x60 [ 245.614405] kernfs_fop_write_iter+0x128/0x1c0 [ 245.618052] new_sync_write+0xc0/0x130 [ 245.622391] vfs_write+0x1d4/0x2a0 [ 245.626123] ksys_write+0x58/0xe0 [ 245.629508] __arm64_sys_write+0x1c/0x30 [ 245.632895] invoke_syscall.constprop.0+0x5c/0x110 [ 245.636890] do_el0_svc+0xa0/0x150 [ 245.641488] el0_svc+0x18/0x60 [ 245.644872] el0t_64_sync_handler+0xa4/0x130 [ 245.647914] el0t_64_sync+0x174/0x178 [ 245.652340] ---[ end trace 0000000000000000 ]---
So, add CLK_IS_CRITICAL flag to the clock so that the kernel won't try to disable the sleep clock.
--- drivers/clk/qcom/gcc-ipq8074.c | 1 + 1 file changed, 1 insertion(+)
drivers/clk/qcom/gcc-ipq8074.c +1 -0
@@ -662,6 +662,7 @@ static struct clk_branch gcc_sleep_clk_src = { }, .num_parents = 1, .ops = &clk_branch2_ops, + .flags = CLK_IS_CRITICAL, }, }, };
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 281/365 uacce: Handle parent device removal or parent driver module rmmod
In reply to Greg Kroah-HartmanFrom: Jean-Philippe Brucker <[email protected]>
[ Upstream commit 80fc671bcc0173836e9032b0c698ea74c13b9d7c ]
The uacce driver must deal with a possible removal of the parent device or parent driver module rmmod at any time.
Although uacce_remove(), called on device removal and on driver unbind, prevents future use of the uacce fops by removing the cdev, fops that were called before that point may still be running.
Serialize uacce_fops_open() and uacce_remove() with uacce->mutex. Serialize other fops against uacce_remove() with q->mutex. Since we need to protect uacce_fops_poll() which gets called on the fast path, replace uacce->queues_lock with q->mutex to improve scalability. The other fops are only used during setup.
uacce_queue_is_valid(), checked under q->mutex or uacce->mutex, denotes whether uacce_remove() has disabled all queues. If that is the case, don't go any further since the parent device is being removed and uacce->ops should not be called anymore.
--- drivers/misc/uacce/uacce.c | 133 ++++++++++++++++++++++++------------- include/linux/uacce.h | 6 +- 2 files changed, 91 insertions(+), 48 deletions(-)
drivers/misc/uacce/uacce.c +87 -46
@@ -9,43 +9,38 @@static struct class *uacce_class;static dev_t uacce_devt; -static DEFINE_MUTEX (uacce_mutex);static DEFINE_XARRAY_ALLOC (uacce_xa); -static int uacce_start_queue (struct uacce_queue *q) +/* +* If the parent driver or the device disappears, the queue state is invalid and +* ops are not usable anymore. +*/ +static bool uacce_queue_is_valid (struct uacce_queue *q) { -int ret =0 ; +return q->state ==UACCE_Q_INIT || q->state ==UACCE_Q_STARTED ; +} -mutex_lock (&uacce_mutex); +static int uacce_start_queue (struct uacce_queue *q) +{ +int ret; -if (q->state !=UACCE_Q_INIT ) { - ret = -EINVAL ; - goto out_with_lock; - } +if (q->state !=UACCE_Q_INIT ) +return -EINVAL ;if (q->uacce->ops->start_queue) { ret = q->uacce->ops->start_queue (q);if (ret <0 ) - goto out_with_lock; +return ret; } q->state =UACCE_Q_STARTED ; - -out_with_lock: -mutex_unlock (&uacce_mutex); - -return ret; +return 0 ; }static int uacce_put_queue (struct uacce_queue *q) {struct uacce_device *uacce = q->uacce; -mutex_lock (&uacce_mutex); - -if (q->state ==UACCE_Q_ZOMBIE ) - goto out; -if ((q->state ==UACCE_Q_STARTED ) && uacce->ops->stop_queue) uacce->ops->stop_queue (q);
@@ -54,8 +49,6 @@ static int uacce_put_queue(struct uacce_queue *q) uacce->ops->put_queue (q); q->state =UACCE_Q_ZOMBIE ; -out: -mutex_unlock (&uacce_mutex);return 0 ; }
@@ -65,20 +58,36 @@ static long uacce_fops_unl_ioctl(struct file *filep, {struct uacce_queue *q = filep->private_data;struct uacce_device *uacce = q->uacce; +long ret = -ENXIO ; + +/* +* uacce->ops->ioctl() may take the mmap_lock when copying arg to/from +* user. Avoid a circular lock dependency with uacce_fops_mmap(), which +* gets called with mmap_lock held, by taking uacce->mutex instead of +* q->mutex. Doing this in uacce_fops_mmap() is not possible because +* uacce_fops_open() calls iommu_sva_bind_device(), which takes +* mmap_lock, while holding uacce->mutex. +*/ +mutex_lock (&uacce->mutex); +if (!uacce_queue_is_valid (q)) + goto out_unlock;switch (cmd) {case UACCE_CMD_START_Q : -return uacce_start_queue (q); - + ret =uacce_start_queue (q); +break ;case UACCE_CMD_PUT_Q : -return uacce_put_queue (q); - + ret =uacce_put_queue (q); +break ;default : -if (!uacce->ops->ioctl) -return -EINVAL ; - -return uacce->ops->ioctl (q, cmd, arg); +if (uacce->ops->ioctl) + ret = uacce->ops->ioctl (q, cmd, arg); +else + ret = -EINVAL ; } +out_unlock: +mutex_unlock (&uacce->mutex); +return ret; }#ifdef CONFIG_COMPAT
@@ -136,6 +145,13 @@ static int uacce_fops_open(struct inode *inode, struct file *filep)if (!q)return -ENOMEM ; +mutex_lock (&uacce->mutex); + +if (!uacce->parent) { + ret = -EINVAL ; + goto out_with_mem; + } + ret =uacce_bind_queue (uacce, q);if (ret) goto out_with_mem;
@@ -152,10 +168,9 @@ static int uacce_fops_open(struct inode *inode, struct file *filep) filep->private_data = q; uacce->inode = inode; q->state =UACCE_Q_INIT ; - -mutex_lock (&uacce->queues_lock); +mutex_init (&q->mutex);list_add (&q->list, &uacce->queues); -mutex_unlock (&uacce->queues_lock); +mutex_unlock (&uacce->mutex);return 0 ;
@@ -163,18 +178,20 @@ static int uacce_fops_open(struct inode *inode, struct file *filep)uacce_unbind_queue (q); out_with_mem:kfree (q); +mutex_unlock (&uacce->mutex);return ret; }static int uacce_fops_release (struct inode *inode,struct file *filep) {struct uacce_queue *q = filep->private_data; +struct uacce_device *uacce = q->uacce; -mutex_lock (&q->uacce->queues_lock); -list_del (&q->list); -mutex_unlock (&q->uacce->queues_lock); +mutex_lock (&uacce->mutex);uacce_put_queue (q);uacce_unbind_queue (q); +list_del (&q->list); +mutex_unlock (&uacce->mutex);kfree (q);return 0 ;
@@ -217,10 +234,9 @@ static int uacce_fops_mmap(struct file *filep, struct vm_area_struct *vma) vma->vm_private_data = q; qfr->type = type; -mutex_lock (&uacce_mutex); - -if (q->state !=UACCE_Q_INIT && q->state !=UACCE_Q_STARTED ) { - ret = -EINVAL ; +mutex_lock (&q->mutex); +if (!uacce_queue_is_valid (q)) { + ret = -ENXIO ; goto out_with_lock; }
@@ -248,12 +264,12 @@ static int uacce_fops_mmap(struct file *filep, struct vm_area_struct *vma) } q->qfrs[type] = qfr; -mutex_unlock (&uacce_mutex); +mutex_unlock (&q->mutex);return ret; out_with_lock: -mutex_unlock (&uacce_mutex); +mutex_unlock (&q->mutex);kfree (qfr);return ret; }
@@ -262,12 +278,20 @@ static __poll_t uacce_fops_poll(struct file *file, poll_table *wait) {struct uacce_queue *q = file->private_data;struct uacce_device *uacce = q->uacce; +__poll_t ret =0 ; + +mutex_lock (&q->mutex); +if (!uacce_queue_is_valid (q)) + goto out_unlock;poll_wait (file, &q->wait, wait); +if (uacce->ops->is_q_updated && uacce->ops->is_q_updated (q)) -return EPOLLIN |EPOLLRDNORM ; + ret =EPOLLIN |EPOLLRDNORM ; -return 0 ; +out_unlock: +mutex_unlock (&q->mutex); +return ret; }static const struct file_operations uacce_fops = {
@@ -450,7 +474,7 @@ struct uacce_device *uacce_alloc(struct device *parent, goto err_with_uacce;INIT_LIST_HEAD (&uacce->queues); -mutex_init (&uacce->queues_lock); +mutex_init (&uacce->mutex);device_initialize (&uacce->dev); uacce->dev.devt =MKDEV (MAJOR (uacce_devt), uacce->dev_id); uacce->dev.class = uacce_class;
@@ -507,13 +531,23 @@ void uacce_remove(struct uacce_device *uacce)if (uacce->inode)unmap_mapping_range (uacce->inode->i_mapping,0 ,0 ,1 ); +/* +* uacce_fops_open() may be running concurrently, even after we remove +* the cdev. Holding uacce->mutex ensures that open() does not obtain a +* removed uacce device. +*/ +mutex_lock (&uacce->mutex);/* ensure no open queue remains */ -mutex_lock (&uacce->queues_lock);list_for_each_entry_safe (q, next_q, &uacce->queues, list) { +/* +* Taking q->mutex ensures that fops do not use the defunct +* uacce->ops after the queue is disabled. +*/ +mutex_lock (&q->mutex);uacce_put_queue (q); +mutex_unlock (&q->mutex);uacce_unbind_queue (q); } -mutex_unlock (&uacce->queues_lock);/* disable sva now since no opened queues */ uacce_disable_sva (uacce);
@@ -521,6 +555,13 @@ void uacce_remove(struct uacce_device *uacce)if (uacce->cdev)cdev_device_del (uacce->cdev, &uacce->dev);xa_erase (&uacce_xa, uacce->dev_id); +/* +* uacce exists as long as there are open fds, but ops will be freed +* now. Ensure that bugs cause NULL deref rather than use-after-free. +*/ + uacce->ops =NULL ; + uacce->parent =NULL ; +mutex_unlock (&uacce->mutex);put_device (&uacce->dev); }EXPORT_SYMBOL_GPL (uacce_remove);
include/linux/uacce.h +4 -2
@@ -70,6 +70,7 @@ enum uacce_q_state {* @wait: wait queue head * @list: index into uacce queues list * @qfrs: pointer of qfr regions +* @mutex: protects queue state * @state: queue state machine * @pasid: pasid associated to the mm * @handle: iommu_sva handle returned by iommu_sva_bind_device()
@@ -80,6 +81,7 @@ struct uacce_queue {wait_queue_head_t wait;struct list_head list;struct uacce_qfile_region *qfrs[UACCE_MAX_REGION ]; +struct mutex mutex;enum uacce_q_state state;u32 pasid;struct iommu_sva *handle;
@@ -97,9 +99,9 @@ struct uacce_queue {* @dev_id: id of the uacce device * @cdev: cdev of the uacce * @dev: dev of the uacce +* @mutex: protects uacce operation * @priv: private pointer of the uacce * @queues: list of queues -* @queues_lock: lock for queues list * @inode: core vfs */ struct uacce_device {
@@ -113,9 +115,9 @@ struct uacce_device {u32 dev_id;struct cdev *cdev;struct device dev; +struct mutex mutex;void *priv;struct list_head queues; -struct mutex queues_lock;struct inode *inode; };
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 282/365 zram: do not lookup algorithm in backends table
In reply to Greg Kroah-HartmanFrom: Sergey Senozhatsky <[email protected]>
[ Upstream commit dc89997264de565999a1cb55db3f295d3a8e457b ]
Always use crypto_has_comp() so that crypto can lookup module, call usermodhelper to load the modules, wait for usermodhelper to finish and so on. Otherwise crypto will do all of these steps under CPU hot-plug lock and this looks like too much stuff to handle under the CPU hot-plug lock. Besides this can end up in a deadlock when usermodhelper triggers a code path that attempts to lock the CPU hot-plug lock, that zram already holds.
An example of such deadlock:
- path A. zram grabs CPU hot-plug lock, execs /sbin/modprobe from crypto and waits for modprobe to finish
disksize_store
zcomp_create
__cpuhp_state_add_instance
__cpuhp_state_add_instance_cpuslocked
zcomp_cpu_up_prepare
crypto_alloc_base
crypto_alg_mod_lookup
call_usermodehelper_exec
wait_for_completion_killable
do_wait_for_common
schedule
- path B. async work kthread that brings in scsi device. It wants to register CPUHP states at some point, and it needs the CPU hot-plug lock for that, which is owned by zram.
async_run_entry_fn
scsi_probe_and_add_lun
scsi_mq_alloc_queue
blk_mq_init_queue
blk_mq_init_allocated_queue
blk_mq_realloc_hw_ctxs
__cpuhp_state_add_instance
__cpuhp_state_add_instance_cpuslocked
mutex_lock
schedule
- path C. modprobe sleeps, waiting for all aync works to finish.
load_module
do_init_module
async_synchronize_full
async_synchronize_cookie_domain
schedule
--- drivers/block/zram/zcomp.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-)
drivers/block/zram/zcomp.c +5 -6
@@ -63,12 +63,6 @@ static int zcomp_strm_init(struct zcomp_strm *zstrm, struct zcomp *comp)bool zcomp_available_algorithm (const char *comp) { -int i; - - i =sysfs_match_string (backends, comp); -if (i >=0 ) -return true; -/* * Crypto does not ignore a trailing new line symbol, * so make sure you don't supply a string containing
@@ -217,6 +211,11 @@ struct zcomp *zcomp_create(const char *compress)struct zcomp *comp;int error; +/* +* Crypto API will execute /sbin/modprobe if the compression module +* is not loaded yet. We must do it here, otherwise we are about to +* call /sbin/modprobe under CPU hot-plug lock. +*/ if (!zcomp_available_algorithm (compress))return ERR_PTR (-EINVAL );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 283/365 clk: qcom: clk-alpha-pll: fix clk_trion_pll_configure description
In reply to Greg Kroah-HartmanFrom: Vladimir Zapolskiy <[email protected]>
[ Upstream commit 94bed9bb05c7850ff5d80b87cc29004901f37956 ]
After merging lucid and trion pll functions in commit 0b01489475c6 ("clk: qcom: clk-alpha-pll: same regs and ops for trion and lucid") the function clk_trion_pll_configure() is left with an old description header, which results in a W=2 compile time warning, fix it.
--- drivers/clk/qcom/clk-alpha-pll.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/clk/qcom/clk-alpha-pll.c +1 -1
@@ -1439,7 +1439,7 @@ const struct clk_ops clk_alpha_pll_postdiv_fabia_ops = {EXPORT_SYMBOL_GPL (clk_alpha_pll_postdiv_fabia_ops);/** -* clk_lucid_pll_configure - configure the lucid pll +* clk_trion_pll_configure - configure the trion pll * * @pll: clk alpha pll * @regmap: register map
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 284/365 scsi: lpfc: Prevent buffer overflow crashes in debugfs with malformed user input
In reply to Greg Kroah-HartmanFrom: James Smart <[email protected]>
[ Upstream commit f8191d40aa612981ce897e66cda6a88db8df17bb ]
Malformed user input to debugfs results in buffer overflow crashes. Adapt input string lengths to fit within internal buffers, leaving space for NULL terminators.
--- drivers/scsi/lpfc/lpfc_debugfs.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-)
drivers/scsi/lpfc/lpfc_debugfs.c +10 -10
@@ -2607,8 +2607,8 @@ lpfc_debugfs_multixripools_write(struct file *file, const char __user *buf,struct lpfc_sli4_hdw_queue *qp;struct lpfc_multixri_pool *multixri_pool; -if (nbytes >64 ) - nbytes =64 ; +if (nbytes >sizeof (mybuf) -1 ) + nbytes =sizeof (mybuf) -1 ;memset (mybuf,0 ,sizeof (mybuf));
@@ -2688,8 +2688,8 @@ lpfc_debugfs_nvmestat_write(struct file *file, const char __user *buf,if (!phba->targetport)return -ENXIO ; -if (nbytes >64 ) - nbytes =64 ; +if (nbytes >sizeof (mybuf) -1 ) + nbytes =sizeof (mybuf) -1 ;memset (mybuf,0 ,sizeof (mybuf));
@@ -2826,8 +2826,8 @@ lpfc_debugfs_ioktime_write(struct file *file, const char __user *buf,char mybuf[64 ];char *pbuf; -if (nbytes >64 ) - nbytes =64 ; +if (nbytes >sizeof (mybuf) -1 ) + nbytes =sizeof (mybuf) -1 ;memset (mybuf,0 ,sizeof (mybuf));
@@ -2954,8 +2954,8 @@ lpfc_debugfs_nvmeio_trc_write(struct file *file, const char __user *buf,char mybuf[64 ];char *pbuf; -if (nbytes >63 ) - nbytes =63 ; +if (nbytes >sizeof (mybuf) -1 ) + nbytes =sizeof (mybuf) -1 ;memset (mybuf,0 ,sizeof (mybuf));
@@ -3060,8 +3060,8 @@ lpfc_debugfs_hdwqstat_write(struct file *file, const char __user *buf,char *pbuf;int i; -if (nbytes >64 ) - nbytes =64 ; +if (nbytes >sizeof (mybuf) -1 ) + nbytes =sizeof (mybuf) -1 ;memset (mybuf,0 ,sizeof (mybuf));
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 285/365 scsi: lpfc: Fix possible memory leak when failing to issue CMF WQE
In reply to Greg Kroah-HartmanFrom: James Smart <[email protected]>
[ Upstream commit 2f67dc7970bce3529edce93a0a14234d88b3fcd5 ]
There is no corresponding free routine if lpfc_sli4_issue_wqe fails to issue the CMF WQE in lpfc_issue_cmf_sync_wqe.
If ret_val is non-zero, then free the iocbq request structure.
--- drivers/scsi/lpfc/lpfc_sli.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/scsi/lpfc/lpfc_sli.c +3 -1
@@ -2003,10 +2003,12 @@ lpfc_issue_cmf_sync_wqe(struct lpfc_hba *phba, u32 ms, u64 total) sync_buf->cmd_flag |=LPFC_IO_CMF ; ret_val =lpfc_sli4_issue_wqe (phba, &phba->sli4_hba.hdwq[0 ], sync_buf); -if (ret_val) +if (ret_val) {lpfc_printf_log (phba,KERN_INFO ,LOG_CGN_MGMT ,"6214 Cannot issue CMF_SYNC_WQE: x%x\n" , ret_val); +__lpfc_sli_release_iocbq (phba, sync_buf); + } out_unlock:spin_unlock_irqrestore (&phba->hbalock, iflags);return ret_val;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 286/365 gadgetfs: ep_io - wait until IRQ finishes
In reply to Greg Kroah-HartmanFrom: Jozef Martiniak <[email protected]>
[ Upstream commit 04cb742d4d8f30dc2e83b46ac317eec09191c68e ]
after usb_ep_queue() if wait_for_completion_interruptible() is interrupted we need to wait until IRQ gets finished.
Otherwise complete() from epio_complete() can corrupt stack.
--- drivers/usb/gadget/legacy/inode.c | 1 + 1 file changed, 1 insertion(+)
drivers/usb/gadget/legacy/inode.c +1 -0
@@ -362,6 +362,7 @@ ep_io (struct ep_data *epdata, void *buf, unsigned len)spin_unlock_irq (&epdata->dev->lock);DBG (epdata->dev,"endpoint gone\n" ); +wait_for_completion (&done); epdata->status = -ENODEV ; } }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 287/365 coresight: etm4x: avoid build failure with unrolled loops
In reply to Greg Kroah-HartmanFrom: Nick Desaulniers <[email protected]>
[ Upstream commit 4d45bc82df667ad9e9cb8361830e54fc1264e993 ]
When the following configs are enabled:
* CORESIGHT
* CORESIGHT_SOURCE_ETM4X
* UBSAN
* UBSAN_TRAP
Clang fails assemble the kernel with the error:
<instantiation>:1:7: error: expected constant expression in '.inst' directive
.inst (0xd5200000|((((2) << 19) | ((1) << 16) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 7) & 0x7)) << 12) | ((((((((((0x160 + (i * 4))))) >> 2))) & 0xf)) << 8) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 4) & 0x7)) << 5)))|(.L__reg_num_x8))
^
drivers/hwtracing/coresight/coresight-etm4x-core.c:702:4: note: while in macro instantiationetm4x_relaxed_read32(csa, TRCCNTVRn(i));
^drivers/hwtracing/coresight/coresight-etm4x.h:403:4: note: expanded from macro 'etm4x_relaxed_read32' read_etm4x_sysreg_offset((offset), false)))
^drivers/hwtracing/coresight/coresight-etm4x.h:383:12: note: expanded from macro 'read_etm4x_sysreg_offset'
__val = read_etm4x_sysreg_const_offset((offset)); \
^drivers/hwtracing/coresight/coresight-etm4x.h:149:2: note: expanded from macro 'read_etm4x_sysreg_const_offset' READ_ETM4x_REG(ETM4x_OFFSET_TO_REG(offset))
^drivers/hwtracing/coresight/coresight-etm4x.h:144:2: note: expanded from macro 'READ_ETM4x_REG' read_sysreg_s(ETM4x_REG_NUM_TO_SYSREG((reg)))
^arch/arm64/include/asm/sysreg.h:1108:15: note: expanded from macro 'read_sysreg_s'
asm volatile(__mrs_s("%0", r) : "=r" (__val)); \
^arch/arm64/include/asm/sysreg.h:1074:2: note: expanded from macro '__mrs_s'
" mrs_s " v ", " __stringify(r) "\n" \
^
Consider the definitions of TRCSSCSRn and TRCCNTVRn:drivers/hwtracing/coresight/coresight-etm4x.h:56
#define TRCCNTVRn(n) (0x160 + (n * 4))drivers/hwtracing/coresight/coresight-etm4x.h:81
#define TRCSSCSRn(n) (0x2A0 + (n * 4))
Where the macro parameter is expanded to i; a loop induction variable from etm4_disable_hw.
When any compiler can determine that loops may be unrolled, then the __builtin_constant_p check in read_etm4x_sysreg_offset() defined in drivers/hwtracing/coresight/coresight-etm4x.h may evaluate to true. This can lead to the expression (0x160 + (i * 4)) being passed to read_etm4x_sysreg_const_offset. Via the trace above, this is passed through READ_ETM4x_REG, read_sysreg_s, and finally to __mrs_s where it is string-ified and used directly in inline asm.
Regardless of which compiler or compiler options determine whether a loop can or can't be unrolled, which determines whether __builtin_constant_p evaluates to true when passed an expression using a loop induction variable, it is NEVER safe to allow the preprocessor to construct inline asm like:
asm volatile (".inst (0x160 + (i * 4))" : "=r"(__val));
^ expected constant expression
Instead of read_etm4x_sysreg_offset() using __builtin_constant_p(), use __is_constexpr from include/linux/const.h instead to ensure only expressions that are valid integer constant expressions get passed through to read_sysreg_s().
This is not a bug in clang; it's a potentially unsafe use of the macro arguments in read_etm4x_sysreg_offset dependent on __builtin_constant_p.
--- drivers/hwtracing/coresight/coresight-etm4x.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/hwtracing/coresight/coresight-etm4x.h +2 -1
@@ -7,6 +7,7 @@#define _CORESIGHT_CORESIGHT_ETM_H#include <asm/local.h> +#include <linux/const.h> #include <linux/spinlock.h> #include <linux/types.h> #include "coresight-priv.h"
@@ -515,7 +516,7 @@ ({ \ u64 __val; \ \ - if (__builtin_constant_p((offset))) \ + if (__is_constexpr((offset))) \ __val = read_etm4x_sysreg_const_offset((offset)); \ else \ __val = etm4x_sysreg_read((offset), true, (_64bit)); \
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 288/365 habanalabs: add terminating NULL to attrs arrays
In reply to Greg Kroah-HartmanFrom: Dafna Hirschfeld <[email protected]>
[ Upstream commit 78d503087be190eab36290644ccec050135e7c70 ]
Arrays of struct attribute are expected to be NULL terminated. This is required by API methods such as device_add_groups. This fixes a crash when loading the driver for Goya device.
--- drivers/misc/habanalabs/common/sysfs.c | 2 ++ drivers/misc/habanalabs/gaudi/gaudi.c | 1 + drivers/misc/habanalabs/goya/goya_hwmgr.c | 2 ++ 3 files changed, 5 insertions(+)
drivers/misc/habanalabs/common/sysfs.c +2 -0
@@ -73,6 +73,7 @@ static DEVICE_ATTR_RO(clk_cur_freq_mhz);static struct attribute *hl_dev_clk_attrs[] = { &dev_attr_clk_max_freq_mhz.attr, &dev_attr_clk_cur_freq_mhz.attr, +NULL , };static ssize_t vrm_ver_show (struct device *dev,struct device_attribute *attr,char *buf)
@@ -93,6 +94,7 @@ static DEVICE_ATTR_RO(vrm_ver);static struct attribute *hl_dev_vrm_attrs[] = { &dev_attr_vrm_ver.attr, +NULL , }; static ssize_t uboot_ver_show(struct device *dev, struct device_attribute *attr,
drivers/misc/habanalabs/gaudi/gaudi.c +1 -0
@@ -9187,6 +9187,7 @@ static DEVICE_ATTR_RO(infineon_ver);static struct attribute *gaudi_vrm_dev_attrs[] = { &dev_attr_infineon_ver.attr, +NULL , }; static void gaudi_add_device_attr(struct hl_device *hdev, struct attribute_group *dev_clk_attr_grp,
drivers/misc/habanalabs/goya/goya_hwmgr.c +2 -0
@@ -359,6 +359,7 @@ static struct attribute *goya_clk_dev_attrs[] = { &dev_attr_pm_mng_profile.attr, &dev_attr_tpc_clk.attr, &dev_attr_tpc_clk_curr.attr, + NULL, };static ssize_t infineon_ver_show (struct device *dev,struct device_attribute *attr,char *buf)
@@ -375,6 +376,7 @@ static DEVICE_ATTR_RO(infineon_ver);static struct attribute *goya_vrm_dev_attrs[] = { &dev_attr_infineon_ver.attr, +NULL , }; void goya_add_device_attr(struct hl_device *hdev, struct attribute_group *dev_clk_attr_grp,
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 289/365 habanalabs/gaudi: invoke device reset from one code block
In reply to Greg Kroah-HartmanFrom: Tal Cohen <[email protected]>
[ Upstream commit be572e67dafbf8004d46a2c9d97338c107efb60e ]
In order to prepare the driver code for device reset event notification, change the event handler function flow to call device reset from one code block.
In addition, the commit fixes an issue that reset was performed w/o checking the 'hard_reset_on_fw_event' state and w/o setting the HL_DRV_RESET_DELAY flag.
--- drivers/misc/habanalabs/gaudi/gaudi.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-)
drivers/misc/habanalabs/gaudi/gaudi.c +16 -9
@@ -7717,10 +7717,10 @@ static void gaudi_handle_eqe(struct hl_device *hdev,struct gaudi_device *gaudi = hdev->asic_specific;u64 data =le64_to_cpu (eq_entry->data[0 ]);u32 ctl =le32_to_cpu (eq_entry->hdr.ctl); -u32 fw_fatal_err_flag =0 ; +u32 fw_fatal_err_flag =0 , flags =0 ;u16 event_type = ((ctl &EQ_CTL_EVENT_TYPE_MASK ) >>EQ_CTL_EVENT_TYPE_SHIFT ); -bool reset_required; +bool reset_required, reset_direct = false;u8 cause;int rc;
@@ -7808,7 +7808,8 @@ static void gaudi_handle_eqe(struct hl_device *hdev,dev_err (hdev->dev,"reset required due to %s\n" , gaudi_irq_map_table[event_type].name); -hl_device_reset (hdev,0 ); + reset_direct = true; + goto reset_device; }else {hl_fw_unmask_irq (hdev, event_type); }
@@ -7830,7 +7831,8 @@ static void gaudi_handle_eqe(struct hl_device *hdev,dev_err (hdev->dev,"reset required due to %s\n" , gaudi_irq_map_table[event_type].name); -hl_device_reset (hdev,0 ); + reset_direct = true; + goto reset_device; }else {hl_fw_unmask_irq (hdev, event_type); }
@@ -7981,12 +7983,17 @@ static void gaudi_handle_eqe(struct hl_device *hdev,return ; reset_device: -if (hdev->asic_prop.fw_security_enabled) -hl_device_reset (hdev,HL_DRV_RESET_HARD - |HL_DRV_RESET_BYPASS_REQ_TO_FW - | fw_fatal_err_flag); + reset_required = true; + +if (hdev->asic_prop.fw_security_enabled && !reset_direct) + flags =HL_DRV_RESET_HARD |HL_DRV_RESET_BYPASS_REQ_TO_FW | fw_fatal_err_flag;else if (hdev->hard_reset_on_fw_events) -hl_device_reset (hdev,HL_DRV_RESET_HARD |HL_DRV_RESET_DELAY | fw_fatal_err_flag); + flags =HL_DRV_RESET_HARD |HL_DRV_RESET_DELAY | fw_fatal_err_flag; +else + reset_required = false; + +if (reset_required) +hl_device_reset (hdev, flags);else hl_fw_unmask_irq (hdev, event_type); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 290/365 habanalabs/gaudi: fix shift out of bounds
In reply to Greg Kroah-HartmanFrom: Ofir Bitton <[email protected]>
[ Upstream commit 01622098aeb05a5efbb727199bbc2a4653393255 ]
When validating NIC queues, queue offset calculation must be performed only for NIC queues.
--- drivers/misc/habanalabs/gaudi/gaudi.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)
drivers/misc/habanalabs/gaudi/gaudi.c +9 -7
@@ -5654,15 +5654,17 @@ static int gaudi_parse_cb_no_ext_queue(struct hl_device *hdev, {struct asic_fixed_properties *asic_prop = &hdev->asic_prop;struct gaudi_device *gaudi = hdev->asic_specific; -u32 nic_mask_q_id =1 << (HW_CAP_NIC_SHIFT + - ((parser->hw_queue_id -GAUDI_QUEUE_ID_NIC_0_0 ) >>2 )); +u32 nic_queue_offset, nic_mask_q_id;if ((parser->hw_queue_id >=GAUDI_QUEUE_ID_NIC_0_0 ) && - (parser->hw_queue_id <=GAUDI_QUEUE_ID_NIC_9_3 ) && - (!(gaudi->hw_cap_initialized & nic_mask_q_id))) { -dev_err (hdev->dev,"h/w queue %d is disabled\n" , - parser->hw_queue_id); -return -EINVAL ; + (parser->hw_queue_id <=GAUDI_QUEUE_ID_NIC_9_3 )) { + nic_queue_offset = parser->hw_queue_id -GAUDI_QUEUE_ID_NIC_0_0 ; + nic_mask_q_id =1 << (HW_CAP_NIC_SHIFT + (nic_queue_offset >>2 )); + +if (!(gaudi->hw_cap_initialized & nic_mask_q_id)) { +dev_err (hdev->dev,"h/w queue %d is disabled\n" , parser->hw_queue_id); +return -EINVAL ; + } }/* For internal queue jobs just check if CB address is valid */
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 291/365 habanalabs/gaudi: mask constant value before cast
In reply to Greg Kroah-HartmanFrom: Oded Gabbay <[email protected]>
[ Upstream commit e3f49437a2e0221a387ecd192d742ae1434e1e3a ]
This fixes a sparse warning of
"cast truncates bits from constant value"
--- drivers/misc/habanalabs/gaudi/gaudi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/misc/habanalabs/gaudi/gaudi.c +4 -4
@@ -3339,19 +3339,19 @@ static void gaudi_init_nic_qman(struct hl_device *hdev, u32 nic_offset,u32 nic_qm_err_cfg, irq_handler_offset;u32 q_off; - mtr_base_en_lo =lower_32_bits (CFG_BASE + + mtr_base_en_lo =lower_32_bits ((CFG_BASE &U32_MAX ) + mmSYNC_MNGR_E_N_SYNC_MNGR_OBJS_MON_PAY_ADDRL_0); mtr_base_en_hi =upper_32_bits (CFG_BASE + mmSYNC_MNGR_E_N_SYNC_MNGR_OBJS_MON_PAY_ADDRL_0); - so_base_en_lo =lower_32_bits (CFG_BASE + + so_base_en_lo =lower_32_bits ((CFG_BASE &U32_MAX ) + mmSYNC_MNGR_E_N_SYNC_MNGR_OBJS_SOB_OBJ_0); so_base_en_hi =upper_32_bits (CFG_BASE + mmSYNC_MNGR_E_N_SYNC_MNGR_OBJS_SOB_OBJ_0); - mtr_base_ws_lo =lower_32_bits (CFG_BASE + + mtr_base_ws_lo =lower_32_bits ((CFG_BASE &U32_MAX ) + mmSYNC_MNGR_W_S_SYNC_MNGR_OBJS_MON_PAY_ADDRL_0); mtr_base_ws_hi =upper_32_bits (CFG_BASE + mmSYNC_MNGR_W_S_SYNC_MNGR_OBJS_MON_PAY_ADDRL_0); - so_base_ws_lo =lower_32_bits (CFG_BASE + + so_base_ws_lo =lower_32_bits ((CFG_BASE &U32_MAX ) + mmSYNC_MNGR_W_S_SYNC_MNGR_OBJS_SOB_OBJ_0); so_base_ws_hi =upper_32_bits (CFG_BASE + mmSYNC_MNGR_W_S_SYNC_MNGR_OBJS_SOB_OBJ_0);
Signature · 1 line
2.35.1