xfrm: Validate address prefix lengths in the xfrm selector.
Subsystems (2)
Sasha Levin
maintainerPATCH 1/100 xfrm: Validate address prefix lengths in the xfrm selector.
From: Steffen Klassert <[email protected]>
[ Upstream commit 07bf7908950a8b14e81aa1807e3c667eab39287a ]
We don't validate the address prefix lengths in the xfrm selector we got from userspace. This can lead to undefined behaviour in the address matching functions if the prefix is too big for the given address family. Fix this by checking the prefixes and refuse SA/policy insertation when a prefix is invalid.
--- net/xfrm/xfrm_user.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
net/xfrm/xfrm_user.c +12 -0
@@ -151,10 +151,16 @@ static int verify_newsa_info(struct xfrm_usersa_info *p, err = -EINVAL ;switch (p->family) {case AF_INET : +if (p->sel.prefixlen_d >32 || p->sel.prefixlen_s >32 ) + goto out; +break ;case AF_INET6 :#if IS_ENABLED (CONFIG_IPV6 ) +if (p->sel.prefixlen_d >128 || p->sel.prefixlen_s >128 ) + goto out; +break ;#else err = -EAFNOSUPPORT ;
@@ -1359,10 +1365,16 @@ static int verify_newpolicy_info(struct xfrm_userpolicy_info *p)switch (p->sel.family) {case AF_INET : +if (p->sel.prefixlen_d >32 || p->sel.prefixlen_s >32 ) +return -EINVAL ; +break ;case AF_INET6 :#if IS_ENABLED (CONFIG_IPV6 ) +if (p->sel.prefixlen_d >128 || p->sel.prefixlen_s >128 ) +return -EINVAL ; +break ;#else return -EAFNOSUPPORT ;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 2/100 xfrm6: call kfree_skb when skb is toobig
From: Thadeu Lima de Souza Cascardo <[email protected]>
[ Upstream commit 215ab0f021c9fea3c18b75e7d522400ee6a49990 ]
After commit d6990976af7c5d8f55903bfb4289b6fb030bf754 ("vti6: fix PMTU caching and reporting on xmit"), some too big skbs might be potentially passed down to __xfrm6_output, causing it to fail to transmit but not free the skb, causing a leak of skb, and consequentially a leak of dst references.
After running pmtu.sh, that shows as failure to unregister devices in a namespace:
[ 311.397671] unregister_netdevice: waiting for veth_b to become free. Usage count = 1
The fix is to call kfree_skb in case of transmit failures.
--- net/ipv6/xfrm6_output.c | 2 ++ 1 file changed, 2 insertions(+)
net/ipv6/xfrm6_output.c +2 -0
@@ -170,9 +170,11 @@ static int __xfrm6_output(struct net *net, struct sock *sk, struct sk_buff *skb)if (toobig &&xfrm6_local_dontfrag (skb)) {xfrm6_local_rxpmtu (skb, mtu); +kfree_skb (skb);return -EMSGSIZE ; }else if (!skb->ignore_df && toobig && skb->sk) {xfrm_local_error (skb, mtu); +kfree_skb (skb);return -EMSGSIZE ; }
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 3/100 xfrm: reset transport header back to network header after all input transforms ahave been applied
In reply to Sasha LevinFrom: Sowmini Varadhan <[email protected]>
[ Upstream commit bfc0698bebcb16d19ecfc89574ad4d696955e5d3 ]
A policy may have been set up with multiple transforms (e.g., ESP and ipcomp). In this situation, the ingress IPsec processing iterates in xfrm_input() and applies each transform in turn, processing the nexthdr to find any additional xfrm that may apply.
This patch resets the transport header back to network header only after the last transformation so that subsequent xfrms can find the correct transport header.
--- net/ipv4/xfrm4_input.c | 1 + net/ipv4/xfrm4_mode_transport.c | 4 +--- net/ipv6/xfrm6_input.c | 1 + net/ipv6/xfrm6_mode_transport.c | 4 +--- 4 files changed, 4 insertions(+), 6 deletions(-)
net/ipv4/xfrm4_input.c +1 -0
@@ -67,6 +67,7 @@ int xfrm4_transport_finish(struct sk_buff *skb, int async)if (xo && (xo->flags &XFRM_GRO )) {skb_mac_header_rebuild (skb); +skb_reset_transport_header (skb);return 0 ; }
net/ipv4/xfrm4_mode_transport.c +1 -3
@@ -46,7 +46,6 @@ static int xfrm4_transport_output(struct xfrm_state *x, struct sk_buff *skb)static int xfrm4_transport_input (struct xfrm_state *x,struct sk_buff *skb) {int ihl = skb->data -skb_transport_header (skb); -struct xfrm_offload *xo =xfrm_offload (skb);if (skb->transport_header != skb->network_header) { memmove(skb_transport_header(skb),
@@ -54,8 +53,7 @@ static int xfrm4_transport_input(struct xfrm_state *x, struct sk_buff *skb) skb->network_header = skb->transport_header; }ip_hdr (skb)->tot_len =htons (skb->len + ihl); -if (!xo || !(xo->flags &XFRM_GRO )) -skb_reset_transport_header (skb); +skb_reset_transport_header (skb);return 0 ; }
net/ipv6/xfrm6_input.c +1 -0
@@ -59,6 +59,7 @@ int xfrm6_transport_finish(struct sk_buff *skb, int async)if (xo && (xo->flags &XFRM_GRO )) {skb_mac_header_rebuild (skb); +skb_reset_transport_header (skb);return -1 ; }
net/ipv6/xfrm6_mode_transport.c +1 -3
@@ -51,7 +51,6 @@ static int xfrm6_transport_output(struct xfrm_state *x, struct sk_buff *skb)static int xfrm6_transport_input (struct xfrm_state *x,struct sk_buff *skb) {int ihl = skb->data -skb_transport_header (skb); -struct xfrm_offload *xo =xfrm_offload (skb);if (skb->transport_header != skb->network_header) { memmove(skb_transport_header(skb),
@@ -60,8 +59,7 @@ static int xfrm6_transport_input(struct xfrm_state *x, struct sk_buff *skb) }ipv6_hdr (skb)->payload_len =htons (skb->len + ihl -sizeof (struct ipv6hdr )); -if (!xo || !(xo->flags &XFRM_GRO )) -skb_reset_transport_header (skb); +skb_reset_transport_header (skb);return 0 ; }
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 4/100 xfrm: reset crypto_done when iterating over multiple input xfrms
In reply to Sasha LevinFrom: Sowmini Varadhan <[email protected]>
[ Upstream commit 782710e333a526780d65918d669cb96646983ba2 ]
We only support one offloaded xfrm (we do not have devices that can handle more than one offload), so reset crypto_done in xfrm_input() when iterating over multiple transforms in xfrm_input, so that we can invoke the appropriate x->type->input for the non-offloaded transforms
--- net/xfrm/xfrm_input.c | 1 + 1 file changed, 1 insertion(+)
net/xfrm/xfrm_input.c +1 -0
@@ -453,6 +453,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)XFRM_INC_STATS (net,LINUX_MIB_XFRMINHDRERROR ); goto drop; } + crypto_done = false; }while (!err); err =xfrm_rcv_cb (skb, family, x->type->proto,0 );
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 5/100 mac80211: Always report TX status
In reply to Sasha LevinFrom: Andrei Otcheretianski <[email protected]>
[ Upstream commit 8682250b3c1b75a45feb7452bc413d004cfe3778 ]
If a frame is dropped for any reason, mac80211 wouldn't report the TX status back to user space.
As the user space may rely on the TX_STATUS to kick its state machines, resends etc, it's better to just report this frame as not acked instead.
--- net/mac80211/status.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
net/mac80211/status.c +2 -5
@@ -479,11 +479,6 @@ static void ieee80211_report_ack_skb(struct ieee80211_local *local,if (!skb)return ; -if (dropped) { -dev_kfree_skb_any (skb); -return ; - } -if (info->flags &IEEE80211_TX_INTFL_NL80211_FRAME_TX ) {u64 cookie =IEEE80211_SKB_CB (skb)->ack.cookie;struct ieee80211_sub_if_data *sdata;
@@ -506,6 +501,8 @@ static void ieee80211_report_ack_skb(struct ieee80211_local *local, }rcu_read_unlock (); +dev_kfree_skb_any (skb); + }else if (dropped) {dev_kfree_skb_any (skb); }else {/* consumes skb */
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 6/100 cfg80211: reg: Init wiphy_idx in regulatory_hint_core()
In reply to Sasha LevinFrom: Andrei Otcheretianski <[email protected]>
[ Upstream commit 24f33e64fcd0d50a4b1a8e5b41bd0257aa66b0e8 ]
Core regulatory hints didn't set wiphy_idx to WIPHY_IDX_INVALID. Since the regulatory request is zeroed, wiphy_idx was always implicitly set to
0. This resulted in updating only phy #0.
Fix that.
--- net/wireless/reg.c | 1 + 1 file changed, 1 insertion(+)
net/wireless/reg.c +1 -0
@@ -2867,6 +2867,7 @@ static int regulatory_hint_core(const char *alpha2) request->alpha2[0 ] = alpha2[0 ]; request->alpha2[1 ] = alpha2[1 ]; request->initiator =NL80211_REGDOM_SET_BY_CORE ; + request->wiphy_idx =WIPHY_IDX_INVALID ;queue_regulatory_request (request);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 7/100 mac80211: fix pending queue hang due to TX_DROP
In reply to Sasha LevinFrom: Bob Copeland <[email protected]>
[ Upstream commit 6eae4a6c2be387fec41b0d2782c4fffb57159498 ]
In our environment running lots of mesh nodes, we are seeing the pending queue hang periodically, with the debugfs queues file showing lines such as:
00: 0x00000000/348
i.e. there are a large number of frames but no stop reason set.
One way this could happen is if queue processing from the pending tasklet exited early without processing all frames, and without having some future event (incoming frame, stop reason flag, ...) to reschedule it.
Exactly this can occur today if ieee80211_tx() returns false due to packet drops or power-save buffering in the tx handlers. In the past, this function would return true in such cases, and the change to false doesn't seem to be intentional. Fix this case by reverting to the previous behavior.
--- net/mac80211/tx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/mac80211/tx.c +1 -1
@@ -1886,7 +1886,7 @@ static bool ieee80211_tx(struct ieee80211_sub_if_data *sdata, sdata->vif.hw_queue[skb_get_queue_mapping (skb)];if (invoke_tx_handlers_early (&tx)) -return false; +return true;if (ieee80211_queue_skb (local, sdata, tx.sta, tx.skb))return true;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 8/100 cfg80211: Address some corner cases in scan result channel updating
In reply to Sasha LevinFrom: Jouni Malinen <[email protected]>
[ Upstream commit 119f94a6fefcc76d47075b83d2b73d04c895df78 ]
cfg80211_get_bss_channel() is used to update the RX channel based on the available frame payload information (channel number from DSSS Parameter Set element or HT Operation element). This is needed on 2.4 GHz channels where frames may be received on neighboring channels due to overlapping frequency range.
This might of some use on the 5 GHz band in some corner cases, but things are more complex there since there is no n:1 or 1:n mapping between channel numbers and frequencies due to multiple different starting frequencies in different operating classes. This could result in ieee80211_channel_to_frequency() returning incorrect frequency and ieee80211_get_channel() returning incorrect channel information (or indication of no match). In the previous implementation, this could result in some scan results being dropped completely, e.g., for the 4.9 GHz channels. That prevented connection to such BSSs.
Fix this by using the driver-provided channel pointer if ieee80211_get_channel() does not find matching channel data for the channel number in the frame payload and if the scan is done with 5 MHz or 10 MHz channel bandwidth. While doing this, also add comments describing what the function is trying to achieve to make it easier to understand what happens here and why.
--- net/wireless/scan.c | 58 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 49 insertions(+), 9 deletions(-)
net/wireless/scan.c +49 -9
@@ -1058,13 +1058,23 @@ cfg80211_bss_update(struct cfg80211_registered_device *rdev,return NULL ; } +/* +* Update RX channel information based on the available frame payload +* information. This is mainly for the 2.4 GHz band where frames can be received +* from neighboring channels and the Beacon frames use the DSSS Parameter Set +* element to indicate the current (transmitting) channel, but this might also +* be needed on other bands if RX frequency does not match with the actual +* operating channel of a BSS. +*/ static struct ieee80211_channel *cfg80211_get_bss_channel (struct wiphy *wiphy,const u8 *ie,size_t ielen, -struct ieee80211_channel *channel) +struct ieee80211_channel *channel, +enum nl80211_bss_scan_width scan_width) {const u8 *tmp;u32 freq;int channel_number =-1 ; +struct ieee80211_channel *alt_channel; tmp =cfg80211_find_ie (WLAN_EID_DS_PARAMS , ie, ielen);if (tmp && tmp[1 ] ==1 ) {
@@ -1078,16 +1088,45 @@ cfg80211_get_bss_channel(struct wiphy *wiphy, const u8 *ie, size_t ielen, } } -if (channel_number <0 ) +if (channel_number <0 ) { +/* No channel information in frame payload */ return channel; + } freq =ieee80211_channel_to_frequency (channel_number, channel->band); - channel =ieee80211_get_channel (wiphy, freq); -if (!channel) -return NULL ; -if (channel->flags &IEEE80211_CHAN_DISABLED ) + alt_channel =ieee80211_get_channel (wiphy, freq); +if (!alt_channel) { +if (channel->band ==NL80211_BAND_2GHZ ) { +/* +* Better not allow unexpected channels when that could +* be going beyond the 1-11 range (e.g., discovering +* BSS on channel 12 when radio is configured for +* channel 11. +*/ +return NULL ; + } + +/* No match for the payload channel number - ignore it */ +return channel; + } + +if (scan_width ==NL80211_BSS_CHAN_WIDTH_10 || + scan_width ==NL80211_BSS_CHAN_WIDTH_5 ) { +/* +* Ignore channel number in 5 and 10 MHz channels where there +* may not be an n:1 or 1:n mapping between frequencies and +* channel numbers. +*/ +return channel; + } + +/* +* Use the channel determined through the payload channel number +* instead of the RX channel reported by the driver. +*/ +if (alt_channel->flags &IEEE80211_CHAN_DISABLED )return NULL ; -return channel; +return alt_channel; }/* Returned bss is reference counted and must be cleaned up appropriately. */
@@ -1112,7 +1151,8 @@ cfg80211_inform_bss_data(struct wiphy *wiphy, (data->signal < 0 || data->signal > 100)))return NULL ; - channel =cfg80211_get_bss_channel (wiphy, ie, ielen, data->chan); + channel =cfg80211_get_bss_channel (wiphy, ie, ielen, data->chan, + data->scan_width);if (!channel)return NULL ;
@@ -1210,7 +1250,7 @@ cfg80211_inform_bss_frame_data(struct wiphy *wiphy,return NULL ; channel =cfg80211_get_bss_channel (wiphy, mgmt->u.beacon.variable, - ielen, data->chan); + ielen, data->chan, data->scan_width);if (!channel)return NULL ;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 9/100 mac80211: TDLS: fix skb queue/priority assignment
In reply to Sasha LevinFrom: Johannes Berg <[email protected]>
[ Upstream commit cb59bc14e830028d2244861216df038165d7625d ]
If the TDLS setup happens over a connection to an AP that doesn't have QoS, we nevertheless assign a non-zero TID (skb->priority) and queue mapping, which may confuse us or drivers later.
Fix it by just assigning the special skb->priority and then using ieee80211_select_queue() just like other data frames would go through.
--- net/mac80211/tdls.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
net/mac80211/tdls.c +4 -4
@@ -16,6 +16,7 @@#include "ieee80211_i.h" #include "driver-ops.h" #include "rate.h" +#include "wme.h" /* give usermode some time for retries in setting up the TDLS session */ #define TDLS_PEER_SETUP_TIMEOUT (15 * HZ)
@@ -1010,14 +1011,13 @@ ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev,switch (action_code) {case WLAN_TDLS_SETUP_REQUEST :case WLAN_TDLS_SETUP_RESPONSE : -skb_set_queue_mapping (skb,IEEE80211_AC_BK ); - skb->priority =2 ; + skb->priority =256 +2 ;break ;default : -skb_set_queue_mapping (skb,IEEE80211_AC_VI ); - skb->priority =5 ; + skb->priority =256 +5 ;break ; } +skb_set_queue_mapping (skb,ieee80211_select_queue (sdata, skb));/* * Set the WLAN_TDLS_TEARDOWN flag to indicate a teardown in progress.
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 10/100 mac80211: fix TX status reporting for ieee80211s
In reply to Sasha LevinFrom: Yuan-Chi Pang <[email protected]>
[ Upstream commit c42055105785580563535e6d3143cad95c7ac7ee ]
TX status reporting to ieee80211s is through ieee80211s_update_metric. There are two problems about ieee80211s_update_metric:
1. The purpose is to estimate the fail probability to a specific link. No need to restrict to data frame.
2. Current implementation does not work if wireless driver does not pass tx_status with skb.
Fix this by removing ieee80211_is_data condition, passing ieee80211_tx_status directly to ieee80211s_update_metric, and putting it in both __ieee80211_tx_status and ieee80211_tx_status_ext.
--- net/mac80211/mesh.h | 3 ++- net/mac80211/mesh_hwmp.c | 9 +++------ net/mac80211/status.c | 4 +++- 3 files changed, 8 insertions(+), 8 deletions(-)
net/mac80211/mesh.h +2 -1
@@ -217,7 +217,8 @@ void mesh_rmc_free(struct ieee80211_sub_if_data *sdata);int mesh_rmc_init (struct ieee80211_sub_if_data *sdata);void ieee80211s_init (void );void ieee80211s_update_metric (struct ieee80211_local *local, -struct sta_info *sta,struct sk_buff *skb); +struct sta_info *sta, +struct ieee80211_tx_status *st);void ieee80211_mesh_init_sdata (struct ieee80211_sub_if_data *sdata);void ieee80211_mesh_teardown_sdata (struct ieee80211_sub_if_data *sdata);int ieee80211_start_mesh (struct ieee80211_sub_if_data *sdata);
net/mac80211/mesh_hwmp.c +3 -6
@@ -295,15 +295,12 @@ int mesh_path_error_tx(struct ieee80211_sub_if_data *sdata, }void ieee80211s_update_metric (struct ieee80211_local *local, -struct sta_info *sta,struct sk_buff *skb) +struct sta_info *sta, +struct ieee80211_tx_status *st) { -struct ieee80211_tx_info *txinfo =IEEE80211_SKB_CB (skb); -struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; +struct ieee80211_tx_info *txinfo = st->info;int failed; -if (!ieee80211_is_data (hdr->frame_control)) -return ; - failed = !(txinfo->flags &IEEE80211_TX_STAT_ACK );/* moving average, scaled to 100.
net/mac80211/status.c +3 -1
@@ -808,7 +808,7 @@ static void __ieee80211_tx_status(struct ieee80211_hw *hw,rate_control_tx_status (local, sband, status);if (ieee80211_vif_is_mesh (&sta->sdata->vif)) -ieee80211s_update_metric (local, sta, skb); +ieee80211s_update_metric (local, sta, status);if (!(info->flags &IEEE80211_TX_CTL_INJECTED ) && acked)ieee80211_frame_acked (sta, skb);
@@ -969,6 +969,8 @@ void ieee80211_tx_status_ext(struct ieee80211_hw *hw, }rate_control_tx_status (local, sband, status); +if (ieee80211_vif_is_mesh (&sta->sdata->vif)) +ieee80211s_update_metric (local, sta, status); }if (acked || noack_success) {
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 11/100 xfrm: Fix NULL pointer dereference when skb_dst_force clears the dst_entry.
In reply to Sasha LevinFrom: Steffen Klassert <[email protected]>
[ Upstream commit 9e1437937807b0122e8da1ca8765be2adca9aee6 ]
Since commit 222d7dbd258d ("net: prevent dst uses after free") skb_dst_force() might clear the dst_entry attached to the skb. The xfrm code don't expect this to happen, so we crash with a NULL pointer dereference in this case. Fix it by checking skb_dst(skb) for NULL after skb_dst_force() and drop the packet in cast the dst_entry was cleared.
--- net/xfrm/xfrm_output.c | 4 ++++ net/xfrm/xfrm_policy.c | 4 ++++ 2 files changed, 8 insertions(+)
net/xfrm/xfrm_output.c +4 -0
@@ -101,6 +101,10 @@ static int xfrm_output_one(struct sk_buff *skb, int err)spin_unlock_bh (&x->lock);skb_dst_force (skb); +if (!skb_dst (skb)) { +XFRM_INC_STATS (net,LINUX_MIB_XFRMOUTERROR ); + goto error_nolock; + }if (xfrm_offload (skb)) { x->type_offload->encap (x, skb);
net/xfrm/xfrm_policy.c +4 -0
@@ -2551,6 +2551,10 @@ int __xfrm_route_forward(struct sk_buff *skb, unsigned short family) }skb_dst_force (skb); +if (!skb_dst (skb)) { +XFRM_INC_STATS (net,LINUX_MIB_XFRMFWDHDRERROR ); +return 0 ; + } dst =xfrm_lookup (net,skb_dst (skb), &fl,NULL ,XFRM_LOOKUP_QUEUE );if (IS_ERR (dst)) {
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 12/100 ARM: 8799/1: mm: fix pci_ioremap_io() offset check
In reply to Sasha LevinFrom: Thomas Petazzoni <[email protected]>
[ Upstream commit 3a58ac65e2d7969bcdf1b6acb70fa4d12a88e53e ]
IO_SPACE_LIMIT is the ending address of the PCI IO space, i.e something like 0xfffff (and not 0x100000).
Therefore, when offset = 0xf0000 is passed as argument, this function fails even though the offset + SZ_64K fits below the IO_SPACE_LIMIT. This makes the last chunk of 64 KB of the I/O space not usable as it cannot be mapped.
This patch fixes that by substracing 1 to offset + SZ_64K, so that we compare the addrss of the last byte of the I/O space against IO_SPACE_LIMIT instead of the address of the first byte of what is after the I/O space.
--- arch/arm/mm/ioremap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/mm/ioremap.c +1 -1
@@ -473,7 +473,7 @@ void pci_ioremap_set_mem_type(int mem_type)int pci_ioremap_io (unsigned int offset,phys_addr_t phys_addr) { -BUG_ON (offset +SZ_64K >IO_SPACE_LIMIT ); +BUG_ON (offset +SZ_64K -1 >IO_SPACE_LIMIT ); return ioremap_page_range(PCI_IO_VIRT_BASE + offset, PCI_IO_VIRT_BASE + offset + SZ_64K,
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 13/100 xfrm: validate template mode
In reply to Sasha LevinFrom: Sean Tranchetti <[email protected]>
[ Upstream commit 32bf94fb5c2ec4ec842152d0e5937cd4bb6738fa ]
XFRM mode parameters passed as part of the user templates in the IP_XFRM_POLICY are never properly validated. Passing values other than valid XFRM modes can cause stack-out-of-bounds reads to occur later in the XFRM processing:
[ 140.535608] ================================================================ [ 140.543058] BUG: KASAN: stack-out-of-bounds in xfrm_state_find+0x17e4/0x1cc4 [ 140.550306] Read of size 4 at addr ffffffc0238a7a58 by task repro/5148 [ 140.557369] [ 140.558927] Call trace: [ 140.558936] dump_backtrace+0x0/0x388 [ 140.558940] show_stack+0x24/0x30 [ 140.558946] __dump_stack+0x24/0x2c [ 140.558949] dump_stack+0x8c/0xd0 [ 140.558956] print_address_description+0x74/0x234 [ 140.558960] kasan_report+0x240/0x264 [ 140.558963] __asan_report_load4_noabort+0x2c/0x38 [ 140.558967] xfrm_state_find+0x17e4/0x1cc4 [ 140.558971] xfrm_resolve_and_create_bundle+0x40c/0x1fb8 [ 140.558975] xfrm_lookup+0x238/0x1444 [ 140.558977] xfrm_lookup_route+0x48/0x11c [ 140.558984] ip_route_output_flow+0x88/0xc4 [ 140.558991] raw_sendmsg+0xa74/0x266c [ 140.558996] inet_sendmsg+0x258/0x3b0 [ 140.559002] sock_sendmsg+0xbc/0xec [ 140.559005] SyS_sendto+0x3a8/0x5a8 [ 140.559008] el0_svc_naked+0x34/0x38 [ 140.559009] [ 140.592245] page dumped because: kasan: bad access detected [ 140.597981] page_owner info is not active (free page?) [ 140.603267] [ 140.653503] ================================================================
--- net/xfrm/xfrm_user.c | 3 +++ 1 file changed, 3 insertions(+)
net/xfrm/xfrm_user.c +3 -0
@@ -1455,6 +1455,9 @@ static int validate_tmpl(int nr, struct xfrm_user_tmpl *ut, u16 family) (ut[i].family != prev_family))return -EINVAL ; +if (ut[i].mode >=XFRM_MODE_MAX ) +return -EINVAL ; + prev_family = ut[i].family;switch (ut[i].family) {
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 14/100 drm/i2c: tda9950: fix timeout counter check
In reply to Sasha LevinFrom: Colin Ian King <[email protected]>
[ Upstream commit d98627d1360d55e3b28f702caca8b6342c4a4e45 ]
Currently the check to see if the timeout has reached zero is incorrect and the check is instead checking if the timeout is non-zero and not zero, hence it will break out of the loop on the first iteration and the msleep is never executed. Fix this by breaking from the loop when timeout is zero.
Detected by CoverityScan, CID#1469404 ("Logically Dead Code")
--- drivers/gpu/drm/i2c/tda9950.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/i2c/tda9950.c +1 -1
@@ -307,7 +307,7 @@ static void tda9950_release(struct tda9950_priv *priv)/* Wait up to .5s for it to signal non-busy */ do { csr =tda9950_read (client,REG_CSR ); -if (!(csr &CSR_BUSY ) || --timeout) +if (!(csr &CSR_BUSY ) || !--timeout)break ;msleep (10 ); }while (1 );
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 15/100 drm/i2c: tda9950: set MAX_RETRIES for errors only
In reply to Sasha LevinFrom: Hans Verkuil <[email protected]>
[ Upstream commit e0dccce1193f87597548d0db6ecc942fb92c04cd ]
The CEC_TX_STATUS_MAX_RETRIES should be set for errors only to prevent the CEC framework from retrying the transmit. If the transmit was successful, then don't set this flag.
Found by running 'cec-compliance -A' on a beaglebone box.
--- drivers/gpu/drm/i2c/tda9950.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/i2c/tda9950.c +2 -1
@@ -188,7 +188,8 @@ static irqreturn_t tda9950_irq(int irq, void *data)break ; }/* TDA9950 executes all retries for us */ - tx_status |=CEC_TX_STATUS_MAX_RETRIES ; +if (tx_status !=CEC_TX_STATUS_OK ) + tx_status |=CEC_TX_STATUS_MAX_RETRIES ;cec_transmit_done (priv->adap, tx_status, arb_lost_cnt, nack_cnt,0 , err_cnt);break ;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 16/100 netfilter: bridge: Don't sabotage nf_hook calls from an l3mdev
In reply to Sasha LevinFrom: David Ahern <[email protected]>
[ Upstream commit a173f066c7cfc031acb8f541708041e009fc9812 ]
For starters, the bridge netfilter code registers operations that are invoked any time nh_hook is called. Specifically, ip_sabotage_in watches for nested calls for NF_INET_PRE_ROUTING when a bridge is in the stack.
Packet wise, the bridge netfilter hook runs first. br_nf_pre_routing allocates nf_bridge, sets in_prerouting to 1 and calls NF_HOOK for NF_INET_PRE_ROUTING. It's finish function, br_nf_pre_routing_finish, then resets in_prerouting flag to 0 and the packet continues up the stack. The packet eventually makes it to the VRF driver and it invokes nf_hook for NF_INET_PRE_ROUTING in case any rules have been added against the vrf device.
Because of the registered operations the call to nf_hook causes ip_sabotage_in to be invoked. That function sees the nf_bridge on the skb and that in_prerouting is not set. Thinking it is an invalid nested call it steals (drops) the packet.
Update ip_sabotage_in to recognize that the bridge or one of its upper devices (e.g., vlan) can be enslaved to a VRF (L3 master device) and allow the packet to go through the nf_hook a second time.
--- net/bridge/br_netfilter_hooks.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
net/bridge/br_netfilter_hooks.c +2 -1
@@ -834,7 +834,8 @@ static unsigned int ip_sabotage_in(void *priv, struct sk_buff *skb, const struct nf_hook_state *state) { -if (skb->nf_bridge && !skb->nf_bridge->in_prerouting) { +if (skb->nf_bridge && !skb->nf_bridge->in_prerouting && + !netif_is_l3_master (skb->dev)) { state->okfn (state->net, state->sk, skb);return NF_STOLEN ; }
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 17/100 netfilter: conntrack: get rid of double sizeof
In reply to Sasha LevinFrom: zhong jiang <[email protected]>
[ Upstream commit 346fa83d10934cf206e2fd0f514bf8ce186f08fe ]
sizeof(sizeof()) is quite strange and does not seem to be what is wanted here.
The issue is detected with the help of Coccinelle.
--- net/netfilter/nf_conntrack_proto_tcp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
net/netfilter/nf_conntrack_proto_tcp.c +2 -2
@@ -1239,8 +1239,8 @@ static const struct nla_policy tcp_nla_policy[CTA_PROTOINFO_TCP_MAX+1] = {#define TCP_NLATTR_SIZE ( \ NLA_ALIGN(NLA_HDRLEN + 1) + \ NLA_ALIGN(NLA_HDRLEN + 1) + \ - NLA_ALIGN(NLA_HDRLEN + sizeof(sizeof(struct nf_ct_tcp_flags))) + \ - NLA_ALIGN(NLA_HDRLEN + sizeof(sizeof(struct nf_ct_tcp_flags)))) + NLA_ALIGN(NLA_HDRLEN + sizeof(struct nf_ct_tcp_flags)) + \ + NLA_ALIGN(NLA_HDRLEN + sizeof(struct nf_ct_tcp_flags)))static int nlattr_to_tcp (struct nlattr *cda[],struct nf_conn *ct) {
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 18/100 arm64: hugetlb: Fix handling of young ptes
In reply to Sasha LevinFrom: Steve Capper <[email protected]>
[ Upstream commit 469ed9d823b7d240d6b9574f061ded7c3834c167 ]
In the contiguous bit hugetlb break-before-make code we assume that all hugetlb pages are young.
In fact, remove_migration_pte is able to place an old hugetlb pte so this assumption is not valid.
This patch fixes the contiguous hugetlb scanning code to preserve young ptes.
--- arch/arm64/mm/hugetlbpage.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
arch/arm64/mm/hugetlbpage.c +9 -3
@@ -117,11 +117,14 @@ static pte_t get_clear_flush(struct mm_struct *mm,/* * If HW_AFDBM is enabled, then the HW could turn on -* the dirty bit for any page in the set, so check -* them all. All hugetlb entries are already young. +* the dirty or accessed bit for any page in the set, +* so check them all. */ if (pte_dirty (pte)) orig_pte =pte_mkdirty (orig_pte); + +if (pte_young (pte)) + orig_pte =pte_mkyoung (orig_pte); }if (valid) {
@@ -340,10 +343,13 @@ int huge_ptep_set_access_flags(struct vm_area_struct *vma,if (!pte_same (orig_pte, pte)) changed =1 ; -/* Make sure we don't lose the dirty state */ +/* Make sure we don't lose the dirty or young state */ if (pte_dirty (orig_pte)) pte =pte_mkdirty (pte); +if (pte_young (orig_pte)) + pte =pte_mkyoung (pte); + hugeprot =pte_pgprot (pte);for (i =0 ; i < ncontig; i++, ptep++, addr += pgsize, pfn += dpfn)set_pte_at (vma->vm_mm, addr, ptep,pfn_pte (pfn, hugeprot));
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 19/100 ARM: dts: BCM63xx: Fix incorrect interrupt specifiers
In reply to Sasha LevinFrom: Florian Fainelli <[email protected]>
[ Upstream commit 3ab97942d0213b6583a5408630a8cbbfbf54730f ]
A number of our interrupts were incorrectly specified, fix both the PPI and SPI interrupts to be correct.
--- arch/arm/boot/dts/bcm63138.dtsi | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
arch/arm/boot/dts/bcm63138.dtsi +8 -6
@@ -106,21 +106,23 @@ global_timer: timer@1e200 { compatible = "arm,cortex-a9-global-timer"; reg = <0x1e200 0x20>; - interrupts = <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <GIC_PPI 11 IRQ_TYPE_EDGE_RISING>; clocks = <&axi_clk>; }; local_timer: local-timer@1e600 { compatible = "arm,cortex-a9-twd-timer"; reg = <0x1e600 0x20>; - interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | + IRQ_TYPE_EDGE_RISING)>; clocks = <&axi_clk>; }; twd_watchdog: watchdog@1e620 { compatible = "arm,cortex-a9-twd-wdt"; reg = <0x1e620 0x20>; - interrupts = <GIC_PPI 14 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | + IRQ_TYPE_LEVEL_HIGH)>; }; armpll: armpll {
@@ -158,7 +160,7 @@ serial0: serial@600 { compatible = "brcm,bcm6345-uart"; reg = <0x600 0x1b>; - interrupts = <GIC_SPI 32 0>; + interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>; clocks = <&periph_clk>; clock-names = "periph"; status = "disabled";
@@ -167,7 +169,7 @@ serial1: serial@620 { compatible = "brcm,bcm6345-uart"; reg = <0x620 0x1b>; - interrupts = <GIC_SPI 33 0>; + interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>; clocks = <&periph_clk>; clock-names = "periph"; status = "disabled";
@@ -180,7 +182,7 @@ reg = <0x2000 0x600>, <0xf0 0x10>; reg-names = "nand", "nand-int-base"; status = "disabled"; - interrupts = <GIC_SPI 38 0>; + interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "nand"; };
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 20/100 net: macb: Clean 64b dma addresses if they are not detected
In reply to Sasha LevinFrom: Michal Simek <[email protected]>
[ Upstream commit e1e5d8a9fe737d94ccc0ccbaf0c97f69a8f3e000 ]
Clear ADDR64 dma bit in DMACFG register in case that HW_DMA_CAP_64B is not detected on 64bit system.
The issue was observed when bootloader(u-boot) does not check macb feature at DCFG6 register (DAW64_OFFSET) and enabling 64bit dma support by default. Then macb driver is reading DMACFG register back and only adding 64bit dma configuration but not cleaning it out.
--- drivers/net/ethernet/cadence/macb_main.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/ethernet/cadence/macb_main.c +1 -0
@@ -2089,6 +2089,7 @@ static void macb_configure_dma(struct macb *bp)else dmacfg &= ~GEM_BIT (TXCOEN ); + dmacfg &= ~GEM_BIT (ADDR64 );#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT if (bp->hw_dma_cap &HW_DMA_CAP_64B ) dmacfg |=GEM_BIT (ADDR64 );
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 21/100 net: hns: fix for unmapping problem when SMMU is on
In reply to Sasha LevinFrom: Yunsheng Lin <[email protected]>
[ Upstream commit 2e9361efa707e186d91b938e44f9e326725259f7 ]
If SMMU is on, there is more likely that skb_shinfo(skb)->frags[i] can not send by a single BD. when this happen, the hns_nic_net_xmit_hw function map the whole data in a frags using skb_frag_dma_map, but unmap each BD' data individually when tx is done, which causes problem when SMMU is on.
This patch fixes this problem by ummapping the whole data in a frags when tx is done.
--- drivers/net/ethernet/hisilicon/hns/hnae.c | 2 +- drivers/net/ethernet/hisilicon/hns/hns_enet.c | 30 ++++++++++++------- 2 files changed, 20 insertions(+), 12 deletions(-)
drivers/net/ethernet/hisilicon/hns/hnae.c +1 -1
@@ -84,7 +84,7 @@ static void hnae_unmap_buffer(struct hnae_ring *ring, struct hnae_desc_cb *cb)if (cb->type ==DESC_TYPE_SKB )dma_unmap_single (ring_to_dev (ring), cb->dma, cb->length,ring_to_dma_dir (ring)); -else +else if (cb->length)dma_unmap_page (ring_to_dev (ring), cb->dma, cb->length,ring_to_dma_dir (ring)); }
drivers/net/ethernet/hisilicon/hns/hns_enet.c +19 -11
@@ -40,9 +40,9 @@#define SKB_TMP_LEN (SKB ) \ (((SKB)->transport_header - (SKB)->mac_header) + tcp_hdrlen(SKB)) -static void fill_v2_desc (struct hnae_ring *ring,void *priv, -int size,dma_addr_t dma,int frag_end, -int buf_num,enum hns_desc_type type,int mtu) +static void fill_v2_desc_hw (struct hnae_ring *ring,void *priv,int size, +int send_sz,dma_addr_t dma,int frag_end, +int buf_num,enum hns_desc_type type,int mtu) {struct hnae_desc *desc = &ring->desc[ring->next_to_use];struct hnae_desc_cb *desc_cb = &ring->desc_cb[ring->next_to_use];
@@ -64,7 +64,7 @@ static void fill_v2_desc(struct hnae_ring *ring, void *priv, desc_cb->type = type; desc->addr =cpu_to_le64 (dma); - desc->tx.send_size =cpu_to_le16 ((u16 )size); + desc->tx.send_size =cpu_to_le16 ((u16 )send_sz);/* config bd buffer end */ hnae_set_bit (rrcfv,HNSV2_TXD_VLD_B ,1 );
@@ -133,6 +133,14 @@ static void fill_v2_desc(struct hnae_ring *ring, void *priv,ring_ptr_move_fw (ring, next_to_use); } +static void fill_v2_desc (struct hnae_ring *ring,void *priv, +int size,dma_addr_t dma,int frag_end, +int buf_num,enum hns_desc_type type,int mtu) +{ +fill_v2_desc_hw (ring, priv, size, size, dma, frag_end, + buf_num, type, mtu); +} +static const struct acpi_device_id hns_enet_acpi_match[] = { {"HISI00C1" ,0 }, {"HISI00C2" ,0 },
@@ -289,15 +297,15 @@ static void fill_tso_desc(struct hnae_ring *ring, void *priv,/* when the frag size is bigger than hardware, split this frag */ for (k =0 ; k < frag_buf_num; k++) -fill_v2_desc (ring, priv, - (k == frag_buf_num -1 ) ? +fill_v2_desc_hw (ring, priv, k ==0 ? size :0 , + (k == frag_buf_num -1 ) ? sizeoflast :BD_MAX_SEND_SIZE , - dma +BD_MAX_SEND_SIZE * k, - frag_end && (k == frag_buf_num -1 ) ?1 :0 , - buf_num, - (type ==DESC_TYPE_SKB && !k) ? + dma +BD_MAX_SEND_SIZE * k, + frag_end && (k == frag_buf_num -1 ) ?1 :0 , + buf_num, + (type ==DESC_TYPE_SKB && !k) ?DESC_TYPE_SKB :DESC_TYPE_PAGE , - mtu); + mtu); } netdev_tx_t hns_nic_net_xmit_hw(struct net_device *ndev,
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 22/100 soc: fsl: qbman: qman: avoid allocating from non existing gen_pool
In reply to Sasha LevinFrom: Alexandre Belloni <[email protected]>
[ Upstream commit 64e9e22e68512da8df3c9a7430f07621e48db3c2 ]
If the qman driver didn't probe, calling qman_alloc_fqid_range, qman_alloc_pool_range or qman_alloc_cgrid_range (as done in dpaa_eth) will pass a NULL pointer to gen_pool_alloc, leading to a NULL pointer dereference.
--- drivers/soc/fsl/qbman/qman.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/soc/fsl/qbman/qman.c +3 -0
@@ -2729,6 +2729,9 @@ static int qman_alloc_range(struct gen_pool *p, u32 *result, u32 cnt) {unsigned long addr; +if (!p) +return -ENODEV ; + addr =gen_pool_alloc (p, cnt);if (!addr)return -ENOMEM ;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 23/100 soc: fsl: qe: Fix copy/paste bug in ucc_get_tdm_sync_shift()
In reply to Sasha LevinFrom: Zhao Qiang <[email protected]>
[ Upstream commit 96fc74333f84cfdf8d434c6c07254e215e2aad00 ]
There is a copy and paste bug so we accidentally use the RX_ shift when we're in TX_ mode.
--- drivers/soc/fsl/qe/ucc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/soc/fsl/qe/ucc.c +1 -1
@@ -626,7 +626,7 @@ static u32 ucc_get_tdm_sync_shift(enum comm_dir mode, u32 tdm_num) {u32 shift; - shift = (mode ==COMM_DIR_RX ) ?RX_SYNC_SHIFT_BASE :RX_SYNC_SHIFT_BASE ; + shift = (mode ==COMM_DIR_RX ) ?RX_SYNC_SHIFT_BASE :TX_SYNC_SHIFT_BASE ; shift -= tdm_num *2 ;return shift;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 24/100 nl80211: Fix possible Spectre-v1 for NL80211_TXRATE_HT
In reply to Sasha LevinFrom: Masashi Honma <[email protected]>
[ Upstream commit 30fe6d50eb088783c8729c7d930f65296b2b3fa7 ]
Use array_index_nospec() to sanitize ridx with respect to speculation.
--- net/wireless/nl80211.c | 1 + 1 file changed, 1 insertion(+)
net/wireless/nl80211.c +1 -0
@@ -3699,6 +3699,7 @@ static bool ht_rateset_to_mask(struct ieee80211_supported_band *sband,return false;/* check availability */ + ridx =array_index_nospec (ridx,IEEE80211_HT_MCS_MASK_LEN );if (sband->ht_cap.mcs.rx_mask[ridx] & rbit) mcs[ridx] |= rbit;else
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 25/100 mac80211_hwsim: fix locking when iterating radios during ns exit
In reply to Sasha LevinFrom: Martin Willi <[email protected]>
[ Upstream commit 628980e5c8f038f730582c6ee50b7410741cd96e ]
The cleanup of radios during namespace exit has recently been reworked to directly delete a radio while temporarily releasing the spinlock, fixing a race condition between the work-queue execution and namespace exits. However, the temporary unlock allows unsafe modifications on the iterated list, resulting in a potential crash when continuing the iteration of additional radios.
Move radios about to destroy to a temporary list, and clean that up after releasing the spinlock once iteration is complete.
--- drivers/net/wireless/mac80211_hwsim.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
drivers/net/wireless/mac80211_hwsim.c +7 -4
@@ -3523,6 +3523,7 @@ static __net_init int hwsim_init_net(struct net *net) static void __net_exit hwsim_exit_net(struct net *net) {struct mac80211_hwsim_data *data, *tmp; +LIST_HEAD (list);spin_lock_bh (&hwsim_radio_lock);list_for_each_entry_safe (data, tmp, &hwsim_radios, list) {
@@ -3533,17 +3534,19 @@ static void __net_exit hwsim_exit_net(struct net *net)if (data->netgroup ==hwsim_net_get_netgroup (&init_net))continue ; -list_del (&data->list); +list_move (&data->list, &list);rhashtable_remove_fast (&hwsim_radios_rht, &data->rht, hwsim_rht_params); hwsim_radios_generation++; -spin_unlock_bh (&hwsim_radio_lock); + } +spin_unlock_bh (&hwsim_radio_lock); + +list_for_each_entry_safe (data, tmp, &list, list) { +list_del (&data->list);mac80211_hwsim_del_radio (data,wiphy_name (data->hw->wiphy),NULL ); -spin_lock_bh (&hwsim_radio_lock); } -spin_unlock_bh (&hwsim_radio_lock);ida_simple_remove (&hwsim_netgroup_ida,hwsim_net_get_netgroup (net)); }
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 26/100 mac80211_hwsim: fix race in radio destruction from netlink notifier
In reply to Sasha LevinFrom: Martin Willi <[email protected]>
[ Upstream commit f1c47eb61d52379de5747d02bb36be20d7a2d0d3 ]
The asynchronous destruction from a work-queue of radios tagged with destroy-on-close may race with the owning namespace about to exit, resulting in potential use-after-free of that namespace.
Instead of using a work-queue, move radios about to destroy to a temporary list, which can be worked on synchronously after releasing the lock. This should be safe to do from the netlink socket notifier, as the namespace is guaranteed to not get released.
--- drivers/net/wireless/mac80211_hwsim.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-)
drivers/net/wireless/mac80211_hwsim.c +9 -13
@@ -519,7 +519,6 @@ struct mac80211_hwsim_data {int channels, idx;bool use_chanctx;bool destroy_on_close; -struct work_struct destroy_work;u32 portid;char alpha2[2 ];const struct ieee80211_regdomain *regd;
@@ -3442,30 +3441,27 @@ static struct genl_family hwsim_genl_family __ro_after_init = { .n_mcgrps = ARRAY_SIZE(hwsim_mcgrps), }; -static void destroy_radio (struct work_struct *work) -{ -struct mac80211_hwsim_data *data = - container_of(work, struct mac80211_hwsim_data, destroy_work); - - hwsim_radios_generation++; -mac80211_hwsim_del_radio (data,wiphy_name (data->hw->wiphy),NULL ); -} -static void remove_user_radios (u32 portid) {struct mac80211_hwsim_data *entry, *tmp; +LIST_HEAD (list);spin_lock_bh (&hwsim_radio_lock);list_for_each_entry_safe (entry, tmp, &hwsim_radios, list) {if (entry->destroy_on_close && entry->portid == portid) { -list_del (&entry->list); +list_move (&entry->list, &list);rhashtable_remove_fast (&hwsim_radios_rht, &entry->rht, hwsim_rht_params); -INIT_WORK (&entry->destroy_work, destroy_radio); -queue_work (hwsim_wq, &entry->destroy_work); + hwsim_radios_generation++; } }spin_unlock_bh (&hwsim_radio_lock); + +list_for_each_entry_safe (entry, tmp, &list, list) { +list_del (&entry->list); +mac80211_hwsim_del_radio (entry,wiphy_name (entry->hw->wiphy), +NULL ); + } } static int mac80211_hwsim_netlink_notify(struct notifier_block *nb,
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 27/100 mac80211_hwsim: do not omit multicast announce of first added radio
In reply to Sasha LevinFrom: Martin Willi <[email protected]>
[ Upstream commit 28ef8b49a338dc1844e86b7954cfffc7dfa2660a ]
The allocation of hwsim radio identifiers uses a post-increment from 0, so the first radio has idx 0. This idx is explicitly excluded from multicast announcements ever since, but it is unclear why.
Drop that idx check and announce the first radio as well. This makes userspace happy if it relies on these events.
--- drivers/net/wireless/mac80211_hwsim.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/net/wireless/mac80211_hwsim.c +1 -2
@@ -2811,8 +2811,7 @@ static int mac80211_hwsim_new_radio(struct genl_info *info, hwsim_radios_generation++;spin_unlock_bh (&hwsim_radio_lock); -if (idx >0 ) -hwsim_mcast_new_radio (idx, info, param); +hwsim_mcast_new_radio (idx, info, param);return idx;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 28/100 Bluetooth: SMP: fix crash in unpairing
In reply to Sasha LevinFrom: Matias Karhumaa <[email protected]>
[ Upstream commit cb28c306b93b71f2741ce1a5a66289db26715f4d ]
In case unpair_device() was called through mgmt interface at the same time when pairing was in progress, Bluetooth kernel module crash was seen.
[ 600.351225] general protection fault: 0000 [#1] SMP PTI [ 600.351235] CPU: 1 PID: 11096 Comm: btmgmt Tainted: G OE 4.19.0-rc1+ #1 [ 600.351238] Hardware name: Dell Inc. Latitude E5440/08RCYC, BIOS A18 05/14/2017 [ 600.351272] RIP: 0010:smp_chan_destroy.isra.10+0xce/0x2c0 [bluetooth] [ 600.351276] Code: c0 0f 84 b4 01 00 00 80 78 28 04 0f 84 53 01 00 00 4d 85 ed 0f 85 ab 00 00 00 48 8b 08 48 8b 50 08 be 10 00 00 00 48 89 51 08 <48> 89 0a 48 b9 00 02 00 00 00 00 ad de 48 89 48 08 48 8b 83 00 01 [ 600.351279] RSP: 0018:ffffa9be839b3b50 EFLAGS: 00010246 [ 600.351282] RAX: ffff9c999ac565a0 RBX: ffff9c9996e98c00 RCX: ffff9c999aa28b60 [ 600.351285] RDX: dead000000000200 RSI: 0000000000000010 RDI: ffff9c999e403500 [ 600.351287] RBP: ffffa9be839b3b70 R08: 0000000000000000 R09: ffffffff92a25c00 [ 600.351290] R10: ffffa9be839b3ae8 R11: 0000000000000001 R12: ffff9c995375b800 [ 600.351292] R13: 0000000000000000 R14: ffff9c99619a5000 R15: ffff9c9962a01c00 [ 600.351295] FS: 00007fb2be27c700(0000) GS:ffff9c999e880000(0000) knlGS:0000000000000000 [ 600.351298] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 600.351300] CR2: 00007fb2bdadbad0 CR3: 000000041c328001 CR4: 00000000001606e0 [ 600.351302] Call Trace: [ 600.351325] smp_failure+0x4f/0x70 [bluetooth] [ 600.351345] smp_cancel_pairing+0x74/0x80 [bluetooth] [ 600.351370] unpair_device+0x1c1/0x330 [bluetooth] [ 600.351399] hci_sock_sendmsg+0x960/0x9f0 [bluetooth] [ 600.351409] ? apparmor_socket_sendmsg+0x1e/0x20 [ 600.351417] sock_sendmsg+0x3e/0x50 [ 600.351422] sock_write_iter+0x85/0xf0 [ 600.351429] do_iter_readv_writev+0x12b/0x1b0 [ 600.351434] do_iter_write+0x87/0x1a0 [ 600.351439] vfs_writev+0x98/0x110 [ 600.351443] ? ep_poll+0x16d/0x3d0 [ 600.351447] ? ep_modify+0x73/0x170 [ 600.351451] do_writev+0x61/0xf0 [ 600.351455] ? do_writev+0x61/0xf0 [ 600.351460] __x64_sys_writev+0x1c/0x20 [ 600.351465] do_syscall_64+0x5a/0x110 [ 600.351471] entry_SYSCALL_64_after_hwframe+0x44/0xa9 [ 600.351474] RIP: 0033:0x7fb2bdb62fe0 [ 600.351477] Code: 73 01 c3 48 8b 0d b8 6e 2c 00 f7 d8 64 89 01 48 83 c8 ff c3 66 0f 1f 44 00 00 83 3d 69 c7 2c 00 00 75 10 b8 14 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 31 c3 48 83 ec 08 e8 de 80 01 00 48 89 04 24 [ 600.351479] RSP: 002b:00007ffe062cb8f8 EFLAGS: 00000246 ORIG_RAX: 0000000000000014 [ 600.351484] RAX: ffffffffffffffda RBX: 000000000255b3d0 RCX: 00007fb2bdb62fe0 [ 600.351487] RDX: 0000000000000001 RSI: 00007ffe062cb920 RDI: 0000000000000004 [ 600.351490] RBP: 00007ffe062cb920 R08: 000000000255bd80 R09: 0000000000000000 [ 600.351494] R10: 0000000000000353 R11: 0000000000000246 R12: 0000000000000001 [ 600.351497] R13: 00007ffe062cbbe0 R14: 0000000000000000 R15: 0000000000000000 [ 600.351501] Modules linked in: algif_hash algif_skcipher af_alg cmac ipt_MASQUERADE nf_conntrack_netlink nfnetlink xfrm_user xfrm_algo iptable_nat nf_nat_ipv4 xt_addrtype iptable_filter ip_tables xt_conntrack x_tables nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 libcrc32c br_netfilter bridge stp llc overlay arc4 nls_iso8859_1 dm_crypt intel_rapl x86_pkg_temp_thermal intel_powerclamp coretemp dell_laptop kvm_intel crct10dif_pclmul dell_smm_hwmon crc32_pclmul ghash_clmulni_intel pcbc aesni_intel aes_x86_64 crypto_simd cryptd glue_helper intel_cstate intel_rapl_perf uvcvideo videobuf2_vmalloc videobuf2_memops videobuf2_v4l2 videobuf2_common videodev media hid_multitouch input_leds joydev serio_raw dell_wmi snd_hda_codec_hdmi snd_hda_codec_realtek snd_hda_codec_generic dell_smbios dcdbas sparse_keymap [ 600.351569] snd_hda_intel btusb snd_hda_codec btrtl btbcm btintel snd_hda_core bluetooth(OE) snd_hwdep snd_pcm iwlmvm ecdh_generic wmi_bmof dell_wmi_descriptor snd_seq_midi mac80211 snd_seq_midi_event lpc_ich iwlwifi snd_rawmidi snd_seq snd_seq_device snd_timer cfg80211 snd soundcore mei_me mei dell_rbtn dell_smo8800 mac_hid parport_pc ppdev lp parport autofs4 hid_generic usbhid hid i915 nouveau kvmgt vfio_mdev mdev vfio_iommu_type1 vfio kvm irqbypass i2c_algo_bit ttm drm_kms_helper syscopyarea sysfillrect sysimgblt mxm_wmi psmouse ahci sdhci_pci cqhci libahci fb_sys_fops sdhci drm e1000e video wmi [ 600.351637] ---[ end trace e49e9f1df09c94fb ]--- [ 600.351664] RIP: 0010:smp_chan_destroy.isra.10+0xce/0x2c0 [bluetooth] [ 600.351666] Code: c0 0f 84 b4 01 00 00 80 78 28 04 0f 84 53 01 00 00 4d 85 ed 0f 85 ab 00 00 00 48 8b 08 48 8b 50 08 be 10 00 00 00 48 89 51 08 <48> 89 0a 48 b9 00 02 00 00 00 00 ad de 48 89 48 08 48 8b 83 00 01 [ 600.351669] RSP: 0018:ffffa9be839b3b50 EFLAGS: 00010246 [ 600.351672] RAX: ffff9c999ac565a0 RBX: ffff9c9996e98c00 RCX: ffff9c999aa28b60 [ 600.351674] RDX: dead000000000200 RSI: 0000000000000010 RDI: ffff9c999e403500 [ 600.351676] RBP: ffffa9be839b3b70 R08: 0000000000000000 R09: ffffffff92a25c00 [ 600.351679] R10: ffffa9be839b3ae8 R11: 0000000000000001 R12: ffff9c995375b800 [ 600.351681] R13: 0000000000000000 R14: ffff9c99619a5000 R15: ffff9c9962a01c00 [ 600.351684] FS: 00007fb2be27c700(0000) GS:ffff9c999e880000(0000) knlGS:0000000000000000 [ 600.351686] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 600.351689] CR2: 00007fb2bdadbad0 CR3: 000000041c328001 CR4: 00000000001606e0
Crash happened because list_del_rcu() was called twice for smp->ltk. This was possible if unpair_device was called right after ltk was generated but before keys were distributed.
In this commit smp_cancel_pairing was refactored to cancel pairing if it is in progress and otherwise just removes keys. Once keys are removed from rcu list, pointers to smp context's keys are set to NULL to make sure removed list items are not accessed later.
This commit also adjusts the functionality of mgmt unpair_device() little bit. Previously pairing was canceled only if pairing was in state that keys were already generated. With this commit unpair_device() cancels pairing already in earlier states.
Bug was found by fuzzing kernel SMP implementation using Synopsys Defensics.
--- net/bluetooth/mgmt.c | 7 ++----- net/bluetooth/smp.c | 29 +++++++++++++++++++++++++---- net/bluetooth/smp.h | 3 ++- 3 files changed, 29 insertions(+), 10 deletions(-)
net/bluetooth/mgmt.c +2 -5
@@ -2298,9 +2298,8 @@ static int unpair_device(struct sock *sk, struct hci_dev *hdev, void *data,/* LE address type */ addr_type =le_addr_type (cp->addr.type); -hci_remove_irk (hdev, &cp->addr.bdaddr, addr_type); - - err =hci_remove_ltk (hdev, &cp->addr.bdaddr, addr_type); +/* Abort any ongoing SMP pairing. Removes ltk and irk if they exist. */ + err =smp_cancel_and_remove_pairing (hdev, &cp->addr.bdaddr, addr_type);if (err <0 ) { err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_UNPAIR_DEVICE, MGMT_STATUS_NOT_PAIRED, &rp,
@@ -2314,8 +2313,6 @@ static int unpair_device(struct sock *sk, struct hci_dev *hdev, void *data, goto done; } -/* Abort any ongoing SMP pairing */ -smp_cancel_pairing (conn);/* Defer clearing up the connection parameters until closing to * give a chance of keeping them if a repairing happens.
net/bluetooth/smp.c +25 -4
@@ -2419,30 +2419,51 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)return ret; } -void smp_cancel_pairing (struct hci_conn *hcon) +int smp_cancel_and_remove_pairing (struct hci_dev *hdev,bdaddr_t *bdaddr, +u8 addr_type) { -struct l2cap_conn *conn = hcon->l2cap_data; +struct hci_conn *hcon; +struct l2cap_conn *conn;struct l2cap_chan *chan;struct smp_chan *smp; +int err; + + err =hci_remove_ltk (hdev, bdaddr, addr_type); +hci_remove_irk (hdev, bdaddr, addr_type); + + hcon =hci_conn_hash_lookup_le (hdev, bdaddr, addr_type); +if (!hcon) + goto done; + conn = hcon->l2cap_data;if (!conn) -return ; + goto done; chan = conn->smp;if (!chan) -return ; + goto done;l2cap_chan_lock (chan); smp = chan->data;if (smp) { +/* Set keys to NULL to make sure smp_failure() does not try to +* remove and free already invalidated rcu list entries. */ + smp->ltk =NULL ; + smp->slave_ltk =NULL ; + smp->remote_irk =NULL ; +if (test_bit (SMP_FLAG_COMPLETE , &smp->flags))smp_failure (conn,0 );else smp_failure (conn,SMP_UNSPECIFIED ); + err =0 ; }l2cap_chan_unlock (chan); + +done: +return err; }static int smp_cmd_encrypt_info (struct l2cap_conn *conn,struct sk_buff *skb)
net/bluetooth/smp.h +2 -1
@@ -181,7 +181,8 @@ enum smp_key_pref { };/* SMP Commands */ -void smp_cancel_pairing (struct hci_conn *hcon); +int smp_cancel_and_remove_pairing (struct hci_dev *hdev,bdaddr_t *bdaddr, +u8 addr_type);bool smp_sufficient_security (struct hci_conn *hcon,u8 sec_level,enum smp_key_pref key_pref);int smp_conn_security (struct hci_conn *hcon,__u8 sec_level);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 29/100 pxa168fb: prepare the clock
In reply to Sasha LevinFrom: Lubomir Rintel <[email protected]>
[ Upstream commit d85536cde91fcfed6fb8d983783bd2b92c843939 ]
Add missing prepare/unprepare operations for fbi->clk, this fixes following kernel warning:
------------[ cut here ]------------ WARNING: CPU: 0 PID: 1 at drivers/clk/clk.c:874 clk_core_enable+0x2c/0x1b0 Enabling unprepared disp0_clk Modules linked in: CPU: 0 PID: 1 Comm: swapper Not tainted 4.18.0-rc8-00032-g02b43ddd4f21-dirty #25 Hardware name: Marvell MMP2 (Device Tree Support) [<c010f7cc>] (unwind_backtrace) from [<c010cc6c>] (show_stack+0x10/0x14) [<c010cc6c>] (show_stack) from [<c011dab4>] (__warn+0xd8/0xf0) [<c011dab4>] (__warn) from [<c011db10>] (warn_slowpath_fmt+0x44/0x6c) [<c011db10>] (warn_slowpath_fmt) from [<c043898c>] (clk_core_enable+0x2c/0x1b0) [<c043898c>] (clk_core_enable) from [<c0439ec8>] (clk_core_enable_lock+0x18/0x2c) [<c0439ec8>] (clk_core_enable_lock) from [<c0436698>] (pxa168fb_probe+0x464/0x6ac) [<c0436698>] (pxa168fb_probe) from [<c04779a0>] (platform_drv_probe+0x48/0x94) [<c04779a0>] (platform_drv_probe) from [<c0475bec>] (driver_probe_device+0x328/0x470) [<c0475bec>] (driver_probe_device) from [<c0475de4>] (__driver_attach+0xb0/0x124) [<c0475de4>] (__driver_attach) from [<c0473c38>] (bus_for_each_dev+0x64/0xa0) [<c0473c38>] (bus_for_each_dev) from [<c0474ee0>] (bus_add_driver+0x1b8/0x230) [<c0474ee0>] (bus_add_driver) from [<c0476a20>] (driver_register+0xac/0xf0) [<c0476a20>] (driver_register) from [<c0102dd4>] (do_one_initcall+0xb8/0x1f0) [<c0102dd4>] (do_one_initcall) from [<c0b010a0>] (kernel_init_freeable+0x294/0x2e0) [<c0b010a0>] (kernel_init_freeable) from [<c07e9eb8>] (kernel_init+0x8/0x10c) [<c07e9eb8>] (kernel_init) from [<c01010e8>] (ret_from_fork+0x14/0x2c) Exception stack(0xd008bfb0 to 0xd008bff8) bfa0: 00000000 00000000 00000000 00000000 bfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 bfe0: 00000000 00000000 00000000 00000000 00000013 00000000 ---[ end trace c0af40f9e2ed7cb4 ]---
--- drivers/video/fbdev/pxa168fb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/video/fbdev/pxa168fb.c +3 -3
@@ -712,7 +712,7 @@ static int pxa168fb_probe(struct platform_device *pdev)/* * enable controller clock */ -clk_enable (fbi->clk); +clk_prepare_enable (fbi->clk);pxa168fb_set_par (info);
@@ -767,7 +767,7 @@ static int pxa168fb_probe(struct platform_device *pdev) failed_free_cmap:fb_dealloc_cmap (&info->cmap); failed_free_clk: -clk_disable (fbi->clk); +clk_disable_unprepare (fbi->clk); failed_free_fbmem:dma_free_coherent (fbi->dev, info->fix.smem_len, info->screen_base, fbi->fb_start_dma);
@@ -807,7 +807,7 @@ static int pxa168fb_remove(struct platform_device *pdev)dma_free_wc (fbi->dev,PAGE_ALIGN (info->fix.smem_len), info->screen_base, info->fix.smem_start); -clk_disable (fbi->clk); +clk_disable_unprepare (fbi->clk);framebuffer_release (info);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 30/100 qed: Avoid implicit enum conversion in qed_set_tunn_cls_info
In reply to Sasha LevinFrom: Nathan Chancellor <[email protected]>
[ Upstream commit a898fba32229efd5e6b6154f83fa86a7145156b9 ]
Clang warns when one enumerated type is implicitly converted to another.
drivers/net/ethernet/qlogic/qed/qed_sp_commands.c:163:25: warning:
implicit conversion from enumeration type 'enum tunnel_clss' to different enumeration type 'enum qed_tunn_clss' [-Wenum-conversion]
p_tun->vxlan.tun_cls = type;
~ ^~~~
drivers/net/ethernet/qlogic/qed/qed_sp_commands.c:165:26: warning:
implicit conversion from enumeration type 'enum tunnel_clss' to
different enumeration type 'enum qed_tunn_clss' [-Wenum-conversion]
p_tun->l2_gre.tun_cls = type;
~ ^~~~
drivers/net/ethernet/qlogic/qed/qed_sp_commands.c:167:26: warning:
implicit conversion from enumeration type 'enum tunnel_clss' to
different enumeration type 'enum qed_tunn_clss' [-Wenum-conversion]
p_tun->ip_gre.tun_cls = type;
~ ^~~~
drivers/net/ethernet/qlogic/qed/qed_sp_commands.c:169:29: warning:
implicit conversion from enumeration type 'enum tunnel_clss' to
different enumeration type 'enum qed_tunn_clss' [-Wenum-conversion]
p_tun->l2_geneve.tun_cls = type;
~ ^~~~
drivers/net/ethernet/qlogic/qed/qed_sp_commands.c:171:29: warning:
implicit conversion from enumeration type 'enum tunnel_clss' to
different enumeration type 'enum qed_tunn_clss' [-Wenum-conversion]
p_tun->ip_geneve.tun_cls = type;
~ ^~~~5 warnings generated.
Avoid this by changing type to an int.
--- drivers/net/ethernet/qlogic/qed/qed_sp_commands.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/qlogic/qed/qed_sp_commands.c +1 -1
@@ -154,7 +154,7 @@ qed_set_pf_update_tunn_mode(struct qed_tunnel_info *p_tun,static void qed_set_tunn_cls_info (struct qed_tunnel_info *p_tun,struct qed_tunnel_info *p_src) { -enum tunnel_clss type; +int type; p_tun->b_update_rx_cls = p_src->b_update_rx_cls; p_tun->b_update_tx_cls = p_src->b_update_tx_cls;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 31/100 qed: Fix mask parameter in qed_vf_prep_tunn_req_tlv
In reply to Sasha LevinFrom: Nathan Chancellor <[email protected]>
[ Upstream commit db803f36e56f23b5a2266807e190d1dc11554d54 ]
Clang complains when one enumerated type is implicitly converted to another.
drivers/net/ethernet/qlogic/qed/qed_vf.c:686:6: warning: implicit conversion from enumeration type 'enum qed_tunn_mode' to different enumeration type 'enum qed_tunn_clss' [-Wenum-conversion]
QED_MODE_L2GENEVE_TUNN,
^~~~~~~~~~~~~~~~~~~~~~Update mask's parameter to expect qed_tunn_mode, which is what was intended.
--- drivers/net/ethernet/qlogic/qed/qed_vf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/ethernet/qlogic/qed/qed_vf.c +2 -2
@@ -572,7 +572,7 @@ int qed_vf_hw_prepare(struct qed_hwfn *p_hwfn)static void __qed_vf_prep_tunn_req_tlv (struct vfpf_update_tunn_param_tlv *p_req,struct qed_tunn_update_type *p_src, -enum qed_tunn_clss mask,u8 *p_cls) +enum qed_tunn_mode mask,u8 *p_cls) {if (p_src->b_update_mode) { p_req->tun_mode_update_mask |=BIT (mask);
@@ -587,7 +587,7 @@ __qed_vf_prep_tunn_req_tlv(struct vfpf_update_tunn_param_tlv *p_req,static void qed_vf_prep_tunn_req_tlv (struct vfpf_update_tunn_param_tlv *p_req,struct qed_tunn_update_type *p_src, -enum qed_tunn_clss mask, +enum qed_tunn_mode mask,u8 *p_cls,struct qed_tunn_update_udp_port *p_port,u8 *p_update_port,u16 *p_udp_port) {
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 32/100 qed: Avoid implicit enum conversion in qed_roce_mode_to_flavor
In reply to Sasha LevinFrom: Nathan Chancellor <[email protected]>
[ Upstream commit d3a315795b4ce8b105a64a90699103121bde04a8 ]
Clang warns when one enumerated type is implicitly converted to another.
drivers/net/ethernet/qlogic/qed/qed_roce.c:153:12: warning: implicit conversion from enumeration type 'enum roce_mode' to different enumeration type 'enum roce_flavor' [-Wenum-conversion]
flavor = ROCE_V2_IPV6;
~ ^~~~~~~~~~~~
drivers/net/ethernet/qlogic/qed/qed_roce.c:156:12: warning: implicit
conversion from enumeration type 'enum roce_mode' to different
enumeration type 'enum roce_flavor' [-Wenum-conversion]
flavor = MAX_ROCE_MODE;
~ ^~~~~~~~~~~~~2 warnings generated.
Use the appropriate values from the expected type, roce_flavor:
ROCE_V2_IPV6 = RROCE_IPV6 = 2MAX_ROCE_MODE = MAX_ROCE_FLAVOR = 3
While we're add it, ditch the local variable flavor, we can just return the value directly from the switch statement.
--- drivers/net/ethernet/qlogic/qed/qed_roce.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-)
drivers/net/ethernet/qlogic/qed/qed_roce.c +4 -11
@@ -138,23 +138,16 @@ static void qed_rdma_copy_gids(struct qed_rdma_qp *qp, __le32 *src_gid,static enum roce_flavor qed_roce_mode_to_flavor (enum roce_mode roce_mode) { -enum roce_flavor flavor; -switch (roce_mode) {case ROCE_V1 : - flavor =PLAIN_ROCE ; -break ; +return PLAIN_ROCE ;case ROCE_V2_IPV4 : - flavor =RROCE_IPV4 ; -break ; +return RROCE_IPV4 ;case ROCE_V2_IPV6 : - flavor =ROCE_V2_IPV6 ; -break ; +return RROCE_IPV6 ;default : - flavor =MAX_ROCE_MODE ; -break ; +return MAX_ROCE_FLAVOR ; } -return flavor; }void qed_roce_free_cid_pair (struct qed_hwfn *p_hwfn,u16 cid)
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 33/100 bonding: pass link-local packets to bonding master also.
In reply to Sasha LevinFrom: Mahesh Bandewar <[email protected]>
[ Upstream commit 6a9e461f6fe4434e6172304b69774daff9a3ac4c ]
Commit b89f04c61efe ("bonding: deliver link-local packets with skb->dev set to link that packets arrived on") changed the behavior of how link-local-multicast packets are processed. The change in the behavior broke some legacy use cases where these packets are expected to arrive on bonding master device also.
This patch passes the packet to the stack with the link it arrived on as well as passes to the bonding-master device to preserve the legacy use case.
--- drivers/net/bonding/bond_main.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-)
drivers/net/bonding/bond_main.c +19 -2
@@ -1177,9 +1177,26 @@ static rx_handler_result_t bond_handle_frame(struct sk_buff **pskb) } } -/* don't change skb->dev for link-local packets */ -if (is_link_local_ether_addr (eth_hdr (skb)->h_dest)) +/* Link-local multicast packets should be passed to the +* stack on the link they arrive as well as pass them to the +* bond-master device. These packets are mostly usable when +* stack receives it with the link on which they arrive +* (e.g. LLDP) they also must be available on master. Some of +* the use cases include (but are not limited to): LLDP agents +* that must be able to operate both on enslaved interfaces as +* well as on bonds themselves; linux bridges that must be able +* to process/pass BPDUs from attached bonds when any kind of +* STP version is enabled on the network. +*/ +if (is_link_local_ether_addr (eth_hdr (skb)->h_dest)) { +struct sk_buff *nskb =skb_clone (skb,GFP_ATOMIC ); + +if (nskb) { + nskb->dev = bond->dev; +netif_rx (nskb); + }return RX_HANDLER_PASS ; + }if (bond_should_deliver_exact_match (skb, slave, bond))return RX_HANDLER_EXACT ;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 34/100 bonding: avoid possible dead-lock
In reply to Sasha LevinFrom: Mahesh Bandewar <[email protected]>
[ Upstream commit d4859d749aa7090ffb743d15648adb962a1baeae ]
Syzkaller reported this on a slightly older kernel but it's still applicable to the current kernel -
======================================================
WARNING: possible circular locking dependency detected
4.18.0-next-20180823+ #46 Not tainted
------------------------------------------------------
syz-executor4/26841 is trying to acquire lock:00000000dd41ef48 ((wq_completion)bond_dev->name){+.+.}, at: flush_workqueue+0x2db/0x1e10 kernel/workqueue.c:2652
but task is already holding lock:00000000768ab431 (rtnl_mutex){+.+.}, at: rtnl_lock net/core/rtnetlink.c:77 [inline] 00000000768ab431 (rtnl_mutex){+.+.}, at: rtnetlink_rcv_msg+0x412/0xc30 net/core/rtnetlink.c:4708
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #2 (rtnl_mutex){+.+.}:
__mutex_lock_common kernel/locking/mutex.c:925 [inline]
__mutex_lock+0x171/0x1700 kernel/locking/mutex.c:1073
mutex_lock_nested+0x16/0x20 kernel/locking/mutex.c:1088
rtnl_lock+0x17/0x20 net/core/rtnetlink.c:77
bond_netdev_notify drivers/net/bonding/bond_main.c:1310 [inline]
bond_netdev_notify_work+0x44/0xd0 drivers/net/bonding/bond_main.c:1320
process_one_work+0xc73/0x1aa0 kernel/workqueue.c:2153
worker_thread+0x189/0x13c0 kernel/workqueue.c:2296
kthread+0x35a/0x420 kernel/kthread.c:246
ret_from_fork+0x3a/0x50 arch/x86/entry/entry_64.S:415-> #1 ((work_completion)(&(&nnw->work)->work)){+.+.}:
process_one_work+0xc0b/0x1aa0 kernel/workqueue.c:2129
worker_thread+0x189/0x13c0 kernel/workqueue.c:2296
kthread+0x35a/0x420 kernel/kthread.c:246
ret_from_fork+0x3a/0x50 arch/x86/entry/entry_64.S:415-> #0 ((wq_completion)bond_dev->name){+.+.}:
lock_acquire+0x1e4/0x4f0 kernel/locking/lockdep.c:3901
flush_workqueue+0x30a/0x1e10 kernel/workqueue.c:2655
drain_workqueue+0x2a9/0x640 kernel/workqueue.c:2820
destroy_workqueue+0xc6/0x9d0 kernel/workqueue.c:4155
__alloc_workqueue_key+0xef9/0x1190 kernel/workqueue.c:4138
bond_init+0x269/0x940 drivers/net/bonding/bond_main.c:4734
register_netdevice+0x337/0x1100 net/core/dev.c:8410
bond_newlink+0x49/0xa0 drivers/net/bonding/bond_netlink.c:453
rtnl_newlink+0xef4/0x1d50 net/core/rtnetlink.c:3099
rtnetlink_rcv_msg+0x46e/0xc30 net/core/rtnetlink.c:4711
netlink_rcv_skb+0x172/0x440 net/netlink/af_netlink.c:2454
rtnetlink_rcv+0x1c/0x20 net/core/rtnetlink.c:4729
netlink_unicast_kernel net/netlink/af_netlink.c:1317 [inline]
netlink_unicast+0x5a0/0x760 net/netlink/af_netlink.c:1343
netlink_sendmsg+0xa18/0xfc0 net/netlink/af_netlink.c:1908
sock_sendmsg_nosec net/socket.c:622 [inline]
sock_sendmsg+0xd5/0x120 net/socket.c:632
___sys_sendmsg+0x7fd/0x930 net/socket.c:2115
__sys_sendmsg+0x11d/0x290 net/socket.c:2153
__do_sys_sendmsg net/socket.c:2162 [inline]
__se_sys_sendmsg net/socket.c:2160 [inline]
__x64_sys_sendmsg+0x78/0xb0 net/socket.c:2160
do_syscall_64+0x1b9/0x820 arch/x86/entry/common.c:290
entry_SYSCALL_64_after_hwframe+0x49/0xbeother info that might help us debug this:
Chain exists of: (wq_completion)bond_dev->name --> (work_completion)(&(&nnw->work)->work) --> rtnl_mutex Possible unsafe locking scenario:
CPU0 CPU1
---- ----
lock(rtnl_mutex);
lock((work_completion)(&(&nnw->work)->work));
lock(rtnl_mutex);lock((wq_completion)bond_dev->name);
*** DEADLOCK ***
1 lock held by syz-executor4/26841:
stack backtrace: CPU: 1 PID: 26841 Comm: syz-executor4 Not tainted 4.18.0-next-20180823+ #46 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Call Trace: __dump_stack lib/dump_stack.c:77 [inline] dump_stack+0x1c9/0x2b4 lib/dump_stack.c:113 print_circular_bug.isra.34.cold.55+0x1bd/0x27d kernel/locking/lockdep.c:1222 check_prev_add kernel/locking/lockdep.c:1862 [inline] check_prevs_add kernel/locking/lockdep.c:1975 [inline] validate_chain kernel/locking/lockdep.c:2416 [inline] __lock_acquire+0x3449/0x5020 kernel/locking/lockdep.c:3412 lock_acquire+0x1e4/0x4f0 kernel/locking/lockdep.c:3901 flush_workqueue+0x30a/0x1e10 kernel/workqueue.c:2655 drain_workqueue+0x2a9/0x640 kernel/workqueue.c:2820 destroy_workqueue+0xc6/0x9d0 kernel/workqueue.c:4155 __alloc_workqueue_key+0xef9/0x1190 kernel/workqueue.c:4138 bond_init+0x269/0x940 drivers/net/bonding/bond_main.c:4734 register_netdevice+0x337/0x1100 net/core/dev.c:8410 bond_newlink+0x49/0xa0 drivers/net/bonding/bond_netlink.c:453 rtnl_newlink+0xef4/0x1d50 net/core/rtnetlink.c:3099 rtnetlink_rcv_msg+0x46e/0xc30 net/core/rtnetlink.c:4711 netlink_rcv_skb+0x172/0x440 net/netlink/af_netlink.c:2454 rtnetlink_rcv+0x1c/0x20 net/core/rtnetlink.c:4729 netlink_unicast_kernel net/netlink/af_netlink.c:1317 [inline] netlink_unicast+0x5a0/0x760 net/netlink/af_netlink.c:1343 netlink_sendmsg+0xa18/0xfc0 net/netlink/af_netlink.c:1908 sock_sendmsg_nosec net/socket.c:622 [inline] sock_sendmsg+0xd5/0x120 net/socket.c:632 ___sys_sendmsg+0x7fd/0x930 net/socket.c:2115 __sys_sendmsg+0x11d/0x290 net/socket.c:2153 __do_sys_sendmsg net/socket.c:2162 [inline] __se_sys_sendmsg net/socket.c:2160 [inline] __x64_sys_sendmsg+0x78/0xb0 net/socket.c:2160 do_syscall_64+0x1b9/0x820 arch/x86/entry/common.c:290 entry_SYSCALL_64_after_hwframe+0x49/0xbe RIP: 0033:0x457089 Code: fd b4 fb ff c3 66 2e 0f 1f 84 00 00 00 00 00 66 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 0f 83 cb b4 fb ff c3 66 2e 0f 1f 84 00 00 00 00 RSP: 002b:00007f2df20a5c78 EFLAGS: 00000246 ORIG_RAX: 000000000000002e RAX: ffffffffffffffda RBX: 00007f2df20a66d4 RCX: 0000000000457089 RDX: 0000000000000000 RSI: 0000000020000180 RDI: 0000000000000003 RBP: 0000000000930140 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 00000000ffffffff R13: 00000000004d40b8 R14: 00000000004c8ad8 R15: 0000000000000001
--- drivers/net/bonding/bond_main.c | 43 +++++++++++++-------------------- include/net/bonding.h | 7 +----- 2 files changed, 18 insertions(+), 32 deletions(-)
drivers/net/bonding/bond_main.c +17 -26
@@ -210,6 +210,7 @@ static void bond_get_stats(struct net_device *bond_dev,static void bond_slave_arr_handler (struct work_struct *work);static bool bond_time_in_interval (struct bonding *bond,unsigned long last_act,int mod); +static void bond_netdev_notify_work (struct work_struct *work);/*---------------------------- General routines -----------------------------*/
@@ -1293,6 +1294,8 @@ static struct slave *bond_alloc_slave(struct bonding *bond)return NULL ; } } +INIT_DELAYED_WORK (&slave->notify_work, bond_netdev_notify_work); +return slave; }
@@ -1300,6 +1303,7 @@ static void bond_free_slave(struct slave *slave) {struct bonding *bond =bond_get_bond_by_slave (slave); +cancel_delayed_work_sync (&slave->notify_work);if (BOND_MODE (bond) ==BOND_MODE_8023AD )kfree (SLAVE_AD_INFO (slave));
@@ -1321,39 +1325,26 @@ static void bond_fill_ifslave(struct slave *slave, struct ifslave *info) info->link_failure_count = slave->link_failure_count; } -static void bond_netdev_notify (struct net_device *dev, -struct netdev_bonding_info *info) -{ -rtnl_lock (); -netdev_bonding_info_change (dev, info); -rtnl_unlock (); -} -static void bond_netdev_notify_work (struct work_struct *_work) { -struct netdev_notify_work *w = - container_of(_work, struct netdev_notify_work, work.work); + struct slave *slave = container_of(_work, struct slave, + notify_work.work); + +if (rtnl_trylock ()) { +struct netdev_bonding_info binfo; -bond_netdev_notify (w->dev, &w->bonding_info); -dev_put (w->dev); -kfree (w); +bond_fill_ifslave (slave, &binfo.slave); +bond_fill_ifbond (slave->bond, &binfo.master); +netdev_bonding_info_change (slave->dev, &binfo); +rtnl_unlock (); + }else { +queue_delayed_work (slave->bond->wq, &slave->notify_work,1 ); + } }void bond_queue_slave_event (struct slave *slave) { -struct bonding *bond = slave->bond; -struct netdev_notify_work *nnw =kzalloc (sizeof (*nnw),GFP_ATOMIC ); - -if (!nnw) -return ; - -dev_hold (slave->dev); - nnw->dev = slave->dev; -bond_fill_ifslave (slave, &nnw->bonding_info.slave); -bond_fill_ifbond (bond, &nnw->bonding_info.master); -INIT_DELAYED_WORK (&nnw->work, bond_netdev_notify_work); - -queue_delayed_work (slave->bond->wq, &nnw->work,0 ); +queue_delayed_work (slave->bond->wq, &slave->notify_work,0 ); }void bond_lower_state_changed (struct slave *slave)
include/net/bonding.h +1 -6
@@ -139,12 +139,6 @@ struct bond_parm_tbl {int mode; }; -struct netdev_notify_work { -struct delayed_work work; -struct net_device *dev; -struct netdev_bonding_info bonding_info; -}; -struct slave {struct net_device *dev;/* first - useful for panic debug */ struct bonding *bond;/* our master */
@@ -172,6 +166,7 @@ struct slave {#ifdef CONFIG_NET_POLL_CONTROLLER struct netpoll *np;#endif +struct delayed_work notify_work;struct kobject kobj;struct rtnl_link_stats64 slave_stats; };
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 35/100 qed: Avoid constant logical operation warning in qed_vf_pf_acquire
In reply to Sasha LevinFrom: Nathan Chancellor <[email protected]>
[ Upstream commit 1c492a9d55ba99079210ed901dd8a5423f980487 ]
Clang warns when a constant is used in a boolean context as it thinks a bitwise operation may have been intended.
drivers/net/ethernet/qlogic/qed/qed_vf.c:415:27: warning: use of logical '&&' with constant operand [-Wconstant-logical-operand]
if (!p_iov->b_pre_fp_hsi &&
^
drivers/net/ethernet/qlogic/qed/qed_vf.c:415:27: note: use '&' for a
bitwise operation
if (!p_iov->b_pre_fp_hsi &&
^~
&
drivers/net/ethernet/qlogic/qed/qed_vf.c:415:27: note: remove constant
to silence this warning
if (!p_iov->b_pre_fp_hsi &&
~^~1 warning generated.
This has been here since commit 1fe614d10f45 ("qed: Relax VF firmware requirements") and I am not entirely sure why since 0 isn't a special case. Just remove the statement causing Clang to warn since it isn't required.
--- drivers/net/ethernet/qlogic/qed/qed_vf.c | 1 - 1 file changed, 1 deletion(-)
drivers/net/ethernet/qlogic/qed/qed_vf.c +0 -1
@@ -413,7 +413,6 @@ static int qed_vf_pf_acquire(struct qed_hwfn *p_hwfn) }if (!p_iov->b_pre_fp_hsi && -ETH_HSI_VER_MINOR && (resp->pfdev_info.minor_fp_hsi <ETH_HSI_VER_MINOR )) { DP_INFO(p_hwfn, "PF is using older fastpath HSI; %02x.%02x is configured\n",
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 36/100 qed: Avoid implicit enum conversion in qed_iwarp_parse_rx_pkt
In reply to Sasha LevinFrom: Nathan Chancellor <[email protected]>
[ Upstream commit 77f2d753819b7d50c16abfb778caf1fe075faed0 ]
Clang warns when one enumerated type is implicitly converted to another.
drivers/net/ethernet/qlogic/qed/qed_iwarp.c:1713:25: warning: implicit conversion from enumeration type 'enum tcp_ip_version' to different enumeration type 'enum qed_tcp_ip_version' [-Wenum-conversion]
cm_info->ip_version = TCP_IPV4;
~ ^~~~~~~~
drivers/net/ethernet/qlogic/qed/qed_iwarp.c:1733:25: warning: implicit
conversion from enumeration type 'enum tcp_ip_version' to different
enumeration type 'enum qed_tcp_ip_version' [-Wenum-conversion]
cm_info->ip_version = TCP_IPV6;
~ ^~~~~~~~2 warnings generated.
Use the appropriate values from the expected type, qed_tcp_ip_version:
TCP_IPV4 = QED_TCP_IPV4 = 0TCP_IPV6 = QED_TCP_IPV6 = 1
--- drivers/net/ethernet/qlogic/qed/qed_iwarp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/ethernet/qlogic/qed/qed_iwarp.c +2 -2
@@ -1710,7 +1710,7 @@ qed_iwarp_parse_rx_pkt(struct qed_hwfn *p_hwfn, cm_info->local_ip[0 ] =ntohl (iph->daddr); cm_info->remote_ip[0 ] =ntohl (iph->saddr); - cm_info->ip_version =TCP_IPV4 ; + cm_info->ip_version =QED_TCP_IPV4 ; ip_hlen = (iph->ihl) *sizeof (u32); *payload_len =ntohs (iph->tot_len) - ip_hlen;
@@ -1730,7 +1730,7 @@ qed_iwarp_parse_rx_pkt(struct qed_hwfn *p_hwfn, cm_info->remote_ip[i] =ntohl (ip6h->saddr.in6_u.u6_addr32[i]); } - cm_info->ip_version =TCP_IPV6 ; + cm_info->ip_version =QED_TCP_IPV6 ; ip_hlen =sizeof (*ip6h); *payload_len =ntohs (ip6h->payload_len);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 37/100 bnxt_en: Fix TX timeout during netpoll.
In reply to Sasha LevinFrom: Michael Chan <[email protected]>
[ Upstream commit 73f21c653f930f438d53eed29b5e4c65c8a0f906 ]
The current netpoll implementation in the bnxt_en driver has problems that may miss TX completion events. bnxt_poll_work() in effect is only handling at most 1 TX packet before exiting. In addition, there may be in flight TX completions that ->poll() may miss even after we fix bnxt_poll_work() to handle all visible TX completions. netpoll may not call ->poll() again and HW may not generate IRQ because the driver does not ARM the IRQ when the budget (0 for netpoll) is reached.
We fix it by handling all TX completions and to always ARM the IRQ when we exit ->poll() with 0 budget.
Also, the logic to ACK the completion ring in case it is almost filled with TX completions need to be adjusted to take care of the 0 budget case, as discussed with Eric Dumazet <[email protected]>
--- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
drivers/net/ethernet/broadcom/bnxt/bnxt.c +10 -3
@@ -1882,8 +1882,11 @@ static int bnxt_poll_work(struct bnxt *bp, struct bnxt_napi *bnapi, int budget)if (TX_CMP_TYPE (txcmp) ==CMP_TYPE_TX_L2_CMP ) { tx_pkts++;/* return full budget so NAPI will complete. */ -if (unlikely (tx_pkts > bp->tx_wake_thresh)) +if (unlikely (tx_pkts > bp->tx_wake_thresh)) { rx_pkts = budget; + raw_cons =NEXT_RAW_CMP (raw_cons); +break ; + } }else if ((TX_CMP_TYPE (txcmp) &0x30 ) ==0x10 ) {if (likely (budget)) rc =bnxt_rx_pkt (bp, bnapi, &raw_cons, &event);
@@ -1911,7 +1914,7 @@ static int bnxt_poll_work(struct bnxt *bp, struct bnxt_napi *bnapi, int budget) } raw_cons =NEXT_RAW_CMP (raw_cons); -if (rx_pkts == budget) +if (rx_pkts && rx_pkts == budget)break ; }
@@ -2025,8 +2028,12 @@ static int bnxt_poll(struct napi_struct *napi, int budget)while (1 ) { work_done +=bnxt_poll_work (bp, bnapi, budget - work_done); -if (work_done >= budget) +if (work_done >= budget) { +if (!budget) +BNXT_CP_DB_REARM (cpr->cp_doorbell, + cpr->cp_raw_cons);break ; + }if (!bnxt_has_work (bp, cpr)) {if (napi_complete_done (napi, work_done))
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 38/100 nl80211: Fix possible Spectre-v1 for CQM RSSI thresholds
In reply to Sasha LevinFrom: Masashi Honma <[email protected]>
[ Upstream commit 1222a16014888ed9733c11e221730d4a8196222b ]
Use array_index_nospec() to sanitize i with respect to speculation.
Note that the user doesn't control i directly, but can make it out of bounds by not finding a threshold in the array.
--- net/wireless/nl80211.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-)
net/wireless/nl80211.c +14 -5
@@ -10125,7 +10125,7 @@ static int cfg80211_cqm_rssi_update(struct cfg80211_registered_device *rdev,struct wireless_dev *wdev = dev->ieee80211_ptr;s32 last, low, high;u32 hyst; -int i, n; +int i, n, low_index;int err;/* RSSI reporting disabled? */
@@ -10162,10 +10162,19 @@ static int cfg80211_cqm_rssi_update(struct cfg80211_registered_device *rdev,if (last < wdev->cqm_config->rssi_thresholds[i])break ; - low = i >0 ? - (wdev->cqm_config->rssi_thresholds[i -1 ] - hyst) :S32_MIN ; - high = i < n ? - (wdev->cqm_config->rssi_thresholds[i] + hyst -1 ) :S32_MAX ; + low_index = i -1 ; +if (low_index >=0 ) { + low_index =array_index_nospec (low_index, n); + low = wdev->cqm_config->rssi_thresholds[low_index] - hyst; + }else { + low =S32_MIN ; + } +if (i < n) { + i =array_index_nospec (i, n); + high = wdev->cqm_config->rssi_thresholds[i] + hyst -1 ; + }else { + high =S32_MAX ; + }return rdev_set_cqm_rssi_range_config (rdev, dev, low, high); }
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 39/100 scsi: qedi: Initialize the stats mutex lock
In reply to Sasha LevinFrom: Nilesh Javali <[email protected]>
[ Upstream commit 3cc5746e5ad7688e274e193fa71278d98aa52759 ]
Fix kernel NULL pointer dereference,
Call Trace: [<ffffffff9b7658e6>] __mutex_lock_slowpath+0xa6/0x1d0 [<ffffffff9b764cef>] mutex_lock+0x1f/0x2f [<ffffffffc061b5e1>] qedi_get_protocol_tlv_data+0x61/0x450 [qedi] [<ffffffff9b1f9d8e>] ? map_vm_area+0x2e/0x40 [<ffffffff9b1fc370>] ? __vmalloc_node_range+0x170/0x280 [<ffffffffc0b81c3d>] ? qed_mfw_process_tlv_req+0x27d/0xbd0 [qed] [<ffffffffc0b6461b>] qed_mfw_fill_tlv_data+0x4b/0xb0 [qed] [<ffffffffc0b81c59>] qed_mfw_process_tlv_req+0x299/0xbd0 [qed] [<ffffffff9b02a59e>] ? __switch_to+0xce/0x580 [<ffffffffc0b61e5b>] qed_slowpath_task+0x5b/0x80 [qed]
--- drivers/scsi/qedi/qedi_main.c | 1 + 1 file changed, 1 insertion(+)
drivers/scsi/qedi/qedi_main.c +1 -0
@@ -2472,6 +2472,7 @@ static int __qedi_probe(struct pci_dev *pdev, int mode)/* start qedi context */ spin_lock_init (&qedi->hba_lock);spin_lock_init (&qedi->task_idx_lock); +mutex_init (&qedi->stats_lock); } qedi_ops->ll2->register_cb_ops (qedi->cdev, &qedi_ll2_cb_ops, qedi); qedi_ops->ll2->start (qedi->cdev, ¶ms);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 40/100 rxrpc: Fix checks as to whether we should set up a new call
In reply to Sasha LevinFrom: David Howells <[email protected]>
[ Upstream commit dc71db34e4f3c06b8277c8f3c2ff014610607a8c ]
There's a check in rxrpc_data_ready() that's checking the CLIENT_INITIATED flag in the packet type field rather than in the packet flags field.
Fix this by creating a pair of helper functions to check whether the packet is going to the client or to the server and use them generally.
--- net/rxrpc/ar-internal.h | 10 ++++++++++ net/rxrpc/conn_object.c | 2 +- net/rxrpc/input.c | 12 ++++-------- 3 files changed, 15 insertions(+), 9 deletions(-)
net/rxrpc/ar-internal.h +10 -0
@@ -462,6 +462,16 @@ struct rxrpc_connection {u8 out_clientflag;/* RXRPC_CLIENT_INITIATED if we are client */ }; +static inline bool rxrpc_to_server (const struct rxrpc_skb_priv *sp) +{ +return sp->hdr.flags &RXRPC_CLIENT_INITIATED ; +} + +static inline bool rxrpc_to_client (const struct rxrpc_skb_priv *sp) +{ +return !rxrpc_to_server (sp); +} +/* * Flags in call->flags. */
net/rxrpc/conn_object.c +1 -1
@@ -99,7 +99,7 @@ struct rxrpc_connection *rxrpc_find_connection_rcu(struct rxrpc_local *local, k.epoch = sp->hdr.epoch; k.cid = sp->hdr.cid &RXRPC_CIDMASK ; -if (sp->hdr.flags &RXRPC_CLIENT_INITIATED ) { +if (rxrpc_to_server (sp)) {/* We need to look up service connections by the full protocol * parameter set. We look up the peer first as an intermediate * step and then the connection from the peer's tree.
net/rxrpc/input.c +4 -8
@@ -1171,10 +1171,6 @@ void rxrpc_data_ready(struct sock *udp_sk)trace_rxrpc_rx_packet (sp); -_net ("Rx RxRPC %s ep=%x call=%x:%x" , - sp->hdr.flags &RXRPC_CLIENT_INITIATED ?"ToServer" :"ToClient" , - sp->hdr.epoch, sp->hdr.cid, sp->hdr.callNumber); -if (sp->hdr.type >=RXRPC_N_PACKET_TYPES || !((RXRPC_SUPPORTED_PACKET_TYPES >> sp->hdr.type) &1 )) {_proto ("Rx Bad Packet Type %u" , sp->hdr.type);
@@ -1183,13 +1179,13 @@ void rxrpc_data_ready(struct sock *udp_sk)switch (sp->hdr.type) {case RXRPC_PACKET_TYPE_VERSION : -if (!(sp->hdr.flags &RXRPC_CLIENT_INITIATED )) +if (rxrpc_to_client (sp)) goto discard;rxrpc_post_packet_to_local (local, skb); goto out;case RXRPC_PACKET_TYPE_BUSY : -if (sp->hdr.flags &RXRPC_CLIENT_INITIATED ) +if (rxrpc_to_server (sp)) goto discard;/* Fall through */
@@ -1269,7 +1265,7 @@ void rxrpc_data_ready(struct sock *udp_sk) call =rcu_dereference (chan->call);if (sp->hdr.callNumber > chan->call_id) { -if (!(sp->hdr.flags &RXRPC_CLIENT_INITIATED )) { +if (rxrpc_to_client (sp)) {rcu_read_unlock (); goto reject_packet; }
@@ -1292,7 +1288,7 @@ void rxrpc_data_ready(struct sock *udp_sk) }if (!call ||atomic_read (&call->usage) ==0 ) { -if (!(sp->hdr.type &RXRPC_CLIENT_INITIATED ) || +if (rxrpc_to_client (sp) || sp->hdr.callNumber ==0 || sp->hdr.type !=RXRPC_PACKET_TYPE_DATA ) goto bad_message_unlock;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 41/100 rxrpc: Fix RTT gathering
In reply to Sasha LevinFrom: David Howells <[email protected]>
[ Upstream commit b604dd9883f783a94020d772e4fe03160f455372 ]
Fix RTT information gathering in AF_RXRPC by the following means:
(1) Enable Rx timestamping on the transport socket with SO_TIMESTAMPNS.
(2) If the sk_buff doesn't have a timestamp set when rxrpc_data_ready() collects it, set it at that point.
(3) Allow ACKs to be requested on the last packet of a client call, but not a service call. We need to be careful lest we undo:
bf7d620abf22c321208a4da4f435e7af52551a21
Author: David Howells <[email protected]>
Date: Thu Oct 6 08:11:51 2016 +0100
rxrpc: Don't request an ACK on the last DATA packet of a call's Tx phase
but that only really applies to service calls that we're handling, since the client side gets to send the final ACK (or not).
(4) When about to transmit an ACK or DATA packet, record the Tx timestamp before only; don't update the timestamp afterwards.
(5) Switch the ordering between recording the serial and recording the timestamp to always set the serial number first. The serial number shouldn't be seen referenced by an ACK packet until we've transmitted the packet bearing it - so in the Rx path, we don't need the timestamp until we've checked the serial number.
--- net/rxrpc/input.c | 8 ++++++-- net/rxrpc/local_object.c | 9 +++++++++ net/rxrpc/output.c | 31 ++++++++++++++++++------------- 3 files changed, 33 insertions(+), 15 deletions(-)
net/rxrpc/input.c +6 -2
@@ -616,13 +616,14 @@ static void rxrpc_input_requested_ack(struct rxrpc_call *call,if (!skb)continue ; + sent_at = skb->tstamp; +smp_rmb ();/* Read timestamp before serial. */ sp =rxrpc_skb (skb);if (sp->hdr.serial != orig_serial)continue ; -smp_rmb (); - sent_at = skb->tstamp; goto found; } +return ; found:
@@ -1137,6 +1138,9 @@ void rxrpc_data_ready(struct sock *udp_sk)return ; } +if (skb->tstamp ==0 ) + skb->tstamp =ktime_get_real (); +rxrpc_new_skb (skb, rxrpc_skb_rx_received);_net ("recv skb %p" , skb);
net/rxrpc/local_object.c +9 -0
@@ -173,6 +173,15 @@ static int rxrpc_open_socket(struct rxrpc_local *local, struct net *net)_debug ("setsockopt failed" ); goto error; } + +/* We want receive timestamps. */ + opt =1 ; + ret =kernel_setsockopt (local->socket,SOL_SOCKET ,SO_TIMESTAMPNS , + (char *)&opt,sizeof (opt)); +if (ret <0 ) { +_debug ("setsockopt failed" ); + goto error; + }break ;default :
net/rxrpc/output.c +18 -13
@@ -124,7 +124,6 @@ int rxrpc_send_ack_packet(struct rxrpc_call *call, bool ping,struct kvec iov[2 ];rxrpc_serial_t serial;rxrpc_seq_t hard_ack, top; -ktime_t now;size_t len, n;int ret;u8 reason;
@@ -196,9 +195,7 @@ int rxrpc_send_ack_packet(struct rxrpc_call *call, bool ping,/* We need to stick a time in before we send the packet in case * the reply gets back before kernel_sendmsg() completes - but * asking UDP to send the packet can take a relatively long -* time, so we update the time after, on the assumption that -* the packet transmission is more likely to happen towards the -* end of the kernel_sendmsg() call. +* time. */ call->ping_time =ktime_get_real ();set_bit (RXRPC_CALL_PINGING , &call->flags);
@@ -206,9 +203,6 @@ int rxrpc_send_ack_packet(struct rxrpc_call *call, bool ping, } ret =kernel_sendmsg (conn->params.local->socket, &msg, iov,2 , len); - now =ktime_get_real (); -if (ping) - call->ping_time = now; conn->params.peer->last_tx_at =ktime_get_seconds ();if (ret <0 ) trace_rxrpc_tx_fail(call->debug_id, serial, ret,
@@ -357,8 +351,14 @@ int rxrpc_send_data_packet(struct rxrpc_call *call, struct sk_buff *skb,/* If our RTT cache needs working on, request an ACK. Also request * ACKs if a DATA packet appears to have been lost. +* +* However, we mustn't request an ACK on the last reply packet of a +* service call, lest OpenAFS incorrectly send us an ACK with some +* soft-ACKs in it and then never follow up with a proper hard ACK. */ - if (!(sp->hdr.flags & RXRPC_LAST_PACKET) && + if ((!(sp->hdr.flags & RXRPC_LAST_PACKET) || + rxrpc_to_server(sp) + ) && (test_and_clear_bit(RXRPC_CALL_EV_ACK_LOST, &call->events) || retrans || call->cong_mode == RXRPC_CALL_SLOW_START ||
@@ -384,6 +384,11 @@ int rxrpc_send_data_packet(struct rxrpc_call *call, struct sk_buff *skb, goto send_fragmentable;down_read (&conn->params.local->defrag_sem); + + sp->hdr.serial = serial; +smp_wmb ();/* Set serial before timestamp */ + skb->tstamp =ktime_get_real (); +/* send the packet by UDP * - returns -EMSGSIZE if UDP would have to fragment the packet * to go out of the interface
@@ -404,12 +409,8 @@ int rxrpc_send_data_packet(struct rxrpc_call *call, struct sk_buff *skb,trace_rxrpc_tx_data (call, sp->hdr.seq, serial, whdr.flags, retrans, lost);if (ret >=0 ) { -ktime_t now =ktime_get_real (); - skb->tstamp = now; -smp_wmb (); - sp->hdr.serial = serial;if (whdr.flags &RXRPC_REQUEST_ACK ) { - call->peer->rtt_last_req = now; + call->peer->rtt_last_req = skb->tstamp;trace_rxrpc_rtt_tx (call, rxrpc_rtt_tx_data, serial);if (call->peer->rtt_usage >1 ) {unsigned long nowj = jiffies, ack_lost_at;
@@ -448,6 +449,10 @@ int rxrpc_send_data_packet(struct rxrpc_call *call, struct sk_buff *skb,down_write (&conn->params.local->defrag_sem); + sp->hdr.serial = serial; +smp_wmb ();/* Set serial before timestamp */ + skb->tstamp =ktime_get_real (); +switch (conn->params.local->srx.transport.family) {case AF_INET : opt =IP_PMTUDISC_DONT ;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 42/100 rxrpc: Fix transport sockopts to get IPv4 errors on an IPv6 socket
In reply to Sasha LevinFrom: David Howells <[email protected]>
[ Upstream commit 37a675e768d7606fe8a53e0c459c9b53e121ac20 ]
It seems that enabling IPV6_RECVERR on an IPv6 socket doesn't also turn on IP_RECVERR, so neither local errors nor ICMP-transported remote errors from IPv4 peer addresses are returned to the AF_RXRPC protocol.
Make the sockopt setting code in rxrpc_open_socket() fall through from the AF_INET6 case to the AF_INET case to turn on all the AF_INET options too in the AF_INET6 case.
--- net/rxrpc/local_object.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-)
net/rxrpc/local_object.c +13 -10
@@ -135,10 +135,10 @@ static int rxrpc_open_socket(struct rxrpc_local *local, struct net *net) }switch (local->srx.transport.family) { -case AF_INET : -/* we want to receive ICMP errors */ +case AF_INET6 : +/* we want to receive ICMPv6 errors */ opt =1 ; - ret =kernel_setsockopt (local->socket,SOL_IP ,IP_RECVERR , + ret =kernel_setsockopt (local->socket,SOL_IPV6 ,IPV6_RECVERR , (char *) &opt,sizeof (opt));if (ret <0 ) {_debug ("setsockopt failed" );
@@ -146,19 +146,22 @@ static int rxrpc_open_socket(struct rxrpc_local *local, struct net *net) }/* we want to set the don't fragment bit */ - opt =IP_PMTUDISC_DO ; - ret =kernel_setsockopt (local->socket,SOL_IP ,IP_MTU_DISCOVER , + opt =IPV6_PMTUDISC_DO ; + ret =kernel_setsockopt (local->socket,SOL_IPV6 ,IPV6_MTU_DISCOVER , (char *) &opt,sizeof (opt));if (ret <0 ) {_debug ("setsockopt failed" ); goto error; } -break ; -case AF_INET6 : +/* Fall through and set IPv4 options too otherwise we don't get +* errors from IPv4 packets sent through the IPv6 socket. +*/ + +case AF_INET :/* we want to receive ICMP errors */ opt =1 ; - ret =kernel_setsockopt (local->socket,SOL_IPV6 ,IPV6_RECVERR , + ret =kernel_setsockopt (local->socket,SOL_IP ,IP_RECVERR , (char *) &opt,sizeof (opt));if (ret <0 ) {_debug ("setsockopt failed" );
@@ -166,8 +169,8 @@ static int rxrpc_open_socket(struct rxrpc_local *local, struct net *net) }/* we want to set the don't fragment bit */ - opt =IPV6_PMTUDISC_DO ; - ret =kernel_setsockopt (local->socket,SOL_IPV6 ,IPV6_MTU_DISCOVER , + opt =IP_PMTUDISC_DO ; + ret =kernel_setsockopt (local->socket,SOL_IP ,IP_MTU_DISCOVER , (char *) &opt,sizeof (opt));if (ret <0 ) {_debug ("setsockopt failed" );
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 43/100 rxrpc: Fix error distribution
In reply to Sasha LevinFrom: David Howells <[email protected]>
[ Upstream commit f334430316e7fd37c4821ebec627e27714bb5d76 ]
Fix error distribution by immediately delivering the errors to all the affected calls rather than deferring them to a worker thread. The problem with the latter is that retries and things can happen in the meantime when we want to stop that sooner.
To this end:
(1) Stop the error distributor from removing calls from the error_targets
list so that peer->lock isn't needed to synchronise against other adds
and removals. (2) Require the peer's error_targets list to be accessed with RCU, thereby
avoiding the need to take peer->lock over distribution.
(3) Don't attempt to affect a call's state if it is already marked complete.
--- include/trace/events/rxrpc.h | 4 +--- net/rxrpc/ar-internal.h | 5 ---- net/rxrpc/call_object.c | 2 +- net/rxrpc/conn_client.c | 4 ++-- net/rxrpc/conn_object.c | 2 +- net/rxrpc/peer_event.c | 46 +++++++++--------------------------- net/rxrpc/peer_object.c | 17 ------------- 7 files changed, 16 insertions(+), 64 deletions(-)
include/trace/events/rxrpc.h +1 -3
@@ -56,7 +56,6 @@ enum rxrpc_peer_trace { rxrpc_peer_new, rxrpc_peer_processing, rxrpc_peer_put, - rxrpc_peer_queued_error, }; enum rxrpc_conn_trace {
@@ -257,8 +256,7 @@ enum rxrpc_tx_fail_trace { EM(rxrpc_peer_got, "GOT") \ EM(rxrpc_peer_new, "NEW") \ EM(rxrpc_peer_processing, "PRO") \ - EM(rxrpc_peer_put, "PUT") \ - E_(rxrpc_peer_queued_error, "QER") + E_(rxrpc_peer_put, "PUT")#define rxrpc_conn_traces \ EM(rxrpc_conn_got, "GOT") \
net/rxrpc/ar-internal.h +0 -5
@@ -293,7 +293,6 @@ struct rxrpc_peer {struct hlist_node hash_link;struct rxrpc_local *local;struct hlist_head error_targets;/* targets for net error distribution */ -struct work_struct error_distributor;struct rb_root service_conns;/* Service connections */ struct list_head keepalive_link;/* Link in net->peer_keepalive[] */ time64_t last_tx_at;/* Last time packet sent here */
@@ -304,8 +303,6 @@ struct rxrpc_peer {unsigned int maxdata;/* data size (MTU - hdrsize) */ unsigned short hdrsize;/* header size (IP + UDP + RxRPC) */ int debug_id;/* debug ID for printks */ -int error_report;/* Net (+0) or local (+1000000) to distribute */ -#define RXRPC_LOCAL_ERROR_OFFSET 1000000struct sockaddr_rxrpc srx;/* remote address */ /* calculated RTT cache */
@@ -1039,7 +1036,6 @@ void rxrpc_send_keepalive(struct rxrpc_peer *);* peer_event.c */ void rxrpc_error_report (struct sock *); -void rxrpc_peer_error_distributor (struct work_struct *);void rxrpc_peer_add_rtt (struct rxrpc_call *,enum rxrpc_rtt_rx_trace ,rxrpc_serial_t ,rxrpc_serial_t ,ktime_t ,ktime_t );void rxrpc_peer_keepalive_worker (struct work_struct *);
@@ -1058,7 +1054,6 @@ void rxrpc_destroy_all_peers(struct rxrpc_net *);struct rxrpc_peer *rxrpc_get_peer (struct rxrpc_peer *);struct rxrpc_peer *rxrpc_get_peer_maybe (struct rxrpc_peer *);void rxrpc_put_peer (struct rxrpc_peer *); -void __rxrpc_queue_peer_error (struct rxrpc_peer *);/* * proc.c
net/rxrpc/call_object.c +1 -1
@@ -400,7 +400,7 @@ void rxrpc_incoming_call(struct rxrpc_sock *rx,rcu_assign_pointer (conn->channels[chan].call, call);spin_lock (&conn->params.peer->lock); -hlist_add_head (&call->error_link, &conn->params.peer->error_targets); +hlist_add_head_rcu (&call->error_link, &conn->params.peer->error_targets);spin_unlock (&conn->params.peer->lock);_net ("CALL incoming %d on CONN %d" , call->debug_id, call->conn->debug_id);
net/rxrpc/conn_client.c +2 -2
@@ -709,8 +709,8 @@ int rxrpc_connect_call(struct rxrpc_call *call, }spin_lock_bh (&call->conn->params.peer->lock); -hlist_add_head (&call->error_link, - &call->conn->params.peer->error_targets); +hlist_add_head_rcu (&call->error_link, + &call->conn->params.peer->error_targets);spin_unlock_bh (&call->conn->params.peer->lock); out:
net/rxrpc/conn_object.c +1 -1
@@ -214,7 +214,7 @@ void rxrpc_disconnect_call(struct rxrpc_call *call) call->peer->cong_cwnd = call->cong_cwnd;spin_lock_bh (&conn->params.peer->lock); -hlist_del_init (&call->error_link); +hlist_del_rcu (&call->error_link);spin_unlock_bh (&conn->params.peer->lock);if (rxrpc_is_client_call (call))
net/rxrpc/peer_event.c +11 -35
86 lines not on this page · raw message
net/rxrpc/peer_object.c +0 -17
@@ -222,8 +222,6 @@ struct rxrpc_peer *rxrpc_alloc_peer(struct rxrpc_local *local, gfp_t gfp)atomic_set (&peer->usage,1 ); peer->local = local;INIT_HLIST_HEAD (&peer->error_targets); -INIT_WORK (&peer->error_distributor, - &rxrpc_peer_error_distributor); peer->service_conns =RB_ROOT ;seqlock_init (&peer->service_conn_lock);spin_lock_init (&peer->lock);
@@ -415,21 +413,6 @@ struct rxrpc_peer *rxrpc_get_peer_maybe(struct rxrpc_peer *peer)return peer; } -/* -* Queue a peer record. This passes the caller's ref to the workqueue. -*/ -void __rxrpc_queue_peer_error (struct rxrpc_peer *peer) -{ -const void *here =__builtin_return_address (0 ); -int n; - - n =atomic_read (&peer->usage); -if (rxrpc_queue_work (&peer->error_distributor)) -trace_rxrpc_peer (peer, rxrpc_peer_queued_error, n, here); -else -rxrpc_put_peer (peer); -} -/* * Discard a peer record. */
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 44/100 netfilter: nft_set_rbtree: add missing rb_erase() in GC routine
In reply to Sasha LevinFrom: Taehee Yoo <[email protected]>
[ Upstream commit a13f814a67b12a2f29d1decf4b4f4e700658a517 ]
The nft_set_gc_batch_check() checks whether gc buffer is full. If gc buffer is full, gc buffer is released by
the nft_set_gc_batch_complete() internally.
In case of rbtree, the rb_erase() should be called before calling the nft_set_gc_batch_complete(). therefore the rb_erase() should be called before calling the nft_set_gc_batch_check() too.
test commands:
table ip filter {
set set1 {
type ipv4_addr; flags interval, timeout;
gc-interval 10s;
timeout 1s;
elements = {
1-2,
3-4,
5-6,
...
10000-10001,
}
} }
%nft -f test.nft
splat looks like:
[ 430.273885] kasan: GPF could be caused by NULL-ptr deref or user memory access [ 430.282158] general protection fault: 0000 [#1] SMP DEBUG_PAGEALLOC KASAN PTI [ 430.283116] CPU: 1 PID: 190 Comm: kworker/1:2 Tainted: G B 4.18.0+ #7 [ 430.283116] Workqueue: events_power_efficient nft_rbtree_gc [nf_tables_set] [ 430.313559] RIP: 0010:rb_next+0x81/0x130 [ 430.313559] Code: 08 49 bd 00 00 00 00 00 fc ff df 48 bb 00 00 00 00 00 fc ff df 48 85 c0 75 05 eb 58 48 89 d4 [ 430.313559] RSP: 0018:ffff88010cdb7680 EFLAGS: 00010207 [ 430.313559] RAX: 0000000000b84854 RBX: dffffc0000000000 RCX: ffffffff83f01973 [ 430.313559] RDX: 000000000017090c RSI: 0000000000000008 RDI: 0000000000b84864 [ 430.313559] RBP: ffff8801060d4588 R08: fffffbfff09bc349 R09: fffffbfff09bc349 [ 430.313559] R10: 0000000000000001 R11: fffffbfff09bc348 R12: ffff880100f081a8 [ 430.313559] R13: dffffc0000000000 R14: ffff880100ff8688 R15: dffffc0000000000 [ 430.313559] FS: 0000000000000000(0000) GS:ffff88011b400000(0000) knlGS:0000000000000000 [ 430.313559] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 430.313559] CR2: 0000000001551008 CR3: 000000005dc16000 CR4: 00000000001006e0 [ 430.313559] Call Trace: [ 430.313559] nft_rbtree_gc+0x112/0x5c0 [nf_tables_set] [ 430.313559] process_one_work+0xc13/0x1ec0 [ 430.313559] ? _raw_spin_unlock_irq+0x29/0x40 [ 430.313559] ? pwq_dec_nr_in_flight+0x3c0/0x3c0 [ 430.313559] ? set_load_weight+0x270/0x270 [ 430.313559] ? __switch_to_asm+0x34/0x70 [ 430.313559] ? __switch_to_asm+0x40/0x70 [ 430.313559] ? __switch_to_asm+0x34/0x70 [ 430.313559] ? __switch_to_asm+0x34/0x70 [ 430.313559] ? __switch_to_asm+0x40/0x70 [ 430.313559] ? __switch_to_asm+0x34/0x70 [ 430.313559] ? __switch_to_asm+0x40/0x70 [ 430.313559] ? __switch_to_asm+0x34/0x70 [ 430.313559] ? __switch_to_asm+0x34/0x70 [ 430.313559] ? __switch_to_asm+0x40/0x70 [ 430.313559] ? __switch_to_asm+0x34/0x70 [ 430.313559] ? __schedule+0x6d3/0x1f50 [ 430.313559] ? find_held_lock+0x39/0x1c0 [ 430.313559] ? __sched_text_start+0x8/0x8 [ 430.313559] ? cyc2ns_read_end+0x10/0x10 [ 430.313559] ? save_trace+0x300/0x300 [ 430.313559] ? sched_clock_local+0xd4/0x140 [ 430.313559] ? find_held_lock+0x39/0x1c0 [ 430.313559] ? worker_thread+0x353/0x1120 [ 430.313559] ? worker_thread+0x353/0x1120 [ 430.313559] ? lock_contended+0xe70/0xe70 [ 430.313559] ? __lock_acquire+0x4500/0x4500 [ 430.535635] ? do_raw_spin_unlock+0xa5/0x330 [ 430.535635] ? do_raw_spin_trylock+0x101/0x1a0 [ 430.535635] ? do_raw_spin_lock+0x1f0/0x1f0 [ 430.535635] ? _raw_spin_lock_irq+0x10/0x70 [ 430.535635] worker_thread+0x15d/0x1120
[ ... ]
--- net/netfilter/nft_set_rbtree.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-)
net/netfilter/nft_set_rbtree.c +14 -14
@@ -355,12 +355,11 @@ static void nft_rbtree_walk(const struct nft_ctx *ctx,static void nft_rbtree_gc (struct work_struct *work) { +struct nft_rbtree_elem *rbe, *rbe_end =NULL , *rbe_prev =NULL ;struct nft_set_gc_batch *gcb =NULL ; -struct rb_node *node, *prev =NULL ; -struct nft_rbtree_elem *rbe;struct nft_rbtree *priv; +struct rb_node *node;struct nft_set *set; -int i; priv = container_of(work, struct nft_rbtree, gc_work.work); set =nft_set_container_of (priv);
@@ -371,7 +370,7 @@ static void nft_rbtree_gc(struct work_struct *work) rbe = rb_entry(node, struct nft_rbtree_elem, node);if (nft_rbtree_interval_end (rbe)) { - prev = node; + rbe_end = rbe;continue ; }if (!nft_set_elem_expired (&rbe->ext))
@@ -379,29 +378,30 @@ static void nft_rbtree_gc(struct work_struct *work)if (nft_set_elem_mark_busy (&rbe->ext))continue ; +if (rbe_prev) { +rb_erase (&rbe_prev->node, &priv->root); + rbe_prev =NULL ; + } gcb =nft_set_gc_batch_check (set, gcb,GFP_ATOMIC );if (!gcb)break ;atomic_dec (&set->nelems);nft_set_gc_batch_add (gcb, rbe); + rbe_prev = rbe; -if (prev) { - rbe = rb_entry(prev, struct nft_rbtree_elem, node); +if (rbe_end) {atomic_dec (&set->nelems); -nft_set_gc_batch_add (gcb, rbe); - prev =NULL ; +nft_set_gc_batch_add (gcb, rbe_end); +rb_erase (&rbe_end->node, &priv->root); + rbe_end =NULL ; } node =rb_next (node);if (!node)break ; } -if (gcb) { -for (i =0 ; i < gcb->head.cnt; i++) { - rbe = gcb->elems[i]; -rb_erase (&rbe->node, &priv->root); - } - } +if (rbe_prev) +rb_erase (&rbe_prev->node, &priv->root);write_seqcount_end (&priv->count);write_unlock_bh (&priv->lock);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 45/100 netfilter: avoid erronous array bounds warning
In reply to Sasha LevinFrom: Florian Westphal <[email protected]>
[ Upstream commit 421c119f558761556afca6a62ad183bc2d8659e0 ]
Unfortunately some versions of gcc emit following warning:
$ make net/xfrm/xfrm_output.o
linux/compiler.h:252:20: warning: array subscript is above array bounds [-Warray-bounds]
hook_head = rcu_dereference(net->nf.hooks_arp[hook]);
^~~~~~~~~~~~~~~~~~~~~
xfrm_output_resume passes skb_dst(skb)->ops->family as its 'pf' arg so compiler
can't know that we'll never access hooks_arp[].
(NFPROTO_IPV4 or NFPROTO_IPV6 are only possible cases).Avoid this by adding an explicit WARN_ON_ONCE() check.
This patch has no effect if the family is a compile-time constant as gcc will remove the switch() construct entirely.
--- include/linux/netfilter.h | 2 ++ 1 file changed, 2 insertions(+)
include/linux/netfilter.h +2 -0
@@ -215,6 +215,8 @@ static inline int nf_hook(u_int8_t pf, unsigned int hook, struct net *net,break ;case NFPROTO_ARP :#ifdef CONFIG_NETFILTER_FAMILY_ARP +if (WARN_ON_ONCE (hook >=ARRAY_SIZE (net->nf.hooks_arp))) +break ; hook_head =rcu_dereference (net->nf.hooks_arp[hook]);#endif break ;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 46/100 qed: Fix shmem structure inconsistency between driver and the mfw.
In reply to Sasha LevinFrom: Sudarsana Reddy Kalluru <[email protected]>
[ Upstream commit 5f672090e44f4951084c5e1d6b0668a5fc422af8 ]
The structure shared between driver and the management FW (mfw) differ in sizes. This would lead to issues when driver try to access the structure members which are not-aligned with the mfw copy e.g., data_ptr usage in the case of mfw_tlv request.
Align the driver structure with mfw copy, add reserved field(s) to driver structure for the members not used by the driver.
--- drivers/net/ethernet/qlogic/qed/qed_hsi.h | 1 + 1 file changed, 1 insertion(+)
drivers/net/ethernet/qlogic/qed/qed_hsi.h +1 -0
@@ -11987,6 +11987,7 @@ struct public_global {u32 running_bundle_id;s32 external_temperature;u32 mdump_reason; +u64 reserved;u32 data_ptr;u32 data_size; };
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 47/100 asix: Check for supported Wake-on-LAN modes
In reply to Sasha LevinFrom: Florian Fainelli <[email protected]>
[ Upstream commit c4ce446e33d7a0e978256ac6fea4c80e59d9de5f ]
The driver currently silently accepts unsupported Wake-on-LAN modes (other than WAKE_PHY or WAKE_MAGIC) without reporting that to the user, which is confusing.
--- drivers/net/usb/asix_common.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/usb/asix_common.c +3 -0
@@ -607,6 +607,9 @@ int asix_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)struct usbnet *dev =netdev_priv (net);u8 opt =0 ; +if (wolinfo->wolopts & ~(WAKE_PHY |WAKE_MAGIC )) +return -EINVAL ; +if (wolinfo->wolopts &WAKE_PHY ) opt |=AX_MONITOR_LINK ;if (wolinfo->wolopts &WAKE_MAGIC )
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 48/100 ax88179_178a: Check for supported Wake-on-LAN modes
In reply to Sasha LevinFrom: Florian Fainelli <[email protected]>
[ Upstream commit 5ba6b4aa9a410c5e2c6417df52b5e2118ea9b467 ]
The driver currently silently accepts unsupported Wake-on-LAN modes (other than WAKE_PHY or WAKE_MAGIC) without reporting that to the user, which is confusing.
--- drivers/net/usb/ax88179_178a.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/usb/ax88179_178a.c +3 -0
@@ -566,6 +566,9 @@ ax88179_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)struct usbnet *dev =netdev_priv (net);u8 opt =0 ; +if (wolinfo->wolopts & ~(WAKE_PHY |WAKE_MAGIC )) +return -EINVAL ; +if (wolinfo->wolopts &WAKE_PHY ) opt |=AX_MONITOR_MODE_RWLC ;if (wolinfo->wolopts &WAKE_MAGIC )
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 49/100 lan78xx: Check for supported Wake-on-LAN modes
In reply to Sasha LevinFrom: Florian Fainelli <[email protected]>
[ Upstream commit eb9ad088f96653a26b340f7c447c44cf023d5cdc ]
The driver supports a fair amount of Wake-on-LAN modes, but is not checking that the user specified one that is supported.
--- drivers/net/usb/lan78xx.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-)
drivers/net/usb/lan78xx.c +4 -13
@@ -1401,19 +1401,10 @@ static int lan78xx_set_wol(struct net_device *netdev,if (ret <0 )return ret; - pdata->wol =0 ; -if (wol->wolopts &WAKE_UCAST ) - pdata->wol |=WAKE_UCAST ; -if (wol->wolopts &WAKE_MCAST ) - pdata->wol |=WAKE_MCAST ; -if (wol->wolopts &WAKE_BCAST ) - pdata->wol |=WAKE_BCAST ; -if (wol->wolopts &WAKE_MAGIC ) - pdata->wol |=WAKE_MAGIC ; -if (wol->wolopts &WAKE_PHY ) - pdata->wol |=WAKE_PHY ; -if (wol->wolopts &WAKE_ARP ) - pdata->wol |=WAKE_ARP ; +if (wol->wolopts & ~WAKE_ALL ) +return -EINVAL ; + + pdata->wol = wol->wolopts;device_set_wakeup_enable (&dev->udev->dev, (bool )wol->wolopts);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 50/100 sr9800: Check for supported Wake-on-LAN modes
In reply to Sasha LevinFrom: Florian Fainelli <[email protected]>
[ Upstream commit c5cb93e994ffb43b7b3b1ff10b9f928f54574a36 ]
The driver currently silently accepts unsupported Wake-on-LAN modes (other than WAKE_PHY or WAKE_MAGIC) without reporting that to the user, which is confusing.
--- drivers/net/usb/sr9800.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/usb/sr9800.c +3 -0
@@ -421,6 +421,9 @@ sr_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)struct usbnet *dev =netdev_priv (net);u8 opt =0 ; +if (wolinfo->wolopts & ~(WAKE_PHY |WAKE_MAGIC )) +return -EINVAL ; +if (wolinfo->wolopts &WAKE_PHY ) opt |=SR_MONITOR_LINK ;if (wolinfo->wolopts &WAKE_MAGIC )
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 51/100 r8152: Check for supported Wake-on-LAN Modes
In reply to Sasha LevinFrom: Florian Fainelli <[email protected]>
[ Upstream commit f2750df1548bd8a2b060eb609fc43ca82811af4c ]
The driver does not check for Wake-on-LAN modes specified by an user, but will conditionally set the device as wake-up enabled or not based on that, which could be a very confusing user experience.
--- drivers/net/usb/r8152.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/usb/r8152.c +3 -0
@@ -4503,6 +4503,9 @@ static int rtl8152_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)if (!rtl_can_wakeup (tp))return -EOPNOTSUPP ; +if (wol->wolopts & ~WAKE_ANY ) +return -EINVAL ; + ret =usb_autopm_get_interface (tp->intf);if (ret <0 ) goto out_set_wol;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 52/100 smsc75xx: Check for Wake-on-LAN modes
In reply to Sasha LevinFrom: Florian Fainelli <[email protected]>
[ Upstream commit 9c734b2769a73eea2e9e9767c0e0bf839ff23679 ]
The driver does not check for Wake-on-LAN modes specified by an user, but will conditionally set the device as wake-up enabled or not based on that, which could be a very confusing user experience.
--- drivers/net/usb/smsc75xx.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/usb/smsc75xx.c +3 -0
@@ -731,6 +731,9 @@ static int smsc75xx_ethtool_set_wol(struct net_device *net,struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0 ]);int ret; +if (wolinfo->wolopts & ~SUPPORTED_WAKE ) +return -EINVAL ; + pdata->wolopts = wolinfo->wolopts &SUPPORTED_WAKE ; ret =device_set_wakeup_enable (&dev->udev->dev, pdata->wolopts);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 53/100 smsc95xx: Check for Wake-on-LAN modes
In reply to Sasha LevinFrom: Florian Fainelli <[email protected]>
[ Upstream commit c530c471ba37bdd9fe1c7185b01455c00ae606fb ]
The driver does not check for Wake-on-LAN modes specified by an user, but will conditionally set the device as wake-up enabled or not based on that, which could be a very confusing user experience.
--- drivers/net/usb/smsc95xx.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/usb/smsc95xx.c +3 -0
@@ -774,6 +774,9 @@ static int smsc95xx_ethtool_set_wol(struct net_device *net,struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0 ]);int ret; +if (wolinfo->wolopts & ~SUPPORTED_WAKE ) +return -EINVAL ; + pdata->wolopts = wolinfo->wolopts &SUPPORTED_WAKE ; ret =device_set_wakeup_enable (&dev->udev->dev, pdata->wolopts);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 54/100 qlcnic: fix Tx descriptor corruption on 82xx devices
In reply to Sasha LevinFrom: Shahed Shaikh <[email protected]>
[ Upstream commit c333fa0c4f220f8f7ea5acd6b0ebf3bf13fd684d ]
In regular NIC transmission flow, driver always configures MAC using Tx queue zero descriptor as a part of MAC learning flow.
But with multi Tx queue supported NIC, regular transmission can occur on any non-zero Tx queue and from that context it uses
Tx queue zero descriptor to configure MAC, at the same time TX queue zero could be used by another CPU for regular transmission which could lead to Tx queue zero descriptor corruption and cause FW abort.
This patch fixes this in such a way that driver always configures learned MAC address from the same Tx queue which is used for regular transmission.
--- drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | 8 +++++--- drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | 3 ++- drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h | 3 ++- drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h | 3 ++- drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c | 12 ++++++------ 5 files changed, 17 insertions(+), 12 deletions(-)
drivers/net/ethernet/qlogic/qlcnic/qlcnic.h +5 -3
@@ -1800,7 +1800,8 @@ struct qlcnic_hardware_ops {int (*config_loopback) (struct qlcnic_adapter *,u8 );int (*clear_loopback) (struct qlcnic_adapter *,u8 );int (*config_promisc_mode) (struct qlcnic_adapter *,u32 ); -void (*change_l2_filter) (struct qlcnic_adapter *,u64 *,u16 ); +void (*change_l2_filter)(struct qlcnic_adapter *adapter,u64 *addr, +u16 vlan,struct qlcnic_host_tx_ring *tx_ring);int (*get_board_info) (struct qlcnic_adapter *);void (*set_mac_filter_count) (struct qlcnic_adapter *);void (*free_mac_list) (struct qlcnic_adapter *);
@@ -2064,9 +2065,10 @@ static inline int qlcnic_nic_set_promisc(struct qlcnic_adapter *adapter, }static inline void qlcnic_change_filter (struct qlcnic_adapter *adapter, -u64 *addr,u16 id) +u64 *addr,u16 vlan, +struct qlcnic_host_tx_ring *tx_ring) { - adapter->ahw->hw_ops->change_l2_filter (adapter, addr, id); + adapter->ahw->hw_ops->change_l2_filter (adapter, addr, vlan, tx_ring); }static inline int qlcnic_get_board_info (struct qlcnic_adapter *adapter)
drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c +2 -1
@@ -2135,7 +2135,8 @@ int qlcnic_83xx_sre_macaddr_change(struct qlcnic_adapter *adapter, u8 *addr, }void qlcnic_83xx_change_l2_filter (struct qlcnic_adapter *adapter,u64 *addr, -u16 vlan_id) +u16 vlan_id, +struct qlcnic_host_tx_ring *tx_ring) {u8 mac[ETH_ALEN ];memcpy (&mac, addr,ETH_ALEN );
drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h +2 -1
@@ -550,7 +550,8 @@ int qlcnic_83xx_wrt_reg_indirect(struct qlcnic_adapter *, ulong, u32);int qlcnic_83xx_nic_set_promisc (struct qlcnic_adapter *,u32 );int qlcnic_83xx_config_hw_lro (struct qlcnic_adapter *,int );int qlcnic_83xx_config_rss (struct qlcnic_adapter *,int ); -void qlcnic_83xx_change_l2_filter (struct qlcnic_adapter *,u64 *,u16 ); +void qlcnic_83xx_change_l2_filter (struct qlcnic_adapter *adapter,u64 *addr, +u16 vlan,struct qlcnic_host_tx_ring *ring);int qlcnic_83xx_get_pci_info (struct qlcnic_adapter *,struct qlcnic_pci_info *);int qlcnic_83xx_set_nic_info (struct qlcnic_adapter *,struct qlcnic_info *);void qlcnic_83xx_initialize_nic (struct qlcnic_adapter *,int );
drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h +2 -1
@@ -173,7 +173,8 @@ int qlcnic_82xx_napi_add(struct qlcnic_adapter *adapter, struct net_device *netdev);void qlcnic_82xx_get_beacon_state (struct qlcnic_adapter *);void qlcnic_82xx_change_filter (struct qlcnic_adapter *adapter, -u64 *uaddr,u16 vlan_id); +u64 *uaddr,u16 vlan_id, +struct qlcnic_host_tx_ring *tx_ring);int qlcnic_82xx_config_intr_coalesce (struct qlcnic_adapter *,struct ethtool_coalesce *);int qlcnic_82xx_set_rx_coalesce (struct qlcnic_adapter *);
drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c +6 -6
@@ -268,13 +268,12 @@ static void qlcnic_add_lb_filter(struct qlcnic_adapter *adapter, }void qlcnic_82xx_change_filter (struct qlcnic_adapter *adapter,u64 *uaddr, -u16 vlan_id) +u16 vlan_id,struct qlcnic_host_tx_ring *tx_ring) {struct cmd_desc_type0 *hwdesc;struct qlcnic_nic_req *req;struct qlcnic_mac_req *mac_req;struct qlcnic_vlan_req *vlan_req; -struct qlcnic_host_tx_ring *tx_ring = adapter->tx_ring;u32 producer;u64 word;
@@ -301,7 +300,8 @@ void qlcnic_82xx_change_filter(struct qlcnic_adapter *adapter, u64 *uaddr,static void qlcnic_send_filter (struct qlcnic_adapter *adapter,struct cmd_desc_type0 *first_desc, -struct sk_buff *skb) +struct sk_buff *skb, +struct qlcnic_host_tx_ring *tx_ring) {struct vlan_ethhdr *vh = (struct vlan_ethhdr *)(skb->data);struct ethhdr *phdr = (struct ethhdr *)(skb->data);
@@ -335,7 +335,7 @@ static void qlcnic_send_filter(struct qlcnic_adapter *adapter, tmp_fil->vlan_id == vlan_id) {if (jiffies > (QLCNIC_READD_AGE *HZ + tmp_fil->ftime))qlcnic_change_filter (adapter, &src_addr, - vlan_id); + vlan_id, tx_ring); tmp_fil->ftime = jiffies;return ; }
@@ -350,7 +350,7 @@ static void qlcnic_send_filter(struct qlcnic_adapter *adapter,if (!fil)return ; -qlcnic_change_filter (adapter, &src_addr, vlan_id); +qlcnic_change_filter (adapter, &src_addr, vlan_id, tx_ring); fil->ftime = jiffies; fil->vlan_id = vlan_id;memcpy (fil->faddr, &src_addr,ETH_ALEN );
@@ -766,7 +766,7 @@ netdev_tx_t qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) }if (adapter->drv_mac_learn) -qlcnic_send_filter (adapter, first_desc, skb); +qlcnic_send_filter (adapter, first_desc, skb, tx_ring); tx_ring->tx_stats.tx_bytes += skb->len; tx_ring->tx_stats.xmit_called++;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 55/100 i2c: i2c-scmi: fix for i2c_smbus_write_block_data
In reply to Sasha LevinFrom: Edgar Cherkasov <[email protected]>
[ Upstream commit 08d9db00fe0e300d6df976e6c294f974988226dd ]
The i2c-scmi driver crashes when the SMBus Write Block transaction is executed:
WARNING: CPU: 9 PID: 2194 at mm/page_alloc.c:3931 __alloc_pages_slowpath+0x9db/0xec0 Call Trace: ? get_page_from_freelist+0x49d/0x11f0 ? alloc_pages_current+0x6a/0xe0 ? new_slab+0x499/0x690 __alloc_pages_nodemask+0x265/0x280 alloc_pages_current+0x6a/0xe0 kmalloc_order+0x18/0x40 kmalloc_order_trace+0x24/0xb0 ? acpi_ut_allocate_object_desc_dbg+0x62/0x10c __kmalloc+0x203/0x220 acpi_os_allocate_zeroed+0x34/0x36 acpi_ut_copy_eobject_to_iobject+0x266/0x31e acpi_evaluate_object+0x166/0x3b2 acpi_smbus_cmi_access+0x144/0x530 [i2c_scmi] i2c_smbus_xfer+0xda/0x370 i2cdev_ioctl_smbus+0x1bd/0x270 i2cdev_ioctl+0xaa/0x250 do_vfs_ioctl+0xa4/0x600 SyS_ioctl+0x79/0x90 do_syscall_64+0x73/0x130 entry_SYSCALL_64_after_hwframe+0x3d/0xa2
ACPI Error: Evaluating _SBW: 4 (20170831/smbus_cmi-185)
This problem occurs because the length of ACPI Buffer object is not defined/initialized in the code before a corresponding ACPI method is called. The obvious patch below fixes this issue.
--- drivers/i2c/busses/i2c-scmi.c | 1 + 1 file changed, 1 insertion(+)
drivers/i2c/busses/i2c-scmi.c +1 -0
@@ -152,6 +152,7 @@ acpi_smbus_cmi_access(struct i2c_adapter *adap, u16 addr, unsigned short flags, mt_params[3 ].type =ACPI_TYPE_INTEGER ; mt_params[3 ].integer.value = len; mt_params[4 ].type =ACPI_TYPE_BUFFER ; + mt_params[4 ].buffer.length = len; mt_params[4 ].buffer.pointer = data->block +1 ; }break ;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 56/100 cfg80211: fix use-after-free in reg_process_hint()
In reply to Sasha LevinFrom: Yu Zhao <[email protected]>
[ Upstream commit 1db58529454742f67ebd96e3588315e880b72837 ]
reg_process_hint_country_ie() can free regulatory_request and return REG_REQ_ALREADY_SET. We shouldn't use regulatory_request after it's called. KASAN error was observed when this happens.
BUG: KASAN: use-after-free in reg_process_hint+0x839/0x8aa [cfg80211] Read of size 4 at addr ffff8800c430d434 by task kworker/1:3/89 <snipped> Workqueue: events reg_todo [cfg80211] Call Trace: dump_stack+0xc1/0x10c ? _atomic_dec_and_lock+0x1ad/0x1ad ? _raw_spin_lock_irqsave+0xa0/0xd2 print_address_description+0x86/0x26f ? reg_process_hint+0x839/0x8aa [cfg80211] kasan_report+0x241/0x29b reg_process_hint+0x839/0x8aa [cfg80211] reg_todo+0x204/0x5b9 [cfg80211] process_one_work+0x55f/0x8d0 ? worker_detach_from_pool+0x1b5/0x1b5 ? _raw_spin_unlock_irq+0x65/0xdd ? _raw_spin_unlock_irqrestore+0xf3/0xf3 worker_thread+0x5dd/0x841 ? kthread_parkme+0x1d/0x1d kthread+0x270/0x285 ? pr_cont_work+0xe3/0xe3 ? rcu_read_unlock_sched_notrace+0xca/0xca ret_from_fork+0x22/0x40 Allocated by task 2718: set_track+0x63/0xfa __kmalloc+0x119/0x1ac regulatory_hint_country_ie+0x38/0x329 [cfg80211] __cfg80211_connect_result+0x854/0xadd [cfg80211] cfg80211_rx_assoc_resp+0x3bc/0x4f0 [cfg80211] smsc95xx v1.0.6 ieee80211_sta_rx_queued_mgmt+0x1803/0x7ed5 [mac80211] ieee80211_iface_work+0x411/0x696 [mac80211] process_one_work+0x55f/0x8d0 worker_thread+0x5dd/0x841 kthread+0x270/0x285 ret_from_fork+0x22/0x40 Freed by task 89: set_track+0x63/0xfa kasan_slab_free+0x6a/0x87 kfree+0xdc/0x470 reg_process_hint+0x31e/0x8aa [cfg80211] reg_todo+0x204/0x5b9 [cfg80211] process_one_work+0x55f/0x8d0 worker_thread+0x5dd/0x841 kthread+0x270/0x285 ret_from_fork+0x22/0x40
<snipped>
--- net/wireless/reg.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
net/wireless/reg.c +4 -3
@@ -2661,11 +2661,12 @@ static void reg_process_hint(struct regulatory_request *reg_request) {struct wiphy *wiphy =NULL ;enum reg_request_treatment treatment; +enum nl80211_reg_initiator initiator = reg_request->initiator;if (reg_request->wiphy_idx !=WIPHY_IDX_INVALID ) wiphy =wiphy_idx_to_wiphy (reg_request->wiphy_idx); -switch (reg_request->initiator) { +switch (initiator) {case NL80211_REGDOM_SET_BY_CORE : treatment =reg_process_hint_core (reg_request);break ;
@@ -2683,7 +2684,7 @@ static void reg_process_hint(struct regulatory_request *reg_request) treatment =reg_process_hint_country_ie (wiphy, reg_request);break ;default : -WARN (1 ,"invalid initiator %d\n" , reg_request->initiator); +WARN (1 ,"invalid initiator %d\n" , initiator); goto out_free; }
@@ -2698,7 +2699,7 @@ static void reg_process_hint(struct regulatory_request *reg_request)*/ if (treatment ==REG_REQ_ALREADY_SET && wiphy && wiphy->regulatory_flags ®ULATORY_STRICT_REG ) { -wiphy_update_regulatory (wiphy, reg_request->initiator); +wiphy_update_regulatory (wiphy, initiator);wiphy_all_share_dfs_chan_state (wiphy);reg_check_channels (); }
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 57/100 KVM: nVMX: Do not expose MPX VMX controls when guest MPX disabled
In reply to Sasha LevinFrom: Liran Alon <[email protected]>
[ Upstream commit 5f76f6f5ff96587af5acd5930f7d9fea81e0d1a8 ]
Before this commit, KVM exposes MPX VMX controls to L1 guest only based on if KVM and host processor supports MPX virtualization. However, these controls should be exposed to guest only in case guest vCPU supports MPX.
Without this change, a L1 guest running with kernel which don't have commit 691bd4340bef ("kvm: vmx: allow host to access guest MSR_IA32_BNDCFGS") asserts in QEMU on the following:
qemu-kvm: error: failed to set MSR 0xd90 to 0x0 qemu-kvm: .../qemu-2.10.0/target/i386/kvm.c:1801 kvm_put_msrs: Assertion 'ret == cpu->kvm_msr_buf->nmsrs failed'
This is because L1 KVM kvm_init_msr_list() will see that vmx_mpx_supported() (As it only checks MPX VMX controls support) and therefore KVM_GET_MSR_INDEX_LIST IOCTL will include MSR_IA32_BNDCFGS. However, later when L1 will attempt to set this MSR via KVM_SET_MSRS IOCTL, it will fail because !guest_cpuid_has_mpx(vcpu).
Therefore, fix the issue by exposing MPX VMX controls to L1 guest only when vCPU supports MPX.
--- arch/x86/kvm/vmx.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-)
arch/x86/kvm/vmx.c +20 -6
@@ -3395,9 +3395,6 @@ static void nested_vmx_setup_ctls_msrs(struct nested_vmx_msrs *msrs, bool apicv)VM_EXIT_LOAD_IA32_EFER |VM_EXIT_SAVE_IA32_EFER |VM_EXIT_SAVE_VMX_PREEMPTION_TIMER |VM_EXIT_ACK_INTR_ON_EXIT ; -if (kvm_mpx_supported ()) - msrs->exit_ctls_high |=VM_EXIT_CLEAR_BNDCFGS ; -/* We support free control of debug control saving. */ msrs->exit_ctls_low &= ~VM_EXIT_SAVE_DEBUG_CONTROLS ;
@@ -3414,8 +3411,6 @@ static void nested_vmx_setup_ctls_msrs(struct nested_vmx_msrs *msrs, bool apicv)VM_ENTRY_LOAD_IA32_PAT ; msrs->entry_ctls_high |= (VM_ENTRY_ALWAYSON_WITHOUT_TRUE_MSR |VM_ENTRY_LOAD_IA32_EFER ); -if (kvm_mpx_supported ()) - msrs->entry_ctls_high |=VM_ENTRY_LOAD_BNDCFGS ;/* We support free control of debug control loading. */ msrs->entry_ctls_low &= ~VM_ENTRY_LOAD_DEBUG_CONTROLS ;
@@ -10825,6 +10820,23 @@ static void nested_vmx_cr_fixed1_bits_update(struct kvm_vcpu *vcpu)#undef cr4_fixed1_update } +static void nested_vmx_entry_exit_ctls_update (struct kvm_vcpu *vcpu) +{ +struct vcpu_vmx *vmx =to_vmx (vcpu); + +if (kvm_mpx_supported ()) { +bool mpx_enabled =guest_cpuid_has (vcpu,X86_FEATURE_MPX ); + +if (mpx_enabled) { + vmx->nested.msrs.entry_ctls_high |=VM_ENTRY_LOAD_BNDCFGS ; + vmx->nested.msrs.exit_ctls_high |=VM_EXIT_CLEAR_BNDCFGS ; + }else { + vmx->nested.msrs.entry_ctls_high &= ~VM_ENTRY_LOAD_BNDCFGS ; + vmx->nested.msrs.exit_ctls_high &= ~VM_EXIT_CLEAR_BNDCFGS ; + } + } +} +static void vmx_cpuid_update (struct kvm_vcpu *vcpu) {struct vcpu_vmx *vmx =to_vmx (vcpu);
@@ -10841,8 +10853,10 @@ static void vmx_cpuid_update(struct kvm_vcpu *vcpu)to_vmx (vcpu)->msr_ia32_feature_control_valid_bits &= ~FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX ; -if (nested_vmx_allowed (vcpu)) +if (nested_vmx_allowed (vcpu)) {nested_vmx_cr_fixed1_bits_update (vcpu); +nested_vmx_entry_exit_ctls_update (vcpu); + } }static void vmx_set_supported_cpuid (u32 func,struct kvm_cpuid_entry2 *entry)
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 58/100 KVM: x86: Do not use kvm_x86_ops->mpx_supported() directly
In reply to Sasha LevinFrom: Liran Alon <[email protected]>
[ Upstream commit 503234b3fdcaa578395c07e393ea3e5d13958824 ]
Commit a87036add092 ("KVM: x86: disable MPX if host did not enable MPX XSAVE features") introduced kvm_mpx_supported() to return true iff MPX is enabled in the host.
However, that commit seems to have missed replacing some calls to kvm_x86_ops->mpx_supported() to kvm_mpx_supported().
Complete original commit by replacing remaining calls to kvm_mpx_supported().
MPX XSAVE features")
--- arch/x86/kvm/vmx.c | 2 +- arch/x86/kvm/x86.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
arch/x86/kvm/vmx.c +1 -1
@@ -11567,7 +11567,7 @@ static void prepare_vmcs02_full(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12)set_cr4_guest_host_mask (vmx); -if (vmx_mpx_supported ()) +if (kvm_mpx_supported ())vmcs_write64 (GUEST_BNDCFGS , vmcs12->guest_bndcfgs);if (enable_vpid) {
arch/x86/kvm/x86.c +1 -1
@@ -4625,7 +4625,7 @@ static void kvm_init_msr_list(void)*/ switch (msrs_to_save[i]) {case MSR_IA32_BNDCFGS : -if (!kvm_x86_ops->mpx_supported ()) +if (!kvm_mpx_supported ())continue ;break ;case MSR_TSC_AUX :
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 59/100 KVM: nVMX: Fix emulation of VM_ENTRY_LOAD_BNDCFGS
In reply to Sasha LevinFrom: Liran Alon <[email protected]>
[ Upstream commit 62cf9bd8118c4009f02c477ef78c723f49e53e16 ]
L2 IA32_BNDCFGS should be updated with vmcs12->guest_bndcfgs only when VM_ENTRY_LOAD_BNDCFGS is specified in vmcs12->vm_entry_controls.
Otherwise, L2 IA32_BNDCFGS should be set to vmcs01->guest_bndcfgs which is L1 IA32_BNDCFGS.
--- arch/x86/kvm/vmx.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
arch/x86/kvm/vmx.c +11 -2
@@ -819,6 +819,7 @@ struct nested_vmx {/* to migrate it to L2 if VM_ENTRY_LOAD_DEBUG_CONTROLS is off */ u64 vmcs01_debugctl; +u64 vmcs01_guest_bndcfgs;u16 vpid02;u16 last_vpid;
@@ -11567,8 +11568,13 @@ static void prepare_vmcs02_full(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12)set_cr4_guest_host_mask (vmx); -if (kvm_mpx_supported ()) -vmcs_write64 (GUEST_BNDCFGS , vmcs12->guest_bndcfgs); +if (kvm_mpx_supported ()) { +if (vmx->nested.nested_run_pending && + (vmcs12->vm_entry_controls &VM_ENTRY_LOAD_BNDCFGS )) +vmcs_write64 (GUEST_BNDCFGS , vmcs12->guest_bndcfgs); +else +vmcs_write64 (GUEST_BNDCFGS , vmx->nested.vmcs01_guest_bndcfgs); + }if (enable_vpid) {if (nested_cpu_has_vpid (vmcs12) && vmx->nested.vpid02)
@@ -12082,6 +12088,9 @@ static int enter_vmx_non_root_mode(struct kvm_vcpu *vcpu)if (!(vmcs12->vm_entry_controls &VM_ENTRY_LOAD_DEBUG_CONTROLS )) vmx->nested.vmcs01_debugctl =vmcs_read64 (GUEST_IA32_DEBUGCTL ); +if (kvm_mpx_supported () && + !(vmcs12->vm_entry_controls &VM_ENTRY_LOAD_BNDCFGS )) + vmx->nested.vmcs01_guest_bndcfgs =vmcs_read64 (GUEST_BNDCFGS );vmx_switch_vmcs (vcpu, &vmx->nested.vmcs02);vmx_segment_cache_clear (vmx);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 60/100 net/mlx5: E-Switch, Fix out of bound access when setting vport rate
In reply to Sasha LevinFrom: Eran Ben Elisha <[email protected]>
[ Upstream commit 11aa5800ed66ed0415b7509f02881c76417d212a ]
The code that deals with eswitch vport bw guarantee was going beyond the eswitch vport array limit, fix that. This was pointed out by the kernel address sanitizer (KASAN).
The error from KASAN log:
[2018-09-15 15:04:45] BUG: KASAN: slab-out-of-bounds in mlx5_eswitch_set_vport_rate+0x8c1/0xae0 [mlx5_core]
--- drivers/net/ethernet/mellanox/mlx5/core/eswitch.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/eswitch.c +2 -2
@@ -2000,7 +2000,7 @@ static u32 calculate_vports_min_rate_divider(struct mlx5_eswitch *esw)u32 max_guarantee =0 ;int i; -for (i =0 ; i <= esw->total_vports; i++) { +for (i =0 ; i < esw->total_vports; i++) { evport = &esw->vports[i];if (!evport->enabled || evport->info.min_rate < max_guarantee)continue ;
@@ -2020,7 +2020,7 @@ static int normalize_vports_min_rate(struct mlx5_eswitch *esw, u32 divider)int err;int i; -for (i =0 ; i <= esw->total_vports; i++) { +for (i =0 ; i < esw->total_vports; i++) { evport = &esw->vports[i];if (!evport->enabled)continue ;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 61/100 net/mlx5e: Set vlan masks for all offloaded TC rules
In reply to Sasha LevinFrom: Jianbo Liu <[email protected]>
[ Upstream commit cee26487620bc9bc3c7db21b6984d91f7bae12ae ]
In flow steering, if asked to, the hardware matches on the first ethertype which is not vlan. It's possible to set a rule as follows, which is meant to match on untagged packet, but will match on a vlan packet:
tc filter add dev eth0 parent ffff: protocol ip flower ...
To avoid this for packets with single tag, we set vlan masks to tell hardware to check the tags for every matched packet.
--- drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +3 -0
@@ -1339,6 +1339,9 @@ static int __parse_cls_flower(struct mlx5e_priv *priv, *match_level =MLX5_MATCH_L2 ; } + }else { +MLX5_SET (fte_match_set_lyr_2_4, headers_c, svlan_tag,1 ); +MLX5_SET (fte_match_set_lyr_2_4, headers_c, cvlan_tag,1 ); }if (dissector_uses_key (f->dissector,FLOW_DISSECTOR_KEY_BASIC )) {
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 62/100 tun: remove unused parameters
In reply to Sasha LevinFrom: Eric Dumazet <[email protected]>
[ Upstream commit 06e55addd3f40b5294e448c2cb7605ca4f28c2e3 ]
tun_napi_disable() and tun_napi_del() do not need a pointer to the tun_struct
--- drivers/net/tun.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/net/tun.c +6 -6
@@ -323,13 +323,13 @@ static void tun_napi_init(struct tun_struct *tun, struct tun_file *tfile, } } -static void tun_napi_disable (struct tun_struct *tun,struct tun_file *tfile) +static void tun_napi_disable (struct tun_file *tfile) {if (tfile->napi_enabled)napi_disable (&tfile->napi); } -static void tun_napi_del (struct tun_struct *tun,struct tun_file *tfile) +static void tun_napi_del (struct tun_file *tfile) {if (tfile->napi_enabled)netif_napi_del (&tfile->napi);
@@ -688,8 +688,8 @@ static void __tun_detach(struct tun_file *tfile, bool clean) tun =rtnl_dereference (tfile->tun);if (tun && clean) { -tun_napi_disable (tun, tfile); -tun_napi_del (tun, tfile); +tun_napi_disable (tfile); +tun_napi_del (tfile); }if (tun && !tfile->detached) {
@@ -756,7 +756,7 @@ static void tun_detach_all(struct net_device *dev)for (i =0 ; i < n; i++) { tfile =rtnl_dereference (tun->tfiles[i]);BUG_ON (!tfile); -tun_napi_disable (tun, tfile); +tun_napi_disable (tfile); tfile->socket.sk->sk_shutdown =RCV_SHUTDOWN ; tfile->socket.sk->sk_data_ready (tfile->socket.sk);RCU_INIT_POINTER (tfile->tun,NULL );
@@ -772,7 +772,7 @@ static void tun_detach_all(struct net_device *dev)synchronize_net ();for (i =0 ; i < n; i++) { tfile =rtnl_dereference (tun->tfiles[i]); -tun_napi_del (tun, tfile); +tun_napi_del (tfile);/* Drop read queue */ tun_queue_purge (tfile);xdp_rxq_info_unreg (&tfile->xdp_rxq);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 63/100 tun: initialize napi_mutex unconditionally
In reply to Sasha LevinFrom: Eric Dumazet <[email protected]>
[ Upstream commit c7256f579f8302ce2c038181c30060d0b40017b2 ]
This is the first part to fix following syzbot report :
console output: https://syzkaller.appspot.com/x/log.txt?x=145378e6400000 kernel config: https://syzkaller.appspot.com/x/.config?x=443816db871edd66 dashboard link: https://syzkaller.appspot.com/bug?extid=e662df0ac1d753b57e80
Following patch is fixing the race condition, but it seems safer to initialize this mutex at tfile creation anyway.
--- drivers/net/tun.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/tun.c +1 -1
@@ -319,7 +319,6 @@ static void tun_napi_init(struct tun_struct *tun, struct tun_file *tfile,netif_napi_add (tun->dev, &tfile->napi, tun_napi_poll,NAPI_POLL_WEIGHT );napi_enable (&tfile->napi); -mutex_init (&tfile->napi_mutex); } }
@@ -3241,6 +3240,7 @@ static int tun_chr_open(struct inode *inode, struct file * file)return -ENOMEM ; } +mutex_init (&tfile->napi_mutex);RCU_INIT_POINTER (tfile->tun,NULL ); tfile->flags =0 ; tfile->ifindex =0 ;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 64/100 r8169: fix network stalls due to missing bit TXCFG_AUTO_FIFO
In reply to Sasha LevinFrom: Heiner Kallweit <[email protected]>
[ Upstream commit ad5f97faff4231e72b96bd96adbe1b6e977a9b86 ]
Some of the chip-specific hw_start functions set bit TXCFG_AUTO_FIFO in register TxConfig. The original patch changed the order of some calls resulting in these changes being overwritten by rtl_set_tx_config_registers() in rtl_hw_start(). This eventually resulted in network stalls especially under high load.
Analyzing the chip-specific hw_start functions all chip version from 34, with the exception of version 39, need this bit set. This patch moves setting this bit to rtl_set_tx_config_registers().
--- drivers/net/ethernet/realtek/r8169.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-)
drivers/net/ethernet/realtek/r8169.c +8 -12
@@ -5041,9 +5041,14 @@ static void rtl8169_hw_reset(struct rtl8169_private *tp)static void rtl_set_tx_config_registers (struct rtl8169_private *tp) { -/* Set DMA burst size and Interframe Gap Time */ -RTL_W32 (tp, TxConfig, (TX_DMA_BURST << TxDMAShift) | - (InterFrameGap << TxInterFrameGapShift)); +u32 val =TX_DMA_BURST << TxDMAShift | + InterFrameGap << TxInterFrameGapShift; + +if (tp->mac_version >=RTL_GIGA_MAC_VER_34 && + tp->mac_version !=RTL_GIGA_MAC_VER_39 ) + val |=TXCFG_AUTO_FIFO ; + +RTL_W32 (tp, TxConfig, val); }static void rtl_set_rx_max_size (struct rtl8169_private *tp)
@@ -5530,7 +5535,6 @@ static void rtl_hw_start_8168e_2(struct rtl8169_private *tp)rtl_disable_clock_request (tp); -RTL_W32 (tp, TxConfig,RTL_R32 (tp, TxConfig) |TXCFG_AUTO_FIFO );RTL_W8 (tp,MCU ,RTL_R8 (tp,MCU ) & ~NOW_IS_OOB );/* Adjust EEE LED frequency */
@@ -5562,7 +5566,6 @@ static void rtl_hw_start_8168f(struct rtl8169_private *tp)rtl_disable_clock_request (tp); -RTL_W32 (tp, TxConfig,RTL_R32 (tp, TxConfig) |TXCFG_AUTO_FIFO );RTL_W8 (tp,MCU ,RTL_R8 (tp,MCU ) & ~NOW_IS_OOB );RTL_W8 (tp,DLLPR ,RTL_R8 (tp,DLLPR ) |PFM_EN );RTL_W32 (tp,MISC ,RTL_R32 (tp,MISC ) |PWM_EN );
@@ -5607,8 +5610,6 @@ static void rtl_hw_start_8411(struct rtl8169_private *tp)static void rtl_hw_start_8168g (struct rtl8169_private *tp) { -RTL_W32 (tp, TxConfig,RTL_R32 (tp, TxConfig) |TXCFG_AUTO_FIFO ); -rtl_eri_write (tp,0xc8 ,ERIAR_MASK_0101 ,0x080002 ,ERIAR_EXGMAC );rtl_eri_write (tp,0xcc ,ERIAR_MASK_0001 ,0x38 ,ERIAR_EXGMAC );rtl_eri_write (tp,0xd0 ,ERIAR_MASK_0001 ,0x48 ,ERIAR_EXGMAC );
@@ -5707,8 +5708,6 @@ static void rtl_hw_start_8168h_1(struct rtl8169_private *tp)RTL_W8 (tp, Config5,RTL_R8 (tp, Config5) & ~ASPM_en);rtl_ephy_init (tp, e_info_8168h_1,ARRAY_SIZE (e_info_8168h_1)); -RTL_W32 (tp, TxConfig,RTL_R32 (tp, TxConfig) |TXCFG_AUTO_FIFO ); -rtl_eri_write (tp,0xc8 ,ERIAR_MASK_0101 ,0x00080002 ,ERIAR_EXGMAC );rtl_eri_write (tp,0xcc ,ERIAR_MASK_0001 ,0x38 ,ERIAR_EXGMAC );rtl_eri_write (tp,0xd0 ,ERIAR_MASK_0001 ,0x48 ,ERIAR_EXGMAC );
@@ -5789,8 +5788,6 @@ static void rtl_hw_start_8168ep(struct rtl8169_private *tp) {rtl8168ep_stop_cmac (tp); -RTL_W32 (tp, TxConfig,RTL_R32 (tp, TxConfig) |TXCFG_AUTO_FIFO ); -rtl_eri_write (tp,0xc8 ,ERIAR_MASK_0101 ,0x00080002 ,ERIAR_EXGMAC );rtl_eri_write (tp,0xcc ,ERIAR_MASK_0001 ,0x2f ,ERIAR_EXGMAC );rtl_eri_write (tp,0xd0 ,ERIAR_MASK_0001 ,0x5f ,ERIAR_EXGMAC );
@@ -6108,7 +6105,6 @@ static void rtl_hw_start_8402(struct rtl8169_private *tp)/* Force LAN exit from ASPM if Rx/Tx are not idle */ RTL_W32 (tp, FuncEvent,RTL_R32 (tp, FuncEvent) |0x002800 ); -RTL_W32 (tp, TxConfig,RTL_R32 (tp, TxConfig) |TXCFG_AUTO_FIFO );RTL_W8 (tp,MCU ,RTL_R8 (tp,MCU ) & ~NOW_IS_OOB );rtl_ephy_init (tp, e_info_8402,ARRAY_SIZE (e_info_8402));
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 65/100 perf/core: Fix perf_pmu_unregister() locking
In reply to Sasha LevinFrom: Peter Zijlstra <[email protected]>
[ Upstream commit a9f9772114c8b07ae75bcb3654bd017461248095 ]
When we unregister a PMU, we fail to serialize the @pmu_idr properly. Fix that by doing the entire thing under pmu_lock.
--- kernel/events/core.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-)
kernel/events/core.c +2 -7
@@ -9436,9 +9436,7 @@ static void free_pmu_context(struct pmu *pmu)if (pmu->task_ctx_nr > perf_invalid_context)return ; -mutex_lock (&pmus_lock);free_percpu (pmu->pmu_cpu_context); -mutex_unlock (&pmus_lock); }/*
@@ -9694,12 +9692,8 @@ EXPORT_SYMBOL_GPL(perf_pmu_register);void perf_pmu_unregister (struct pmu *pmu) { -int remove_device; -mutex_lock (&pmus_lock); - remove_device = pmu_bus_running;list_del_rcu (&pmu->entry); -mutex_unlock (&pmus_lock);/* * We dereference the pmu list under both SRCU and regular RCU, so
@@ -9711,13 +9705,14 @@ void perf_pmu_unregister(struct pmu *pmu)free_percpu (pmu->pmu_disable_count);if (pmu->type >=PERF_TYPE_MAX )idr_remove (&pmu_idr, pmu->type); -if (remove_device) { +if (pmu_bus_running) {if (pmu->nr_addr_filters)device_remove_file (pmu->dev, &dev_attr_nr_addr_filters);device_del (pmu->dev);put_device (pmu->dev); }free_pmu_context (pmu); +mutex_unlock (&pmus_lock); }EXPORT_SYMBOL_GPL (perf_pmu_unregister);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 66/100 perf/x86/intel/uncore: Use boot_cpu_data.phys_proc_id instead of hardcorded physical package ID 0
In reply to Sasha LevinFrom: Masayoshi Mizuma <[email protected]>
[ Upstream commit 6265adb9726098b7f4f7ca70bc51992b25fdd9d6 ]
Physical package id 0 doesn't always exist, we should use boot_cpu_data.phys_proc_id here.
--- arch/x86/events/intel/uncore_snbep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/events/intel/uncore_snbep.c +1 -1
@@ -3061,7 +3061,7 @@ static struct event_constraint bdx_uncore_pcu_constraints[] = {void bdx_uncore_cpu_init (void ) { -int pkg =topology_phys_to_logical_pkg (0 ); +int pkg =topology_phys_to_logical_pkg (boot_cpu_data.phys_proc_id);if (bdx_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores) bdx_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 67/100 perf/ring_buffer: Prevent concurent ring buffer access
In reply to Sasha LevinFrom: Jiri Olsa <[email protected]>
[ Upstream commit cd6fb677ce7e460c25bdd66f689734102ec7d642 ]
Some of the scheduling tracepoints allow the perf_tp_event code to write to ring buffer under different cpu than the code is running on.
This results in corrupted ring buffer data demonstrated in following perf commands:
# perf record -e 'sched:sched_switch,sched:sched_wakeup' perf bench sched messaging # Running 'sched/messaging' benchmark: # 20 sender and receiver processes per group # 10 groups == 400 processes run
Total time: 0.383 [sec]
[ perf record: Woken up 8 times to write data ]
0x42b890 [0]: failed to process type: -1765585640
[ perf record: Captured and wrote 4.825 MB perf.data (29669 samples) ]
# perf report --stdio 0x42b890 [0]: failed to process type: -1765585640
The reason for the corruption are some of the scheduling tracepoints, that have __perf_task dfined and thus allow to store data to another cpu ring buffer:
sched_waking
sched_wakeup
sched_wakeup_new
sched_stat_wait
sched_stat_sleep
sched_stat_iowait
sched_stat_blocked
The perf_tp_event function first store samples for current cpu related events defined for tracepoint:
hlist_for_each_entry_rcu(event, head, hlist_entry)
perf_swevent_event(event, count, &data, regs);
And then iterates events of the 'task' and store the sample for any task's event that passes tracepoint checks:
ctx = rcu_dereference(task->perf_event_ctxp[perf_sw_context]);
list_for_each_entry_rcu(event, &ctx->event_list, event_entry) {
if (event->attr.type != PERF_TYPE_TRACEPOINT)
continue;
if (event->attr.config != entry->type)
continue;perf_swevent_event(event, count, &data, regs);
}
Above code can race with same code running on another cpu, ending up with 2 cpus trying to store under the same ring buffer, which is specifically not allowed.
This patch prevents the problem, by allowing only events with the same current cpu to receive the event.
NOTE: this requires the use of (per-task-)per-cpu buffers for this feature to work; perf-record does this.
--- kernel/events/core.c | 2 ++ 1 file changed, 2 insertions(+)
kernel/events/core.c +2 -0
@@ -8319,6 +8319,8 @@ void perf_tp_event(u16 event_type, u64 count, void *record, int entry_size, goto unlock;list_for_each_entry_rcu (event, &ctx->event_list, event_entry) { +if (event->cpu !=smp_processor_id ()) +continue ;if (event->attr.type !=PERF_TYPE_TRACEPOINT )continue ;if (event->attr.config != entry->type)
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 68/100 perf/x86/intel/uncore: Fix PCI BDF address of M3UPI on SKX
In reply to Sasha LevinFrom: Kan Liang <[email protected]>
[ Upstream commit 9d92cfeaf5215158d26d2991be7f7ff865cb98f3 ]
The counters on M3UPI Link 0 and Link 3 don't count properly, and writing 0 to these counters may causes system crash on some machines.
The PCI BDF addresses of the M3UPI in the current code are incorrect.
The correct addresses should be:
D18:F1 0x204D
D18:F2 0x204E
D18:F5 0x204D
--- arch/x86/events/intel/uncore_snbep.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
arch/x86/events/intel/uncore_snbep.c +6 -6
@@ -3931,16 +3931,16 @@ static const struct pci_device_id skx_uncore_pci_ids[] = { .driver_data = UNCORE_PCI_DEV_FULL_DATA(21, 5, SKX_PCI_UNCORE_M2PCIE, 3), }, {/* M3UPI0 Link 0 */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x204C), - .driver_data =UNCORE_PCI_DEV_FULL_DATA (18 ,0 ,SKX_PCI_UNCORE_M3UPI ,0 ), + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x204D), + .driver_data =UNCORE_PCI_DEV_FULL_DATA (18 ,1 ,SKX_PCI_UNCORE_M3UPI ,0 ), }, { /* M3UPI0 Link 1 */ -PCI_DEVICE (PCI_VENDOR_ID_INTEL ,0x204D ), - .driver_data = UNCORE_PCI_DEV_FULL_DATA(18, 1, SKX_PCI_UNCORE_M3UPI, 1), +PCI_DEVICE (PCI_VENDOR_ID_INTEL ,0x204E ), + .driver_data = UNCORE_PCI_DEV_FULL_DATA(18, 2, SKX_PCI_UNCORE_M3UPI, 1), }, { /* M3UPI1 Link 2 */ -PCI_DEVICE (PCI_VENDOR_ID_INTEL ,0x204C ), - .driver_data = UNCORE_PCI_DEV_FULL_DATA(18, 4, SKX_PCI_UNCORE_M3UPI, 2), +PCI_DEVICE (PCI_VENDOR_ID_INTEL ,0x204D ), + .driver_data = UNCORE_PCI_DEV_FULL_DATA(18, 5, SKX_PCI_UNCORE_M3UPI, 2), }, { /* end: all zeroes */ } };
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 69/100 perf/x86/amd/uncore: Set ThreadMask and SliceMask for L3 Cache perf events
In reply to Sasha LevinFrom: "Natarajan, Janakarajan" <[email protected]>
[ Upstream commit d7cbbe49a9304520181fb8c9272d1327deec8453 ]
In Family 17h, some L3 Cache Performance events require the ThreadMask and SliceMask to be set. For other events, these fields do not affect the count either way.
Set ThreadMask and SliceMask to 0xFF and 0xF respectively.
--- arch/x86/events/amd/uncore.c | 10 ++++++++++ arch/x86/include/asm/perf_event.h | 8 ++++++++ 2 files changed, 18 insertions(+)
arch/x86/events/amd/uncore.c +10 -0
@@ -36,6 +36,7 @@static int num_counters_llc;static int num_counters_nb; +static bool l3_mask;static HLIST_HEAD (uncore_unused_list);
@@ -209,6 +210,13 @@ static int amd_uncore_event_init(struct perf_event *event) hwc->config = event->attr.config &AMD64_RAW_EVENT_MASK_NB ; hwc->idx =-1 ; +/* +* SliceMask and ThreadMask need to be set for certain L3 events in +* Family 17h. For other events, the two fields do not affect the count. +*/ +if (l3_mask) + hwc->config |= (AMD64_L3_SLICE_MASK |AMD64_L3_THREAD_MASK ); +if (event->cpu <0 )return -EINVAL ;
@@ -525,6 +533,7 @@ static int __init amd_uncore_init(void) amd_llc_pmu.name ="amd_l3" ; format_attr_event_df.show = &event_show_df; format_attr_event_l3.show = &event_show_l3; + l3_mask = true; }else { num_counters_nb =NUM_COUNTERS_NB ; num_counters_llc =NUM_COUNTERS_L2 ;
@@ -532,6 +541,7 @@ static int __init amd_uncore_init(void) amd_llc_pmu.name ="amd_l2" ; format_attr_event_df = format_attr_event; format_attr_event_l3 = format_attr_event; + l3_mask = false; } amd_nb_pmu.attr_groups = amd_uncore_attr_groups_df;
arch/x86/include/asm/perf_event.h +8 -0
@@ -46,6 +46,14 @@#define INTEL_ARCH_EVENT_MASK \ (ARCH_PERFMON_EVENTSEL_UMASK | ARCH_PERFMON_EVENTSEL_EVENT) +#define AMD64_L3_SLICE_SHIFT 48 +#define AMD64_L3_SLICE_MASK \ + ((0xFULL) << AMD64_L3_SLICE_SHIFT) + +#define AMD64_L3_THREAD_SHIFT 56 +#define AMD64_L3_THREAD_MASK \ + ((0xFFULL) << AMD64_L3_THREAD_SHIFT) +#define X86_RAW_EVENT_MASK \ (ARCH_PERFMON_EVENTSEL_EVENT | \ ARCH_PERFMON_EVENTSEL_UMASK | \
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 70/100 thunderbolt: Do not handle ICM events after domain is stopped
In reply to Sasha LevinFrom: Mika Westerberg <[email protected]>
[ Upstream commit 86da809dda64a63fc27e05a215475325c3aaae92 ]
If there is a long chain of devices connected when the driver is loaded ICM sends device connected event for each and those are put to tb->wq for later processing. Now if the driver gets unloaded in the middle, so that the work queue is not yet empty it gets flushed by tb_domain_stop(). However, by that time the root switch is already removed so the driver crashes when it tries to dereference it in ICM event handling callbacks.
Fix this by checking whether the root switch is already removed. If it is we know that the domain is stopped and we should merely skip handling the event.
--- drivers/thunderbolt/icm.c | 49 ++++++++++++++++----------------------- 1 file changed, 20 insertions(+), 29 deletions(-)
drivers/thunderbolt/icm.c +20 -29
@@ -653,14 +653,6 @@ icm_fr_xdomain_connected(struct tb *tb, const struct icm_pkg_header *hdr)bool approved;u64 route; -/* -* After NVM upgrade adding root switch device fails because we -* initiated reset. During that time ICM might still send -* XDomain connected message which we ignore here. -*/ -if (!tb->root_switch) -return ; - link = pkg->link_info &ICM_LINK_INFO_LINK_MASK ; depth = (pkg->link_info &ICM_LINK_INFO_DEPTH_MASK ) >>ICM_LINK_INFO_DEPTH_SHIFT ;
@@ -950,14 +942,6 @@ icm_tr_device_connected(struct tb *tb, const struct icm_pkg_header *hdr)if (pkg->hdr.packet_id)return ; -/* -* After NVM upgrade adding root switch device fails because we -* initiated reset. During that time ICM might still send device -* connected message which we ignore here. -*/ -if (!tb->root_switch) -return ; - route =get_route (pkg->route_hi, pkg->route_lo); authorized = pkg->link_info &ICM_LINK_INFO_APPROVED ; security_level = (pkg->hdr.flags & ICM_FLAGS_SLEVEL_MASK) >>
@@ -1317,19 +1301,26 @@ static void icm_handle_notification(struct work_struct *work)mutex_lock (&tb->lock); -switch (n->pkg->code) { -case ICM_EVENT_DEVICE_CONNECTED : - icm->device_connected (tb, n->pkg); -break ; -case ICM_EVENT_DEVICE_DISCONNECTED : - icm->device_disconnected (tb, n->pkg); -break ; -case ICM_EVENT_XDOMAIN_CONNECTED : - icm->xdomain_connected (tb, n->pkg); -break ; -case ICM_EVENT_XDOMAIN_DISCONNECTED : - icm->xdomain_disconnected (tb, n->pkg); -break ; +/* +* When the domain is stopped we flush its workqueue but before +* that the root switch is removed. In that case we should treat +* the queued events as being canceled. +*/ +if (tb->root_switch) { +switch (n->pkg->code) { +case ICM_EVENT_DEVICE_CONNECTED : + icm->device_connected (tb, n->pkg); +break ; +case ICM_EVENT_DEVICE_DISCONNECTED : + icm->device_disconnected (tb, n->pkg); +break ; +case ICM_EVENT_XDOMAIN_CONNECTED : + icm->xdomain_connected (tb, n->pkg); +break ; +case ICM_EVENT_XDOMAIN_DISCONNECTED : + icm->xdomain_disconnected (tb, n->pkg); +break ; + } }mutex_unlock (&tb->lock);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 71/100 thunderbolt: Initialize after IOMMUs
In reply to Sasha LevinFrom: Mika Westerberg <[email protected]>
[ Upstream commit eafa717bc145963c944bb0a64d16add683861b35 ]
If IOMMU is enabled and Thunderbolt driver is built into the kernel image, it will be probed before IOMMUs are attached to the PCI bus. Because of this DMA mappings the driver does will not go through IOMMU and start failing right after IOMMUs are enabled.
For this reason move the Thunderbolt driver initialization happen at rootfs level.
--- drivers/thunderbolt/nhi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/thunderbolt/nhi.c +1 -1
@@ -1147,5 +1147,5 @@ static void __exit nhi_unload(void)tb_domain_exit (); } -fs_initcall (nhi_init); +rootfs_initcall (nhi_init);module_exit (nhi_unload);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 72/100 net: fec: fix rare tx timeout
In reply to Sasha LevinFrom: Rickard x Andersson <[email protected]>
[ Upstream commit 657ade07df72847f591ccdb36bd9b91ed0edbac3 ]
During certain heavy network loads TX could time out with TX ring dump.
TX is sometimes never restarted after reaching "tx_stop_threshold" because function "fec_enet_tx_queue" only tests the first queue.
In addition the TX timeout callback function failed to recover because it also operated only on the first queue.
--- drivers/net/ethernet/freescale/fec_main.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/net/ethernet/freescale/fec_main.c +4 -4
@@ -1157,7 +1157,7 @@ static void fec_enet_timeout_work(struct work_struct *work)napi_disable (&fep->napi);netif_tx_lock_bh (ndev);fec_restart (ndev); -netif_wake_queue (ndev); +netif_tx_wake_all_queues (ndev);netif_tx_unlock_bh (ndev);napi_enable (&fep->napi); }
@@ -1272,7 +1272,7 @@ fec_enet_tx_queue(struct net_device *ndev, u16 queue_id)/* Since we have freed up a buffer, the ring is no longer full */ -if (netif_queue_stopped (ndev)) { +if (netif_tx_queue_stopped (nq)) { entries_free =fec_enet_get_free_txdesc_num (txq);if (entries_free >= txq->tx_wake_threshold)netif_tx_wake_queue (nq);
@@ -1745,7 +1745,7 @@ static void fec_enet_adjust_link(struct net_device *ndev)napi_disable (&fep->napi);netif_tx_lock_bh (ndev);fec_restart (ndev); -netif_wake_queue (ndev); +netif_tx_wake_all_queues (ndev);netif_tx_unlock_bh (ndev);napi_enable (&fep->napi); }
@@ -2246,7 +2246,7 @@ static int fec_enet_set_pauseparam(struct net_device *ndev,napi_disable (&fep->napi);netif_tx_lock_bh (ndev);fec_restart (ndev); -netif_wake_queue (ndev); +netif_tx_wake_all_queues (ndev);netif_tx_unlock_bh (ndev);napi_enable (&fep->napi); }
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 73/100 declance: Fix continuation with the adapter identification message
In reply to Sasha LevinFrom: "Maciej W. Rozycki" <[email protected]>
[ Upstream commit fe3a83af6a50199bf250fa331e94216912f79395 ]
Fix a commit 4bcc595ccd80 ("printk: reinstate KERN_CONT for printing continuation lines") regression with the `declance' driver, which caused the adapter identification message to be split between two lines, e.g.:
declance.c: v0.011 by Linux MIPS DECstation task force
tc6: PMAD-AA
, addr = 08:00:2b:1b:2a:6a, irq = 14
tc6: registered as eth0.
Address that properly, by printing identification with a single call, making the messages now look like:
declance.c: v0.011 by Linux MIPS DECstation task force
tc6: PMAD-AA, addr = 08:00:2b:1b:2a:6a, irq = 14
tc6: registered as eth0.
--- drivers/net/ethernet/amd/declance.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
drivers/net/ethernet/amd/declance.c +6 -4
@@ -1031,6 +1031,7 @@ static int dec_lance_probe(struct device *bdev, const int type)int i, ret;unsigned long esar_base;unsigned char *esar; +const char *desc;if (dec_lance_debug && version_printed++ ==0 )printk (version);
@@ -1216,19 +1217,20 @@ static int dec_lance_probe(struct device *bdev, const int type)*/ switch (type) {case ASIC_LANCE : -printk ("%s: IOASIC onboard LANCE" , name); + desc ="IOASIC onboard LANCE" ;break ;case PMAD_LANCE : -printk ("%s: PMAD-AA" , name); + desc ="PMAD-AA" ;break ;case PMAX_LANCE : -printk ("%s: PMAX onboard LANCE" , name); + desc ="PMAX onboard LANCE" ;break ; }for (i =0 ; i <6 ; i++) dev->dev_addr[i] = esar[i *4 ]; -printk (", addr = %pM, irq = %d\n" , dev->dev_addr, dev->irq); +printk ("%s: %s, addr = %pM, irq = %d\n" , + name, desc, dev->dev_addr, dev->irq); dev->netdev_ops = &lance_netdev_ops; dev->watchdog_timeo =5 *HZ ;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 74/100 nfp: avoid soft lockups under control message storm
In reply to Sasha LevinFrom: Jakub Kicinski <[email protected]>
[ Upstream commit ff58e2df62ce29d0552278c290ae494b30fe0c6f ]
When FW floods the driver with control messages try to exit the cmsg processing loop every now and then to avoid soft lockups. Cmsg processing is generally very lightweight so 512 seems like a reasonable budget, which should not be exceeded under normal conditions.
--- .../net/ethernet/netronome/nfp/nfp_net_common.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-)
drivers/net/ethernet/netronome/nfp/nfp_net_common.c +12 -5
@@ -2068,14 +2068,17 @@ nfp_ctrl_rx_one(struct nfp_net *nn, struct nfp_net_dp *dp,return true; } -static void nfp_ctrl_rx (struct nfp_net_r_vector *r_vec) +static bool nfp_ctrl_rx (struct nfp_net_r_vector *r_vec) {struct nfp_net_rx_ring *rx_ring = r_vec->rx_ring;struct nfp_net *nn = r_vec->nfp_net;struct nfp_net_dp *dp = &nn->dp; +unsigned int budget =512 ; -while (nfp_ctrl_rx_one (nn, dp, r_vec, rx_ring)) +while (nfp_ctrl_rx_one (nn, dp, r_vec, rx_ring) && budget--)continue ; + +return budget; }static void nfp_ctrl_poll (unsigned long arg)
@@ -2087,9 +2090,13 @@ static void nfp_ctrl_poll(unsigned long arg)__nfp_ctrl_tx_queued (r_vec);spin_unlock_bh (&r_vec->lock); -nfp_ctrl_rx (r_vec); - -nfp_net_irq_unmask (r_vec->nfp_net, r_vec->irq_entry); +if (nfp_ctrl_rx (r_vec)) { +nfp_net_irq_unmask (r_vec->nfp_net, r_vec->irq_entry); + }else { +tasklet_schedule (&r_vec->tasklet); +nn_dp_warn (&r_vec->nfp_net->dp, +"control message budget exceeded!\n" ); + } }/* Setup and Configuration
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 75/100 RISCV: Fix end PFN for low memory
In reply to Sasha LevinFrom: Atish Patra <[email protected]>
[ Upstream commit ef1f2258748b675422ca0107e5bfb9ceeac675de ]
Use memblock_end_of_DRAM which provides correct last low memory PFN. Without that, DMA32 region becomes empty resulting in zero pages being allocated for DMA32.
This patch is based on earlier patch from palmer which never merged into 4.19. I just edited the commit text to make more sense.
--- arch/riscv/kernel/setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/riscv/kernel/setup.c +1 -1
@@ -165,7 +165,7 @@ static void __init setup_bootmem(void)BUG_ON (mem_size ==0 );set_max_mapnr (PFN_DOWN (mem_size)); - max_low_pfn = pfn_base +PFN_DOWN (mem_size); + max_low_pfn =memblock_end_of_DRAM ();#ifdef CONFIG_BLK_DEV_INITRD setup_initrd ();
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 76/100 Revert "serial: 8250_dw: Fix runtime PM handling"
In reply to Sasha LevinFrom: Guenter Roeck <[email protected]>
[ Upstream commit beeeac43b6fae5f5eaf707b6fcc2bf1e09deb785 ]
This reverts commit d76c74387e1c978b6c5524a146ab0f3f72206f98.
While commit d76c74387e1c ("serial: 8250_dw: Fix runtime PM handling") fixes runtime PM handling when using kgdb, it introduces a traceback for everyone else.
BUG: sleeping function called from invalid context at /mnt/host/source/src/third_party/kernel/next/drivers/base/power/runtime.c:1034
in_atomic(): 1, irqs_disabled(): 1, pid: 1, name: swapper/0
7 locks held by swapper/0/1:
#0: 000000005ec5bc72 (&dev->mutex){....}, at: __driver_attach+0xb5/0x12b #1: 000000005d5fa9e5 (&dev->mutex){....}, at: __device_attach+0x3e/0x15b #2: 0000000047e93286 (serial_mutex){+.+.}, at: serial8250_register_8250_port+0x51/0x8bb #3: 000000003b328f07 (port_mutex){+.+.}, at: uart_add_one_port+0xab/0x8b0 #4: 00000000fa313d4d (&port->mutex){+.+.}, at: uart_add_one_port+0xcc/0x8b0 #5: 00000000090983ca (console_lock){+.+.}, at: vprintk_emit+0xdb/0x217 #6: 00000000c743e583 (console_owner){-...}, at: console_unlock+0x211/0x60f
irq event stamp: 735222 __down_trylock_console_sem+0x4a/0x84 console_unlock+0x338/0x60f __do_softirq+0x4a4/0x50d irq_exit+0x64/0xe2 CPU: 2 PID: 1 Comm: swapper/0 Not tainted 4.19.0-rc5 #6 Hardware name: Google Caroline/Caroline, BIOS Google_Caroline.7820.286.0 03/15/2017 Call Trace: dump_stack+0x7d/0xbd ___might_sleep+0x238/0x259 __pm_runtime_resume+0x4e/0xa4 ? serial8250_rpm_get+0x2e/0x44 serial8250_console_write+0x44/0x301 ? lock_acquire+0x1b8/0x1fa console_unlock+0x577/0x60f vprintk_emit+0x1f0/0x217 printk+0x52/0x6e register_console+0x43b/0x524 uart_add_one_port+0x672/0x8b0 ? set_io_from_upio+0x150/0x162 serial8250_register_8250_port+0x825/0x8bb dw8250_probe+0x80c/0x8b0 ? dw8250_serial_inq+0x8e/0x8e ? dw8250_check_lcr+0x108/0x108 ? dw8250_runtime_resume+0x5b/0x5b ? dw8250_serial_outq+0xa1/0xa1 ? dw8250_remove+0x115/0x115 platform_drv_probe+0x76/0xc5 really_probe+0x1f1/0x3ee ? driver_allows_async_probing+0x5d/0x5d driver_probe_device+0xd6/0x112 ? driver_allows_async_probing+0x5d/0x5d bus_for_each_drv+0xbe/0xe5 __device_attach+0xdd/0x15b bus_probe_device+0x5a/0x10b device_add+0x501/0x894 ? _raw_write_unlock+0x27/0x3a platform_device_add+0x224/0x2b7 mfd_add_device+0x718/0x75b ? __kmalloc+0x144/0x16a ? mfd_add_devices+0x38/0xdb mfd_add_devices+0x9b/0xdb intel_lpss_probe+0x7d4/0x8ee intel_lpss_pci_probe+0xac/0xd4 pci_device_probe+0x101/0x18e
...
Revert the offending patch until a more comprehensive solution is available.
--- drivers/tty/serial/8250/8250_dw.c | 4 ---- 1 file changed, 4 deletions(-)
drivers/tty/serial/8250/8250_dw.c +0 -4
@@ -576,10 +576,6 @@ static int dw8250_probe(struct platform_device *pdev)if (!data->skip_autocfg)dw8250_setup_port (p); -#ifdef CONFIG_PM - uart.capabilities |=UART_CAP_RPM ; -#endif -/* If we have a valid fifosize, try hooking up DMA */ if (p->fifosize) { data->dma.rxconf.src_maxburst = p->fifosize /4 ;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 77/100 bonding: fix warning message
In reply to Sasha LevinFrom: Mahesh Bandewar <[email protected]>
[ Upstream commit 0f3b914c9cfcd7bbedd445dc4ac5dd999fa213c2 ]
RX queue config for bonding master could be different from its slave device(s). With the commit 6a9e461f6fe4 ("bonding: pass link-local packets to bonding master also."), the packet is reinjected into stack with skb->dev as bonding master. This potentially triggers the message:
"bondX received packet on queue Y, but number of RX queues is Z"
whenever the queue that packet is received on is higher than the numrxqueues on bonding master (Y > Z).
--- drivers/net/bonding/bond_main.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/bonding/bond_main.c +1 -0
@@ -1194,6 +1194,7 @@ static rx_handler_result_t bond_handle_frame(struct sk_buff **pskb)if (nskb) { nskb->dev = bond->dev; + nskb->queue_mapping =0 ;netif_rx (nskb); }return RX_HANDLER_PASS ;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 78/100 net: qualcomm: rmnet: Skip processing loopback packets
In reply to Sasha LevinFrom: Sean Tranchetti <[email protected]>
[ Upstream commit a07f388e2cde2be74b263f85df6f672fea0305a1 ]
RMNET RX handler was processing invalid packets that were originally sent on the real device and were looped back via dev_loopback_xmit(). This was detected using syzkaller.
--- drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c +3 -0
@@ -189,6 +189,9 @@ rx_handler_result_t rmnet_rx_handler(struct sk_buff **pskb)if (!skb) goto done; +if (skb->pkt_type ==PACKET_LOOPBACK ) +return RX_HANDLER_PASS ; + dev = skb->dev; port =rmnet_get_port (dev);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 79/100 net: qualcomm: rmnet: Fix incorrect allocation flag in transmit
In reply to Sasha LevinFrom: Subash Abhinov Kasiviswanathan <[email protected]>
[ Upstream commit 6392ff3c8e4c23d0a09b0ae9f94feb3effed490b ]
The incoming skb needs to be reallocated in case the headroom is not sufficient to add the MAP header. This allocation needs to be atomic otherwise it results in the following splat
[32805.801456] BUG: sleeping function called from invalid context [32805.841141] Internal error: Oops - BUG: 0 [#1] PREEMPT SMP [32805.904773] task: ffffffd7c5f62280 task.stack: ffffff80464a8000 [32805.910851] pc : ___might_sleep+0x180/0x188 [32805.915143] lr : ___might_sleep+0x180/0x188 [32806.131520] Call trace: [32806.134041] ___might_sleep+0x180/0x188 [32806.137980] __might_sleep+0x50/0x84 [32806.141653] __kmalloc_track_caller+0x80/0x3bc [32806.146215] __kmalloc_reserve+0x3c/0x88 [32806.150241] pskb_expand_head+0x74/0x288 [32806.154269] rmnet_egress_handler+0xb0/0x1d8 [32806.162239] rmnet_vnd_start_xmit+0xc8/0x13c [32806.166627] dev_hard_start_xmit+0x148/0x280 [32806.181181] sch_direct_xmit+0xa4/0x198 [32806.185125] __qdisc_run+0x1f8/0x310 [32806.188803] net_tx_action+0x23c/0x26c [32806.192655] __do_softirq+0x220/0x408 [32806.196420] do_softirq+0x4c/0x70
--- drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c +1 -1
@@ -147,7 +147,7 @@ static int rmnet_map_egress_handler(struct sk_buff *skb, }if (skb_headroom (skb) < required_headroom) { -if (pskb_expand_head (skb, required_headroom,0 ,GFP_KERNEL )) +if (pskb_expand_head (skb, required_headroom,0 ,GFP_ATOMIC ))return -ENOMEM ; }
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 80/100 net: qualcomm: rmnet: Fix incorrect allocation flag in receive path
In reply to Sasha LevinFrom: Subash Abhinov Kasiviswanathan <[email protected]>
[ Upstream commit ec405641e2b73160e26ef17580d0cf28565d146c ]
The incoming skb needs to be reallocated in case the headroom is not sufficient to adjust the ethernet header. This allocation needs to be atomic otherwise it results in this splat
[<600601bb>] ___might_sleep+0x185/0x1a3 [<603f6314>] ? _raw_spin_unlock_irqrestore+0x0/0x27 [<60069bb0>] ? __wake_up_common_lock+0x95/0xd1 [<600602b0>] __might_sleep+0xd7/0xe2 [<60065598>] ? enqueue_task_fair+0x112/0x209 [<600eea13>] __kmalloc_track_caller+0x5d/0x124 [<600ee9b6>] ? __kmalloc_track_caller+0x0/0x124 [<602696d5>] __kmalloc_reserve.isra.34+0x30/0x7e [<603f629b>] ? _raw_spin_lock_irqsave+0x0/0x3d [<6026b744>] pskb_expand_head+0xbf/0x310 [<6025ca6a>] rmnet_rx_handler+0x7e/0x16b [<6025c9ec>] ? rmnet_rx_handler+0x0/0x16b [<6027ad0c>] __netif_receive_skb_core+0x301/0x96f [<60033c17>] ? set_signals+0x0/0x40 [<6027bbcb>] __netif_receive_skb+0x24/0x8e
--- drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c +1 -1
@@ -113,7 +113,7 @@ rmnet_map_ingress_handler(struct sk_buff *skb,struct sk_buff *skbn;if (skb->dev->type ==ARPHRD_ETHER ) { -if (pskb_expand_head (skb,ETH_HLEN ,0 ,GFP_KERNEL )) { +if (pskb_expand_head (skb,ETH_HLEN ,0 ,GFP_ATOMIC )) {kfree_skb (skb);return ; }
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 81/100 locking/ww_mutex: Fix runtime warning in the WW mutex selftest
In reply to Sasha LevinFrom: Guenter Roeck <[email protected]>
[ Upstream commit e4a02ed2aaf447fa849e3254bfdb3b9b01e1e520 ]
If CONFIG_WW_MUTEX_SELFTEST=y is enabled, booting an image in an arm64 virtual machine results in the following traceback if 8 CPUs are enabled:
DEBUG_LOCKS_WARN_ON(__owner_task(owner) != current)
WARNING: CPU: 2 PID: 537 at kernel/locking/mutex.c:1033 __mutex_unlock_slowpath+0x1a8/0x2e0 ... Call trace: __mutex_unlock_slowpath() ww_mutex_unlock() test_cycle_work() process_one_work() worker_thread() kthread() ret_from_fork()
If requesting b_mutex fails with -EDEADLK, the error variable is reassigned to the return value from calling ww_mutex_lock on a_mutex again. If this call fails, a_mutex is not locked. It is, however, unconditionally unlocked subsequently, causing the reported warning. Fix the problem by using two error variables.
With this change, the selftest still fails as follows:
cyclic deadlock not resolved, ret[7/8] = -35
However, the traceback is gone.
--- kernel/locking/test-ww_mutex.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
kernel/locking/test-ww_mutex.c +6 -4
@@ -260,7 +260,7 @@ static void test_cycle_work(struct work_struct *work) {struct test_cycle *cycle =container_of (work,typeof (*cycle), work);struct ww_acquire_ctx ctx; -int err; +int err, erra =0 ;ww_acquire_init (&ctx, &ww_class);ww_mutex_lock (&cycle->a_mutex, &ctx);
@@ -270,17 +270,19 @@ static void test_cycle_work(struct work_struct *work) err =ww_mutex_lock (cycle->b_mutex, &ctx);if (err == -EDEADLK ) { + err =0 ;ww_mutex_unlock (&cycle->a_mutex);ww_mutex_lock_slow (cycle->b_mutex, &ctx); - err =ww_mutex_lock (&cycle->a_mutex, &ctx); + erra =ww_mutex_lock (&cycle->a_mutex, &ctx); }if (!err)ww_mutex_unlock (cycle->b_mutex); -ww_mutex_unlock (&cycle->a_mutex); +if (!erra) +ww_mutex_unlock (&cycle->a_mutex);ww_acquire_fini (&ctx); - cycle->result = err; + cycle->result = err ?: erra; }static int __test_cycle (unsigned int nthreads)
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 82/100 drm/amd/display: Signal hw_done() after waiting for flip_done()
In reply to Sasha LevinFrom: Shirish S <[email protected]>
[ Upstream commit 987bf116445db5d63a5c2ed94c4479687d9c9973 ]
In amdgpu_dm_commit_tail(), wait until flip_done() is signaled before we signal hw_done().
[Why]
This is to temporarily address a paging error that occurs when a nonblocking commit contends with another commit, particularly in a mirrored display configuration where at least 2 CRTCs are updated. The error occurs in drm_atomic_helper_wait_for_flip_done(), when we attempt to access the contents of new_crtc_state->commit.
Here's the sequence for a mirrored 2 display setup (irrelevant steps left out for clarity):
**THREAD 1** | **THREAD 2**
|
Initialize atomic state for flip |
|
Queue worker |...
| Do work for flip
|
| Signal hw_done() on CRTC 1 | Signal hw_done() on CRTC 2 |
| Wait for flip_done() on CRTC 1
<---- **PREEMPTED BY THREAD 1**
Initialize atomic state for cursor |
update (1) |
|
Do cursor update work on both CRTCs |
|
Clear atomic state (2) |
**DONE** |
...
|
| Wait for flip_done() on CRTC 2
| *ERROR*
|The issue starts with (1). When the atomic state is initialized, the current CRTC states are duplicated to be the new_crtc_states, and referenced to be the old_crtc_states. (The new_crtc_states are to be filled with update data.)
Some things to note:
* Due to the mirrored configuration, the cursor updates on both CRTCs.
* At this point, the pflip IRQ has already been handled, and flip_done signaled on all CRTCs. The cursor commit can therefore continue.
* The old_crtc_states used by the cursor update are the **same states** as the new_crtc_states used by the flip worker.
At (2), the old_crtc_state is freed (*), and the cursor commit completes. We then context switch back to the flip worker, where we attempt to access the new_crtc_state->commit object. This is problematic, as this state has already been freed.
(*) Technically, 'state->crtcs[i].state' is freed, which was made to
reference old_crtc_state in drm_atomic_helper_swap_state()
[How]
By moving hw_done() after wait_for_flip_done(), we're guaranteed that the new_crtc_state (from the flip worker's perspective) still exists. This is because any other commit will be blocked, waiting for the hw_done() signal.
Note that both the i915 and imx drivers have this sequence flipped already, masking this problem.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +8 -2
@@ -4494,12 +4494,18 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) }spin_unlock_irqrestore (&adev->ddev->event_lock, flags); -/* Signal HW programming completion */ -drm_atomic_helper_commit_hw_done (state);if (wait_for_vblank)drm_atomic_helper_wait_for_flip_done (dev, state); +/* +* FIXME: +* Delay hw_done() until flip_done() is signaled. This is to block +* another commit from freeing the CRTC state while we're still +* waiting on flip_done. +*/ +drm_atomic_helper_commit_hw_done (state); +drm_atomic_helper_cleanup_planes (dev, state);/* Finally, drop a runtime PM reference for each newly disabled CRTC,
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 83/100 net/usb: cancel pending work when unbinding smsc75xx
In reply to Sasha LevinFrom: Yu Zhao <[email protected]>
[ Upstream commit f7b2a56e1f3dcbdb4cf09b2b63e859ffe0e09df8 ]
Cancel pending work before freeing smsc75xx private data structure during binding. This fixes the following crash in the driver:
BUG: unable to handle kernel NULL pointer dereference at 0000000000000050 IP: mutex_lock+0x2b/0x3f <snipped> Workqueue: events smsc75xx_deferred_multicast_write [smsc75xx] task: ffff8caa83e85700 task.stack: ffff948b80518000 RIP: 0010:mutex_lock+0x2b/0x3f <snipped> Call Trace: smsc75xx_deferred_multicast_write+0x40/0x1af [smsc75xx] process_one_work+0x18d/0x2fc worker_thread+0x1a2/0x269 ? pr_cont_work+0x58/0x58 kthread+0xfa/0x10a ? pr_cont_work+0x58/0x58 ? rcu_read_unlock_sched_notrace+0x48/0x48 ret_from_fork+0x22/0x40
--- drivers/net/usb/smsc75xx.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/usb/smsc75xx.c +1 -0
@@ -1520,6 +1520,7 @@ static void smsc75xx_unbind(struct usbnet *dev, struct usb_interface *intf) {struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0 ]);if (pdata) { +cancel_work_sync (&pdata->set_multicast);netif_dbg (dev, ifdown, dev->net,"free pdata\n" );kfree (pdata); pdata =NULL ;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 84/100 team: Forbid enslaving team device to itself
In reply to Sasha LevinFrom: Ido Schimmel <[email protected]>
[ Upstream commit 471b83bd8bbe4e89743683ef8ecb78f7029d8288 ]
team's ndo_add_slave() acquires 'team->lock' and later tries to open the newly enslaved device via dev_open(). This emits a 'NETDEV_UP' event that causes the VLAN driver to add VLAN 0 on the team device. team's ndo_vlan_rx_add_vid() will also try to acquire 'team->lock' and deadlock.
Fix this by checking early at the enslavement function that a team device is not being enslaved to itself.
A similar check was added to the bond driver in commit 09a89c219baf ("bonding: disallow enslaving a bond to itself").
WARNING: possible recursive locking detected
4.18.0-rc7+ #176 Not tainted
--------------------------------------------
syz-executor4/6391 is trying to acquire lock:
(____ptrval____) (&team->lock){+.+.}, at: team_vlan_rx_add_vid+0x3b/0x1e0 drivers/net/team/team.c:1868
but task is already holding lock:
(____ptrval____) (&team->lock){+.+.}, at: team_add_slave+0xdb/0x1c30 drivers/net/team/team.c:1947
other info that might help us debug this:
Possible unsafe locking scenario:
CPU0
---- lock(&team->lock);
lock(&team->lock);
*** DEADLOCK ***
May be due to missing lock nesting notation
2 locks held by syz-executor4/6391:
#0: (____ptrval____) (rtnl_mutex){+.+.}, at: rtnl_lock net/core/rtnetlink.c:77 [inline] #0: (____ptrval____) (rtnl_mutex){+.+.}, at: rtnetlink_rcv_msg+0x412/0xc30 net/core/rtnetlink.c:4662 #1: (____ptrval____) (&team->lock){+.+.}, at: team_add_slave+0xdb/0x1c30 drivers/net/team/team.c:1947
stack backtrace: CPU: 1 PID: 6391 Comm: syz-executor4 Not tainted 4.18.0-rc7+ #176 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Call Trace: __dump_stack lib/dump_stack.c:77 [inline] dump_stack+0x1c9/0x2b4 lib/dump_stack.c:113 print_deadlock_bug kernel/locking/lockdep.c:1765 [inline] check_deadlock kernel/locking/lockdep.c:1809 [inline] validate_chain kernel/locking/lockdep.c:2405 [inline] __lock_acquire.cold.64+0x1fb/0x486 kernel/locking/lockdep.c:3435 lock_acquire+0x1e4/0x540 kernel/locking/lockdep.c:3924 __mutex_lock_common kernel/locking/mutex.c:757 [inline] __mutex_lock+0x176/0x1820 kernel/locking/mutex.c:894 mutex_lock_nested+0x16/0x20 kernel/locking/mutex.c:909 team_vlan_rx_add_vid+0x3b/0x1e0 drivers/net/team/team.c:1868 vlan_add_rx_filter_info+0x14a/0x1d0 net/8021q/vlan_core.c:210 __vlan_vid_add net/8021q/vlan_core.c:278 [inline] vlan_vid_add+0x63e/0x9d0 net/8021q/vlan_core.c:308 vlan_device_event.cold.12+0x2a/0x2f net/8021q/vlan.c:381 notifier_call_chain+0x180/0x390 kernel/notifier.c:93 __raw_notifier_call_chain kernel/notifier.c:394 [inline] raw_notifier_call_chain+0x2d/0x40 kernel/notifier.c:401 call_netdevice_notifiers_info+0x3f/0x90 net/core/dev.c:1735 call_netdevice_notifiers net/core/dev.c:1753 [inline] dev_open+0x173/0x1b0 net/core/dev.c:1433 team_port_add drivers/net/team/team.c:1219 [inline] team_add_slave+0xa8b/0x1c30 drivers/net/team/team.c:1948 do_set_master+0x1c9/0x220 net/core/rtnetlink.c:2248 do_setlink+0xba4/0x3e10 net/core/rtnetlink.c:2382 rtnl_setlink+0x2a9/0x400 net/core/rtnetlink.c:2636 rtnetlink_rcv_msg+0x46e/0xc30 net/core/rtnetlink.c:4665 netlink_rcv_skb+0x172/0x440 net/netlink/af_netlink.c:2455 rtnetlink_rcv+0x1c/0x20 net/core/rtnetlink.c:4683 netlink_unicast_kernel net/netlink/af_netlink.c:1317 [inline] netlink_unicast+0x5a0/0x760 net/netlink/af_netlink.c:1343 netlink_sendmsg+0xa18/0xfd0 net/netlink/af_netlink.c:1908 sock_sendmsg_nosec net/socket.c:642 [inline] sock_sendmsg+0xd5/0x120 net/socket.c:652 ___sys_sendmsg+0x7fd/0x930 net/socket.c:2126 __sys_sendmsg+0x11d/0x290 net/socket.c:2164 __do_sys_sendmsg net/socket.c:2173 [inline] __se_sys_sendmsg net/socket.c:2171 [inline] __x64_sys_sendmsg+0x78/0xb0 net/socket.c:2171 do_syscall_64+0x1b9/0x820 arch/x86/entry/common.c:290 entry_SYSCALL_64_after_hwframe+0x49/0xbe RIP: 0033:0x456b29 Code: fd b4 fb ff c3 66 2e 0f 1f 84 00 00 00 00 00 66 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 0f 83 cb b4 fb ff c3 66 2e 0f 1f 84 00 00 00 00 RSP: 002b:00007f9706bf8c78 EFLAGS: 00000246 ORIG_RAX: 000000000000002e RAX: ffffffffffffffda RBX: 00007f9706bf96d4 RCX: 0000000000456b29 RDX: 0000000000000000 RSI: 0000000020000240 RDI: 0000000000000004 RBP: 00000000009300a0 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 00000000ffffffff R13: 00000000004d3548 R14: 00000000004c8227 R15: 0000000000000000
--- drivers/net/team/team.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/net/team/team.c +6 -0
@@ -1172,6 +1172,12 @@ static int team_port_add(struct team *team, struct net_device *port_dev,return -EBUSY ; } +if (dev == port_dev) { +NL_SET_ERR_MSG (extack,"Cannot enslave team device to itself" ); +netdev_err (dev,"Cannot enslave team device to itself\n" ); +return -EINVAL ; + } +if (port_dev->features &NETIF_F_VLAN_CHALLENGED &&vlan_uses_dev (dev)) {NL_SET_ERR_MSG (extack,"Device is VLAN challenged and team device has VLAN set up" );
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 85/100 bnxt_en: Fix VNIC reservations on the PF.
In reply to Sasha LevinFrom: Michael Chan <[email protected]>
[ Upstream commit dbe80d446c859873820eedfff4abc61c71f1927b ]
The enables bit for VNIC was set wrong when calling the HWRM_FUNC_CFG firmware call to reserve VNICs. This has the effect that the firmware will keep a large number of VNICs for the PF, and having very few for VFs. DPDK driver running on the VFs, which requires more VNICs, may not work properly as a result.
--- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/broadcom/bnxt/bnxt.c +1 -1
@@ -4650,7 +4650,7 @@ __bnxt_hwrm_reserve_pf_rings(struct bnxt *bp, struct hwrm_func_cfg_input *req, FUNC_CFG_REQ_ENABLES_NUM_STAT_CTXS :0 ; enables |= ring_grps ?FUNC_CFG_REQ_ENABLES_NUM_HW_RING_GRPS :0 ; - enables |= vnics ?FUNC_VF_CFG_REQ_ENABLES_NUM_VNICS :0 ; + enables |= vnics ?FUNC_CFG_REQ_ENABLES_NUM_VNICS :0 ; req->num_rx_rings =cpu_to_le16 (rx_rings); req->num_hw_ring_grps =cpu_to_le16 (ring_grps);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 86/100 bnxt_en: Fix enables field in HWRM_QUEUE_COS2BW_CFG request
In reply to Sasha LevinFrom: Vasundhara Volam <[email protected]>
[ Upstream commit 5db0e0969af6501ad45fe0494039d3b9c797822b ]
In HWRM_QUEUE_COS2BW_CFG request, enables field should have the bits set only for the queue ids which are having the valid parameters.
This causes firmware to return error when the TC to hardware CoS queue mapping is not 1:1 during DCBNL ETS setup.
--- drivers/net/ethernet/broadcom/bnxt/bnxt_dcb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/net/ethernet/broadcom/bnxt/bnxt_dcb.c +3 -3
@@ -98,13 +98,13 @@ static int bnxt_hwrm_queue_cos2bw_cfg(struct bnxt *bp, struct ieee_ets *ets,bnxt_hwrm_cmd_hdr_init (bp, &req,HWRM_QUEUE_COS2BW_CFG ,-1 ,-1 );for (i =0 ; i < max_tc; i++) { -u8 qidx; +u8 qidx = bp->tc_to_qidx[i]; req.enables |=cpu_to_le32 ( -QUEUE_COS2BW_CFG_REQ_ENABLES_COS_QUEUE_ID0_VALID << i); +QUEUE_COS2BW_CFG_REQ_ENABLES_COS_QUEUE_ID0_VALID << + qidx);memset (&cos2bw,0 ,sizeof (cos2bw)); - qidx = bp->tc_to_qidx[i]; cos2bw.queue_id = bp->q_info[qidx].queue_id;if (ets->tc_tsa[i] ==IEEE_8021QAZ_TSA_STRICT ) { cos2bw.tsa =
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 87/100 bnxt_en: get the reduced max_irqs by the ones used by RDMA
In reply to Sasha LevinFrom: Vasundhara Volam <[email protected]>
[ Upstream commit c78fe058879bdea919d44f23e21da26f603e9166 ]
When getting the max rings supported, get the reduced max_irqs by the ones used by RDMA.
If the number MSIX is the limiting factor, this bug may cause the max ring count to be higher than it should be when RDMA driver is loaded and may result in ring allocation failures.
--- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/broadcom/bnxt/bnxt.c +1 -1
@@ -8500,7 +8500,7 @@ static void _bnxt_get_max_rings(struct bnxt *bp, int *max_rx, int *max_tx, *max_tx = hw_resc->max_tx_rings; *max_rx = hw_resc->max_rx_rings; *max_cp =min_t (int,bnxt_get_max_func_cp_rings_for_en (bp), - hw_resc->max_irqs); + hw_resc->max_irqs -bnxt_get_ulp_msix_num (bp)); *max_cp =min_t (int, *max_cp, hw_resc->max_stat_ctxs); max_ring_grps = hw_resc->max_hw_ring_grps;if (BNXT_CHIP_TYPE_NITRO_A0 (bp) &&BNXT_PF (bp)) {
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 88/100 net: dsa: b53: Keep CPU port as tagged in all VLANs
In reply to Sasha LevinFrom: Florian Fainelli <[email protected]>
[ Upstream commit ca8931948344c485569b04821d1f6bcebccd376b ]
Commit c499696e7901 ("net: dsa: b53: Stop using dev->cpu_port incorrectly") was a bit too trigger happy in removing the CPU port from the VLAN membership because we rely on DSA to program the CPU port VLAN, which it does, except it does not bother itself with tagged/untagged and just usese untagged.
Having the CPU port "follow" the user ports tagged/untagged is not great and does not allow for properly differentiating, so keep the CPU port tagged in all VLANs.
--- drivers/net/dsa/b53/b53_common.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/dsa/b53/b53_common.c +2 -2
@@ -1107,7 +1107,7 @@ void b53_vlan_add(struct dsa_switch *ds, int port,b53_get_vlan_entry (dev, vid, vl); vl->members |=BIT (port); -if (untagged) +if (untagged && !dsa_is_cpu_port (ds, port)) vl->untag |=BIT (port);else vl->untag &= ~BIT (port);
@@ -1149,7 +1149,7 @@ int b53_vlan_del(struct dsa_switch *ds, int port, pvid =0 ; } -if (untagged) +if (untagged && !dsa_is_cpu_port (ds, port)) vl->untag &= ~(BIT (port));b53_set_vlan_entry (dev, vid, vl);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 89/100 be2net: don't flip hw_features when VXLANs are added/deleted
In reply to Sasha LevinFrom: Davide Caratti <[email protected]>
[ Upstream commit 2d52527e80c2dc0c5f43f50adf183781262ec565 ]
the be2net implementation of .ndo_tunnel_{add,del}() changes the value of NETIF_F_GSO_UDP_TUNNEL bit in 'features' and 'hw_features', but it forgets to call netdev_features_change(). Moreover, ethtool setting for that bit can potentially be reverted after a tunnel is added or removed.
GSO already does software segmentation when 'hw_enc_features' is 0, even if VXLAN offload is turned on. In addition, commit 096de2f83ebc ("benet:
stricter vxlan offloading check in be_features_check") avoids hardware segmentation of non-VXLAN tunneled packets, or VXLAN packets having wrong destination port. So, it's safe to avoid flipping the above feature on addition/deletion of VXLAN tunnels.
--- drivers/net/ethernet/emulex/benet/be_main.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
drivers/net/ethernet/emulex/benet/be_main.c +1 -4
@@ -3915,8 +3915,6 @@ static int be_enable_vxlan_offloads(struct be_adapter *adapter) netdev->hw_enc_features |=NETIF_F_IP_CSUM |NETIF_F_IPV6_CSUM |NETIF_F_TSO |NETIF_F_TSO6 |NETIF_F_GSO_UDP_TUNNEL ; - netdev->hw_features |=NETIF_F_GSO_UDP_TUNNEL ; - netdev->features |=NETIF_F_GSO_UDP_TUNNEL ;dev_info (dev,"Enabled VxLAN offloads for UDP port %d\n" ,be16_to_cpu (port));
@@ -3938,8 +3936,6 @@ static void be_disable_vxlan_offloads(struct be_adapter *adapter) adapter->vxlan_port =0 ; netdev->hw_enc_features =0 ; - netdev->hw_features &= ~(NETIF_F_GSO_UDP_TUNNEL ); - netdev->features &= ~(NETIF_F_GSO_UDP_TUNNEL ); } static void be_calculate_vf_res(struct be_adapter *adapter, u16 num_vfs,
@@ -5232,6 +5228,7 @@ static void be_netdev_init(struct net_device *netdev)struct be_adapter *adapter =netdev_priv (netdev); netdev->hw_features |=NETIF_F_SG |NETIF_F_TSO |NETIF_F_TSO6 | +NETIF_F_GSO_UDP_TUNNEL |NETIF_F_IP_CSUM |NETIF_F_IPV6_CSUM |NETIF_F_RXCSUM |NETIF_F_HW_VLAN_CTAG_TX ;if ((be_if_cap_flags (adapter) &BE_IF_FLAGS_RSS ))
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 90/100 net: phy: phylink: fix SFP interface autodetection
In reply to Sasha LevinFrom: Baruch Siach <[email protected]>
[ Upstream commit 7e4183752735deb7543e179a44f4f4b44917cd6f ]
When connecting SFP PHY to phylink use the detected interface. Otherwise, the link fails to come up when the configured 'phy-mode' differs from the SFP detected mode.
Move most of phylink_connect_phy() into __phylink_connect_phy(), and leave phylink_connect_phy() as a wrapper. phylink_sfp_connect_phy() can now pass the SFP detected PHY interface to __phylink_connect_phy().
This fixes 1GB SFP module link up on eth3 of the Macchiatobin board that is configured in the DT to "2500base-x" phy-mode.
--- drivers/net/phy/phylink.c | 48 +++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 20 deletions(-)
drivers/net/phy/phylink.c +28 -20
@@ -717,6 +717,30 @@ static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy)return 0 ; } +static int __phylink_connect_phy (struct phylink *pl,struct phy_device *phy, +phy_interface_t interface) +{ +int ret; + +if (WARN_ON (pl->link_an_mode ==MLO_AN_FIXED || + (pl->link_an_mode ==MLO_AN_INBAND && +phy_interface_mode_is_8023z (interface)))) +return -EINVAL ; + +if (pl->phydev) +return -EBUSY ; + + ret =phy_attach_direct (pl->netdev, phy,0 , interface); +if (ret) +return ret; + + ret =phylink_bringup_phy (pl, phy); +if (ret) +phy_detach (phy); + +return ret; +} +/** * phylink_connect_phy() - connect a PHY to the phylink instance * @pl: a pointer to a &struct phylink returned from phylink_create()
@@ -734,31 +758,13 @@ static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy)*/ int phylink_connect_phy (struct phylink *pl,struct phy_device *phy) { -int ret; - -if (WARN_ON (pl->link_an_mode ==MLO_AN_FIXED || - (pl->link_an_mode ==MLO_AN_INBAND && -phy_interface_mode_is_8023z (pl->link_interface)))) -return -EINVAL ; - -if (pl->phydev) -return -EBUSY ; -/* Use PHY device/driver interface */ if (pl->link_interface ==PHY_INTERFACE_MODE_NA ) { pl->link_interface = phy->interface; pl->link_config.interface = pl->link_interface; } - ret =phy_attach_direct (pl->netdev, phy,0 , pl->link_interface); -if (ret) -return ret; - - ret =phylink_bringup_phy (pl, phy); -if (ret) -phy_detach (phy); - -return ret; +return __phylink_connect_phy (pl, phy, pl->link_interface); }EXPORT_SYMBOL_GPL (phylink_connect_phy);
@@ -1672,7 +1678,9 @@ static void phylink_sfp_link_up(void *upstream)static int phylink_sfp_connect_phy (void *upstream,struct phy_device *phy) { -return phylink_connect_phy (upstream, phy); +struct phylink *pl = upstream; + +return __phylink_connect_phy (upstream, phy, pl->link_config.interface); }static void phylink_sfp_disconnect_phy (void *upstream)
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 91/100 powerpc/numa: Skip onlining a offline node in kdump path
In reply to Sasha LevinFrom: Srikar Dronamraju <[email protected]>
[ Upstream commit ac1788cc7da4ce54edcfd2e499afdb0a23d5c41d ]
With commit 2ea626306810 ("powerpc/topology: Get topology for shared processors at boot"), kdump kernel on shared LPAR may crash.
The necessary conditions are
- Shared LPAR with at least 2 nodes having memory and CPUs.
- Memory requirement for kdump kernel must be met by the first N-1 nodes where there are at least N nodes with memory and CPUs.
Example numactl of such a machine.
$ numactl -H
available: 5 nodes (0,2,5-7)
node 0 cpus:
node 0 size: 0 MB
node 0 free: 0 MB
node 2 cpus:
node 2 size: 255 MB
node 2 free: 189 MB
node 5 cpus: 24 25 26 27 28 29 30 31
node 5 size: 4095 MB
node 5 free: 4024 MB
node 6 cpus: 0 1 2 3 4 5 6 7 16 17 18 19 20 21 22 23
node 6 size: 6353 MB
node 6 free: 5998 MB
node 7 cpus: 8 9 10 11 12 13 14 15 32 33 34 35 36 37 38 39
node 7 size: 7640 MB
node 7 free: 7164 MB
node distances:
node 0 2 5 6 7
0: 10 40 40 40 40
2: 40 10 40 40 40
5: 40 40 10 40 40
6: 40 40 40 10 20
7: 40 40 40 20 10Steps to reproduce.
1. Load / start kdump service.
2. Trigger a kdump (for example : echo c > /proc/sysrq-trigger)
When booting a kdump kernel with 2048M:
kexec: Starting switchover sequence.
I'm in purgatory
Using 1TB segments
hash-mmu: Initializing hash mmu with SLB
Linux version 4.19.0-rc5-master+ (srikar@linux-xxu6) (gcc version 4.8.5 (SUSE Linux)) #1 SMP Thu Sep 27 19:45:00 IST 2018 Found initrd at 0xc000000009e70000:0xc00000000ae554b4
Using pSeries machine description
-----------------------------------------------------
ppc64_pft_size = 0x1e
phys_mem_size = 0x88000000
dcache_bsize = 0x80
icache_bsize = 0x80
cpu_features = 0x000000ff8f5d91a7
possible = 0x0000fbffcf5fb1a7
always = 0x0000006f8b5c91a1
cpu_user_features = 0xdc0065c2 0xef000000
mmu_features = 0x7c006001
firmware_features = 0x00000007c45bfc57
htab_hash_mask = 0x7fffff
physical_start = 0x8000000
-----------------------------------------------------
numa: NODE_DATA [mem 0x87d5e300-0x87d67fff]
numa: NODE_DATA(0) on node 6
numa: NODE_DATA [mem 0x87d54600-0x87d5e2ff]
Top of RAM: 0x88000000, Total RAM: 0x88000000
Memory hole size: 0MB
Zone ranges:
DMA [mem 0x0000000000000000-0x0000000087ffffff]
DMA32 empty
Normal empty
Movable zone start for each node
Early memory node ranges
node 6: [mem 0x0000000000000000-0x0000000087ffffff] Could not find start_pfn for node 0
Initmem setup node 0 [mem 0x0000000000000000-0x0000000000000000] On node 0 totalpages: 0
Initmem setup node 6 [mem 0x0000000000000000-0x0000000087ffffff] On node 6 totalpages: 34816
Unable to handle kernel paging request for data at address 0x00000060 Faulting instruction address: 0xc000000008703a54 Oops: Kernel access of bad area, sig: 11 [#1] LE SMP NR_CPUS=2048 NUMA pSeries Modules linked in: CPU: 11 PID: 1 Comm: swapper/11 Not tainted 4.19.0-rc5-master+ #1 NIP: c000000008703a54 LR: c000000008703a38 CTR: 0000000000000000 REGS: c00000000b673440 TRAP: 0380 Not tainted (4.19.0-rc5-master+) MSR: 8000000002009033 <SF,VEC,EE,ME,IR,DR,RI,LE> CR: 24022022 XER: 20000002 CFAR: c0000000086fc238 IRQMASK: 0 GPR00: c000000008703a38 c00000000b6736c0 c000000009281900 0000000000000000 GPR04: 0000000000000000 0000000000000000 fffffffffffff001 c00000000b660080 GPR08: 0000000000000000 0000000000000000 0000000000000000 0000000000000220 GPR12: 0000000000002200 c000000009e51400 0000000000000000 0000000000000008 GPR16: 0000000000000000 c000000008c152e8 c000000008c152a8 0000000000000000 GPR20: c000000009422fd8 c000000009412fd8 c000000009426040 0000000000000008 GPR24: 0000000000000000 0000000000000000 c000000009168bc8 c000000009168c78 GPR28: c00000000b126410 0000000000000000 c00000000916a0b8 c00000000b126400 NIP [c000000008703a54] bus_add_device+0x84/0x1e0 LR [c000000008703a38] bus_add_device+0x68/0x1e0 Call Trace: [c00000000b6736c0] [c000000008703a38] bus_add_device+0x68/0x1e0 (unreliable) [c00000000b673740] [c000000008700194] device_add+0x454/0x7c0 [c00000000b673800] [c00000000872e660] __register_one_node+0xb0/0x240 [c00000000b673860] [c00000000839a6bc] __try_online_node+0x12c/0x180 [c00000000b673900] [c00000000839b978] try_online_node+0x58/0x90 [c00000000b673930] [c0000000080846d8] find_and_online_cpu_nid+0x158/0x190 [c00000000b673a10] [c0000000080848a0] numa_update_cpu_topology+0x190/0x580 [c00000000b673c00] [c000000008d3f2e4] smp_cpus_done+0x94/0x108 [c00000000b673c70] [c000000008d5c00c] smp_init+0x174/0x19c [c00000000b673d00] [c000000008d346b8] kernel_init_freeable+0x1e0/0x450 [c00000000b673dc0] [c0000000080102e8] kernel_init+0x28/0x160 [c00000000b673e30] [c00000000800b65c] ret_from_kernel_thread+0x5c/0x80 Instruction dump: 60000000 60000000 e89e0020 7fe3fb78 4bff87d5 60000000 7c7d1b79 4082008c e8bf0050 e93e0098 3b9f0010 2fa50000 <e8690060> 38630018 419e0114 7f84e378 ---[ end trace 593577668c2daa65 ]---
However a regular kernel with 4096M (2048 gets reserved for crash kernel) boots properly.
Unlike regular kernels, which mark all available nodes as online, kdump kernel only marks just enough nodes as online and marks the rest as offline at boot. However kdump kernel boots with all available CPUs. With Commit 2ea626306810 ("powerpc/topology: Get topology for shared processors at boot"), all CPUs are onlined on their respective nodes at boot time. try_online_node() tries to online the offline nodes but fails as all needed subsystems are not yet initialized.
As part of fix, detect and skip early onlining of a offline node.
--- arch/powerpc/mm/numa.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
arch/powerpc/mm/numa.c +3 -2
@@ -1215,9 +1215,10 @@ int find_and_online_cpu_nid(int cpu)* Need to ensure that NODE_DATA is initialized for a node from * available memory (see memblock_alloc_try_nid). If unable to * init the node, then default to nearest node that has memory -* installed. +* installed. Skip onlining a node if the subsystems are not +* yet initialized. */ -if (try_online_node (new_nid)) +if (!topology_inited ||try_online_node (new_nid)) new_nid = first_online_node;#else /*
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 92/100 net: cxgb3_main: fix a missing-check bug
In reply to Sasha LevinFrom: Wenwen Wang <[email protected]>
[ Upstream commit 2c05d88818ab6571816b93edce4d53703870d7ae ]
In cxgb_extension_ioctl(), the command of the ioctl is firstly copied from the user-space buffer 'useraddr' to 'cmd' and checked through the switch statement. If the command is not as expected, an error code EOPNOTSUPP is returned. In the following execution, i.e., the cases of the switch statement, the whole buffer of 'useraddr' is copied again to a specific data structure, according to what kind of command is requested. However, after the second copy, there is no re-check on the newly-copied command. Given that the buffer 'useraddr' is in the user space, a malicious user can race to change the command between the two copies. By doing so, the attacker can supply malicious data to the kernel and cause undefined behavior.
This patch adds a re-check in each case of the switch statement if there is a second copy in that case, to re-check whether the command obtained in the second copy is the same as the one in the first copy. If not, an error code EINVAL is returned.
--- drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c +17 -0
@@ -2159,6 +2159,8 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr)return -EPERM ;if (copy_from_user (&t, useraddr,sizeof (t)))return -EFAULT ; +if (t.cmd !=CHELSIO_SET_QSET_PARAMS ) +return -EINVAL ;if (t.qset_idx >=SGE_QSETS )return -EINVAL ; if (!in_range(t.intr_lat, 0, M_NEWTIMER) ||
@@ -2258,6 +2260,9 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr)if (copy_from_user (&t, useraddr,sizeof (t)))return -EFAULT ; +if (t.cmd !=CHELSIO_GET_QSET_PARAMS ) +return -EINVAL ; +/* Display qsets for all ports when offload enabled */ if (test_bit (OFFLOAD_DEVMAP_BIT , &adapter->open_device_map)) { q1 =0 ;
@@ -2303,6 +2308,8 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr)return -EBUSY ;if (copy_from_user (&edata, useraddr,sizeof (edata)))return -EFAULT ; +if (edata.cmd !=CHELSIO_SET_QSET_NUM ) +return -EINVAL ;if (edata.val <1 || (edata.val >1 && !(adapter->flags &USING_MSIX )))return -EINVAL ;
@@ -2343,6 +2350,8 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr)return -EPERM ;if (copy_from_user (&t, useraddr,sizeof (t)))return -EFAULT ; +if (t.cmd !=CHELSIO_LOAD_FW ) +return -EINVAL ;/* Check t.len sanity ? */ fw_data =memdup_user (useraddr +sizeof (t), t.len);if (IS_ERR (fw_data))
@@ -2366,6 +2375,8 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr)return -EBUSY ;if (copy_from_user (&m, useraddr,sizeof (m)))return -EFAULT ; +if (m.cmd !=CHELSIO_SETMTUTAB ) +return -EINVAL ;if (m.nmtus !=NMTUS )return -EINVAL ;if (m.mtus[0 ] <81 )/* accommodate SACK */
@@ -2407,6 +2418,8 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr)return -EBUSY ;if (copy_from_user (&m, useraddr,sizeof (m)))return -EFAULT ; +if (m.cmd !=CHELSIO_SET_PM ) +return -EINVAL ;if (!is_power_of_2 (m.rx_pg_sz) || !is_power_of_2 (m.tx_pg_sz))return -EINVAL ;/* not power of 2 */
@@ -2440,6 +2453,8 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr)return -EIO ;/* need the memory controllers */ if (copy_from_user (&t, useraddr,sizeof (t)))return -EFAULT ; +if (t.cmd !=CHELSIO_GET_MEM ) +return -EINVAL ;if ((t.addr &7 ) || (t.len &7 ))return -EINVAL ;if (t.mem_id ==MEM_CM )
@@ -2492,6 +2507,8 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr)return -EAGAIN ;if (copy_from_user (&t, useraddr,sizeof (t)))return -EFAULT ; +if (t.cmd !=CHELSIO_SET_TRACE_FILTER ) +return -EINVAL ; tp = (const struct trace_params *)&t.sip;if (t.config_tx)
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 93/100 yam: fix a missing-check bug
In reply to Sasha LevinFrom: Wenwen Wang <[email protected]>
[ Upstream commit 0781168e23a2fc8dceb989f11fc5b39b3ccacc35 ]
In yam_ioctl(), the concrete ioctl command is firstly copied from the user-space buffer 'ifr->ifr_data' to 'ioctl_cmd' and checked through the following switch statement. If the command is not as expected, an error code EINVAL is returned. In the following execution the buffer 'ifr->ifr_data' is copied again in the cases of the switch statement to specific data structures according to what kind of ioctl command is requested. However, after the second copy, no re-check is enforced on the newly-copied command. Given that the buffer 'ifr->ifr_data' is in the user space, a malicious user can race to change the command between the two copies. This way, the attacker can inject inconsistent data and cause undefined behavior.
This patch adds a re-check in each case of the switch statement if there is a second copy in that case, to re-check whether the command obtained in the second copy is the same as the one in the first copy. If not, an error code EINVAL will be returned.
--- drivers/net/hamradio/yam.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/net/hamradio/yam.c +4 -0
@@ -966,6 +966,8 @@ static int yam_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) sizeof(struct yamdrv_ioctl_mcs));if (IS_ERR (ym))return PTR_ERR (ym); +if (ym->cmd !=SIOCYAMSMCS ) +return -EINVAL ;if (ym->bitrate >YAM_MAXBITRATE ) {kfree (ym);return -EINVAL ;
@@ -981,6 +983,8 @@ static int yam_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)if (copy_from_user (&yi, ifr->ifr_data,sizeof (struct yamdrv_ioctl_cfg )))return -EFAULT ; +if (yi.cmd !=SIOCYAMSCFG ) +return -EINVAL ;if ((yi.cfg.mask &YAM_IOBASE ) &&netif_running (dev))return -EINVAL ;/* Cannot change this parameter when up */ if ((yi.cfg.mask &YAM_IRQ ) &&netif_running (dev))
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 94/100 net: mvpp2: Extract the correct ethtype from the skb for tx csum offload
In reply to Sasha LevinFrom: Maxime Chevallier <[email protected]>
[ Upstream commit 35f3625c21852ad839f20c91c7d81c4c1101e207 ]
When offloading the L3 and L4 csum computation on TX, we need to extract the l3_proto from the ethtype, independently of the presence of a vlan tag.
The actual driver uses skb->protocol as-is, resulting in packets with the wrong L4 checksum being sent when there's a vlan tag in the packet header and checksum offloading is enabled.
This commit makes use of vlan_protocol_get() to get the correct ethtype regardless the presence of a vlan tag.
--- drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +5 -4
@@ -1725,7 +1725,7 @@ static void mvpp2_txq_desc_put(struct mvpp2_tx_queue *txq) }/* Set Tx descriptors fields relevant for CSUM calculation */ -static u32 mvpp2_txq_desc_csum (int l3_offs,int l3_proto, +static u32 mvpp2_txq_desc_csum (int l3_offs,__be16 l3_proto,int ip_hdr_len,int l4_proto) {u32 command;
@@ -2600,14 +2600,15 @@ static u32 mvpp2_skb_tx_csum(struct mvpp2_port *port, struct sk_buff *skb)if (skb->ip_summed ==CHECKSUM_PARTIAL ) {int ip_hdr_len =0 ;u8 l4_proto; +__be16 l3_proto =vlan_get_protocol (skb); -if (skb->protocol ==htons (ETH_P_IP )) { +if (l3_proto ==htons (ETH_P_IP )) {struct iphdr *ip4h =ip_hdr (skb);/* Calculate IPv4 checksum and L4 checksum */ ip_hdr_len = ip4h->ihl; l4_proto = ip4h->protocol; - }else if (skb->protocol ==htons (ETH_P_IPV6 )) { + }else if (l3_proto ==htons (ETH_P_IPV6 )) {struct ipv6hdr *ip6h =ipv6_hdr (skb);/* Read l4_protocol from one of IPv6 extra headers */
@@ -2619,7 +2620,7 @@ static u32 mvpp2_skb_tx_csum(struct mvpp2_port *port, struct sk_buff *skb) }return mvpp2_txq_desc_csum (skb_network_offset (skb), - skb->protocol, ip_hdr_len, l4_proto); + l3_proto, ip_hdr_len, l4_proto); }return MVPP2_TXD_L4_CSUM_NOT |MVPP2_TXD_IP_CSUM_DISABLE ;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 95/100 ocfs2: fix crash in ocfs2_duplicate_clusters_by_page()
In reply to Sasha LevinFrom: Larry Chen <[email protected]>
[ Upstream commit 69eb7765b9c6902444c89c54e7043242faf981e5 ]
ocfs2_duplicate_clusters_by_page() may crash if one of the extent's pages is dirty. When a page has not been written back, it is still in dirty state. If ocfs2_duplicate_clusters_by_page() is called against the dirty page, the crash happens.
To fix this bug, we can just unlock the page and wait until the page until its not dirty.
The following is the backtrace:
kernel BUG at /root/code/ocfs2/refcounttree.c:2961! [exception RIP: ocfs2_duplicate_clusters_by_page+822]
__ocfs2_move_extent+0x80/0x450 [ocfs2] ? __ocfs2_claim_clusters+0x130/0x250 [ocfs2] ocfs2_defrag_extent+0x5b8/0x5e0 [ocfs2] __ocfs2_move_extents_range+0x2a4/0x470 [ocfs2] ocfs2_move_extents+0x180/0x3b0 [ocfs2] ? ocfs2_wait_for_recovery+0x13/0x70 [ocfs2] ocfs2_ioctl_move_extents+0x133/0x2d0 [ocfs2] ocfs2_ioctl+0x253/0x640 [ocfs2] do_vfs_ioctl+0x90/0x5f0 SyS_ioctl+0x74/0x80 do_syscall_64+0x74/0x140 entry_SYSCALL_64_after_hwframe+0x3d/0xa2
Once we find the page is dirty, we do not wait until it's clean, rather we use write_one_page() to write it back
--- fs/ocfs2/refcounttree.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-)
fs/ocfs2/refcounttree.c +12 -4
@@ -2946,6 +2946,7 @@ int ocfs2_duplicate_clusters_by_page(handle_t *handle,if (map_end & (PAGE_SIZE -1 )) to = map_end & (PAGE_SIZE -1 ); +retry: page =find_or_create_page (mapping, page_index,GFP_NOFS );if (!page) { ret = -ENOMEM ;
@@ -2954,11 +2955,18 @@ int ocfs2_duplicate_clusters_by_page(handle_t *handle, }/* -* In case PAGE_SIZE <= CLUSTER_SIZE, This page -* can't be dirtied before we CoW it out. +* In case PAGE_SIZE <= CLUSTER_SIZE, we do not expect a dirty +* page, so write it back. */ -if (PAGE_SIZE <=OCFS2_SB (sb)->s_clustersize) -BUG_ON (PageDirty (page)); +if (PAGE_SIZE <=OCFS2_SB (sb)->s_clustersize) { +if (PageDirty (page)) { +/* +* write_on_page will unlock the page on return +*/ + ret =write_one_page (page); + goto retry; + } + }if (!PageUptodate (page)) { ret =block_read_full_page (page, ocfs2_get_block);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 96/100 mm/gup_benchmark: fix unsigned comparison to zero in __gup_benchmark_ioctl
In reply to Sasha LevinFrom: YueHaibing <[email protected]>
[ Upstream commit 51896864579d5a3349740847083f4db5c6487164 ]
get_user_pages_fast() will return negative value if no pages were pinned, then be converted to a unsigned, which is compared to zero, giving the wrong result.
--- mm/gup_benchmark.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
mm/gup_benchmark.c +2 -1
@@ -19,7 +19,8 @@ static int __gup_benchmark_ioctl(unsigned int cmd, struct gup_benchmark *gup) {ktime_t start_time, end_time; -unsigned long i, nr, nr_pages, addr, next; +unsigned long i, nr_pages, addr, next; +int nr;struct page **pages; nr_pages = gup->size /PAGE_SIZE ;
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 97/100 mm/migrate.c: split only transparent huge pages when allocation fails
In reply to Sasha LevinFrom: Anshuman Khandual <[email protected]>
[ Upstream commit e6112fc300702f96374f34368513d57795fc6d23 ]
split_huge_page_to_list() fails on HugeTLB pages. I was experimenting with moving 32MB contig HugeTLB pages on arm64 (with a debug patch applied) and hit the following stack trace when the kernel crashed.
[ 3732.462797] Call trace: [ 3732.462835] split_huge_page_to_list+0x3b0/0x858 [ 3732.462913] migrate_pages+0x728/0xc20 [ 3732.462999] soft_offline_page+0x448/0x8b0 [ 3732.463097] __arm64_sys_madvise+0x724/0x850 [ 3732.463197] el0_svc_handler+0x74/0x110 [ 3732.463297] el0_svc+0x8/0xc [ 3732.463347] Code: d1000400 f90b0e60 f2fbd5a2 a94982a1 (f9000420)
When unmap_and_move[_huge_page]() fails due to lack of memory, the splitting should happen only for transparent huge pages not for HugeTLB pages. PageTransHuge() returns true for both THP and HugeTLB pages. Hence the conditonal check should test PagesHuge() flag to make sure that given pages is not a HugeTLB one.
--- mm/migrate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
mm/migrate.c +1 -1
@@ -1415,7 +1415,7 @@ int migrate_pages(struct list_head *from, new_page_t get_new_page,* we encounter them after the rest of the list * is processed. */ -if (PageTransHuge (page)) { +if (PageTransHuge (page) && !PageHuge (page)) {lock_page (page); rc =split_huge_page_to_list (page, from);unlock_page (page);
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 98/100 mm/vmstat.c: fix outdated vmstat_text
In reply to Sasha LevinFrom: Jann Horn <[email protected]>
[ Upstream commit 28e2c4bb99aa40f9d5f07ac130cbc4da0ea93079 ]
7a9cdebdcc17 ("mm: get rid of vmacache_flush_all() entirely") removed the VMACACHE_FULL_FLUSHES statistics, but didn't remove the corresponding entry in vmstat_text. This causes an out-of-bounds access in vmstat_show().
Luckily this only affects kernels with CONFIG_DEBUG_VM_VMACACHE=y, which is probably very rare.
--- mm/vmstat.c | 1 - 1 file changed, 1 deletion(-)
mm/vmstat.c +0 -1
@@ -1286,7 +1286,6 @@ const char * const vmstat_text[] = {#ifdef CONFIG_DEBUG_VM_VMACACHE "vmacache_find_calls" ,"vmacache_find_hits" , -"vmacache_full_flushes" , #endif #ifdef CONFIG_SWAP "swap_ra",
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 99/100 x86/paravirt: Fix some warning messages
In reply to Sasha LevinFrom: Dan Carpenter <[email protected]>
[ Upstream commit 571d0563c8881595f4ab027aef9ed1c55e3e7b7c ]
The first argument to WARN_ONCE() is a condition.
--- arch/x86/kernel/paravirt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/x86/kernel/paravirt.c +2 -2
@@ -90,7 +90,7 @@ unsigned paravirt_patch_call(void *insnbuf,if (len <5 ) {#ifdef CONFIG_RETPOLINE -WARN_ONCE ("Failing to patch indirect CALL in %ps\n" , (void *)addr); +WARN_ONCE (1 ,"Failing to patch indirect CALL in %ps\n" , (void *)addr);#endif return len;/* call too long for patch site */ }
@@ -110,7 +110,7 @@ unsigned paravirt_patch_jmp(void *insnbuf, const void *target,if (len <5 ) {#ifdef CONFIG_RETPOLINE -WARN_ONCE ("Failing to patch indirect JMP in %ps\n" , (void *)addr); +WARN_ONCE (1 ,"Failing to patch indirect JMP in %ps\n" , (void *)addr);#endif return len;/* call too long for patch site */ }
Signature · 1 line
2.17.1
Sasha Levin
maintainerPATCH 100/100 clk: mvebu: armada-37xx-periph: Remove unused var num_parents
In reply to Sasha LevinFrom: Anders Roxell <[email protected]>
[ Upstream commit 8927c27b32703e28041ae19bf25ea53461be83a1 ]
When building armada-37xx-periph, num_parents isn't used in function clk_pm_cpu_get_parent:drivers/clk/mvebu/armada-37xx-periph.c: In function ‘clk_pm_cpu_get_parent’:drivers/clk/mvebu/armada-37xx-periph.c:419:6: warning: unused variable ‘num_parents’ [-Wunused-variable]
int num_parents = clk_hw_get_num_parents(hw);
^~~~~~~~~~~Remove the declaration of num_parents to dispose the warning.
--- drivers/clk/mvebu/armada-37xx-periph.c | 1 - 1 file changed, 1 deletion(-)
drivers/clk/mvebu/armada-37xx-periph.c +0 -1
@@ -419,7 +419,6 @@ static unsigned int armada_3700_pm_dvfs_get_cpu_parent(struct regmap *base)static u8 clk_pm_cpu_get_parent (struct clk_hw *hw) {struct clk_pm_cpu *pm_cpu =to_clk_pm_cpu (hw); -int num_parents =clk_hw_get_num_parents (hw);u32 val;if (armada_3700_pm_dvfs_is_enabled (pm_cpu->nb_pm_base)) {
Signature · 1 line
2.17.1