5.9.9-rc1 review
Subsystems (9)
Greg Kroah-Hartman
maintainerPATCH 155/255 igc: Fix returning wrong statistics
In reply to Greg Kroah-HartmanFrom: Vinicius Costa Gomes <[email protected]>
[ Upstream commit 6b7ed22ae4c96a415001f0c3116ebee15bb8491a ]
'igc_update_stats()' was not updating 'netdev->stats', so the returned statistics, for example, requested by:
$ ip -s link show dev enp3s0
were not being updated and were always zero.
Fix by returning a set of statistics that are actually being updated (adapter->stats64).
--- drivers/net/ethernet/intel/igc/igc_main.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
drivers/net/ethernet/intel/igc/igc_main.c +8 -6
@@ -3890,21 +3890,23 @@ static int igc_change_mtu(struct net_device *netdev, int new_mtu) }/** -* igc_get_stats - Get System Network Statistics +* igc_get_stats64 - Get System Network Statistics * @netdev: network interface device structure +* @stats: rtnl_link_stats64 pointer * * Returns the address of the device statistics structure. * The statistics are updated here and also from the timer callback. */ -static struct net_device_stats *igc_get_stats (struct net_device *netdev) +static void igc_get_stats64 (struct net_device *netdev, +struct rtnl_link_stats64 *stats) {struct igc_adapter *adapter =netdev_priv (netdev); +spin_lock (&adapter->stats64_lock);if (!test_bit (__IGC_RESETTING, &adapter->state))igc_update_stats (adapter); - -/* only return the current stats */ -return &netdev->stats; +memcpy (stats, &adapter->stats64,sizeof (*stats)); +spin_unlock (&adapter->stats64_lock); } static netdev_features_t igc_fix_features(struct net_device *netdev,
@@ -4833,7 +4835,7 @@ static const struct net_device_ops igc_netdev_ops = { .ndo_set_rx_mode = igc_set_rx_mode, .ndo_set_mac_address = igc_set_mac, .ndo_change_mtu = igc_change_mtu, - .ndo_get_stats = igc_get_stats, + .ndo_get_stats64 = igc_get_stats64, .ndo_fix_features = igc_fix_features, .ndo_set_features = igc_set_features, .ndo_features_check = igc_features_check,
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 156/255 lan743x: correctly handle chips with internal PHY
In reply to Greg Kroah-HartmanFrom: Sven Van Asbroeck <[email protected]>
[ Upstream commit 902a66e08ceaadb9a7a1ab3a4f3af611cd1d8cba ]
Commit 6f197fb63850 ("lan743x: Added fixed link and RGMII support") assumes that chips with an internal PHY will never have a devicetree entry. This is incorrect: even for these chips, a devicetree entry can be useful e.g. to pass the mac address from bootloader to chip:
&pcie {
status = "okay";
host@0 {
reg = <0 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
lan7430: ethernet@0 {
/* LAN7430 with internal PHY */
compatible = "microchip,lan743x";
status = "okay";
reg = <0 0 0 0 0>;
/* filled in by bootloader */
local-mac-address = [00 00 00 00 00 00];
};
};
};If a devicetree entry is present, the driver will not attach the chip to its internal phy, and the chip will be non-operational.
Fix by tweaking the phy connection algorithm:
- first try to connect to a phy specified in the devicetree (could be 'real' phy, or just a 'fixed-link')
- if that doesn't succeed, try to connect to an internal phy, even if the chip has a devnode
Tested on a LAN7430 with internal PHY. I cannot test a device using fixed-link, as I do not have access to one.
--- drivers/net/ethernet/microchip/lan743x_main.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
drivers/net/ethernet/microchip/lan743x_main.c +6 -4
@@ -1027,9 +1027,9 @@ static int lan743x_phy_open(struct lan743x_adapter *adapter) netdev = adapter->netdev; phynode =of_node_get (adapter->pdev->dev.of_node); - adapter->phy_mode =PHY_INTERFACE_MODE_GMII ;if (phynode) { +/* try devicetree phy, or fixed link */ of_get_phy_mode (phynode, &adapter->phy_mode);if (of_phy_is_fixed_link (phynode)) {
@@ -1045,13 +1045,15 @@ static int lan743x_phy_open(struct lan743x_adapter *adapter) lan743x_phy_link_status_change,0 , adapter->phy_mode);of_node_put (phynode); -if (!phydev) - goto return_error; - }else { + } + +if (!phydev) { +/* try internal phy */ phydev =phy_find_first (adapter->mdiobus);if (!phydev) goto return_error; + adapter->phy_mode =PHY_INTERFACE_MODE_GMII ; ret =phy_connect_direct (netdev, phydev, lan743x_phy_link_status_change, adapter->phy_mode);
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 157/255 net: phy: realtek: support paged operations on RTL8201CP
In reply to Greg Kroah-HartmanFrom: Heiner Kallweit <[email protected]>
[ Upstream commit f3037c5a31b58a73b32a36e938ad0560085acadd ]
The RTL8401-internal PHY identifies as RTL8201CP, and the init sequence in r8169, copied from vendor driver r8168, uses paged operations. Therefore set the same paged operation callbacks as for the other Realtek PHY's.
--- drivers/net/phy/realtek.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/phy/realtek.c +2 -0
@@ -542,6 +542,8 @@ static struct phy_driver realtek_drvs[] = { { PHY_ID_MATCH_EXACT(0x00008201), .name = "RTL8201CP Ethernet", + .read_page = rtl821x_read_page, + .write_page = rtl821x_write_page, }, {PHY_ID_MATCH_EXACT (0x001cc816 ), .name = "RTL8201F Fast Ethernet",
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 158/255 xfs: fix flags argument to rmap lookup when converting shared file rmaps
In reply to Greg Kroah-HartmanFrom: Darrick J. Wong <[email protected]>
[ Upstream commit ea8439899c0b15a176664df62aff928010fad276 ]
Pass the same oldext argument (which contains the existing rmapping's unwritten state) to xfs_rmap_lookup_le_range at the start of xfs_rmap_convert_shared. At this point in the code, flags is zero, which means that we perform lookups using the wrong key.
--- fs/xfs/libxfs/xfs_rmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/xfs/libxfs/xfs_rmap.c +1 -1
@@ -1514,7 +1514,7 @@ xfs_rmap_convert_shared(* record for our insertion point. This will also give us the record for * start block contiguity tests. */ - error =xfs_rmap_lookup_le_range (cur, bno, owner, offset, flags, + error =xfs_rmap_lookup_le_range (cur, bno, owner, offset, oldext, &PREV , &i);if (error) goto done;
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 159/255 xfs: set the unwritten bit in rmap lookup flags in xchk_bmap_get_rmapextents
In reply to Greg Kroah-HartmanFrom: Darrick J. Wong <[email protected]>
[ Upstream commit 5dda3897fd90783358c4c6115ef86047d8c8f503 ]
When the bmbt scrubber is looking up rmap extents, we need to set the extent flags from the bmbt record fully. This will matter once we fix the rmap btree comparison functions to check those flags correctly.
--- fs/xfs/scrub/bmap.c | 2 ++ 1 file changed, 2 insertions(+)
fs/xfs/scrub/bmap.c +2 -0
@@ -113,6 +113,8 @@ xchk_bmap_get_rmap(if (info->whichfork ==XFS_ATTR_FORK ) rflags |=XFS_RMAP_ATTR_FORK ; +if (irec->br_state ==XFS_EXT_UNWRITTEN ) + rflags |=XFS_RMAP_UNWRITTEN ;/* * CoW staging extents are owned (on disk) by the refcountbt, so
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 160/255 xfs: fix rmap key and record comparison functions
In reply to Greg Kroah-HartmanFrom: Darrick J. Wong <[email protected]>
[ Upstream commit 6ff646b2ceb0eec916101877f38da0b73e3a5b7f ]
Keys for extent interval records in the reverse mapping btree are supposed to be computed as follows:
(physical block, owner, fork, is_btree, is_unwritten, offset)
This provides users the ability to look up a reverse mapping from a bmbt record -- start with the physical block; then if there are multiple records for the same block, move on to the owner; then the inode fork type; and so on to the file offset.
However, the key comparison functions incorrectly remove the fork/btree/unwritten information that's encoded in the on-disk offset. This means that lookup comparisons are only done with:
(physical block, owner, offset)
This means that queries can return incorrect results. On consistent filesystems this hasn't been an issue because blocks are never shared between forks or with bmbt blocks; and are never unwritten. However, this bug means that online repair cannot always detect corruption in the key information in internal rmapbt nodes.
Found by fuzzing keys[1].attrfork = ones on xfs/371.
--- fs/xfs/libxfs/xfs_rmap_btree.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
fs/xfs/libxfs/xfs_rmap_btree.c +8 -8
@@ -243,8 +243,8 @@ xfs_rmapbt_key_diff(else if (y > x)return -1 ; - x =XFS_RMAP_OFF (be64_to_cpu (kp->rm_offset)); - y = rec->rm_offset; + x =be64_to_cpu (kp->rm_offset); + y =xfs_rmap_irec_offset_pack (rec);if (x > y)return 1 ;else if (y > x)
@@ -275,8 +275,8 @@ xfs_rmapbt_diff_two_keys(else if (y > x)return -1 ; - x =XFS_RMAP_OFF (be64_to_cpu (kp1->rm_offset)); - y =XFS_RMAP_OFF (be64_to_cpu (kp2->rm_offset)); + x =be64_to_cpu (kp1->rm_offset); + y =be64_to_cpu (kp2->rm_offset);if (x > y)return 1 ;else if (y > x)
@@ -390,8 +390,8 @@ xfs_rmapbt_keys_inorder(return 1 ; else if (a > b) return 0; - a =XFS_RMAP_OFF (be64_to_cpu (k1->rmap.rm_offset)); - b =XFS_RMAP_OFF (be64_to_cpu (k2->rmap.rm_offset)); + a =be64_to_cpu (k1->rmap.rm_offset); + b =be64_to_cpu (k2->rmap.rm_offset);if (a <= b)return 1 ;return 0 ;
@@ -420,8 +420,8 @@ xfs_rmapbt_recs_inorder(return 1 ; else if (a > b) return 0; - a =XFS_RMAP_OFF (be64_to_cpu (r1->rmap.rm_offset)); - b =XFS_RMAP_OFF (be64_to_cpu (r2->rmap.rm_offset)); + a =be64_to_cpu (r1->rmap.rm_offset); + b =be64_to_cpu (r2->rmap.rm_offset);if (a <= b)return 1 ;return 0 ;
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 161/255 xfs: fix brainos in the refcount scrubbers rmap fragment processor
In reply to Greg Kroah-HartmanFrom: Darrick J. Wong <[email protected]>
[ Upstream commit 54e9b09e153842ab5adb8a460b891e11b39e9c3d ]
Fix some serious WTF in the reference count scrubber's rmap fragment processing. The code comment says that this loop is supposed to move all fragment records starting at or before bno onto the worklist, but there's no obvious reason why nr (the number of items added) should increment starting from 1, and breaking the loop when we've added the target number seems dubious since we could have more rmap fragments that should have been added to the worklist.
This seems to manifest in xfs/411 when adding one to the refcount field.
--- fs/xfs/scrub/refcount.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-)
fs/xfs/scrub/refcount.c +3 -5
@@ -170,7 +170,6 @@ xchk_refcountbt_process_rmap_fragments(*/ INIT_LIST_HEAD (&worklist); rbno =NULLAGBLOCK ; - nr =1 ;/* Make sure the fragments actually /are/ in agbno order. */ bno =0 ;
@@ -184,15 +183,14 @@ xchk_refcountbt_process_rmap_fragments(* Find all the rmaps that start at or before the refc extent, * and put them on the worklist. */ + nr =0 ;list_for_each_entry_safe (frag, n, &refchk->fragments, list) { -if (frag->rm.rm_startblock > refchk->bno) - goto done; +if (frag->rm.rm_startblock > refchk->bno || nr > target_nr) +break ; bno = frag->rm.rm_startblock + frag->rm.rm_blockcount;if (bno < rbno) rbno = bno;list_move_tail (&frag->list, &worklist); -if (nr == target_nr) -break ; nr++; }
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 162/255 lan743x: fix "BUG: invalid wait context" when setting rx mode
In reply to Greg Kroah-HartmanFrom: Sven Van Asbroeck <[email protected]>
[ Upstream commit 2b52a4b65bc8f14520fe6e996ea7fb3f7e400761 ]
In the net core, the struct net_device_ops -> ndo_set_rx_mode() callback is called with the dev->addr_list_lock spinlock held.
However, this driver's ndo_set_rx_mode callback eventually calls lan743x_dp_write(), which acquires a mutex. Mutex acquisition may sleep, and this is not allowed when holding a spinlock.
Fix by removing the dp_lock mutex entirely. Its purpose is to prevent concurrent accesses to the data port. No concurrent accesses are possible, because the dev->addr_list_lock spinlock in the core only lets through one thread at a time.
--- drivers/net/ethernet/microchip/lan743x_main.c | 12 +++--------- drivers/net/ethernet/microchip/lan743x_main.h | 3 --- 2 files changed, 3 insertions(+), 12 deletions(-)
drivers/net/ethernet/microchip/lan743x_main.c +3 -9
@@ -675,14 +675,12 @@ clean_up:static int lan743x_dp_write (struct lan743x_adapter *adapter,u32 select,u32 addr,u32 length,u32 *buf) { -int ret = -EIO ;u32 dp_sel;int i; -mutex_lock (&adapter->dp_lock);if (lan743x_csr_wait_for_bit (adapter,DP_SEL ,DP_SEL_DPRDY_ ,1 ,40 ,100 ,100 )) - goto unlock; +return -EIO ; dp_sel =lan743x_csr_read (adapter,DP_SEL ); dp_sel &= ~DP_SEL_MASK_ ; dp_sel |= select;
@@ -694,13 +692,10 @@ static int lan743x_dp_write(struct lan743x_adapter *adapter,lan743x_csr_write (adapter,DP_CMD ,DP_CMD_WRITE_ );if (lan743x_csr_wait_for_bit (adapter,DP_SEL ,DP_SEL_DPRDY_ ,1 ,40 ,100 ,100 )) - goto unlock; +return -EIO ; } - ret =0 ; -unlock: -mutex_unlock (&adapter->dp_lock); -return ret; +return 0 ; }static u32 lan743x_mac_mii_access (u16 id,u16 index,int read)
@@ -2737,7 +2732,6 @@ static int lan743x_hardware_init(struct lan743x_adapter *adapter, adapter->intr.irq = adapter->pdev->irq;lan743x_csr_write (adapter,INT_EN_CLR ,0xFFFFFFFF ); -mutex_init (&adapter->dp_lock); ret =lan743x_gpio_init (adapter);if (ret)
drivers/net/ethernet/microchip/lan743x_main.h +0 -3
@@ -712,9 +712,6 @@ struct lan743x_adapter {struct lan743x_csr csr;struct lan743x_intr intr; -/* lock, used to prevent concurrent access to data port */ -struct mutex dp_lock; -struct lan743x_gpio gpio;struct lan743x_ptp ptp;
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 163/255 xfs: fix a missing unlock on error in xfs_fs_map_blocks
In reply to Greg Kroah-HartmanFrom: Christoph Hellwig <[email protected]>
[ Upstream commit 2bd3fa793aaa7e98b74e3653fdcc72fa753913b5 ]
We also need to drop the iolock when invalidate_inode_pages2 fails, not only on all other error or successful cases.
--- fs/xfs/xfs_pnfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/xfs/xfs_pnfs.c +1 -1
@@ -134,7 +134,7 @@ xfs_fs_map_blocks( goto out_unlock; error =invalidate_inode_pages2 (inode->i_mapping);if (WARN_ON_ONCE (error)) -return error; + goto out_unlock; end_fsb =XFS_B_TO_FSB (mp, (xfs_ufsize_t )offset + length); offset_fsb =XFS_B_TO_FSBT (mp, offset);
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 164/255 of/address: Fix of_node memory leak in of_dma_is_coherent
In reply to Greg Kroah-HartmanFrom: Evan Nimmo <[email protected]>
[ Upstream commit a5bea04fcc0b3c0aec71ee1fd58fd4ff7ee36177 ]
Commit dabf6b36b83a ("of: Add OF_DMA_DEFAULT_COHERENT & select it on powerpc") added a check to of_dma_is_coherent which returns early if OF_DMA_DEFAULT_COHERENT is enabled. This results in the of_node_put() being skipped causing a memory leak. Moved the of_node_get() below this check so we now we only get the node if OF_DMA_DEFAULT_COHERENT is not enabled.
--- drivers/of/address.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/of/address.c +3 -1
@@ -1043,11 +1043,13 @@ out:*/ bool of_dma_is_coherent (struct device_node *np) { -struct device_node *node =of_node_get (np); +struct device_node *node;if (IS_ENABLED (CONFIG_OF_DMA_DEFAULT_COHERENT ))return true; + node =of_node_get (np); +while (node) {if (of_property_read_bool (node,"dma-coherent" )) {of_node_put (node);
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 165/255 ch_ktls: Update cheksum information
In reply to Greg Kroah-HartmanFrom: Rohit Maheshwari <[email protected]>
[ Upstream commit 86716b51d14fc2201938939b323ba3ad99186910 ]
Checksum update was missing in the WR.
--- drivers/crypto/chelsio/chcr_ktls.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-)
drivers/crypto/chelsio/chcr_ktls.c +11 -4
@@ -926,6 +926,7 @@ chcr_ktls_write_tcp_options(struct chcr_ktls_info *tx_info, struct sk_buff *skb,struct iphdr *ip;int credits;u8 buf[150 ]; +u64 cntrl1;void *pos; iplen =skb_network_header_len (skb);
@@ -964,22 +965,28 @@ chcr_ktls_write_tcp_options(struct chcr_ktls_info *tx_info, struct sk_buff *skb, TXPKT_PF_V(tx_info->adap->pf)); cpl->pack =0 ; cpl->len =htons (pktlen); -/* checksum offload */ - cpl->ctrl1 =0 ; - - pos = cpl +1 ;memcpy (buf, skb->data, pktlen);if (tx_info->ip_family ==AF_INET ) {/* we need to correct ip header len */ ip = (struct iphdr *)(buf + maclen); ip->tot_len =htons (pktlen - maclen); + cntrl1 =TXPKT_CSUM_TYPE_V (TX_CSUM_TCPIP );#if IS_ENABLED (CONFIG_IPV6 ) } else { ip6 = (struct ipv6hdr *)(buf + maclen); ip6->payload_len =htons (pktlen - maclen - iplen); + cntrl1 =TXPKT_CSUM_TYPE_V (TX_CSUM_TCPIP6 );#endif } + + cntrl1 |=T6_TXPKT_ETHHDR_LEN_V (maclen -ETH_HLEN ) | +TXPKT_IPHDR_LEN_V (iplen); +/* checksum offload */ + cpl->ctrl1 =cpu_to_be64 (cntrl1); + + pos = cpl +1 ; +/* now take care of the tcp header, if fin is not set then clear push * bit as well, and if fin is set, it will be sent at the last so we * need to update the tcp sequence number as per the last packet.
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 166/255 ch_ktls: tcb update fails sometimes
In reply to Greg Kroah-HartmanFrom: Rohit Maheshwari <[email protected]>
[ Upstream commit 7d01c428c86b525dc780226924d74df2048cf411 ]
context id and port id should be filled while sending tcb update.
--- drivers/crypto/chelsio/chcr_ktls.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
drivers/crypto/chelsio/chcr_ktls.c +8 -4
@@ -659,7 +659,8 @@ int chcr_ktls_cpl_set_tcb_rpl(struct adapter *adap, unsigned char *input) }static void *__chcr_write_cpl_set_tcb_ulp (struct chcr_ktls_info *tx_info, -u32 tid,void *pos,u16 word,u64 mask, +u32 tid,void *pos,u16 word, +struct sge_eth_txq *q,u64 mask,u64 val,u32 reply) {struct cpl_set_tcb_field_core *cpl;
@@ -668,7 +669,10 @@ static void *__chcr_write_cpl_set_tcb_ulp(struct chcr_ktls_info *tx_info,/* ULP_TXPKT */ txpkt = pos; - txpkt->cmd_dest =htonl (ULPTX_CMD_V (ULP_TX_PKT ) |ULP_TXPKT_DEST_V (0 )); + txpkt->cmd_dest =htonl (ULPTX_CMD_V (ULP_TX_PKT ) | +ULP_TXPKT_CHANNELID_V (tx_info->port_id) | +ULP_TXPKT_FID_V (q->q.cntxt_id) | +ULP_TXPKT_RO_F ); txpkt->len =htonl (DIV_ROUND_UP (CHCR_SET_TCB_FIELD_LEN ,16 ));/* ULPTX_IDATA sub-command */
@@ -723,7 +727,7 @@ static void *chcr_write_cpl_set_tcb_ulp(struct chcr_ktls_info *tx_info, }else {u8 buf[48 ] = {0 }; -__chcr_write_cpl_set_tcb_ulp (tx_info, tid, buf, word, +__chcr_write_cpl_set_tcb_ulp (tx_info, tid, buf, word, q, mask, val, reply); return chcr_copy_to_txd(buf, &q->q, pos,
@@ -731,7 +735,7 @@ static void *chcr_write_cpl_set_tcb_ulp(struct chcr_ktls_info *tx_info, } } - pos =__chcr_write_cpl_set_tcb_ulp (tx_info, tid, pos, word, + pos =__chcr_write_cpl_set_tcb_ulp (tx_info, tid, pos, word, q, mask, val, reply);/* check again if we are at the end of the queue */
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 167/255 cosa: Add missing kfree in error path of cosa_write
In reply to Greg Kroah-HartmanFrom: Wang Hai <[email protected]>
[ Upstream commit 52755b66ddcef2e897778fac5656df18817b59ab ]
If memory allocation for 'kbuf' succeed, cosa_write() doesn't have a corresponding kfree() in exception handling. Thus add kfree() for this function implementation.
--- drivers/net/wan/cosa.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/wan/cosa.c +1 -0
@@ -889,6 +889,7 @@ static ssize_t cosa_write(struct file *file, chan->tx_status =1 ;spin_unlock_irqrestore (&cosa->lock, flags);up (&chan->wsem); +kfree (kbuf);return -ERESTARTSYS ; } }
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 168/255 hwmon: (applesmc) Re-work SMC comms
In reply to Greg Kroah-HartmanFrom: Brad Campbell <[email protected]>
[ Upstream commit 4d64bb4ba5ecf4831448cdb2fe16d0ae91b2b40b ]
Commit fff2d0f701e6 ("hwmon: (applesmc) avoid overlong udelay()") introduced an issue whereby communication with the SMC became unreliable with write errors like :
[ 120.378614] applesmc: send_byte(0x00, 0x0300) fail: 0x40 [ 120.378621] applesmc: LKSB: write data fail [ 120.512782] applesmc: send_byte(0x00, 0x0300) fail: 0x40 [ 120.512787] applesmc: LKSB: write data fail
The original code appeared to be timing sensitive and was not reliable with the timing changes in the aforementioned commit.
This patch re-factors the SMC communication to remove the timing dependencies and restore function with the changes previously committed.
Tested on : MacbookAir6,2 MacBookPro11,1 iMac12,2, MacBookAir1,1, MacBookAir3,1
--- drivers/hwmon/applesmc.c | 130 ++++++++++++++++++++++++--------------- 1 file changed, 82 insertions(+), 48 deletions(-)
drivers/hwmon/applesmc.c +82 -48
@@ -32,6 +32,7 @@#include <linux/hwmon.h> #include <linux/workqueue.h> #include <linux/err.h> +#include <linux/bits.h> /* data port used by Apple SMC */ #define APPLESMC_DATA_PORT 0x300
@@ -42,10 +43,13 @@#define APPLESMC_MAX_DATA_LENGTH 32 -/* wait up to 128 ms for a status change. */ -#define APPLESMC_MIN_WAIT 0x0010 -#define APPLESMC_RETRY_WAIT 0x0100 -#define APPLESMC_MAX_WAIT 0x20000 +/* Apple SMC status bits */ +#define SMC_STATUS_AWAITING_DATA BIT(0)/* SMC has data waiting to be read */ +#define SMC_STATUS_IB_CLOSED BIT(1)/* Will ignore any input */ +#define SMC_STATUS_BUSY BIT(2)/* Command in progress */ + +/* Initial wait is 8us */ +#define APPLESMC_MIN_WAIT 0x0008#define APPLESMC_READ_CMD 0x10#define APPLESMC_WRITE_CMD 0x11
@@ -151,65 +155,84 @@ static unsigned int key_at_index;static struct workqueue_struct *applesmc_led_wq;/* -* wait_read - Wait for a byte to appear on SMC port. Callers must -* hold applesmc_lock. +* Wait for specific status bits with a mask on the SMC. +* Used before all transactions. +* This does 10 fast loops of 8us then exponentially backs off for a +* minimum total wait of 262ms. Depending on usleep_range this could +* run out past 500ms. */ -static int wait_read (void ) + +static int wait_status (u8 val,u8 mask) { -unsigned long end = jiffies + (APPLESMC_MAX_WAIT *HZ ) /USEC_PER_SEC ;u8 status;int us; +int i; -for (us =APPLESMC_MIN_WAIT ; us <APPLESMC_MAX_WAIT ; us <<=1 ) { -usleep_range (us, us *16 ); + us =APPLESMC_MIN_WAIT ; +for (i =0 ; i <24 ; i++) { status =inb (APPLESMC_CMD_PORT ); -/* read: wait for smc to settle */ -if (status &0x01 ) +if ((status & mask) == val)return 0 ; -/* timeout: give up */ -if (time_after (jiffies, end)) -break ; +usleep_range (us, us *2 ); +if (i >9 ) + us <<=1 ; } - -pr_warn ("wait_read() fail: 0x%02x\n" , status);return -EIO ; } -/* -* send_byte - Write to SMC port, retrying when necessary. Callers -* must hold applesmc_lock. -*/ +/* send_byte - Write to SMC data port. Callers must hold applesmc_lock. */ +static int send_byte (u8 cmd,u16 port) { -u8 status; -int us; -unsigned long end = jiffies + (APPLESMC_MAX_WAIT *HZ ) /USEC_PER_SEC ; +int status; + + status =wait_status (0 ,SMC_STATUS_IB_CLOSED ); +if (status) +return status; +/* +* This needs to be a separate read looking for bit 0x04 +* after bit 0x02 falls. If consolidated with the wait above +* this extra read may not happen if status returns both +* simultaneously and this would appear to be required. +*/ + status =wait_status (SMC_STATUS_BUSY ,SMC_STATUS_BUSY ); +if (status) +return status;outb (cmd, port); -for (us =APPLESMC_MIN_WAIT ; us <APPLESMC_MAX_WAIT ; us <<=1 ) { -usleep_range (us, us *16 ); - status =inb (APPLESMC_CMD_PORT ); -/* write: wait for smc to settle */ -if (status &0x02 ) -continue ; -/* ready: cmd accepted, return */ -if (status &0x04 ) -return 0 ; -/* timeout: give up */ -if (time_after (jiffies, end)) -break ; -/* busy: long wait and resend */ -udelay (APPLESMC_RETRY_WAIT ); -outb (cmd, port); - } - -pr_warn ("send_byte(0x%02x, 0x%04x) fail: 0x%02x\n" , cmd, port, status); -return -EIO ; +return 0 ; } +/* send_command - Write a command to the SMC. Callers must hold applesmc_lock. */ +static int send_command (u8 cmd) { -return send_byte (cmd,APPLESMC_CMD_PORT ); +int ret; + + ret =wait_status (0 ,SMC_STATUS_IB_CLOSED ); +if (ret) +return ret; +outb (cmd,APPLESMC_CMD_PORT ); +return 0 ; +} + +/* +* Based on logic from the Apple driver. This is issued before any interaction +* If busy is stuck high, issue a read command to reset the SMC state machine. +* If busy is stuck high after the command then the SMC is jammed. +*/ + +static int smc_sane (void ) +{ +int ret; + + ret =wait_status (0 ,SMC_STATUS_BUSY ); +if (!ret) +return ret; + ret =send_command (APPLESMC_READ_CMD ); +if (ret) +return ret; +return wait_status (0 ,SMC_STATUS_BUSY ); }static int send_argument (const char *key)
@@ -226,6 +249,11 @@ static int read_smc(u8 cmd, const char *key, u8 *buffer, u8 len) {u8 status, data =0 ;int i; +int ret; + + ret =smc_sane (); +if (ret) +return ret;if (send_command (cmd) ||send_argument (key)) {pr_warn ("%.4s: read arg fail\n" , key);
@@ -239,7 +267,8 @@ static int read_smc(u8 cmd, const char *key, u8 *buffer, u8 len) }for (i =0 ; i < len; i++) { -if (wait_read ()) { +if (wait_status (SMC_STATUS_AWAITING_DATA |SMC_STATUS_BUSY , +SMC_STATUS_AWAITING_DATA |SMC_STATUS_BUSY )) {pr_warn ("%.4s: read data[%d] fail\n" , key, i);return -EIO ; }
@@ -250,19 +279,24 @@ static int read_smc(u8 cmd, const char *key, u8 *buffer, u8 len)for (i =0 ; i <16 ; i++) {udelay (APPLESMC_MIN_WAIT ); status =inb (APPLESMC_CMD_PORT ); -if (!(status &0x01 )) +if (!(status &SMC_STATUS_AWAITING_DATA ))break ; data =inb (APPLESMC_DATA_PORT ); }if (i)pr_warn ("flushed %d bytes, last value is: %d\n" , i, data); -return 0 ; +return wait_status (0 ,SMC_STATUS_BUSY ); }static int write_smc (u8 cmd,const char *key,const u8 *buffer,u8 len) {int i; +int ret; + + ret =smc_sane (); +if (ret) +return ret;if (send_command (cmd) ||send_argument (key)) {pr_warn ("%s: write arg fail\n" , key);
@@ -281,7 +315,7 @@ static int write_smc(u8 cmd, const char *key, const u8 *buffer, u8 len) } } -return 0 ; +return wait_status (0 ,SMC_STATUS_BUSY ); }static int read_register_count (unsigned int *count)
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 169/255 NFS: Fix listxattr receive buffer size
In reply to Greg Kroah-HartmanFrom: Chuck Lever <[email protected]>
[ Upstream commit 6c2190b3fcbc92cb79e39cc7e7531656b341e463 ]
Certain NFSv4.2/RDMA tests fail with v5.9-rc1.
rpcrdma_convert_kvec() runs off the end of the rl_segments array because rq_rcv_buf.tail[0].iov_len holds a very large positive value. The resultant kernel memory corruption is enough to crash the client system.
Callers of rpc_prepare_reply_pages() must reserve an extra XDR_UNIT in the maximum decode size for a possible XDR pad of the contents of the xdr_buf's pages. That guarantees the allocated receive buffer will be large enough to accommodate the usual contents plus that XDR pad word.
encode_op_hdr() cannot add that extra word. If it does, xdr_inline_pages() underruns the length of the tail iovec.
--- fs/nfs/nfs42xdr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
fs/nfs/nfs42xdr.c +2 -2
@@ -179,7 +179,7 @@ 1 + nfs4_xattr_name_maxsz + 1)#define decode_setxattr_maxsz (op_decode_hdr_maxsz + decode_change_info_maxsz)#define encode_listxattrs_maxsz (op_encode_hdr_maxsz + 2 + 1) -#define decode_listxattrs_maxsz (op_decode_hdr_maxsz + 2 + 1 + 1) +#define decode_listxattrs_maxsz (op_decode_hdr_maxsz + 2 + 1 + 1 + 1)#define encode_removexattr_maxsz (op_encode_hdr_maxsz + 1 + \ nfs4_xattr_name_maxsz)#define decode_removexattr_maxsz (op_decode_hdr_maxsz + \
@@ -504,7 +504,7 @@ static void encode_listxattrs(struct xdr_stream *xdr, {__be32 *p; -encode_op_hdr (xdr,OP_LISTXATTRS , decode_listxattrs_maxsz +1 , hdr); +encode_op_hdr (xdr,OP_LISTXATTRS , decode_listxattrs_maxsz, hdr); p =reserve_space (xdr,12 );if (unlikely (!p))
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 170/255 vrf: Fix fast path output packet handling with async Netfilter rules
In reply to Greg Kroah-HartmanFrom: Martin Willi <[email protected]>
[ Upstream commit 9e2b7fa2df4365e99934901da4fb4af52d81e820 ]
VRF devices use an optimized direct path on output if a default qdisc is involved, calling Netfilter hooks directly. This path, however, does not consider Netfilter rules completing asynchronously, such as with NFQUEUE. The Netfilter okfn() is called for asynchronously accepted packets, but the VRF never passes that packet down the stack to send it out over the slave device. Using the slower redirect path for this seems not feasible, as we do not know beforehand if a Netfilter hook has asynchronously completing rules.
Fix the use of asynchronously completing Netfilter rules in OUTPUT and POSTROUTING by using a special completion function that additionally calls dst_output() to pass the packet down the stack. Also, slightly adjust the use of nf_reset_ct() so that is called in the asynchronous case, too.
--- drivers/net/vrf.c | 92 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 69 insertions(+), 23 deletions(-)
drivers/net/vrf.c +69 -23
@@ -608,8 +608,7 @@ static netdev_tx_t vrf_xmit(struct sk_buff *skb, struct net_device *dev)return ret; } -static int vrf_finish_direct (struct net *net,struct sock *sk, -struct sk_buff *skb) +static void vrf_finish_direct (struct sk_buff *skb) {struct net_device *vrf_dev = skb->dev;
@@ -628,7 +627,8 @@ static int vrf_finish_direct(struct net *net, struct sock *sk,skb_pull (skb,ETH_HLEN ); } -return 1 ; +/* reset skb device */ +nf_reset_ct (skb); }#if IS_ENABLED (CONFIG_IPV6 )
@@ -707,15 +707,41 @@ static struct sk_buff *vrf_ip6_out_redirect(struct net_device *vrf_dev,return skb; } +static int vrf_output6_direct_finish (struct net *net,struct sock *sk, +struct sk_buff *skb) +{ +vrf_finish_direct (skb); + +return vrf_ip6_local_out (net, sk, skb); +} +static int vrf_output6_direct (struct net *net,struct sock *sk,struct sk_buff *skb) { +int err =1 ; + skb->protocol =htons (ETH_P_IPV6 ); -return NF_HOOK_COND (NFPROTO_IPV6 ,NF_INET_POST_ROUTING , - net, sk, skb,NULL , skb->dev, - vrf_finish_direct, - !(IPCB (skb)->flags &IPSKB_REROUTED )); +if (!(IPCB (skb)->flags &IPSKB_REROUTED )) + err =nf_hook (NFPROTO_IPV6 ,NF_INET_POST_ROUTING , net, sk, skb, +NULL , skb->dev, vrf_output6_direct_finish); + +if (likely (err ==1 )) +vrf_finish_direct (skb); + +return err; +} + +static int vrf_ip6_out_direct_finish (struct net *net,struct sock *sk, +struct sk_buff *skb) +{ +int err; + + err =vrf_output6_direct (net, sk, skb); +if (likely (err ==1 )) + err =vrf_ip6_local_out (net, sk, skb); + +return err; } static struct sk_buff *vrf_ip6_out_direct(struct net_device *vrf_dev,
@@ -728,18 +754,15 @@ static struct sk_buff *vrf_ip6_out_direct(struct net_device *vrf_dev, skb->dev = vrf_dev; err =nf_hook (NFPROTO_IPV6 ,NF_INET_LOCAL_OUT , net, sk, - skb,NULL , vrf_dev, vrf_output6_direct); + skb,NULL , vrf_dev, vrf_ip6_out_direct_finish);if (likely (err ==1 )) err =vrf_output6_direct (net, sk, skb); -/* reset skb device */ if (likely (err ==1 )) -nf_reset_ct (skb); -else - skb =NULL ; +return skb; -return skb; +return NULL ; } static struct sk_buff *vrf_ip6_out(struct net_device *vrf_dev,
@@ -919,15 +942,41 @@ static struct sk_buff *vrf_ip_out_redirect(struct net_device *vrf_dev,return skb; } +static int vrf_output_direct_finish (struct net *net,struct sock *sk, +struct sk_buff *skb) +{ +vrf_finish_direct (skb); + +return vrf_ip_local_out (net, sk, skb); +} +static int vrf_output_direct (struct net *net,struct sock *sk,struct sk_buff *skb) { +int err =1 ; + skb->protocol =htons (ETH_P_IP ); -return NF_HOOK_COND (NFPROTO_IPV4 ,NF_INET_POST_ROUTING , - net, sk, skb,NULL , skb->dev, - vrf_finish_direct, - !(IPCB (skb)->flags &IPSKB_REROUTED )); +if (!(IPCB (skb)->flags &IPSKB_REROUTED )) + err =nf_hook (NFPROTO_IPV4 ,NF_INET_POST_ROUTING , net, sk, skb, +NULL , skb->dev, vrf_output_direct_finish); + +if (likely (err ==1 )) +vrf_finish_direct (skb); + +return err; +} + +static int vrf_ip_out_direct_finish (struct net *net,struct sock *sk, +struct sk_buff *skb) +{ +int err; + + err =vrf_output_direct (net, sk, skb); +if (likely (err ==1 )) + err =vrf_ip_local_out (net, sk, skb); + +return err; } static struct sk_buff *vrf_ip_out_direct(struct net_device *vrf_dev,
@@ -940,18 +989,15 @@ static struct sk_buff *vrf_ip_out_direct(struct net_device *vrf_dev, skb->dev = vrf_dev; err =nf_hook (NFPROTO_IPV4 ,NF_INET_LOCAL_OUT , net, sk, - skb,NULL , vrf_dev, vrf_output_direct); + skb,NULL , vrf_dev, vrf_ip_out_direct_finish);if (likely (err ==1 )) err =vrf_output_direct (net, sk, skb); -/* reset skb device */ if (likely (err ==1 )) -nf_reset_ct (skb); -else - skb =NULL ; +return skb; -return skb; +return NULL ; } static struct sk_buff *vrf_ip_out(struct net_device *vrf_dev,
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 171/255 lan743x: fix use of uninitialized variable
In reply to Greg Kroah-HartmanFrom: Sven Van Asbroeck <[email protected]>
[ Upstream commit edbc21113bde13ca3d06eec24b621b1f628583dd ]
When no devicetree is present, the driver will use an uninitialized variable.
Fix by initializing this variable.
--- drivers/net/ethernet/microchip/lan743x_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/microchip/lan743x_main.c +1 -1
@@ -1015,8 +1015,8 @@ static void lan743x_phy_close(struct lan743x_adapter *adapter)static int lan743x_phy_open (struct lan743x_adapter *adapter) {struct lan743x_phy *phy = &adapter->phy; +struct phy_device *phydev =NULL ;struct device_node *phynode; -struct phy_device *phydev;struct net_device *netdev;int ret = -EIO ;
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 172/255 arm64/mm: Validate hotplug range before creating linear mapping
In reply to Greg Kroah-HartmanFrom: Anshuman Khandual <[email protected]>
[ Upstream commit 58284a901b426e6130672e9f14c30dfd5a9dbde0 ]
During memory hotplug process, the linear mapping should not be created for a given memory range if that would fall outside the maximum allowed linear range. Else it might cause memory corruption in the kernel virtual space.
Maximum linear mapping region is [PAGE_OFFSET..(PAGE_END -1)] accommodating both its ends but excluding PAGE_END. Max physical range that can be mapped inside this linear mapping range, must also be derived from its end points.
This ensures that arch_add_memory() validates memory hot add range for its potential linear mapping requirements, before creating it with __create_pgd_mapping().
--- arch/arm64/mm/mmu.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
arch/arm64/mm/mmu.c +17 -0
@@ -1433,11 +1433,28 @@ static void __remove_pgd_mapping(pgd_t *pgdir, unsigned long start, u64 size)free_empty_tables (start, end,PAGE_OFFSET ,PAGE_END ); } +static bool inside_linear_region (u64 start,u64 size) +{ +/* +* Linear mapping region is the range [PAGE_OFFSET..(PAGE_END - 1)] +* accommodating both its ends but excluding PAGE_END. Max physical +* range which can be mapped inside this linear mapping range, must +* also be derived from its end points. +*/ +return start >=__pa (_PAGE_OFFSET (vabits_actual)) && + (start + size -1 ) <=__pa (PAGE_END -1 ); +} +int arch_add_memory (int nid,u64 start,u64 size,struct mhp_params *params) {int ret, flags =0 ; +if (!inside_linear_region (start, size)) { +pr_err ("[%llx %llx] is outside linear mapping region\n" , start, start + size); +return -EINVAL ; + } +if (rodata_full ||debug_pagealloc_enabled ()) flags =NO_BLOCK_MAPPINGS |NO_CONT_MAPPINGS ;
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 173/255 kernel/watchdog: fix watchdog_allowed_mask not used warning
In reply to Greg Kroah-HartmanFrom: Santosh Sivaraj <[email protected]>
[ Upstream commit e7e046155af04cdca5e1157f28b07e1651eb317b ]
Define watchdog_allowed_mask only when SOFTLOCKUP_DETECTOR is enabled.
--- kernel/watchdog.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/watchdog.c +2 -2
@@ -44,8 +44,6 @@ int __read_mostly soft_watchdog_user_enabled = 1;int __read_mostly watchdog_thresh =10 ;static int __read_mostly nmi_watchdog_available; -static struct cpumask watchdog_allowed_mask__read_mostly ; -struct cpumask watchdog_cpumask__read_mostly ;unsigned long *watchdog_cpumask_bits =cpumask_bits (&watchdog_cpumask);
@@ -162,6 +160,8 @@ static void lockup_detector_update_enable(void)int __read_mostly sysctl_softlockup_all_cpu_backtrace;#endif +static struct cpumask watchdog_allowed_mask__read_mostly ; +/* Global variables, exported for sysctl */ unsigned int __read_mostly softlockup_panic =CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE ;
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 174/255 mm: memcontrol: fix missing wakeup polling thread
In reply to Greg Kroah-HartmanFrom: Muchun Song <[email protected]>
[ Upstream commit 8b21ca0218d29cc6bb7028125c7e5a10dfb4730c ]
When we poll the swap.events, we can miss being woken up when the swap event occurs. Because we didn't notify.
--- include/linux/memcontrol.h | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
include/linux/memcontrol.h +9 -2
@@ -897,12 +897,19 @@ static inline void count_memcg_event_mm(struct mm_struct *mm,static inline void memcg_memory_event (struct mem_cgroup *memcg,enum memcg_memory_event event) { +bool swap_event = event ==MEMCG_SWAP_HIGH || event ==MEMCG_SWAP_MAX || + event ==MEMCG_SWAP_FAIL ; +atomic_long_inc (&memcg->memory_events_local[event]); -cgroup_file_notify (&memcg->events_local_file); +if (!swap_event) +cgroup_file_notify (&memcg->events_local_file); do { atomic_long_inc(&memcg->memory_events[event]); - cgroup_file_notify(&memcg->events_file); + if (swap_event) + cgroup_file_notify(&memcg->swap_events_file); + else + cgroup_file_notify(&memcg->events_file); if (!cgroup_subsys_on_dfl(memory_cgrp_subsys)) break;
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 175/255 afs: Fix afs_write_end() when called with copied == 0 [ver #3]
In reply to Greg Kroah-HartmanFrom: David Howells <[email protected]>
[ Upstream commit 3ad216ee73abc554ed8f13f4f8b70845a7bef6da ]
When afs_write_end() is called with copied == 0, it tries to set the dirty region, but there's no way to actually encode a 0-length region in the encoding in page->private.
"0,0", for example, indicates a 1-byte region at offset 0. The maths miscalculates this and sets it incorrectly.
Fix it to just do nothing but unlock and put the page in this case. We don't actually need to mark the page dirty as nothing presumably changed.
--- fs/afs/write.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
fs/afs/write.c +4 -1
@@ -169,11 +169,14 @@ int afs_write_end(struct file *file, struct address_space *mapping,unsigned int f, from = pos & (PAGE_SIZE -1 );unsigned int t, to = from + copied;loff_t i_size, maybe_i_size; -int ret; +int ret =0 ;_enter ("{%llx:%llu},{%lx}" , vnode->fid.vid, vnode->fid.vnode, page->index); +if (copied ==0 ) + goto out; + maybe_i_size = pos + copied; i_size =i_size_read (&vnode->vfs_inode);
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 176/255 perf: Fix get_recursion_context()
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
[ Upstream commit ce0f17fc93f63ee91428af10b7b2ddef38cd19e5 ]
One should use in_serving_softirq() to detect SoftIRQ context.
--- kernel/events/internal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/events/internal.h +1 -1
@@ -211,7 +211,7 @@ static inline int get_recursion_context(int *recursion) rctx =3 ; else if (in_irq()) rctx =2 ; - else if (in_softirq()) + else if (in_serving_softirq()) rctx =1 ; else rctx =0 ;
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 177/255 nvme: factor out a nvme_configure_metadata helper
In reply to Greg Kroah-HartmanFrom: Christoph Hellwig <[email protected]>
[ Upstream commit d4609ea8b3d3fb3423f35805843a82774cb4ef2f ]
Factor out a helper from nvme_update_ns_info that configures the per-namespaces metadata and PI settings. Also make sure the helpers clear the flags explicitly instead of all of ->features to allow for potentially reusing ->features for future non-metadata flags.
--- drivers/nvme/host/core.c | 78 ++++++++++++++++++++++++---------------- 1 file changed, 47 insertions(+), 31 deletions(-)
drivers/nvme/host/core.c +47 -31
@@ -1946,6 +1946,50 @@ static int nvme_setup_streams_ns(struct nvme_ctrl *ctrl, struct nvme_ns *ns,return 0 ; } +static int nvme_configure_metadata (struct nvme_ns *ns,struct nvme_id_ns *id) +{ +struct nvme_ctrl *ctrl = ns->ctrl; + +/* +* The PI implementation requires the metadata size to be equal to the +* t10 pi tuple size. +*/ + ns->ms =le16_to_cpu (id->lbaf[id->flbas &NVME_NS_FLBAS_LBA_MASK ].ms); +if (ns->ms ==sizeof (struct t10_pi_tuple )) + ns->pi_type = id->dps &NVME_NS_DPS_PI_MASK ; +else + ns->pi_type =0 ; + + ns->features &= ~(NVME_NS_METADATA_SUPPORTED |NVME_NS_EXT_LBAS ); +if (!ns->ms || !(ctrl->ops->flags &NVME_F_METADATA_SUPPORTED )) +return 0 ; +if (ctrl->ops->flags &NVME_F_FABRICS ) { +/* +* The NVMe over Fabrics specification only supports metadata as +* part of the extended data LBA. We rely on HCA/HBA support to +* remap the separate metadata buffer from the block layer. +*/ +if (WARN_ON_ONCE (!(id->flbas &NVME_NS_FLBAS_META_EXT ))) +return -EINVAL ; +if (ctrl->max_integrity_segments) + ns->features |= + (NVME_NS_METADATA_SUPPORTED |NVME_NS_EXT_LBAS ); + }else { +/* +* For PCIe controllers, we can't easily remap the separate +* metadata buffer from the block layer and thus require a +* separate metadata buffer for block layer metadata/PI support. +* We allow extended LBAs for the passthrough interface, though. +*/ +if (id->flbas &NVME_NS_FLBAS_META_EXT ) + ns->features |=NVME_NS_EXT_LBAS ; +else + ns->features |=NVME_NS_METADATA_SUPPORTED ; + } + +return 0 ; +} +static void nvme_update_disk_info (struct gendisk *disk,struct nvme_ns *ns,struct nvme_id_ns *id) {
@@ -2096,37 +2140,9 @@ static int __nvme_revalidate_disk(struct gendisk *disk, struct nvme_id_ns *id)return -ENODEV ; } - ns->features =0 ; - ns->ms =le16_to_cpu (id->lbaf[lbaf].ms); -/* the PI implementation requires metadata equal t10 pi tuple size */ -if (ns->ms ==sizeof (struct t10_pi_tuple )) - ns->pi_type = id->dps &NVME_NS_DPS_PI_MASK ; -else - ns->pi_type =0 ; - -if (ns->ms) { -/* -* For PCIe only the separate metadata pointer is supported, -* as the block layer supplies metadata in a separate bio_vec -* chain. For Fabrics, only metadata as part of extended data -* LBA is supported on the wire per the Fabrics specification, -* but the HBA/HCA will do the remapping from the separate -* metadata buffers for us. -*/ -if (id->flbas &NVME_NS_FLBAS_META_EXT ) { - ns->features |=NVME_NS_EXT_LBAS ; -if ((ctrl->ops->flags &NVME_F_FABRICS ) && - (ctrl->ops->flags &NVME_F_METADATA_SUPPORTED ) && - ctrl->max_integrity_segments) - ns->features |=NVME_NS_METADATA_SUPPORTED ; - }else { -if (WARN_ON_ONCE (ctrl->ops->flags &NVME_F_FABRICS )) -return -EINVAL ; -if (ctrl->ops->flags &NVME_F_METADATA_SUPPORTED ) - ns->features |=NVME_NS_METADATA_SUPPORTED ; - } - } - + ret =nvme_configure_metadata (ns, id); +if (ret) +return ret;nvme_set_chunk_sectors (ns, id);nvme_update_disk_info (disk, ns, id);#ifdef CONFIG_NVME_MULTIPATH
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 178/255 nvme: freeze the queue over ->lba_shift updates
In reply to Greg Kroah-Hartman[ Upstream commit f9d5f4579feafa721dba2f350fc064a1852c6f8c ]
Ensure that there can't be any I/O in flight went we change the disk geometry in nvme_update_ns_info, most notable the LBA size by lifting the queue free from nvme_update_disk_info into the caller
--- drivers/nvme/host/core.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-)
drivers/nvme/host/core.c +14 -6
@@ -2001,7 +2001,7 @@ static void nvme_update_disk_info(struct gendisk *disk,/* unsupported block size, set capacity to 0 later */ bs = (1 <<9 ); } -blk_mq_freeze_queue (disk->queue); +blk_integrity_unregister (disk); atomic_bs = phys_bs = bs;
@@ -2066,8 +2066,6 @@ static void nvme_update_disk_info(struct gendisk *disk,set_disk_ro (disk, true); elseset_disk_ro (disk ,false ); - -blk_mq_unfreeze_queue (disk->queue); }static inline bool nvme_first_scan (struct gendisk *disk)
@@ -2114,6 +2112,7 @@ static int __nvme_revalidate_disk(struct gendisk *disk, struct nvme_id_ns *id)struct nvme_ctrl *ctrl = ns->ctrl;int ret; +blk_mq_freeze_queue (ns->disk->queue);/* * If identify namespace failed, use default 512 byte block size so * block layer can use before failing read/write for 0 capacity.
@@ -2131,29 +2130,38 @@ static int __nvme_revalidate_disk(struct gendisk *disk, struct nvme_id_ns *id)dev_warn (ctrl->device,"failed to add zoned namespace:%u ret:%d\n" , ns->head->ns_id, ret); -return ret; + goto out_unfreeze; }break ;default :dev_warn (ctrl->device,"unknown csi:%u ns:%u\n" , ns->head->ids.csi, ns->head->ns_id); -return -ENODEV ; + ret = -ENODEV ; + goto out_unfreeze; } ret =nvme_configure_metadata (ns, id);if (ret) -return ret; + goto out_unfreeze;nvme_set_chunk_sectors (ns, id);nvme_update_disk_info (disk, ns, id); +blk_mq_unfreeze_queue (ns->disk->queue); +#ifdef CONFIG_NVME_MULTIPATH if (ns->head->disk) { +blk_mq_freeze_queue (ns->head->disk->queue);nvme_update_disk_info (ns->head->disk, ns, id);blk_stack_limits (&ns->head->disk->queue->limits, &ns->queue->limits,0 );nvme_mpath_update_disk_size (ns->head->disk); +blk_mq_unfreeze_queue (ns->head->disk->queue); }#endif return 0 ; + +out_unfreeze: +blk_mq_unfreeze_queue (ns->disk->queue); +return ret; }static int _nvme_revalidate_disk (struct gendisk *disk)
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 179/255 nvme: fix incorrect behavior when BLKROSET is called by the user
In reply to Greg Kroah-HartmanFrom: Sagi Grimberg <[email protected]>
[ Upstream commit 65c5a055b0d567b7e7639d942c0605da9cc54c5e ]
The offending commit breaks BLKROSET ioctl because a device revalidation will blindly override BLKROSET setting. Hence, we remove the disk rw setting in case NVME_NS_ATTR_RO is cleared from by the controller.
--- drivers/nvme/host/core.c | 2 -- 1 file changed, 2 deletions(-)
drivers/nvme/host/core.c +0 -2
@@ -2064,8 +2064,6 @@ static void nvme_update_disk_info(struct gendisk *disk,if (id->nsattr &NVME_NS_ATTR_RO )set_disk_ro (disk, true); -else -set_disk_ro (disk, false); }static inline bool nvme_first_scan (struct gendisk *disk)
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 180/255 perf: Simplify group_sched_in()
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
[ Upstream commit 251ff2d49347793d348babcff745289b11910e96 ]
Collate the error paths. Code duplication only leads to divergence and extra bugs.
--- kernel/events/core.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-)
kernel/events/core.c +3 -7
@@ -2565,11 +2565,8 @@ group_sched_in(struct perf_event *group_event, pmu->start_txn (pmu,PERF_PMU_TXN_ADD ); -if (event_sched_in (group_event, cpuctx, ctx)) { - pmu->cancel_txn (pmu); -perf_mux_hrtimer_restart (cpuctx); -return -EAGAIN ; - } +if (event_sched_in (group_event, cpuctx, ctx)) + goto error;/* * Schedule in siblings as one group (if any):
@@ -2598,10 +2595,9 @@ group_error: }event_sched_out (group_event, cpuctx, ctx); +error: pmu->cancel_txn (pmu); -perf_mux_hrtimer_restart (cpuctx); -return -EAGAIN ; }
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 181/255 perf: Fix event multiplexing for exclusive groups
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
[ Upstream commit 2714c3962f304d031d5016c963c4b459337b0749 ]
Commit 9e6302056f80 ("perf: Use hrtimers for event multiplexing") placed the hrtimer (re)start call in the wrong place. Instead of capturing all scheduling failures, it only considered the PMU failure.
The result is that groups using perf_event_attr::exclusive are no longer rotated.
--- kernel/events/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/events/core.c +1 -1
@@ -2597,7 +2597,6 @@ group_error: error: pmu->cancel_txn (pmu); -perf_mux_hrtimer_restart (cpuctx);return -EAGAIN ; }
@@ -3653,6 +3652,7 @@ static int merge_sched_in(struct perf_event *event, void *data) *can_add_hw =0 ; ctx->rotate_necessary =1 ; +perf_mux_hrtimer_restart (cpuctx); }return 0 ;
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 182/255 firmware: xilinx: fix out-of-bounds access
In reply to Greg Kroah-HartmanFrom: Arnd Bergmann <[email protected]>
commit f3217d6f2f7a76b36a3326ad58c8897f4d5fbe31 upstream.
The zynqmp_pm_set_suspend_mode() and zynqmp_pm_get_trustzone_version() functions pass values as api_id into zynqmp_pm_invoke_fn that are beyond PM_API_MAX, resulting in an out-of-bounds access:
drivers/firmware/xilinx/zynqmp.c: In function 'zynqmp_pm_set_suspend_mode':drivers/firmware/xilinx/zynqmp.c:150:24: warning: array subscript 2562 is above array bounds of 'u32[64]' {aka 'unsigned int[64]'} [-Warray-bounds]
150 | if (zynqmp_pm_features[api_id] != PM_FEATURE_UNCHECKED)
| ~~~~~~~~~~~~~~~~~~^~~~~~~~
drivers/firmware/xilinx/zynqmp.c:28:12: note: while referencing 'zynqmp_pm_features'
28 | static u32 zynqmp_pm_features[PM_API_MAX];
| ^~~~~~~~~~~~~~~~~~Replace the resulting undefined behavior with an error return. This may break some things that happen to work at the moment but seems better than randomly overwriting kernel data.
I assume we need additional fixes for the two functions that now return an error.
--- drivers/firmware/xilinx/zynqmp.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/firmware/xilinx/zynqmp.c +3 -0
@@ -147,6 +147,9 @@ static int zynqmp_pm_feature(u32 api_id)return 0 ;/* Return value if feature is already checked */ +if (api_id >ARRAY_SIZE (zynqmp_pm_features)) +return PM_FEATURE_INVALID ; +if (zynqmp_pm_features[api_id] !=PM_FEATURE_UNCHECKED )return zynqmp_pm_features[api_id];
Greg Kroah-Hartman
maintainerPATCH 183/255 erofs: fix setting up pcluster for temporary pages
In reply to Greg Kroah-HartmanFrom: Gao Xiang <[email protected]>
commit a30573b3cdc77b8533d004ece1ea7c0146b437a0 upstream.
pcluster should be only set up for all managed pages instead of temporary pages. Since it currently uses page->mapping to identify, the impact is minor for now.
[ Update: Vladimir reported the kernel log becomes polluted
because PAGE_FLAGS_CHECK_AT_FREE flag(s) set if the page allocation debug option is enabled. ]
--- fs/erofs/zdata.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
fs/erofs/zdata.c +5 -2
@@ -1080,8 +1080,11 @@ out_allocpage:cond_resched (); goto repeat; } -set_page_private (page, (unsigned long )pcl); -SetPagePrivate (page); + +if (tocache) { +set_page_private (page, (unsigned long )pcl); +SetPagePrivate (page); + } out:/* the only exit (for tracing and debugging) */ return page; }
Greg Kroah-Hartman
maintainerPATCH 184/255 erofs: derive atime instead of leaving it empty
In reply to Greg Kroah-HartmanFrom: Gao Xiang <[email protected]>
commit d3938ee23e97bfcac2e0eb6b356875da73d700df upstream.
EROFS has _only one_ ondisk timestamp (ctime is currently documented and recorded, we might also record mtime instead with a new compat feature if needed) for each extended inode since EROFS isn't mainly for archival purposes so no need to keep all timestamps on disk especially for Android scenarios due to security concerns. Also, romfs/cramfs don't have their own on-disk timestamp, and squashfs only records mtime instead.
Let's also derive access time from ondisk timestamp rather than leaving it empty, and if mtime/atime for each file are really needed for specific scenarios as well, we can also use xattrs to record them then.
--- fs/erofs/inode.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-)
fs/erofs/inode.c +11 -10
@@ -107,11 +107,9 @@ static struct page *erofs_read_inode(stri_gid_write (inode,le32_to_cpu (die->i_gid));set_nlink (inode,le32_to_cpu (die->i_nlink)); -/* ns timestamp */ - inode->i_mtime.tv_sec = inode->i_ctime.tv_sec = -le64_to_cpu (die->i_ctime); - inode->i_mtime.tv_nsec = inode->i_ctime.tv_nsec = -le32_to_cpu (die->i_ctime_nsec); +/* extended inode has its own timestamp */ + inode->i_ctime.tv_sec =le64_to_cpu (die->i_ctime); + inode->i_ctime.tv_nsec =le32_to_cpu (die->i_ctime_nsec); inode->i_size =le64_to_cpu (die->i_size);
@@ -149,11 +147,9 @@ static struct page *erofs_read_inode(stri_gid_write (inode,le16_to_cpu (dic->i_gid));set_nlink (inode,le16_to_cpu (dic->i_nlink)); -/* use build time to derive all file time */ - inode->i_mtime.tv_sec = inode->i_ctime.tv_sec = - sbi->build_time; - inode->i_mtime.tv_nsec = inode->i_ctime.tv_nsec = - sbi->build_time_nsec; +/* use build time for compact inodes */ + inode->i_ctime.tv_sec = sbi->build_time; + inode->i_ctime.tv_nsec = sbi->build_time_nsec; inode->i_size =le32_to_cpu (dic->i_size);if (erofs_inode_is_data_compressed (vi->datalayout))
@@ -167,6 +163,11 @@ static struct page *erofs_read_inode(str goto err_out; } + inode->i_mtime.tv_sec = inode->i_ctime.tv_sec; + inode->i_atime.tv_sec = inode->i_ctime.tv_sec; + inode->i_mtime.tv_nsec = inode->i_ctime.tv_nsec; + inode->i_atime.tv_nsec = inode->i_ctime.tv_nsec; +if (!nblks)/* measure inode.i_blocks as generic filesystems */ inode->i_blocks =roundup (inode->i_size,EROFS_BLKSIZ ) >>9 ;
Greg Kroah-Hartman
maintainerPATCH 185/255 ext4: correctly report "not supported" for {usr,grp}jquota when !CONFIG_QUOTA
In reply to Greg Kroah-HartmanFrom: Kaixu Xia <[email protected]>
commit 174fe5ba2d1ea0d6c5ab2a7d4aa058d6d497ae4d upstream.
The macro MOPT_Q is used to indicates the mount option is related to quota stuff and is defined to be MOPT_NOSUPPORT when CONFIG_QUOTA is disabled. Normally the quota options are handled explicitly, so it didn't matter that the MOPT_STRING flag was missing, even though the usrjquota and grpjquota mount options take a string argument. It's important that's present in the !CONFIG_QUOTA case, since without MOPT_STRING, the mount option matcher will match usrjquota= followed by an integer, and will otherwise skip the table entry, and so "mount option not supported" error message is never reported.
[ Fixed up the commit description to better explain why the fix
works. --TYT ]
--- fs/ext4/super.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
fs/ext4/super.c +2 -2
@@ -1829,8 +1829,8 @@ static const struct mount_opts { {Opt_noquota, (EXT4_MOUNT_QUOTA |EXT4_MOUNT_USRQUOTA |EXT4_MOUNT_GRPQUOTA |EXT4_MOUNT_PRJQUOTA ), MOPT_CLEAR | MOPT_Q}, - {Opt_usrjquota, 0, MOPT_Q}, - {Opt_grpjquota, 0, MOPT_Q}, + {Opt_usrjquota, 0, MOPT_Q | MOPT_STRING}, + {Opt_grpjquota, 0, MOPT_Q | MOPT_STRING}, {Opt_offusrjquota, 0, MOPT_Q}, {Opt_offgrpjquota, 0, MOPT_Q}, {Opt_jqfmt_vfsold, QFMT_VFS_OLD, MOPT_QFMT},
Greg Kroah-Hartman
maintainerPATCH 186/255 ext4: unlock xattr_sem properly in ext4_inline_data_truncate()
In reply to Greg Kroah-HartmanFrom: Joseph Qi <[email protected]>
commit 7067b2619017d51e71686ca9756b454de0e5826a upstream.
It takes xattr_sem to check inline data again but without unlock it in case not have. So unlock it before return.
--- fs/ext4/inline.c | 1 + 1 file changed, 1 insertion(+)
fs/ext4/inline.c +1 -0
@@ -1880,6 +1880,7 @@ int ext4_inline_data_truncate(struct inoext4_write_lock_xattr (inode, &no_expand);if (!ext4_has_inline_data (inode)) { +ext4_write_unlock_xattr (inode, &no_expand); *has_inline =0 ;ext4_journal_stop (handle);return 0 ;
Greg Kroah-Hartman
maintainerPATCH 187/255 btrfs: fix potential overflow in cluster_pages_for_defrag on 32bit arch
In reply to Greg Kroah-HartmanFrom: Matthew Wilcox (Oracle) <[email protected]>
commit a1fbc6750e212c5675a4e48d7f51d44607eb8756 upstream.
On 32-bit systems, this shift will overflow for files larger than 4GB as start_index is unsigned long while the calls to btrfs_delalloc_*_space expect u64.
--- fs/btrfs/ioctl.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-)
fs/btrfs/ioctl.c +4 -6
@@ -1261,6 +1261,7 @@ static int cluster_pages_for_defrag(struu64 page_start;u64 page_end;u64 page_cnt; +u64 start = (u64 )start_index <<PAGE_SHIFT ;int ret;int i;int i_done;
@@ -1277,8 +1278,7 @@ static int cluster_pages_for_defrag(stru page_cnt =min_t (u64, (u64 )num_pages, (u64 )file_end - start_index +1 ); ret =btrfs_delalloc_reserve_space (BTRFS_I (inode), &data_reserved, - start_index <<PAGE_SHIFT , - page_cnt <<PAGE_SHIFT ); + start, page_cnt <<PAGE_SHIFT );if (ret)return ret; i_done =0 ;
@@ -1367,8 +1367,7 @@ again:btrfs_mod_outstanding_extents (BTRFS_I (inode),1 );spin_unlock (&BTRFS_I (inode)->lock);btrfs_delalloc_release_space (BTRFS_I (inode), data_reserved, - start_index <<PAGE_SHIFT , - (page_cnt - i_done) <<PAGE_SHIFT , true); + start, (page_cnt - i_done) <<PAGE_SHIFT , true); }
@@ -1395,8 +1394,7 @@ out:put_page (pages[i]); }btrfs_delalloc_release_space (BTRFS_I (inode), data_reserved, - start_index <<PAGE_SHIFT , - page_cnt <<PAGE_SHIFT , true); + start, page_cnt <<PAGE_SHIFT , true);btrfs_delalloc_release_extents (BTRFS_I (inode), page_cnt <<PAGE_SHIFT );extent_changeset_free (data_reserved);return ret;
Greg Kroah-Hartman
maintainerPATCH 188/255 btrfs: ref-verify: fix memory leak in btrfs_ref_tree_mod
In reply to Greg Kroah-HartmanFrom: Dinghao Liu <[email protected]>
commit 468600c6ec28613b756193c5f780aac062f1acdf upstream.
There is one error handling path that does not free ref, which may cause a minor memory leak.
--- fs/btrfs/ref-verify.c | 1 + 1 file changed, 1 insertion(+)
fs/btrfs/ref-verify.c +1 -0
@@ -860,6 +860,7 @@ int btrfs_ref_tree_mod(struct btrfs_fs_i "dropping a ref for a root that doesn't have a ref on the block");dump_block_entry (fs_info, be);dump_ref_action (fs_info, ra); +kfree (ref);kfree (ra); goto out_unlock; }
Greg Kroah-Hartman
maintainerPATCH 189/255 btrfs: fix min reserved size calculation in merge_reloc_root
In reply to Greg Kroah-HartmanFrom: Josef Bacik <[email protected]>
commit fca3a45d08782a2bb85e048fb8e3128b1388d7b7 upstream.
The minimum reserve size was adjusted to take into account the height of the tree we are merging, however we can have a root with a level == 0. What we want is root_level + 1 to get the number of nodes we may have to cow. This fixes the enospc_debug warning pops with btrfs/101.
Nikolay: this fixes failures on btrfs/060 btrfs/062 btrfs/063 and btrfs/195 That I was seeing, the call trace was:
[ 3680.515564] ------------[ cut here ]------------ [ 3680.515566] BTRFS: block rsv returned -28 [ 3680.515585] WARNING: CPU: 2 PID: 8339 at fs/btrfs/block-rsv.c:521 btrfs_use_block_rsv+0x162/0x180 [ 3680.515587] Modules linked in: [ 3680.515591] CPU: 2 PID: 8339 Comm: btrfs Tainted: G W 5.9.0-rc8-default #95 [ 3680.515593] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1ubuntu1 04/01/2014 [ 3680.515595] RIP: 0010:btrfs_use_block_rsv+0x162/0x180 [ 3680.515600] RSP: 0018:ffffa01ac9753910 EFLAGS: 00010282 [ 3680.515602] RAX: 0000000000000000 RBX: ffff984b34200000 RCX: 0000000000000027 [ 3680.515604] RDX: 0000000000000027 RSI: 0000000000000000 RDI: ffff984b3bd19e28 [ 3680.515606] RBP: 0000000000004000 R08: ffff984b3bd19e20 R09: 0000000000000001 [ 3680.515608] R10: 0000000000000004 R11: 0000000000000046 R12: ffff984b264fdc00 [ 3680.515609] R13: ffff984b13149000 R14: 00000000ffffffe4 R15: ffff984b34200000 [ 3680.515613] FS: 00007f4e2912b8c0(0000) GS:ffff984b3bd00000(0000) knlGS:0000000000000000 [ 3680.515615] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 3680.515617] CR2: 00007fab87122150 CR3: 0000000118e42000 CR4: 00000000000006e0 [ 3680.515620] Call Trace: [ 3680.515627] btrfs_alloc_tree_block+0x8b/0x340 [ 3680.515633] ? __lock_acquire+0x51a/0xac0 [ 3680.515646] alloc_tree_block_no_bg_flush+0x4f/0x60 [ 3680.515651] __btrfs_cow_block+0x14e/0x7e0 [ 3680.515662] btrfs_cow_block+0x144/0x2c0 [ 3680.515670] merge_reloc_root+0x4d4/0x610 [ 3680.515675] ? btrfs_lookup_fs_root+0x78/0x90 [ 3680.515686] merge_reloc_roots+0xee/0x280 [ 3680.515695] relocate_block_group+0x2ce/0x5e0 [ 3680.515704] btrfs_relocate_block_group+0x16e/0x310 [ 3680.515711] btrfs_relocate_chunk+0x38/0xf0 [ 3680.515716] btrfs_shrink_device+0x200/0x560 [ 3680.515728] btrfs_rm_device+0x1ae/0x6a6 [ 3680.515744] ? _copy_from_user+0x6e/0xb0 [ 3680.515750] btrfs_ioctl+0x1afe/0x28c0 [ 3680.515755] ? find_held_lock+0x2b/0x80 [ 3680.515760] ? do_user_addr_fault+0x1f8/0x418 [ 3680.515773] ? __x64_sys_ioctl+0x77/0xb0 [ 3680.515775] __x64_sys_ioctl+0x77/0xb0 [ 3680.515781] do_syscall_64+0x31/0x70 [ 3680.515785] entry_SYSCALL_64_after_hwframe+0x44/0xa9
--- fs/btrfs/relocation.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
fs/btrfs/relocation.c +3 -1
@@ -1646,6 +1646,7 @@ static noinline_for_stack int merge_relostruct btrfs_root_item *root_item;struct btrfs_path *path;struct extent_buffer *leaf; +int reserve_level;int level;int max_level;int replaced =0 ;
@@ -1694,7 +1695,8 @@ static noinline_for_stack int merge_relo* Thus the needed metadata size is at most root_level * nodesize, * and * 2 since we have two trees to COW. */ - min_reserved = fs_info->nodesize *btrfs_root_level (root_item) *2 ; + reserve_level =max_t (int,1 ,btrfs_root_level (root_item)); + min_reserved = fs_info->nodesize * reserve_level *2 ;memset (&next_key,0 ,sizeof (next_key));while (1 ) {
Greg Kroah-Hartman
maintainerPATCH 190/255 btrfs: dev-replace: fail mount if we dont have replace item with target device
In reply to Greg Kroah-HartmanFrom: Anand Jain <[email protected]>
commit cf89af146b7e62af55470cf5f3ec3c56ec144a5e upstream.
If there is a device BTRFS_DEV_REPLACE_DEVID without the device replace item, then it means the filesystem is inconsistent state. This is either corruption or a crafted image. Fail the mount as this needs a closer look what is actually wrong.
As of now if BTRFS_DEV_REPLACE_DEVID is present without the replace item, in __btrfs_free_extra_devids() we determine that there is an extra device, and free those extra devices but continue to mount the device.
However, we were wrong in keeping tack of the rw_devices so the syzbot testcase failed:
WARNING: CPU: 1 PID: 3612 at fs/btrfs/volumes.c:1166 close_fs_devices.part.0+0x607/0x800 fs/btrfs/volumes.c:1166 Kernel panic - not syncing: panic_on_warn set ... CPU: 1 PID: 3612 Comm: syz-executor.2 Not tainted 5.9.0-rc4-syzkaller #0 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+0x198/0x1fd lib/dump_stack.c:118 panic+0x347/0x7c0 kernel/panic.c:231 __warn.cold+0x20/0x46 kernel/panic.c:600 report_bug+0x1bd/0x210 lib/bug.c:198 handle_bug+0x38/0x90 arch/x86/kernel/traps.c:234 exc_invalid_op+0x14/0x40 arch/x86/kernel/traps.c:254 asm_exc_invalid_op+0x12/0x20 arch/x86/include/asm/idtentry.h:536 RIP: 0010:close_fs_devices.part.0+0x607/0x800 fs/btrfs/volumes.c:1166 RSP: 0018:ffffc900091777e0 EFLAGS: 00010246 RAX: 0000000000040000 RBX: ffffffffffffffff RCX: ffffc9000c8b7000 RDX: 0000000000040000 RSI: ffffffff83097f47 RDI: 0000000000000007 RBP: dffffc0000000000 R08: 0000000000000001 R09: ffff8880988a187f R10: 0000000000000000 R11: 0000000000000001 R12: ffff88809593a130 R13: ffff88809593a1ec R14: ffff8880988a1908 R15: ffff88809593a050 close_fs_devices fs/btrfs/volumes.c:1193 [inline] btrfs_close_devices+0x95/0x1f0 fs/btrfs/volumes.c:1179 open_ctree+0x4984/0x4a2d fs/btrfs/disk-io.c:3434 btrfs_fill_super fs/btrfs/super.c:1316 [inline] btrfs_mount_root.cold+0x14/0x165 fs/btrfs/super.c:1672
The fix here is, when we determine that there isn't a replace item then fail the mount if there is a replace target device (devid 0).
--- fs/btrfs/dev-replace.c | 26 ++++++++++++++++++++++++-- fs/btrfs/volumes.c | 26 +++++++------------------- 2 files changed, 31 insertions(+), 21 deletions(-)
fs/btrfs/dev-replace.c +24 -2
@@ -95,6 +95,17 @@ int btrfs_init_dev_replace(struct btrfs_ ret =btrfs_search_slot (NULL , dev_root, &key, path,0 ,0 );if (ret) { no_valid_dev_replace_entry_found: +/* +* We don't have a replace item or it's corrupted. If there is +* a replace target, fail the mount. +*/ +if (btrfs_find_device (fs_info->fs_devices, +BTRFS_DEV_REPLACE_DEVID ,NULL ,NULL , false)) { +btrfs_err (fs_info, +"found replace target device without a valid replace item" ); + ret = -EUCLEAN ; + goto out; + } ret =0 ; dev_replace->replace_state =BTRFS_IOCTL_DEV_REPLACE_STATE_NEVER_STARTED ;
@@ -147,8 +158,19 @@ no_valid_dev_replace_entry_found:case BTRFS_IOCTL_DEV_REPLACE_STATE_NEVER_STARTED :case BTRFS_IOCTL_DEV_REPLACE_STATE_FINISHED :case BTRFS_IOCTL_DEV_REPLACE_STATE_CANCELED : - dev_replace->srcdev =NULL ; - dev_replace->tgtdev =NULL ; +/* +* We don't have an active replace item but if there is a +* replace target, fail the mount. +*/ +if (btrfs_find_device (fs_info->fs_devices, +BTRFS_DEV_REPLACE_DEVID ,NULL ,NULL , false)) { +btrfs_err (fs_info, +"replace devid present without an active replace item" ); + ret = -EUCLEAN ; + }else { + dev_replace->srcdev =NULL ; + dev_replace->tgtdev =NULL ; + }break ;case BTRFS_IOCTL_DEV_REPLACE_STATE_STARTED :case BTRFS_IOCTL_DEV_REPLACE_STATE_SUSPENDED :
fs/btrfs/volumes.c +7 -19
@@ -1064,22 +1064,13 @@ again:continue ; } -if (device->devid ==BTRFS_DEV_REPLACE_DEVID ) { -/* -* In the first step, keep the device which has -* the correct fsid and the devid that is used -* for the dev_replace procedure. -* In the second step, the dev_replace state is -* read from the device tree and it is known -* whether the procedure is really active or -* not, which means whether this device is -* used or whether it should be removed. -*/ -if (step ==0 ||test_bit (BTRFS_DEV_STATE_REPLACE_TGT , - &device->dev_state)) { -continue ; - } - } +/* +* We have already validated the presence of BTRFS_DEV_REPLACE_DEVID, +* in btrfs_init_dev_replace() so just continue. +*/ +if (device->devid ==BTRFS_DEV_REPLACE_DEVID ) +continue ; +if (device->bdev) {blkdev_put (device->bdev, device->mode); device->bdev =NULL ;
@@ -1088,9 +1079,6 @@ again:if (test_bit (BTRFS_DEV_STATE_WRITEABLE , &device->dev_state)) {list_del_init (&device->dev_alloc_list);clear_bit (BTRFS_DEV_STATE_WRITEABLE , &device->dev_state); -if (!test_bit (BTRFS_DEV_STATE_REPLACE_TGT , - &device->dev_state)) - fs_devices->rw_devices--; }list_del_init (&device->dev_list); fs_devices->num_devices--;
Greg Kroah-Hartman
maintainerPATCH 191/255 KVM: arm64: Dont hide ID registers from userspace
In reply to Greg Kroah-HartmanFrom: Andrew Jones <[email protected]>
commit f81cb2c3ad41ac6d8cb2650e3d72d5f67db1aa28 upstream.
ID registers are RAZ until they've been allocated a purpose, but that doesn't mean they should be removed from the KVM_GET_REG_LIST list. So far we only have one register, SYS_ID_AA64ZFR0_EL1, that is hidden from userspace when its function, SVE, is not present.
Expose SYS_ID_AA64ZFR0_EL1 to userspace as RAZ when SVE is not implemented. Removing the userspace visibility checks is enough to reexpose it, as it will already return zero to userspace when SVE is not present. The register already behaves as RAZ for the guest when SVE is not present.
--- arch/arm64/kvm/sys_regs.c | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-)
arch/arm64/kvm/sys_regs.c +1 -17
@@ -1193,16 +1193,6 @@ static unsigned int sve_visibility(constreturn REG_HIDDEN_USER |REG_HIDDEN_GUEST ; } -/* Visibility overrides for SVE-specific ID registers */ -static unsigned int sve_id_visibility (const struct kvm_vcpu *vcpu, -const struct sys_reg_desc *rd) -{ -if (vcpu_has_sve (vcpu)) -return 0 ; - -return REG_HIDDEN_USER ; -} -/* Generate the emulated ID_AA64ZFR0_EL1 value exposed to the guest */ static u64 guest_id_aa64zfr0_el1 (const struct kvm_vcpu *vcpu) {
@@ -1229,9 +1219,6 @@ static int get_id_aa64zfr0_el1(struct kv {u64 val; -if (WARN_ON (!vcpu_has_sve (vcpu))) -return -ENOENT ; - val =guest_id_aa64zfr0_el1 (vcpu);return reg_to_user (uaddr, &val, reg->id); }
@@ -1244,9 +1231,6 @@ static int set_id_aa64zfr0_el1(struct kvint err;u64 val; -if (WARN_ON (!vcpu_has_sve (vcpu))) -return -ENOENT ; - err =reg_from_user (&val, uaddr, id);if (err)return err;
@@ -1509,7 +1493,7 @@ static const struct sys_reg_desc sys_regID_SANITISED (ID_AA64PFR1_EL1 ),ID_UNALLOCATED (4 ,2 ),ID_UNALLOCATED (4 ,3 ), - { SYS_DESC(SYS_ID_AA64ZFR0_EL1), access_id_aa64zfr0_el1, .get_user = get_id_aa64zfr0_el1, .set_user = set_id_aa64zfr0_el1, .visibility = sve_id_visibility }, + { SYS_DESC(SYS_ID_AA64ZFR0_EL1), access_id_aa64zfr0_el1, .get_user = get_id_aa64zfr0_el1, .set_user = set_id_aa64zfr0_el1, },ID_UNALLOCATED (4 ,5 ),ID_UNALLOCATED (4 ,6 ), ID_UNALLOCATED(4,7),
Greg Kroah-Hartman
maintainerPATCH 192/255 speakup: Fix var_id_t values and thus keymap
In reply to Greg Kroah-HartmanFrom: Samuel Thibault <[email protected]>
commit d7012df3c9aecdcfb50f7a2ebad766952fd1410e upstream.
commit d97a9d7aea04 ("staging/speakup: Add inflection synth parameter") introduced a new "inflection" speakup parameter next to "pitch", but the values of the var_id_t enum are actually used by the keymap tables so we must not renumber them. The effect was that notably the volume control shortcut (speakup-1 or 2) was actually changing the inflection.
This moves the INFLECTION value at the end of the var_id_t enum to fix back the enum values. This also adds a warning about it.
--- drivers/accessibility/speakup/spk_types.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/accessibility/speakup/spk_types.h +6 -2
@@ -32,6 +32,10 @@ enum { E_NEW_DEFAULT, }; +/* +* Note: add new members at the end, speakupmap.h depends on the values of the +* enum starting from SPELL_DELAY (see inc_dec_var) +*/ enum var_id_t {VERSION =0 ,SYNTH ,SILENT ,SYNTH_DIRECT ,KEYMAP ,CHARS ,
@@ -42,9 +46,9 @@ enum var_id_t {SAY_CONTROL ,SAY_WORD_CTL ,NO_INTERRUPT ,KEY_ECHO ,SPELL_DELAY ,PUNC_LEVEL ,READING_PUNC ,ATTRIB_BLEEP ,BLEEPS , -RATE ,PITCH ,INFLECTION ,VOL ,TONE ,PUNCT ,VOICE ,FREQUENCY ,LANG , +RATE ,PITCH ,VOL ,TONE ,PUNCT ,VOICE ,FREQUENCY ,LANG ,DIRECT ,PAUSE , -CAPS_START ,CAPS_STOP ,CHARTAB , +CAPS_START ,CAPS_STOP ,CHARTAB ,INFLECTION ,MAXVARS };
Greg Kroah-Hartman
maintainerPATCH 193/255 speakup ttyio: Do not schedule() in ttyio_in_nowait
In reply to Greg Kroah-HartmanFrom: Samuel Thibault <[email protected]>
commit 3ed1cfb2cee4355ddef49489897bfe474daeeaec upstream.
With the ltlk and spkout drivers, the index read function, i.e. in_nowait, is getting called from the read_all_doc mechanism, from the timer softirq:
Call Trace: <IRQ> dump_stack+0x71/0x98 dequeue_task_idle+0x1f/0x28 __schedule+0x167/0x5d6 ? trace_hardirqs_on+0x2e/0x3a ? usleep_range+0x7f/0x7f schedule+0x8a/0xae schedule_timeout+0xb1/0xea ? del_timer_sync+0x31/0x31 do_wait_for_common+0xba/0x12b ? wake_up_q+0x45/0x45 wait_for_common+0x37/0x50 ttyio_in+0x2a/0x6b spk_ttyio_in_nowait+0xc/0x13 spk_get_index_count+0x20/0x93 cursor_done+0x1c6/0x4c6 ? read_all_doc+0xb1/0xb1 call_timer_fn+0x89/0x140 run_timer_softirq+0x164/0x1a5 ? read_all_doc+0xb1/0xb1 ? hrtimer_forward+0x7b/0x87 ? timerqueue_add+0x62/0x68 ? enqueue_hrtimer+0x95/0x9f __do_softirq+0x181/0x31f irq_exit+0x6a/0x86 smp_apic_timer_interrupt+0x15e/0x183 apic_timer_interrupt+0xf/0x20 </IRQ>
We thus should not schedule() at all, even with timeout == 0, this crashes the kernel. We can however use try_wait_for_completion() instead of wait_for_completion_timeout(0).
--- drivers/accessibility/speakup/spk_ttyio.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
drivers/accessibility/speakup/spk_ttyio.c +6 -4
@@ -298,11 +298,13 @@ static unsigned char ttyio_in(int timeoustruct spk_ldisc_data *ldisc_data = speakup_tty->disc_data;char rv; -if (wait_for_completion_timeout (&ldisc_data->completion, +if (!timeout) { +if (!try_wait_for_completion (&ldisc_data->completion)) +return 0xff ; + }else if (wait_for_completion_timeout (&ldisc_data->completion,usecs_to_jiffies (timeout)) ==0 ) { -if (timeout) -pr_warn ("spk_ttyio: timeout (%d) while waiting for input\n" , - timeout); +pr_warn ("spk_ttyio: timeout (%d) while waiting for input\n" , + timeout);return 0xff ; }
Greg Kroah-Hartman
maintainerPATCH 194/255 speakup: Fix clearing selection in safe context
In reply to Greg Kroah-HartmanFrom: Samuel Thibault <[email protected]>
commit 640969a69ca4dd2ac025fe873c6bf25eba8f11b3 upstream.
speakup_cut() calls speakup_clear_selection() which calls console_lock. Problem is: speakup_cut() is called from a keyboard interrupt context. This would hang if speakup_cut is pressed while the console lock is unfortunately already held.
We can however as well just defer calling clear_selection() until the already-deferred set_selection_kernel() call.
This was spotted by the lock hardener:
Possible unsafe locking scenario:\x0a
CPU0
----
lock(console_lock);
<Interrupt>
lock(console_lock);
\x0a *** DEADLOCK ***\x0a
[...]
Call Trace:
<IRQ>
dump_stack+0xc2/0x11a
print_usage_bug.cold+0x3e0/0x4b1
mark_lock+0xd95/0x1390
? print_irq_inversion_bug+0xa0/0xa0
__lock_acquire+0x21eb/0x5730
? __kasan_check_read+0x11/0x20
? check_chain_key+0x215/0x5e0
? register_lock_class+0x1580/0x1580
? lock_downgrade+0x7a0/0x7a0
? __rwlock_init+0x140/0x140
lock_acquire+0x13f/0x370
? speakup_clear_selection+0xe/0x20 [speakup]
console_lock+0x33/0x50
? speakup_clear_selection+0xe/0x20 [speakup]
speakup_clear_selection+0xe/0x20 [speakup]
speakup_cut+0x19e/0x4b0 [speakup]
keyboard_notifier_call+0x1f04/0x4a40 [speakup]
? read_all_doc+0x240/0x240 [speakup]
notifier_call_chain+0xbf/0x130
__atomic_notifier_call_chain+0x80/0x130
atomic_notifier_call_chain+0x16/0x20
kbd_event+0x7d7/0x3b20
? k_pad+0x850/0x850
? sysrq_filter+0x450/0xd40
input_to_handler+0x362/0x4b0
? rcu_read_lock_sched_held+0xe0/0xe0
input_pass_values+0x408/0x5a0
? __rwlock_init+0x140/0x140
? lock_acquire+0x13f/0x370
input_handle_event+0x70e/0x1380
input_event+0x67/0x90
atkbd_interrupt+0xe62/0x1d4e [atkbd]
? __kasan_check_write+0x14/0x20
? atkbd_event_work+0x130/0x130 [atkbd]
? _raw_spin_lock_irqsave+0x26/0x70
serio_interrupt+0x93/0x120 [serio]
i8042_interrupt+0x232/0x510 [i8042]
? rcu_read_lock_bh_held+0xd0/0xd0
? handle_irq_event+0xa5/0x13a
? i8042_remove+0x1f0/0x1f0 [i8042]
__handle_irq_event_percpu+0xe6/0x6c0
handle_irq_event_percpu+0x71/0x150
? __handle_irq_event_percpu+0x6c0/0x6c0
? __kasan_check_read+0x11/0x20
? do_raw_spin_unlock+0x5c/0x240
handle_irq_event+0xad/0x13a
handle_edge_irq+0x233/0xa90
do_IRQ+0x10b/0x310
common_interrupt+0xf/0xf
</IRQ>--- drivers/accessibility/speakup/main.c | 1 - drivers/accessibility/speakup/selection.c | 11 ++++------- drivers/accessibility/speakup/speakup.h | 1 - 3 files changed, 4 insertions(+), 9 deletions(-)
drivers/accessibility/speakup/main.c +0 -1
@@ -357,7 +357,6 @@ static void speakup_cut(struct vc_data * mark_cut_flag =0 ;synth_printf ("%s\n" ,spk_msg_get (MSG_CUT )); -speakup_clear_selection (); ret =speakup_set_selection (tty);switch (ret) {
drivers/accessibility/speakup/selection.c +4 -7
@@ -22,13 +22,6 @@ struct speakup_selection_work {struct tty_struct *tty; }; -void speakup_clear_selection (void ) -{ -console_lock (); -clear_selection (); -console_unlock (); -} -static void __speakup_set_selection (struct work_struct *work) { struct speakup_selection_work *ssw =
@@ -51,6 +44,10 @@ static void __speakup_set_selection(stru goto unref; } +console_lock (); +clear_selection (); +console_unlock (); +set_selection_kernel (&sel, tty); unref:
drivers/accessibility/speakup/speakup.h +0 -1
@@ -70,7 +70,6 @@ void spk_do_flush(void);void speakup_start_ttys (void );void synth_buffer_add (u16 ch);void synth_buffer_clear (void ); -void speakup_clear_selection (void );int speakup_set_selection (struct tty_struct *tty);void speakup_cancel_selection (void );int speakup_paste_selection (struct tty_struct *tty);
Greg Kroah-Hartman
maintainerPATCH 195/255 thunderbolt: Fix memory leak if ida_simple_get() fails in enumerate_services()
In reply to Greg Kroah-HartmanFrom: Mika Westerberg <[email protected]>
commit a663e0df4a374b8537562a44d1cecafb472cd65b upstream.
The svc->key field is not released as it should be if ida_simple_get() fails so fix that.
--- drivers/thunderbolt/xdomain.c | 1 + 1 file changed, 1 insertion(+)
drivers/thunderbolt/xdomain.c +1 -0
@@ -881,6 +881,7 @@ static void enumerate_services(struct tb id =ida_simple_get (&xd->service_ids,0 ,0 ,GFP_KERNEL );if (id <0 ) { +kfree (svc->key);kfree (svc);break ; }
Greg Kroah-Hartman
maintainerPATCH 196/255 thunderbolt: Add the missed ida_simple_remove() in ring_request_msix()
In reply to Greg Kroah-HartmanFrom: Jing Xiangfeng <[email protected]>
commit 7342ca34d931a357d408aaa25fadd031e46af137 upstream.
ring_request_msix() misses to call ida_simple_remove() in an error path. Add a label 'err_ida_remove' and jump to it.
--- drivers/thunderbolt/nhi.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-)
drivers/thunderbolt/nhi.c +15 -4
@@ -405,12 +405,23 @@ static int ring_request_msix(struct tb_r ring->vector = ret; - ring->irq =pci_irq_vector (ring->nhi->pdev, ring->vector); -if (ring->irq <0 ) -return ring->irq; + ret =pci_irq_vector (ring->nhi->pdev, ring->vector); +if (ret <0 ) + goto err_ida_remove; + + ring->irq = ret; irqflags = no_suspend ?IRQF_NO_SUSPEND :0 ; -return request_irq (ring->irq, ring_msix, irqflags,"thunderbolt" , ring); + ret =request_irq (ring->irq, ring_msix, irqflags,"thunderbolt" , ring); +if (ret) + goto err_ida_remove; + +return 0 ; + +err_ida_remove: +ida_simple_remove (&nhi->msix_ida, ring->vector); + +return ret; }static void ring_release_msix (struct tb_ring *ring)
Greg Kroah-Hartman
maintainerPATCH 197/255 block: add a return value to set_capacity_revalidate_and_notify
In reply to Greg Kroah-HartmanFrom: Christoph Hellwig <[email protected]>
commit 7e890c37c25c7cbca37ff0ab292873d8146e713b upstream.
Return if the function ended up sending an uevent or not.
--- block/genhd.c | 5 ++++- include/linux/genhd.h | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-)
block/genhd.c +4 -1
@@ -49,7 +49,7 @@ static void disk_release_events(struct g* Set disk capacity and notify if the size is not currently * zero and will not be set to zero */ -void set_capacity_revalidate_and_notify (struct gendisk *disk,sector_t size, +bool set_capacity_revalidate_and_notify (struct gendisk *disk,sector_t size,bool revalidate) {sector_t capacity =get_capacity (disk);
@@ -63,7 +63,10 @@ void set_capacity_revalidate_and_notify(char *envp[] = {"RESIZE=1" ,NULL };kobject_uevent_env (&disk_to_dev (disk)->kobj,KOBJ_CHANGE , envp); +return true; } + +return false; }EXPORT_SYMBOL_GPL (set_capacity_revalidate_and_notify);
include/linux/genhd.h +1 -1
@@ -315,7 +315,7 @@ static inline int get_disk_ro(struct genextern void disk_block_events (struct gendisk *disk);extern void disk_unblock_events (struct gendisk *disk);extern void disk_flush_events (struct gendisk *disk,unsigned int mask); -extern void set_capacity_revalidate_and_notify (struct gendisk *disk, +extern bool set_capacity_revalidate_and_notify (struct gendisk *disk,sector_t size,bool revalidate);extern unsigned int disk_clear_events (struct gendisk *disk,unsigned int mask);
Greg Kroah-Hartman
maintainerPATCH 198/255 loop: Fix occasional uevent drop
In reply to Greg Kroah-HartmanFrom: Petr Vorel <[email protected]>
commit c01a21b77722db0474bbcc4eafc8c4e0d8fed6d8 upstream.
Commit 716ad0986cbd ("loop: Switch to set_capacity_revalidate_and_notify") causes an occasional drop of loop device uevent, which are no longer triggered in loop_set_size() but in a different part of code.
Bug is reproducible with LTP test uevent01 [1]:
i=0; while true; do
i=$((i+1)); echo "== $i =="
lsmod |grep -q loop && rmmod -f loop
./uevent01 || breakdone
Put back triggering through code called in loop_set_size().
Fix required to add yet another parameter toset_capacity_revalidate_and_notify().
[1] https://github.com/linux-test-project/ltp/blob/master/testcases/kernel/uevents/uevent01.c
[hch: rebased on a different change to the prototype of
set_capacity_revalidate_and_notify]
--- drivers/block/loop.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/block/loop.c +2 -1
@@ -255,7 +255,8 @@ static void loop_set_size(struct loop_debd_set_size (bdev, size <<SECTOR_SHIFT ); -set_capacity_revalidate_and_notify (lo->lo_disk, size, false); +if (!set_capacity_revalidate_and_notify (lo->lo_disk, size, false)) +kobject_uevent (&disk_to_dev (bdev->bd_disk)->kobj,KOBJ_CHANGE ); } static inline int
Greg Kroah-Hartman
maintainerPATCH 199/255 uio: Fix use-after-free in uio_unregister_device()
In reply to Greg Kroah-HartmanFrom: Shin'ichiro Kawasaki <[email protected]>
commit 092561f06702dd4fdd7fb74dd3a838f1818529b7 upstream.
Commit 8fd0e2a6df26 ("uio: free uio id after uio file node is freed") triggered KASAN use-after-free failure at deletion of TCM-user backstores [1].
In uio_unregister_device(), struct uio_device *idev is passed to uio_free_minor() to refer idev->minor. However, before uio_free_minor() call, idev is already freed by uio_device_release() during call to device_unregister().
To avoid reference to idev->minor after idev free, keep idev->minor value in a local variable. Also modify uio_free_minor() argument to receive the value.
[1]
BUG: KASAN: use-after-free in uio_unregister_device+0x166/0x190 Read of size 4 at addr ffff888105196508 by task targetcli/49158 CPU: 3 PID: 49158 Comm: targetcli Not tainted 5.10.0-rc1 #1 Hardware name: Supermicro Super Server/X10SRL-F, BIOS 2.0 12/17/2015 Call Trace: dump_stack+0xae/0xe5 ? uio_unregister_device+0x166/0x190 print_address_description.constprop.0+0x1c/0x210 ? uio_unregister_device+0x166/0x190 ? uio_unregister_device+0x166/0x190 kasan_report.cold+0x37/0x7c ? kobject_put+0x80/0x410 ? uio_unregister_device+0x166/0x190 uio_unregister_device+0x166/0x190 tcmu_destroy_device+0x1c4/0x280 [target_core_user] ? tcmu_release+0x90/0x90 [target_core_user] ? __mutex_unlock_slowpath+0xd6/0x5d0 target_free_device+0xf3/0x2e0 [target_core_mod] config_item_cleanup+0xea/0x210 configfs_rmdir+0x651/0x860 ? detach_groups.isra.0+0x380/0x380 vfs_rmdir.part.0+0xec/0x3a0 ? __lookup_hash+0x20/0x150 do_rmdir+0x252/0x320 ? do_file_open_root+0x420/0x420 ? strncpy_from_user+0xbc/0x2f0 ? getname_flags.part.0+0x8e/0x450 do_syscall_64+0x33/0x40 entry_SYSCALL_64_after_hwframe+0x44/0xa9 RIP: 0033:0x7f9e2bfc91fb Code: 73 01 c3 48 8b 0d 9d ec 0c 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa b8 54 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 6d ec 0c 00 f7 d8 64 89 01 48 RSP: 002b:00007ffdd2baafe8 EFLAGS: 00000246 ORIG_RAX: 0000000000000054 RAX: ffffffffffffffda RBX: 00007f9e2beb44a0 RCX: 00007f9e2bfc91fb RDX: 0000000000000000 RSI: 0000000000000000 RDI: 00007f9e1c20be90 RBP: 00007ffdd2bab000 R08: 0000000000000000 R09: 00007f9e2bdf2440 R10: 00007ffdd2baaf37 R11: 0000000000000246 R12: 00000000ffffff9c R13: 000055f9abb7e390 R14: 000055f9abcf9558 R15: 00007f9e2be7a780 Allocated by task 34735: kasan_save_stack+0x1b/0x40 __kasan_kmalloc.constprop.0+0xc2/0xd0 __uio_register_device+0xeb/0xd40 tcmu_configure_device+0x5a0/0xbc0 [target_core_user] target_configure_device+0x12f/0x760 [target_core_mod] target_dev_enable_store+0x32/0x50 [target_core_mod] configfs_write_file+0x2bb/0x450 vfs_write+0x1ce/0x610 ksys_write+0xe9/0x1b0 do_syscall_64+0x33/0x40 entry_SYSCALL_64_after_hwframe+0x44/0xa9 Freed by task 49158: kasan_save_stack+0x1b/0x40 kasan_set_track+0x1c/0x30 kasan_set_free_info+0x1b/0x30 __kasan_slab_free+0x110/0x150 slab_free_freelist_hook+0x5a/0x170 kfree+0xc6/0x560 device_release+0x9b/0x210 kobject_put+0x13e/0x410 uio_unregister_device+0xf9/0x190 tcmu_destroy_device+0x1c4/0x280 [target_core_user] target_free_device+0xf3/0x2e0 [target_core_mod] config_item_cleanup+0xea/0x210 configfs_rmdir+0x651/0x860 vfs_rmdir.part.0+0xec/0x3a0 do_rmdir+0x252/0x320 do_syscall_64+0x33/0x40 entry_SYSCALL_64_after_hwframe+0x44/0xa9 The buggy address belongs to the object at ffff888105196000 which belongs to the cache kmalloc-2k of size 2048 The buggy address is located 1288 bytes inside of 2048-byte region [ffff888105196000, ffff888105196800) The buggy address belongs to the page: page:0000000098e6ca81 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x105190 head:0000000098e6ca81 order:3 compound_mapcount:0 compound_pincount:0 flags: 0x17ffffc0010200(slab|head) raw: 0017ffffc0010200 dead000000000100 dead000000000122 ffff888100043040 raw: 0000000000000000 0000000000080008 00000001ffffffff ffff88810eb55c01 page dumped because: kasan: bad access detected
page->mem_cgroup:ffff88810eb55c01
Memory state around the buggy address:
ffff888105196400: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff888105196480: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>ffff888105196500: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
^
ffff888105196580: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff888105196600: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb--- drivers/uio/uio.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
drivers/uio/uio.c +6 -4
@@ -413,10 +413,10 @@ static int uio_get_minor(struct uio_devireturn retval; } -static void uio_free_minor (struct uio_device *idev) +static void uio_free_minor (unsigned long minor) {mutex_lock (&minor_lock); -idr_remove (&uio_idr, idev->minor); +idr_remove (&uio_idr, minor);mutex_unlock (&minor_lock); }
@@ -990,7 +990,7 @@ err_request_irq: err_uio_dev_add_attributes:device_del (&idev->dev); err_device_create: -uio_free_minor (idev); +uio_free_minor (idev->minor);put_device (&idev->dev);return ret; }
@@ -1042,11 +1042,13 @@ EXPORT_SYMBOL_GPL(__devm_uio_register_devoid uio_unregister_device (struct uio_info *info) {struct uio_device *idev; +unsigned long minor;if (!info || !info->uio_dev)return ; idev = info->uio_dev; + minor = idev->minor;mutex_lock (&idev->info_lock);uio_dev_del_attributes (idev);
@@ -1062,7 +1064,7 @@ void uio_unregister_device(struct uio_indevice_unregister (&idev->dev); -uio_free_minor (idev); +uio_free_minor (minor);return ; }
Greg Kroah-Hartman
maintainerPATCH 200/255 Revert "usb: musb: convert to devm_platform_ioremap_resource_byname"
In reply to Greg Kroah-HartmanFrom: Geert Uytterhoeven <[email protected]>
commit ffa13d2d94029882eca22a565551783787f121e5 upstream.
This reverts commit 2d30e408a2a6b3443d3232593e3d472584a3e9f8.
On Beaglebone Black, where each interface has 2 children:
musb-dsps 47401c00.usb: can't request region for resource [mem 0x47401800-0x474019ff] musb-hdrc musb-hdrc.1: musb_init_controller failed with status -16
musb-hdrc: probe of musb-hdrc.1 failed with error -16
musb-dsps 47401400.usb: can't request region for resource [mem 0x47401000-0x474011ff] musb-hdrc musb-hdrc.0: musb_init_controller failed with status -16
musb-hdrc: probe of musb-hdrc.0 failed with error -16
Before, devm_ioremap_resource() was called on "dev" ("musb-hdrc.0" or "musb-hdrc.1"), after it is called on "&pdev->dev" ("47401400.usb" or "47401c00.usb"), leading to a duplicate region request, which fails.
--- drivers/usb/musb/musb_dsps.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/usb/musb/musb_dsps.c +3 -1
@@ -429,10 +429,12 @@ static int dsps_musb_init(struct musb *mstruct platform_device *parent =to_platform_device (dev->parent);const struct dsps_musb_wrapper *wrp = glue->wrp;void __iomem *reg_base; +struct resource *r;u32 rev, val;int ret; - reg_base =devm_platform_ioremap_resource_byname (parent,"control" ); + r =platform_get_resource_byname (parent,IORESOURCE_MEM ,"control" ); + reg_base =devm_ioremap_resource (dev, r);if (IS_ERR (reg_base))return PTR_ERR (reg_base); musb->ctrl_base = reg_base;
Greg Kroah-Hartman
maintainerPATCH 201/255 usb: cdc-acm: Add DISABLE_ECHO for Renesas USB Download mode
In reply to Greg Kroah-HartmanFrom: Chris Brandt <[email protected]>
commit 6d853c9e4104b4fc8d55dc9cd3b99712aa347174 upstream.
Renesas R-Car and RZ/G SoCs have a firmware download mode over USB. However, on reset a banner string is transmitted out which is not expected to be echoed back and will corrupt the protocol.
--- drivers/usb/class/cdc-acm.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/usb/class/cdc-acm.c +9 -0
@@ -1706,6 +1706,15 @@ static const struct usb_device_id acm_id { USB_DEVICE(0x0870, 0x0001), /* Metricom GS Modem */ .driver_info =NO_UNION_NORMAL ,/* has no union descriptor */ }, + { USB_DEVICE(0x045b, 0x023c), /* Renesas USB Download mode */ + .driver_info = DISABLE_ECHO, /* Don't echo banner */ + }, + { USB_DEVICE(0x045b, 0x0248), /* Renesas USB Download mode */ + .driver_info = DISABLE_ECHO, /* Don't echo banner */ + }, + { USB_DEVICE(0x045b, 0x024D), /* Renesas USB Download mode */ + .driver_info = DISABLE_ECHO, /* Don't echo banner */ + }, { USB_DEVICE(0x0e8d, 0x0003), /* FIREFLY, MediaTek Inc; [email protected] */ .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ },
Greg Kroah-Hartman
maintainerPATCH 202/255 usb: typec: ucsi: Report power supply changes
In reply to Greg Kroah-HartmanFrom: Heikki Krogerus <[email protected]>
commit 0e6371fbfba3a4f76489e6e97c1c7f8386ad5fd2 upstream.
When the ucsi power supply goes online/offline, and when the power levels change, the power supply class needs to be notified so it can inform the user space.
--- drivers/usb/typec/ucsi/psy.c | 9 +++++++++ drivers/usb/typec/ucsi/ucsi.c | 7 ++++++- drivers/usb/typec/ucsi/ucsi.h | 2 ++ 3 files changed, 17 insertions(+), 1 deletion(-)
drivers/usb/typec/ucsi/psy.c +9 -0
@@ -238,4 +238,13 @@ void ucsi_unregister_port_psy(struct ucsreturn ;power_supply_unregister (con->psy); + con->psy =NULL ; +} + +void ucsi_port_psy_changed (struct ucsi_connector *con) +{ +if (IS_ERR_OR_NULL (con->psy)) +return ; + +power_supply_changed (con->psy); }
drivers/usb/typec/ucsi/ucsi.c +6 -1
@@ -643,8 +643,10 @@ static void ucsi_handle_connector_change role = !!(con->status.flags &UCSI_CONSTAT_PWR_DIR );if (con->status.change &UCSI_CONSTAT_POWER_OPMODE_CHANGE || - con->status.change &UCSI_CONSTAT_POWER_LEVEL_CHANGE ) + con->status.change &UCSI_CONSTAT_POWER_LEVEL_CHANGE ) {ucsi_pwr_opmode_change (con); +ucsi_port_psy_changed (con); + }if (con->status.change &UCSI_CONSTAT_POWER_DIR_CHANGE ) {typec_set_pwr_role (con->port, role);
@@ -674,6 +676,8 @@ static void ucsi_handle_connector_changeucsi_register_partner (con); elseucsi_unregister_partner (con ); + +ucsi_port_psy_changed (con); }if (con->status.change &UCSI_CONSTAT_CAM_CHANGE ) {
@@ -994,6 +998,7 @@ static int ucsi_register_port(struct ucs !!(con->status.flags & UCSI_CONSTAT_PWR_DIR));ucsi_pwr_opmode_change (con);ucsi_register_partner (con); +ucsi_port_psy_changed (con); }if (con->partner) {
drivers/usb/typec/ucsi/ucsi.h +2 -0
@@ -340,9 +340,11 @@ int ucsi_resume(struct ucsi *ucsi);#if IS_ENABLED (CONFIG_POWER_SUPPLY )int ucsi_register_port_psy (struct ucsi_connector *con);void ucsi_unregister_port_psy (struct ucsi_connector *con); +void ucsi_port_psy_changed (struct ucsi_connector *con);#else static inline int ucsi_register_port_psy (struct ucsi_connector *con) {return 0 ; }static inline void ucsi_unregister_port_psy (struct ucsi_connector *con) { } +static inline void ucsi_port_psy_changed (struct ucsi_connector *con) { }#endif /* CONFIG_POWER_SUPPLY */ #if IS_ENABLED (CONFIG_TYPEC_DP_ALTMODE )
Greg Kroah-Hartman
maintainerPATCH 203/255 xhci: hisilicon: fix refercence leak in xhci_histb_probe
In reply to Greg Kroah-HartmanFrom: Zhang Qilong <[email protected]>
commit 76255470ffa2795a44032e8b3c1ced11d81aa2db upstream.
pm_runtime_get_sync() will increment pm usage at first and it will resume the device later. We should decrease the usage count whetever it succeeded or failed(maybe runtime of the device has error, or device is in inaccessible state, or other error state). If we do not call put operation to decrease the reference, it will result in reference leak in xhci_histb_probe. Moreover, this device cannot enter the idle state and always stay busy or other non-idle state later. So we fixed it by jumping to error handling branch.
--- drivers/usb/host/xhci-histb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/host/xhci-histb.c +1 -1
@@ -240,7 +240,7 @@ static int xhci_histb_probe(struct platf/* Initialize dma_mask and coherent_dma_mask to 32-bits */ ret =dma_set_mask_and_coherent (dev,DMA_BIT_MASK (32 ));if (ret) -return ret; + goto disable_pm; hcd =usb_create_hcd (driver, dev,dev_name (dev));if (!hcd) {
Greg Kroah-Hartman
maintainerPATCH 204/255 virtio: virtio_console: fix DMA memory allocation for rproc serial
In reply to Greg Kroah-HartmanFrom: Alexander Lobakin <[email protected]>
commit 9d516aa82b7d4fbe7f6303348697960ba03a530b upstream.
Since commit 086d08725d34 ("remoteproc: create vdev subdevice with specific dma memory pool"), every remoteproc has a DMA subdevice ("remoteprocX#vdevYbuffer") for each virtio device, which inherits DMA capabilities from the corresponding platform device. This allowed to associate different DMA pools with each vdev, and required from virtio drivers to perform DMA operations with the parent device (vdev->dev.parent) instead of grandparent (vdev->dev.parent->parent).
virtio_rpmsg_bus was already changed in the same merge cycle with commit d999b622fcfb ("rpmsg: virtio: allocate buffer from parent"), but virtio_console did not. In fact, operations using the grandparent worked fine while the grandparent was the platform device, but since commit c774ad010873 ("remoteproc: Fix and restore the parenting hierarchy for vdev") this was changed, and now the grandparent device is the remoteproc device without any DMA capabilities.
So, starting v5.8-rc1 the following warning is observed:
[ 2.483925] ------------[ cut here ]------------ [ 2.489148] WARNING: CPU: 3 PID: 101 at kernel/dma/mapping.c:427 0x80e7eee8 [ 2.489152] Modules linked in: virtio_console(+) [ 2.503737] virtio_rpmsg_bus rpmsg_core [ 2.508903] [ 2.528898] <Other modules, stack and call trace here> [ 2.913043] [ 2.914907] ---[ end trace 93ac8746beab612c ]--- [ 2.920102] virtio-ports vport1p0: Error allocating inbufs
kernel/dma/mapping.c:427 is:
WARN_ON_ONCE(!dev->coherent_dma_mask);
obviously because the grandparent now is remoteproc dev without any DMA caps:
[ 3.104943] Parent: remoteproc0#vdev1buffer, grandparent: remoteproc0
Fix this the same way as it was for virtio_rpmsg_bus, using just the parent device (vdev->dev.parent, "remoteprocX#vdevYbuffer") for DMA operations.
This also allows now to reserve DMA pools/buffers for rproc serial via Device Tree.
Date: Thu, 5 Nov 2020 11:10:24 +0800
--- drivers/char/virtio_console.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/char/virtio_console.c +4 -4
@@ -435,12 +435,12 @@ static struct port_buffer *alloc_buf(str/* * Allocate DMA memory from ancestor. When a virtio * device is created by remoteproc, the DMA memory is -* associated with the grandparent device: -* vdev => rproc => platform-dev. +* associated with the parent device: +* virtioY => remoteprocX#vdevYbuffer. */ -if (!vdev->dev.parent || !vdev->dev.parent->parent) + buf->dev = vdev->dev.parent; +if (!buf->dev) goto free_buf; - buf->dev = vdev->dev.parent->parent;/* Increase device refcnt to avoid freeing it */ get_device (buf->dev);
Greg Kroah-Hartman
maintainerPATCH 205/255 mei: protect mei_cl_mtu from null dereference
In reply to Greg Kroah-HartmanFrom: Alexander Usyskin <[email protected]>
commit bcbc0b2e275f0a797de11a10eff495b4571863fc upstream.
A receive callback is queued while the client is still connected but can still be called after the client was disconnected. Upon disconnect cl->me_cl is set to NULL, hence we need to check that ME client is not-NULL in mei_cl_mtu to avoid
null dereference.
--- drivers/misc/mei/client.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/misc/mei/client.h +2 -2
@@ -164,11 +164,11 @@ static inline u8 mei_cl_me_id(const stru* * @cl: host client * -* Return: mtu +* Return: mtu or 0 if client is not connected */ static inline size_t mei_cl_mtu (const struct mei_cl *cl) { -return cl->me_cl->props.max_msg_length; +return cl->me_cl ? cl->me_cl->props.max_msg_length :0 ; }/**
Greg Kroah-Hartman
maintainerPATCH 206/255 futex: Dont enable IRQs unconditionally in put_pi_state()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
commit 1e106aa3509b86738769775969822ffc1ec21bf4 upstream.
The exit_pi_state_list() function calls put_pi_state() with IRQs disabled and is not expecting that IRQs will be enabled inside the function.
Use the _irqsave() variant so that IRQs are restored to the original state instead of being enabled unconditionally.
--- kernel/futex.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
kernel/futex.c +3 -2
@@ -788,8 +788,9 @@ static void put_pi_state(struct futex_pi*/ if (pi_state->owner) {struct task_struct *owner; +unsigned long flags; -raw_spin_lock_irq (&pi_state->pi_mutex.wait_lock); +raw_spin_lock_irqsave (&pi_state->pi_mutex.wait_lock, flags); owner = pi_state->owner;if (owner) {raw_spin_lock (&owner->pi_lock);
@@ -797,7 +798,7 @@ static void put_pi_state(struct futex_piraw_spin_unlock (&owner->pi_lock); }rt_mutex_proxy_unlock (&pi_state->pi_mutex, owner); -raw_spin_unlock_irq (&pi_state->pi_mutex.wait_lock); +raw_spin_unlock_irqrestore (&pi_state->pi_mutex.wait_lock, flags); }if (current->pi_state_cache) {
Greg Kroah-Hartman
maintainerPATCH 207/255 jbd2: fix up sparse warnings in checkpoint code
In reply to Greg Kroah-HartmanFrom: Theodore Ts'o <[email protected]>
commit 05d5233df85e9621597c5838e95235107eb624a2 upstream.
Add missing __acquires() and __releases() annotations. Also, in an "this should never happen" WARN_ON check, if it *does* actually happen, we need to release j_state_lock since this function is always supposed to release that lock. Otherwise, things will quickly grind to a halt after the WARN_ON trips.
--- fs/jbd2/checkpoint.c | 2 ++ fs/jbd2/transaction.c | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-)
fs/jbd2/checkpoint.c +2 -0
@@ -106,6 +106,8 @@ static int __try_to_free_cp_buf(struct j* for a checkpoint to free up some space in the log. */ void __jbd2_log_wait_for_space (journal_t *journal) +__acquires(&journal->j_state_lock) +__releases(&journal->j_state_lock) {int nblocks, space_left;/* assert_spin_locked(&journal->j_state_lock); */
fs/jbd2/transaction.c +3 -1
@@ -195,8 +195,10 @@ static void wait_transaction_switching(jDEFINE_WAIT (wait);if (WARN_ON (!journal->j_running_transaction || - journal->j_running_transaction->t_state !=T_SWITCH )) + journal->j_running_transaction->t_state !=T_SWITCH )) { +read_unlock (&journal->j_state_lock);return ; + }prepare_to_wait (&journal->j_wait_transaction_locked, &wait,TASK_UNINTERRUPTIBLE );read_unlock (&journal->j_state_lock);
Greg Kroah-Hartman
maintainerPATCH 208/255 bootconfig: Extend the magic check range to the preceding 3 bytes
In reply to Greg Kroah-HartmanFrom: Masami Hiramatsu <[email protected]>
commit 50b8a742850fce7293bed45753152c425f7e931b upstream.
Since Grub may align the size of initrd to 4 if user pass initrd from cpio, we have to check the preceding 3 bytes as well.
--- init/main.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
init/main.c +12 -2
@@ -267,14 +267,24 @@ static void * __init get_boot_config_frou32 size, csum;char *data;u32 *hdr; +int i;if (!initrd_end)return NULL ; data = (char *)initrd_end -BOOTCONFIG_MAGIC_LEN ; -if (memcmp (data,BOOTCONFIG_MAGIC ,BOOTCONFIG_MAGIC_LEN )) -return NULL ; +/* +* Since Grub may align the size of initrd to 4, we must +* check the preceding 3 bytes as well. +*/ +for (i =0 ; i <4 ; i++) { +if (!memcmp (data,BOOTCONFIG_MAGIC ,BOOTCONFIG_MAGIC_LEN )) + goto found; + data--; + } +return NULL ; +found: hdr = (u32 *)(data -8 ); size = hdr[0 ]; csum = hdr[1 ];
Greg Kroah-Hartman
maintainerPATCH 209/255 mm/compaction: count pages and stop correctly during page isolation
In reply to Greg Kroah-HartmanFrom: Zi Yan <[email protected]>
commit 38935861d85a4d9a353d1dd5a156c97700e2765d upstream.
In isolate_migratepages_block, when cc->alloc_contig is true, we are able to isolate compound pages. But nr_migratepages and nr_isolated did not count compound pages correctly, causing us to isolate more pages than we thought.
So count compound pages as the number of base pages they contain. Otherwise, we might be trapped in too_many_isolated while loop, since the actual isolated pages can go up to COMPACT_CLUSTER_MAX*512=16384, where COMPACT_CLUSTER_MAX is 32, since we stop isolation after cc->nr_migratepages reaches to COMPACT_CLUSTER_MAX.
In addition, after we fix the issue above, cc->nr_migratepages could never be equal to COMPACT_CLUSTER_MAX if compound pages are isolated, thus page isolation could not stop as we intended. Change the isolation stop condition to '>='.
The issue can be triggered as follows:
In a system with 16GB memory and an 8GB CMA region reserved by hugetlb_cma, if we first allocate 10GB THPs and mlock them (so some THPs are allocated in the CMA region and mlocked), reserving 6 1GB hugetlb pages via /sys/kernel/mm/hugepages/hugepages-1048576kB/nr_hugepages will get stuck (looping in too_many_isolated function) until we kill either task. With the patch applied, oom will kill the application with 10GB THPs and let hugetlb page reservation finish.
[[email protected]: v3]
--- mm/compaction.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
mm/compaction.c +4 -4
@@ -1013,8 +1013,8 @@ isolate_migratepages_block(struct compac isolate_success:list_add (&page->lru, &cc->migratepages); - cc->nr_migratepages++; - nr_isolated++; + cc->nr_migratepages +=compound_nr (page); + nr_isolated +=compound_nr (page);/* * Avoid isolating too much unless this block is being
@@ -1022,7 +1022,7 @@ isolate_success:* or a lock is contended. For contention, isolate quickly to * potentially remove one source of contention. */ -if (cc->nr_migratepages ==COMPACT_CLUSTER_MAX && +if (cc->nr_migratepages >=COMPACT_CLUSTER_MAX && !cc->rescan && !cc->contended) { ++low_pfn;break ;
@@ -1133,7 +1133,7 @@ isolate_migratepages_range(struct compacif (!pfn)break ; -if (cc->nr_migratepages ==COMPACT_CLUSTER_MAX ) +if (cc->nr_migratepages >=COMPACT_CLUSTER_MAX )break ; }
Greg Kroah-Hartman
maintainerPATCH 210/255 mm/compaction: stop isolation if too many pages are isolated and we have pages to migrate
In reply to Greg Kroah-HartmanFrom: Zi Yan <[email protected]>
commit d20bdd571ee5c9966191568527ecdb1bd4b52368 upstream.
In isolate_migratepages_block, if we have too many isolated pages and nr_migratepages is not zero, we should try to migrate what we have without wasting time on isolating.
In theory it's possible that multiple parallel compactions will cause too_many_isolated() to become true even if each has isolated less than COMPACT_CLUSTER_MAX, and loop forever in the while loop. Bailing immediately prevents that.
[[email protected]: changelog addition]
--- mm/compaction.c | 4 ++++ 1 file changed, 4 insertions(+)
mm/compaction.c +4 -0
@@ -818,6 +818,10 @@ isolate_migratepages_block(struct compac* delay for some time until fewer pages are isolated */ while (unlikely (too_many_isolated (pgdat))) { +/* stop isolation if there are still pages not migrated */ +if (cc->nr_migratepages) +return 0 ; +/* async migration should just abort */ if (cc->mode ==MIGRATE_ASYNC )return 0 ;
Greg Kroah-Hartman
maintainerPATCH 211/255 mm/slub: fix panic in slab_alloc_node()
In reply to Greg Kroah-HartmanFrom: Laurent Dufour <[email protected]>
commit 22e4663e916321b72972c69ca0c6b962f529bd78 upstream.
While doing memory hot-unplug operation on a PowerPC VM running 1024 CPUs with 11TB of ram, I hit the following panic:
BUG: Kernel NULL pointer dereference on read at 0x00000007
Faulting instruction address: 0xc000000000456048
Oops: Kernel access of bad area, sig: 11 [#2]
LE PAGE_SIZE=64K MMU=Hash SMP NR_CPUS= 2048 NUMA pSeries
Modules linked in: rpadlpar_io rpaphp
CPU: 160 PID: 1 Comm: systemd Tainted: G D 5.9.0 #1
NIP: c000000000456048 LR: c000000000455fd4 CTR: c00000000047b350
REGS: c00006028d1b77a0 TRAP: 0300 Tainted: G D (5.9.0)
MSR: 8000000000009033 <SF,EE,ME,IR,DR,RI,LE> CR: 24004228 XER: 00000000
CFAR: c00000000000f1b0 DAR: 0000000000000007 DSISR: 40000000 IRQMASK: 0
GPR00: c000000000455fd4 c00006028d1b7a30 c000000001bec800 0000000000000000
GPR04: 0000000000000dc0 0000000000000000 00000000000374ef c00007c53df99320
GPR08: 000007c53c980000 0000000000000000 000007c53c980000 0000000000000000
GPR12: 0000000000004400 c00000001e8e4400 0000000000000000 0000000000000f6a
GPR16: 0000000000000000 c000000001c25930 c000000001d62528 00000000000000c1
GPR20: c000000001d62538 c00006be469e9000 0000000fffffffe0 c0000000003c0ff8
GPR24: 0000000000000018 0000000000000000 0000000000000dc0 0000000000000000
GPR28: c00007c513755700 c000000001c236a4 c00007bc4001f800 0000000000000001
NIP [c000000000456048] __kmalloc_node+0x108/0x790
LR [c000000000455fd4] __kmalloc_node+0x94/0x790
Call Trace:
kvmalloc_node+0x58/0x110
mem_cgroup_css_online+0x10c/0x270
online_css+0x48/0xd0
cgroup_apply_control_enable+0x2c4/0x470
cgroup_mkdir+0x408/0x5f0
kernfs_iop_mkdir+0x90/0x100
vfs_mkdir+0x138/0x250
do_mkdirat+0x154/0x1c0
system_call_exception+0xf8/0x200
system_call_common+0xf0/0x27c
Instruction dump:
e93e0000 e90d0030 39290008 7cc9402a e94d0030 e93e0000 7ce95214 7f89502a
2fbc0000 419e0018 41920230 e9270010 <89290007> 7f994800 419e0220 7ee6bb78This pointing to the following code:
mm/slub.c:2851
if (unlikely(!object || !node_match(page, node))) {
c000000000456038: 00 00 bc 2f cmpdi cr7,r28,0
c00000000045603c: 18 00 9e 41 beq cr7,c000000000456054 <__kmalloc_node+0x114>
node_match():
mm/slub.c:2491
if (node != NUMA_NO_NODE && page_to_nid(page) != node)
c000000000456040: 30 02 92 41 beq cr4,c000000000456270 <__kmalloc_node+0x330>
page_to_nid():
include/linux/mm.h:1294
c000000000456044: 10 00 27 e9 ld r9,16(r7)
c000000000456048: 07 00 29 89 lbz r9,7(r9) <<<< r9 = NULL
node_match():
mm/slub.c:2491
c00000000045604c: 00 48 99 7f cmpw cr7,r25,r9
c000000000456050: 20 02 9e 41 beq cr7,c000000000456270 <__kmalloc_node+0x330>The panic occurred in slab_alloc_node() when checking for the page's node:
object = c->freelist;
page = c->page;
if (unlikely(!object || !node_match(page, node))) {
object = __slab_alloc(s, gfpflags, node, addr, c);
stat(s, ALLOC_SLOWPATH);The issue is that object is not NULL while page is NULL which is odd but may happen if the cache flush happened after loading object but before loading page. Thus checking for the page pointer is required too.
The cache flush is done through an inter processor interrupt when a piece of memory is off-lined. That interrupt is triggered when a memory hot-unplug operation is initiated and offline_pages() is calling the slub's MEM_GOING_OFFLINE callback slab_mem_going_offline_callback() which is calling flush_cpu_slab(). If that interrupt is caught between the reading of c->freelist and the reading of c->page, this could lead to such a situation. That situation is expected and the later call to this_cpu_cmpxchg_double() will detect the change to c->freelist and redo the whole operation.
In commit 6159d0f5c03e ("mm/slub.c: page is always non-NULL in node_match()") check on the page pointer has been removed assuming that page is always valid when it is called. It happens that this is not true in that particular case, so check for page before calling node_match() here.
--- mm/slub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
mm/slub.c +1 -1
@@ -2848,7 +2848,7 @@ redo: object = c->freelist; page = c->page; -if (unlikely (!object || !node_match (page, node))) { +if (unlikely (!object || !page || !node_match (page, node))) { object =__slab_alloc (s, gfpflags, node, addr, c);stat (s,ALLOC_SLOWPATH ); }else {
Greg Kroah-Hartman
maintainerPATCH 212/255 mm/vmscan: fix NR_ISOLATED_FILE corruption on 64-bit
In reply to Greg Kroah-HartmanFrom: Nicholas Piggin <[email protected]>
commit 2da9f6305f306ffbbb44790675799328fb73119d upstream.
Previously the negated unsigned long would be cast back to signed long which would have the correct negative value. After commit 730ec8c01a2b ("mm/vmscan.c: change prototype for shrink_page_list"), the large unsigned int converts to a large positive signed long.
Symptoms include CMA allocations hanging forever holding the cma_mutex due to alloc_contig_range->...->isolate_migratepages_block waiting forever in "while (unlikely(too_many_isolated(pgdat)))".
[[email protected]: fix -stat.nr_lazyfree_fail as well, per Michal]
--- mm/vmscan.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
mm/vmscan.c +3 -2
@@ -1514,7 +1514,8 @@ unsigned int reclaim_clean_pages_from_li nr_reclaimed =shrink_page_list (&clean_pages, zone->zone_pgdat, &sc,TTU_IGNORE_ACCESS , &stat, true);list_splice (&clean_pages, page_list); -mod_node_page_state (zone->zone_pgdat,NR_ISOLATED_FILE , -nr_reclaimed); +mod_node_page_state (zone->zone_pgdat,NR_ISOLATED_FILE , + -(long )nr_reclaimed);/* * Since lazyfree pages are isolated from file LRU from the beginning, * they will rotate back to anonymous LRU in the end if it failed to
@@ -1524,7 +1525,7 @@ unsigned int reclaim_clean_pages_from_limod_node_page_state (zone->zone_pgdat,NR_ISOLATED_ANON , stat.nr_lazyfree_fail);mod_node_page_state (zone->zone_pgdat,NR_ISOLATED_FILE , - -stat.nr_lazyfree_fail); + -(long )stat.nr_lazyfree_fail);return nr_reclaimed; }
Greg Kroah-Hartman
maintainerPATCH 213/255 mm/gup: use unpin_user_pages() in __gup_longterm_locked()
In reply to Greg Kroah-HartmanFrom: Jason Gunthorpe <[email protected]>
commit 96e1fac162cc0086c50b2b14062112adb2ba640e upstream.
When FOLL_PIN is passed to __get_user_pages() the page list must be put back using unpin_user_pages() otherwise the page pin reference persists in a corrupted state.
There are two places in the unwind of __gup_longterm_locked() that put the pages back without checking. Normally on error this function would return the partial page list making this the caller's responsibility, but in these two cases the caller is not allowed to see these pages at all.
--- mm/gup.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)
mm/gup.c +10 -4
@@ -1637,8 +1637,11 @@ check_again:/* * drop the above get_user_pages reference. */ -for (i =0 ; i < nr_pages; i++) -put_page (pages[i]); +if (gup_flags &FOLL_PIN ) +unpin_user_pages (pages, nr_pages); +else +for (i =0 ; i < nr_pages; i++) +put_page (pages[i]);if (migrate_pages (&cma_page_list, alloc_migration_target,NULL , (unsigned long )&mtc,MIGRATE_SYNC ,MR_CONTIG_RANGE )) {
@@ -1718,8 +1721,11 @@ static long __gup_longterm_locked(struct goto out;if (check_dax_vmas (vmas_tmp, rc)) { -for (i =0 ; i < rc; i++) -put_page (pages[i]); +if (gup_flags &FOLL_PIN ) +unpin_user_pages (pages, rc); +else +for (i =0 ; i < rc; i++) +put_page (pages[i]); rc = -EOPNOTSUPP ; goto out; }
Greg Kroah-Hartman
maintainerPATCH 214/255 Revert "kernel/reboot.c: convert simple_strtoul to kstrtoint"
In reply to Greg Kroah-HartmanFrom: Matteo Croce <[email protected]>
commit 8b92c4ff4423aa9900cf838d3294fcade4dbda35 upstream.
Patch series "fix parsing of reboot= cmdline", v3.
The parsing of the reboot= cmdline has two major errors:
- a missing bound check can crash the system on reboot
- parsing of the cpu number only works if specified last
Fix both.
This patch (of 2):
This reverts commit 616feab753972b97.
kstrtoint() and simple_strtoul() have a subtle difference which makes them non interchangeable: if a non digit character is found amid the parsing, the former will return an error, while the latter will just stop parsing, e.g. simple_strtoul("123xyx") = 123.
The kernel cmdline reboot= argument allows to specify the CPU used for rebooting, with the syntax s#### among the other flags, e.g. "reboot=warm,s31,force", so if this flag is not the last given, it's silently ignored as well as the subsequent ones.
--- kernel/reboot.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-)
kernel/reboot.c +7 -14
@@ -551,22 +551,15 @@ static int __init reboot_setup(char *strbreak ;case 's' : - { -int rc; - -if (isdigit (*(str+1 ))) { - rc =kstrtoint (str+1 ,0 , &reboot_cpu); -if (rc) -return rc; - }else if (str[1 ] =='m' && str[2 ] =='p' && -isdigit (*(str+3 ))) { - rc =kstrtoint (str+3 ,0 , &reboot_cpu); -if (rc) -return rc; - }else +if (isdigit (*(str+1 ))) + reboot_cpu =simple_strtoul (str+1 ,NULL ,0 ); +else if (str[1 ] =='m' && str[2 ] =='p' && +isdigit (*(str+3 ))) + reboot_cpu =simple_strtoul (str+3 ,NULL ,0 ); +else *mode =REBOOT_SOFT ;break ; - } +case 'g' : *mode =REBOOT_GPIO ;break ;
Greg Kroah-Hartman
maintainerPATCH 215/255 reboot: fix overflow parsing reboot cpu number
In reply to Greg Kroah-HartmanFrom: Matteo Croce <[email protected]>
commit df5b0ab3e08a156701b537809914b339b0daa526 upstream.
Limit the CPU number to num_possible_cpus(), because setting it to a value lower than INT_MAX but higher than NR_CPUS produces the following error on reboot and shutdown:
BUG: unable to handle page fault for address: ffffffff90ab1bb0
#PF: supervisor read access in kernel mode
#PF: error_code(0x0000) - not-present page
PGD 1c09067 P4D 1c09067 PUD 1c0a063 PMD 0
Oops: 0000 [#1] SMP
CPU: 1 PID: 1 Comm: systemd-shutdow Not tainted 5.9.0-rc8-kvm #110
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.13.0-2.fc32 04/01/2014
RIP: 0010:migrate_to_reboot_cpu+0xe/0x60
Code: ea ea 00 48 89 fa 48 c7 c7 30 57 f1 81 e9 fa ef ff ff 66 2e 0f 1f 84 00 00 00 00 00 53 8b 1d d5 ea ea 00 e8 14 33 fe ff 89 da <48> 0f a3 15 ea fc bd 00 48 89 d0 73 29 89 c2 c1 e8 06 65 48 8b 3c
RSP: 0018:ffffc90000013e08 EFLAGS: 00010246
RAX: ffff88801f0a0000 RBX: 0000000077359400 RCX: 0000000000000000
RDX: 0000000077359400 RSI: 0000000000000002 RDI: ffffffff81c199e0
RBP: ffffffff81c1e3c0 R08: ffff88801f41f000 R09: ffffffff81c1e348
R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000
R13: 00007f32bedf8830 R14: 00000000fee1dead R15: 0000000000000000
FS: 00007f32bedf8980(0000) GS:ffff88801f480000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: ffffffff90ab1bb0 CR3: 000000001d057000 CR4: 00000000000006a0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
__do_sys_reboot.cold+0x34/0x5b
do_syscall_64+0x2d/0x40--- kernel/reboot.c | 7 +++++++ 1 file changed, 7 insertions(+)
kernel/reboot.c +7 -0
@@ -558,6 +558,13 @@ static int __init reboot_setup(char *str reboot_cpu =simple_strtoul (str+3 ,NULL ,0 ); else *mode =REBOOT_SOFT ; +if (reboot_cpu >=num_possible_cpus ()) { +pr_err ("Ignoring the CPU number in reboot= option. " +"CPU %d exceeds possible cpu number %d\n" , + reboot_cpu,num_possible_cpus ()); + reboot_cpu =0 ; +break ; + }break ;case 'g' :
Greg Kroah-Hartman
maintainerPATCH 216/255 hugetlbfs: fix anon huge page migration race
In reply to Greg Kroah-HartmanFrom: Mike Kravetz <[email protected]>
commit 336bf30eb76580b579dc711ded5d599d905c0217 upstream.
Qian Cai reported the following BUG in [1]
LTP: starting move_pages12
BUG: unable to handle page fault for address: ffffffffffffffe0
...
RIP: 0010:anon_vma_interval_tree_iter_first+0xa2/0x170 avc_start_pgoff at mm/interval_tree.c:63
Call Trace:
rmap_walk_anon+0x141/0xa30 rmap_walk_anon at mm/rmap.c:1864
try_to_unmap+0x209/0x2d0 try_to_unmap at mm/rmap.c:1763
migrate_pages+0x1005/0x1fb0
move_pages_and_store_status.isra.47+0xd7/0x1a0
__x64_sys_move_pages+0xa5c/0x1100
do_syscall_64+0x5f/0x310
entry_SYSCALL_64_after_hwframe+0x44/0xa9Hugh Dickins diagnosed this as a migration bug caused by code introduced to use i_mmap_rwsem for pmd sharing synchronization. Specifically, the routine unmap_and_move_huge_page() is always passing the TTU_RMAP_LOCKED flag to try_to_unmap() while holding i_mmap_rwsem. This is wrong for anon pages as the anon_vma_lock should be held in this case. Further analysis suggested that i_mmap_rwsem was not required to he held at all when calling try_to_unmap for anon pages as an anon page could never be part of a shared pmd mapping.
Discussion also revealed that the hack in hugetlb_page_mapping_lock_write to drop page lock and acquire i_mmap_rwsem is wrong. There is no way to keep mapping valid while dropping page lock.
This patch does the following:
- Do not take i_mmap_rwsem and set TTU_RMAP_LOCKED for anon pages when calling try_to_unmap.
- Remove the hacky code in hugetlb_page_mapping_lock_write. The routine will now simply do a 'trylock' while still holding the page lock. If the trylock fails, it will return NULL. This could impact the callers:
- migration calling code will receive -EAGAIN and retry up to the hard coded limit (10).
- memory error code will treat the page as BUSY. This will force killing (SIGKILL) instead of SIGBUS any mapping tasks.
Do note that this change in behavior only happens when there is a race. None of the standard kernel testing suites actually hit this race, but it is possible.
[1] https://lore.kernel.org/lkml/[email protected]/
[2] https://lore.kernel.org/linux-mm/[email protected]/
--- mm/hugetlb.c | 90 ++-------------------------------------------------- mm/memory-failure.c | 36 +++++++++----------- mm/migrate.c | 46 ++++++++++++++------------ mm/rmap.c | 5 -- 4 files changed, 48 insertions(+), 129 deletions(-)
mm/hugetlb.c +5 -85
@@ -1579,103 +1579,23 @@ int PageHeadHuge(struct page *page_head) }/* -* Find address_space associated with hugetlbfs page. -* Upon entry page is locked and page 'was' mapped although mapped state -* could change. If necessary, use anon_vma to find vma and associated -* address space. The returned mapping may be stale, but it can not be -* invalid as page lock (which is held) is required to destroy mapping. -*/ -static struct address_space *_get_hugetlb_page_mapping (struct page *hpage) -{ -struct anon_vma *anon_vma; -pgoff_t pgoff_start, pgoff_end; -struct anon_vma_chain *avc; -struct address_space *mapping =page_mapping (hpage); - -/* Simple file based mapping */ -if (mapping) -return mapping; - -/* -* Even anonymous hugetlbfs mappings are associated with an -* underlying hugetlbfs file (see hugetlb_file_setup in mmap -* code). Find a vma associated with the anonymous vma, and -* use the file pointer to get address_space. -*/ - anon_vma =page_lock_anon_vma_read (hpage); -if (!anon_vma) -return mapping;/* NULL */ - -/* Use first found vma */ - pgoff_start =page_to_pgoff (hpage); - pgoff_end = pgoff_start +pages_per_huge_page (page_hstate (hpage)) -1 ; -anon_vma_interval_tree_foreach (avc, &anon_vma->rb_root, - pgoff_start, pgoff_end) { -struct vm_area_struct *vma = avc->vma; - - mapping = vma->vm_file->f_mapping; -break ; - } - -anon_vma_unlock_read (anon_vma); -return mapping; -} - -/* * Find and lock address space (mapping) in write mode. * -* Upon entry, the page is locked which allows us to find the mapping -* even in the case of an anon page. However, locking order dictates -* the i_mmap_rwsem be acquired BEFORE the page lock. This is hugetlbfs -* specific. So, we first try to lock the sema while still holding the -* page lock. If this works, great! If not, then we need to drop the -* page lock and then acquire i_mmap_rwsem and reacquire page lock. Of -* course, need to revalidate state along the way. +* Upon entry, the page is locked which means that page_mapping() is +* stable. Due to locking order, we can only trylock_write. If we can +* not get the lock, simply return NULL to caller. */ struct address_space *hugetlb_page_mapping_lock_write (struct page *hpage) { -struct address_space *mapping, *mapping2; +struct address_space *mapping =page_mapping (hpage); - mapping =_get_hugetlb_page_mapping (hpage); -retry:if (!mapping)return mapping; -/* -* If no contention, take lock and return -*/ if (i_mmap_trylock_write (mapping))return mapping; -/* -* Must drop page lock and wait on mapping sema. -* Note: Once page lock is dropped, mapping could become invalid. -* As a hack, increase map count until we lock page again. -*/ -atomic_inc (&hpage->_mapcount); -unlock_page (hpage); -i_mmap_lock_write (mapping); -lock_page (hpage); -atomic_add_negative (-1 , &hpage->_mapcount); - -/* verify page is still mapped */ -if (!page_mapped (hpage)) { -i_mmap_unlock_write (mapping); -return NULL ; - } - -/* -* Get address space again and verify it is the same one -* we locked. If not, drop lock and retry. -*/ - mapping2 =_get_hugetlb_page_mapping (hpage); -if (mapping2 != mapping) { -i_mmap_unlock_write (mapping); - mapping = mapping2; - goto retry; - } - -return mapping; +return NULL ; }pgoff_t __basepage_index (struct page *page)
mm/memory-failure.c +17 -19
@@ -1031,27 +1031,25 @@ static bool hwpoison_user_mappings(strucif (!PageHuge (hpage)) { unmap_success =try_to_unmap (hpage, ttu); }else { -/* -* For hugetlb pages, try_to_unmap could potentially call -* huge_pmd_unshare. Because of this, take semaphore in -* write mode here and set TTU_RMAP_LOCKED to indicate we -* have taken the lock at this higer level. -* -* Note that the call to hugetlb_page_mapping_lock_write -* is necessary even if mapping is already set. It handles -* ugliness of potentially having to drop page lock to obtain -* i_mmap_rwsem. -*/ - mapping =hugetlb_page_mapping_lock_write (hpage); - -if (mapping) { - unmap_success =try_to_unmap (hpage, +if (!PageAnon (hpage)) { +/* +* For hugetlb pages in shared mappings, try_to_unmap +* could potentially call huge_pmd_unshare. Because of +* this, take semaphore in write mode here and set +* TTU_RMAP_LOCKED to indicate we have taken the lock +* at this higer level. +*/ + mapping =hugetlb_page_mapping_lock_write (hpage); +if (mapping) { + unmap_success =try_to_unmap (hpage, ttu|TTU_RMAP_LOCKED ); -i_mmap_unlock_write (mapping); +i_mmap_unlock_write (mapping); + }else { +pr_info ("Memory failure: %#lx: could not lock mapping for mapped huge page\n" , pfn); + unmap_success = false; + } }else { -pr_info ("Memory failure: %#lx: could not find mapping for mapped huge page\n" , - pfn); - unmap_success = false; + unmap_success =try_to_unmap (hpage, ttu); } }if (!unmap_success)
mm/migrate.c +25 -21
59 lines not on this page · raw message
mm/rmap.c +1 -4
@@ -1413,9 +1413,6 @@ static bool try_to_unmap_one(struct page/* * If sharing is possible, start and end will be adjusted * accordingly. -* -* If called for a huge page, caller must hold i_mmap_rwsem -* in write mode as it is possible to call huge_pmd_unshare. */ adjust_range_if_pmd_sharing_possible (vma, &range.start, &range.end);
@@ -1462,7 +1459,7 @@ static bool try_to_unmap_one(struct page subpage = page -page_to_pfn (page) +pte_pfn (*pvmw.pte); address = pvmw.address; -if (PageHuge (page)) { +if (PageHuge (page) && !PageAnon (page)) {/* * To call huge_pmd_unshare, i_mmap_rwsem must be * held in write mode. Caller needs to explicitly
Greg Kroah-Hartman
maintainerPATCH 217/255 ocfs2: initialize ip_next_orphan
In reply to Greg Kroah-HartmanFrom: Wengang Wang <[email protected]>
commit f5785283dd64867a711ca1fb1f5bb172f252ecdf upstream.
Though problem if found on a lower 4.1.12 kernel, I think upstream has same issue.
In one node in the cluster, there is the following callback trace:
# cat /proc/21473/stack __ocfs2_cluster_lock.isra.36+0x336/0x9e0 [ocfs2] ocfs2_inode_lock_full_nested+0x121/0x520 [ocfs2] ocfs2_evict_inode+0x152/0x820 [ocfs2] evict+0xae/0x1a0 iput+0x1c6/0x230 ocfs2_orphan_filldir+0x5d/0x100 [ocfs2] ocfs2_dir_foreach_blk+0x490/0x4f0 [ocfs2] ocfs2_dir_foreach+0x29/0x30 [ocfs2] ocfs2_recover_orphans+0x1b6/0x9a0 [ocfs2] ocfs2_complete_recovery+0x1de/0x5c0 [ocfs2] process_one_work+0x169/0x4a0 worker_thread+0x5b/0x560 kthread+0xcb/0xf0 ret_from_fork+0x61/0x90
The above stack is not reasonable, the final iput shouldn't happen in ocfs2_orphan_filldir() function. Looking at the code,
2067 /* Skip inodes which are already added to recover list, since dio may
2068 * happen concurrently with unlink/rename */
2069 if (OCFS2_I(iter)->ip_next_orphan) {
2070 iput(iter);
2071 return 0;
2072 }
2073The logic thinks the inode is already in recover list on seeing ip_next_orphan is non-NULL, so it skip this inode after dropping a reference which incremented in ocfs2_iget().
While, if the inode is already in recover list, it should have another reference and the iput() at line 2070 should not be the final iput (dropping the last reference). So I don't think the inode is really in the recover list (no vmcore to confirm).
Note that ocfs2_queue_orphans(), though not shown up in the call back trace, is holding cluster lock on the orphan directory when looking up for unlinked inodes. The on disk inode eviction could involve a lot of IOs which may need long time to finish. That means this node could hold the cluster lock for very long time, that can lead to the lock requests (from other nodes) to the orhpan directory hang for long time.
Looking at more on ip_next_orphan, I found it's not initialized when allocating a new ocfs2_inode_info structure.
This causes te reflink operations from some nodes hang for very long time waiting for the cluster lock on the orphan directory.
Fix: initialize ip_next_orphan as NULL.
--- fs/ocfs2/super.c | 1 + 1 file changed, 1 insertion(+)
fs/ocfs2/super.c +1 -0
@@ -1713,6 +1713,7 @@ static void ocfs2_inode_init_once(void * oi->ip_blkno =0ULL ; oi->ip_clusters =0 ; + oi->ip_next_orphan =NULL ;ocfs2_resv_init_once (&oi->ip_la_data_resv);
Greg Kroah-Hartman
maintainerPATCH 218/255 hwmon: (amd_energy) modify the visibility of the counters
In reply to Greg Kroah-HartmanFrom: Naveen Krishna Chatradhi <[email protected]>
commit 60268b0e8258fdea9a3c9f4b51e161c123571db3 upstream.
This patch limits the visibility to owner and groups only for the energy counters exposed through the hwmon based amd_energy driver.
--- drivers/hwmon/amd_energy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/hwmon/amd_energy.c +1 -1
@@ -209,7 +209,7 @@ static umode_t amd_energy_is_visible(conenum hwmon_sensor_types type, u32 attr, int channel) { - return 0444; + return 0440; }static int energy_accumulator (void *p)
Greg Kroah-Hartman
maintainerPATCH 219/255 selinux: Fix error return code in sel_ib_pkey_sid_slow()
In reply to Greg Kroah-HartmanFrom: Chen Zhou <[email protected]>
commit c350f8bea271782e2733419bd2ab9bf4ec2051ef upstream.
Fix to return a negative error code from the error handling case instead of 0 in function sel_ib_pkey_sid_slow(), as done elsewhere in this function.
--- security/selinux/ibpkey.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
security/selinux/ibpkey.c +3 -1
@@ -151,8 +151,10 @@ static int sel_ib_pkey_sid_slow(u64 subn* is valid, it just won't be added to the cache. */ new =kzalloc (sizeof (*new),GFP_ATOMIC ); -if (!new) +if (!new) { + ret = -ENOMEM ; goto out; + } new->psec.subnet_prefix = subnet_prefix; new->psec.pkey = pkey_num;
Greg Kroah-Hartman
maintainerPATCH 220/255 io_uring: round-up cq size before comparing with rounded sq size
In reply to Greg Kroah-HartmanFrom: Jens Axboe <[email protected]>
commit 88ec3211e46344a7d10cf6cb5045f839f7785f8e upstream.
If an application specifies IORING_SETUP_CQSIZE to set the CQ ring size to a specific size, we ensure that the CQ size is at least that of the SQ ring size. But in doing so, we compare the already rounded up to power of two SQ size to the as-of yet unrounded CQ size. This means that if an application passes in non power of two sizes, we can return -EINVAL when the final value would've been fine. As an example, an application passing in 100/100 for sq/cq size should end up with 128 for both. But since we round the SQ size first, we compare the CQ size of 100 to 128, and return -EINVAL as that is too small.
--- fs/io_uring.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/io_uring.c +1 -1
@@ -8878,6 +8878,7 @@ static int io_uring_create(unsigned entr* to a power-of-two, if it isn't already. We do NOT impose * any cq vs sq ring sizing. */ + p->cq_entries =roundup_pow_of_two (p->cq_entries);if (p->cq_entries < p->sq_entries)return -EINVAL ;if (p->cq_entries >IORING_MAX_CQ_ENTRIES ) {
@@ -8885,7 +8886,6 @@ static int io_uring_create(unsigned entrreturn -EINVAL ; p->cq_entries =IORING_MAX_CQ_ENTRIES ; } - p->cq_entries =roundup_pow_of_two (p->cq_entries); }else { p->cq_entries =2 * p->sq_entries; }
Greg Kroah-Hartman
maintainerPATCH 221/255 gpio: sifive: Fix SiFive gpio probe
In reply to Greg Kroah-HartmanFrom: Damien Le Moal <[email protected]>
commit b72de3ff19fdc4bbe4d4bb3f4483c7e46e00bac3 upstream.
Fix the check on the number of IRQs to allow up to the maximum (32) instead of only the maximum minus one.
--- drivers/gpio/gpio-sifive.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpio/gpio-sifive.c +1 -1
@@ -183,7 +183,7 @@ static int sifive_gpio_probe(struct platreturn PTR_ERR (chip->regs); ngpio =of_irq_count (node); -if (ngpio >=SIFIVE_GPIO_MAX ) { +if (ngpio >SIFIVE_GPIO_MAX ) {dev_err (dev,"Too many GPIO interrupts (max=%d)\n" ,SIFIVE_GPIO_MAX );return -ENXIO ;
Greg Kroah-Hartman
maintainerPATCH 222/255 gpio: pcie-idio-24: Fix irq mask when masking
In reply to Greg Kroah-HartmanFrom: Arnaud de Turckheim <[email protected]>
commit d8f270efeac850c569c305dc0baa42ac3d607988 upstream.
Fix the bitwise operation to remove only the corresponding bit from the mask.
--- drivers/gpio/gpio-pcie-idio-24.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpio/gpio-pcie-idio-24.c +1 -1
@@ -339,7 +339,7 @@ static void idio_24_irq_mask(struct irq_raw_spin_lock_irqsave (&idio24gpio->lock, flags); - idio24gpio->irq_mask &=BIT (bit_offset); + idio24gpio->irq_mask &= ~BIT (bit_offset); new_irq_mask = idio24gpio->irq_mask >> bank_offset;if (!new_irq_mask) {
Greg Kroah-Hartman
maintainerPATCH 223/255 gpio: pcie-idio-24: Fix IRQ Enable Register value
In reply to Greg Kroah-HartmanFrom: Arnaud de Turckheim <[email protected]>
commit 23a7fdc06ebcc334fa667f0550676b035510b70b upstream.
This fixes the COS Enable Register value for enabling/disabling the corresponding IRQs bank.
--- drivers/gpio/gpio-pcie-idio-24.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/gpio/gpio-pcie-idio-24.c +4 -4
@@ -334,13 +334,13 @@ static void idio_24_irq_mask(struct irq_unsigned long flags;const unsigned long bit_offset =irqd_to_hwirq (data) -24 ;unsigned char new_irq_mask; -const unsigned long bank_offset = bit_offset/8 *8 ; +const unsigned long bank_offset = bit_offset /8 ;unsigned char cos_enable_state;raw_spin_lock_irqsave (&idio24gpio->lock, flags); idio24gpio->irq_mask &= ~BIT (bit_offset); - new_irq_mask = idio24gpio->irq_mask >> bank_offset; + new_irq_mask = idio24gpio->irq_mask >> bank_offset *8 ;if (!new_irq_mask) { cos_enable_state =ioread8 (&idio24gpio->reg->cos_enable);
@@ -363,12 +363,12 @@ static void idio_24_irq_unmask(struct irunsigned long flags;unsigned char prev_irq_mask;const unsigned long bit_offset =irqd_to_hwirq (data) -24 ; -const unsigned long bank_offset = bit_offset/8 *8 ; +const unsigned long bank_offset = bit_offset /8 ;unsigned char cos_enable_state;raw_spin_lock_irqsave (&idio24gpio->lock, flags); - prev_irq_mask = idio24gpio->irq_mask >> bank_offset; + prev_irq_mask = idio24gpio->irq_mask >> bank_offset *8 ; idio24gpio->irq_mask |=BIT (bit_offset);if (!prev_irq_mask) {
Greg Kroah-Hartman
maintainerPATCH 224/255 gpio: pcie-idio-24: Enable PEX8311 interrupts
In reply to Greg Kroah-HartmanFrom: Arnaud de Turckheim <[email protected]>
commit 10a2f11d3c9e48363c729419e0f0530dea76e4fe upstream.
This enables the PEX8311 internal PCI wire interrupt and the PEX8311 local interrupt input so the local interrupts are forwarded to the PCI.
--- drivers/gpio/gpio-pcie-idio-24.c | 52 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-)
drivers/gpio/gpio-pcie-idio-24.c +51 -1
@@ -28,6 +28,47 @@#include <linux/spinlock.h> #include <linux/types.h> +/* +* PLX PEX8311 PCI LCS_INTCSR Interrupt Control/Status +* +* Bit: Description +* 0: Enable Interrupt Sources (Bit 0) +* 1: Enable Interrupt Sources (Bit 1) +* 2: Generate Internal PCI Bus Internal SERR# Interrupt +* 3: Mailbox Interrupt Enable +* 4: Power Management Interrupt Enable +* 5: Power Management Interrupt +* 6: Slave Read Local Data Parity Check Error Enable +* 7: Slave Read Local Data Parity Check Error Status +* 8: Internal PCI Wire Interrupt Enable +* 9: PCI Express Doorbell Interrupt Enable +* 10: PCI Abort Interrupt Enable +* 11: Local Interrupt Input Enable +* 12: Retry Abort Enable +* 13: PCI Express Doorbell Interrupt Active +* 14: PCI Abort Interrupt Active +* 15: Local Interrupt Input Active +* 16: Local Interrupt Output Enable +* 17: Local Doorbell Interrupt Enable +* 18: DMA Channel 0 Interrupt Enable +* 19: DMA Channel 1 Interrupt Enable +* 20: Local Doorbell Interrupt Active +* 21: DMA Channel 0 Interrupt Active +* 22: DMA Channel 1 Interrupt Active +* 23: Built-In Self-Test (BIST) Interrupt Active +* 24: Direct Master was the Bus Master during a Master or Target Abort +* 25: DMA Channel 0 was the Bus Master during a Master or Target Abort +* 26: DMA Channel 1 was the Bus Master during a Master or Target Abort +* 27: Target Abort after internal 256 consecutive Master Retrys +* 28: PCI Bus wrote data to LCS_MBOX0 +* 29: PCI Bus wrote data to LCS_MBOX1 +* 30: PCI Bus wrote data to LCS_MBOX2 +* 31: PCI Bus wrote data to LCS_MBOX3 +*/ +#define PLX_PEX8311_PCI_LCS_INTCSR 0x68 +#define INTCSR_INTERNAL_PCI_WIRE BIT(8) +#define INTCSR_LOCAL_INPUT BIT(11) +/** * struct idio_24_gpio_reg - GPIO device registers structure * @out0_7: Read: FET Outputs 0-7
@@ -92,6 +133,7 @@ struct idio_24_gpio_reg {struct idio_24_gpio {struct gpio_chip chip;raw_spinlock_t lock; +__u8 __iomem *plx;struct idio_24_gpio_reg __iomem *reg;unsigned long irq_mask; };
@@ -455,6 +497,7 @@ static int idio_24_probe(struct pci_devstruct device *const dev = &pdev->dev;struct idio_24_gpio *idio24gpio;int err; +const size_t pci_plx_bar_index =1 ;const size_t pci_bar_index =2 ;const char *const name =pci_name (pdev);struct gpio_irq_chip *girq;
@@ -469,12 +512,13 @@ static int idio_24_probe(struct pci_devreturn err; } - err =pcim_iomap_regions (pdev,BIT (pci_bar_index), name); + err =pcim_iomap_regions (pdev,BIT (pci_plx_bar_index) |BIT (pci_bar_index), name);if (err) {dev_err (dev,"Unable to map PCI I/O addresses (%d)\n" , err);return err; } + idio24gpio->plx =pcim_iomap_table (pdev)[pci_plx_bar_index]; idio24gpio->reg =pcim_iomap_table (pdev)[pci_bar_index]; idio24gpio->chip.label = name;
@@ -504,6 +548,12 @@ static int idio_24_probe(struct pci_dev/* Software board reset */ iowrite8 (0 , &idio24gpio->reg->soft_reset); +/* +* enable PLX PEX8311 internal PCI wire interrupt and local interrupt +* input +*/ +iowrite8 ((INTCSR_INTERNAL_PCI_WIRE |INTCSR_LOCAL_INPUT ) >>8 , + idio24gpio->plx +PLX_PEX8311_PCI_LCS_INTCSR +1 ); err =devm_gpiochip_add_data (dev, &idio24gpio->chip, idio24gpio);if (err) {
Greg Kroah-Hartman
maintainerPATCH 225/255 mmc: sdhci-of-esdhc: Handle pulse width detection erratum for more SoCs
In reply to Greg Kroah-HartmanFrom: Yangbo Lu <[email protected]>
commit 71b053276a87ddfa40c8f236315d81543219bfb9 upstream.
Apply erratum workaround of unreliable pulse width detection to more affected platforms (LX2160A Rev2.0 and LS1028A Rev1.0).
--- drivers/mmc/host/sdhci-of-esdhc.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/mmc/host/sdhci-of-esdhc.c +2 -0
@@ -1324,6 +1324,8 @@ static struct soc_device_attribute soc_fstatic struct soc_device_attribute soc_unreliable_pulse_detection[] = { { .family ="QorIQ LX2160A" , .revision ="1.0" , }, + { .family ="QorIQ LX2160A" , .revision ="2.0" , }, + { .family ="QorIQ LS1028A" , .revision ="1.0" , }, { }, };
Greg Kroah-Hartman
maintainerPATCH 226/255 mmc: renesas_sdhi_core: Add missing tmio_mmc_host_free() at remove
In reply to Greg Kroah-HartmanFrom: Yoshihiro Shimoda <[email protected]>
commit e8973201d9b281375b5a8c66093de5679423021a upstream.
The commit 94b110aff867 ("mmc: tmio: add tmio_mmc_host_alloc/free()") added tmio_mmc_host_free(), but missed the function calling in the sh_mobile_sdhi_remove() at that time. So, fix it. Otherwise, we cannot rebind the sdhi/mmc devices when we use aliases of mmc.
--- drivers/mmc/host/renesas_sdhi_core.c | 1 + 1 file changed, 1 insertion(+)
drivers/mmc/host/renesas_sdhi_core.c +1 -0
@@ -997,6 +997,7 @@ int renesas_sdhi_remove(struct platform_tmio_mmc_host_remove (host);renesas_sdhi_clk_disable (host); +tmio_mmc_host_free (host);return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 227/255 dont dump the threads that had been already exiting when zapped.
In reply to Greg Kroah-HartmanFrom: Al Viro <[email protected]>
commit 77f6ab8b7768cf5e6bdd0e72499270a0671506ee upstream.
Coredump logics needs to report not only the registers of the dumping thread, but (since 2.5.43) those of other threads getting killed.
Doing that might require extra state saved on the stack in asm glue at kernel entry; signal delivery logics does that (we need to be able to save sigcontext there, at the very least) and so does seccomp.
That covers all callers of do_coredump(). Secondary threads get hit with SIGKILL and caught as soon as they reach exit_mm(), which normally happens in signal delivery, so those are also fine most of the time. Unfortunately, it is possible to end up with secondary zapped when it has already entered exit(2) (or, worse yet, is oopsing). In those cases we reach exit_mm() when mm->core_state is already set, but the stack contents is not what we would have in signal delivery.
At least on two architectures (alpha and m68k) it leads to infoleaks - we end up with a chunk of kernel stack written into coredump, with the contents consisting of normal C stack frames of the call chain leading to exit_mm() instead of the expected copy of userland registers. In case of alpha we leak 312 bytes of stack. Other architectures (including the regset-using ones) might have similar problems - the normal user of regsets is ptrace and the state of tracee at the time of such calls is special in the same way signal delivery is.
Note that had the zapper gotten to the exiting thread slightly later, it wouldn't have been included into coredump anyway - we skip the threads that have already cleared their ->mm. So let's pretend that zapper always loses the race. IOW, have exit_mm() only insert into the dumper list if we'd gotten there from handling a fatal signal[*]
As the result, the callers of do_exit() that have *not* gone through get_signal() are not seen by coredump logics as secondary threads. Which excludes voluntary exit()/oopsen/traps/etc. The dumper thread itself is unaffected by that, so seccomp is fine.
[*] originally I intended to add a new flag in tsk->flags, but ebiederman pointed out that PF_SIGNALED is already doing just what we need.
History-tree: https://git.kernel.org/pub/scm/linux/kernel/git/tglx/history.git
--- kernel/exit.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
kernel/exit.c +4 -1
@@ -454,7 +454,10 @@ static void exit_mm(void)mmap_read_unlock (mm); self.task = current; - self.next =xchg (&core_state->dumper.next, &self); +if (self.task->flags &PF_SIGNALED ) + self.next =xchg (&core_state->dumper.next, &self); +else + self.task =NULL ;/* * Implies mb(), the result of xchg() must be visible * to core_state->dumper.
Greg Kroah-Hartman
maintainerPATCH 228/255 drm/amd/display: Add missing pflip irq
In reply to Greg Kroah-HartmanFrom: Bhawanpreet Lakha <[email protected]>
commit a422490a595600659664901b609aacccdbba4a5f upstream.
If we have more than 4 displays we will run
into dummy irq calls or flip timout issues.
--- drivers/gpu/drm/amd/display/dc/irq/dcn30/irq_service_dcn30.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/amd/display/dc/irq/dcn30/irq_service_dcn30.c +2 -2
@@ -306,8 +306,8 @@ irq_source_info_dcn30[DAL_IRQ_SOURCES_NUpflip_int_entry (1 ),pflip_int_entry (2 ),pflip_int_entry (3 ), - [DC_IRQ_SOURCE_PFLIP5] = dummy_irq_entry(), - [DC_IRQ_SOURCE_PFLIP6] = dummy_irq_entry(), +pflip_int_entry (4 ), + pflip_int_entry(5), [DC_IRQ_SOURCE_PFLIP_UNDERLAY0 ] =dummy_irq_entry (),gpio_pad_int_entry (0 ), gpio_pad_int_entry(1),
Greg Kroah-Hartman
maintainerPATCH 229/255 drm/i915: Correctly set SFC capability for video engines
In reply to Greg Kroah-HartmanFrom: Venkata Sandeep Dhanalakota <[email protected]>
commit 5ce6861d36ed5207aff9e5eead4c7cc38a986586 upstream.
SFC capability of video engines is not set correctly because i915 is testing for incorrect bits.
--- drivers/gpu/drm/i915/gt/intel_engine_cs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/i915/gt/intel_engine_cs.c +2 -1
@@ -370,7 +370,8 @@ static void __setup_engine_capabilities(* instances. */ if ((INTEL_GEN (i915) >=11 && - engine->gt->info.vdbox_sfc_access & engine->mask) || + (engine->gt->info.vdbox_sfc_access & +BIT (engine->instance))) || (INTEL_GEN (i915) >=9 && engine->instance ==0 )) engine->uabi_capabilities |=I915_VIDEO_AND_ENHANCE_CLASS_CAPABILITY_SFC ;
Greg Kroah-Hartman
maintainerPATCH 230/255 drm/gma500: Fix out-of-bounds access to struct drm_device.vblank[]
In reply to Greg Kroah-HartmanFrom: Thomas Zimmermann <[email protected]>
commit 06ad8d339524bf94b89859047822c31df6ace239 upstream.
The gma500 driver expects 3 pipelines in several it's IRQ functions. Accessing struct drm_device.vblank[], this fails with devices that only have 2 pipelines. An example KASAN report is shown below.
[ 62.267688] ================================================================== [ 62.268856] BUG: KASAN: slab-out-of-bounds in psb_irq_postinstall+0x250/0x3c0 [gma500_gfx] [ 62.269450] Read of size 1 at addr ffff8880012bc6d0 by task systemd-udevd/285 [ 62.269949] [ 62.270192] CPU: 0 PID: 285 Comm: systemd-udevd Tainted: G E 5.10.0-rc1-1-default+ #572 [ 62.270807] Hardware name: /DN2800MT, BIOS MTCDT10N.86A.0164.2012.1213.1024 12/13/2012 [ 62.271366] Call Trace: [ 62.271705] dump_stack+0xae/0xe5 [ 62.272180] print_address_description.constprop.0+0x17/0xf0 [ 62.272987] ? psb_irq_postinstall+0x250/0x3c0 [gma500_gfx] [ 62.273474] __kasan_report.cold+0x20/0x38 [ 62.273989] ? psb_irq_postinstall+0x250/0x3c0 [gma500_gfx] [ 62.274460] kasan_report+0x3a/0x50 [ 62.274891] psb_irq_postinstall+0x250/0x3c0 [gma500_gfx] [ 62.275380] drm_irq_install+0x131/0x1f0 <...> [ 62.300751] Allocated by task 285: [ 62.301223] kasan_save_stack+0x1b/0x40 [ 62.301731] __kasan_kmalloc.constprop.0+0xbf/0xd0 [ 62.302293] drmm_kmalloc+0x55/0x100 [ 62.302773] drm_vblank_init+0x77/0x210
Resolve the issue by only handling vblank entries up to the number of CRTCs.
I'm adding a Fixes tag for reference, although the bug has been present since the driver's initial commit.
--- drivers/gpu/drm/gma500/psb_irq.c | 34 ++++++++++++---------------------- 1 file changed, 12 insertions(+), 22 deletions(-)
drivers/gpu/drm/gma500/psb_irq.c +12 -22
@@ -347,6 +347,7 @@ int psb_irq_postinstall(struct drm_devic {struct drm_psb_private *dev_priv = dev->dev_private;unsigned long irqflags; +unsigned int i;spin_lock_irqsave (&dev_priv->irqmask_lock, irqflags);
@@ -359,20 +360,12 @@ int psb_irq_postinstall(struct drm_devicPSB_WVDC32 (dev_priv->vdc_irq_mask,PSB_INT_ENABLE_R );PSB_WVDC32 (0xFFFFFFFF ,PSB_HWSTAM ); -if (dev->vblank[0 ].enabled) -psb_enable_pipestat (dev_priv,0 ,PIPE_VBLANK_INTERRUPT_ENABLE ); -else -psb_disable_pipestat (dev_priv,0 ,PIPE_VBLANK_INTERRUPT_ENABLE ); - -if (dev->vblank[1 ].enabled) -psb_enable_pipestat (dev_priv,1 ,PIPE_VBLANK_INTERRUPT_ENABLE ); -else -psb_disable_pipestat (dev_priv,1 ,PIPE_VBLANK_INTERRUPT_ENABLE ); - -if (dev->vblank[2 ].enabled) -psb_enable_pipestat (dev_priv,2 ,PIPE_VBLANK_INTERRUPT_ENABLE ); -else -psb_disable_pipestat (dev_priv,2 ,PIPE_VBLANK_INTERRUPT_ENABLE ); +for (i =0 ; i < dev->num_crtcs; ++i) { +if (dev->vblank[i].enabled) +psb_enable_pipestat (dev_priv, i,PIPE_VBLANK_INTERRUPT_ENABLE ); +else +psb_disable_pipestat (dev_priv, i,PIPE_VBLANK_INTERRUPT_ENABLE ); + }if (dev_priv->ops->hotplug_enable) dev_priv->ops->hotplug_enable (dev, true);
@@ -385,6 +378,7 @@ void psb_irq_uninstall(struct drm_device {struct drm_psb_private *dev_priv = dev->dev_private;unsigned long irqflags; +unsigned int i;spin_lock_irqsave (&dev_priv->irqmask_lock, irqflags);
@@ -393,14 +387,10 @@ void psb_irq_uninstall(struct drm_devicePSB_WVDC32 (0xFFFFFFFF ,PSB_HWSTAM ); -if (dev->vblank[0 ].enabled) -psb_disable_pipestat (dev_priv,0 ,PIPE_VBLANK_INTERRUPT_ENABLE ); - -if (dev->vblank[1 ].enabled) -psb_disable_pipestat (dev_priv,1 ,PIPE_VBLANK_INTERRUPT_ENABLE ); - -if (dev->vblank[2 ].enabled) -psb_disable_pipestat (dev_priv,2 ,PIPE_VBLANK_INTERRUPT_ENABLE ); +for (i =0 ; i < dev->num_crtcs; ++i) { +if (dev->vblank[i].enabled) +psb_disable_pipestat (dev_priv, i,PIPE_VBLANK_INTERRUPT_ENABLE ); + } dev_priv->vdc_irq_mask &= _PSB_IRQ_SGX_FLAG | _PSB_IRQ_MSVDX_FLAG |
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
Greg Kroah-Hartman
maintainerPATCH 231/255 NFSv4.2: fix failure to unregister shrinker
In reply to Greg Kroah-HartmanFrom: J. Bruce Fields <[email protected]>
commit 70438afbf17e5194dd607dd17759560a363b7bb4 upstream.
We forgot to unregister the nfs4_xattr_large_entry_shrinker.
That leaves the global list of shrinkers corrupted after unload of the nfs module, after which possibly unrelated code that calls register_shrinker() or unregister_shrinker() gets a BUG() with "supervisor write access in kernel mode".
And similarly for the nfs4_xattr_large_entry_lru.
--- fs/nfs/nfs42xattr.c | 2 ++ 1 file changed, 2 insertions(+)
fs/nfs/nfs42xattr.c +2 -0
@@ -1048,8 +1048,10 @@ out4:void nfs4_xattr_cache_exit (void ) { +unregister_shrinker (&nfs4_xattr_large_entry_shrinker);unregister_shrinker (&nfs4_xattr_entry_shrinker);unregister_shrinker (&nfs4_xattr_cache_shrinker); +list_lru_destroy (&nfs4_xattr_large_entry_lru);list_lru_destroy (&nfs4_xattr_entry_lru);list_lru_destroy (&nfs4_xattr_cache_lru);kmem_cache_destroy (nfs4_xattr_cache_cachep);
Greg Kroah-Hartman
maintainerPATCH 232/255 pinctrl: amd: use higher precision for 512 RtcClk
In reply to Greg Kroah-HartmanFrom: Coiby Xu <[email protected]>
commit c64a6a0d4a928c63e5bc3b485552a8903a506c36 upstream.
RTC is 32.768kHz thus 512 RtcClk equals 15625 usec. The documentation likely has dropped precision and that's why the driver mistakenly took the slightly deviated value.
--- drivers/pinctrl/pinctrl-amd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/pinctrl/pinctrl-amd.c +1 -1
@@ -156,7 +156,7 @@ static int amd_gpio_set_debounce(struct pin_reg |=BIT (DB_TMR_OUT_UNIT_OFF ); pin_reg &= ~BIT (DB_TMR_LARGE_OFF ); }else if (debounce <250000 ) { - time = debounce /15600 ; + time = debounce /15625 ; pin_reg |= time &DB_TMR_OUT_MASK ; pin_reg &= ~BIT (DB_TMR_OUT_UNIT_OFF ); pin_reg |=BIT (DB_TMR_LARGE_OFF );
Greg Kroah-Hartman
maintainerPATCH 233/255 pinctrl: amd: fix incorrect way to disable debounce filter
In reply to Greg Kroah-HartmanFrom: Coiby Xu <[email protected]>
commit 06abe8291bc31839950f7d0362d9979edc88a666 upstream.
The correct way to disable debounce filter is to clear bit 5 and 6 of the register.
--- drivers/pinctrl/pinctrl-amd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/pinctrl/pinctrl-amd.c +2 -2
@@ -166,14 +166,14 @@ static int amd_gpio_set_debounce(struct pin_reg |=BIT (DB_TMR_OUT_UNIT_OFF ); pin_reg |=BIT (DB_TMR_LARGE_OFF ); }else { - pin_reg &= ~DB_CNTRl_MASK; + pin_reg &= ~(DB_CNTRl_MASK <<DB_CNTRL_OFF ); ret = -EINVAL ; } }else { pin_reg &= ~BIT (DB_TMR_OUT_UNIT_OFF ); pin_reg &= ~BIT (DB_TMR_LARGE_OFF ); pin_reg &= ~DB_TMR_OUT_MASK ; - pin_reg &= ~DB_CNTRl_MASK; + pin_reg &= ~(DB_CNTRl_MASK <<DB_CNTRL_OFF ); }writel (pin_reg, gpio_dev->base + offset *4 );raw_spin_unlock_irqrestore (&gpio_dev->lock, flags);
Greg Kroah-Hartman
maintainerPATCH 234/255 swiotlb: fix "x86: Dont panic if can not alloc buffer for swiotlb"
In reply to Greg Kroah-HartmanFrom: Stefano Stabellini <[email protected]>
commit e9696d259d0fb5d239e8c28ca41089838ea76d13 upstream.
kernel/dma/swiotlb.c:swiotlb_init gets called first and tries to allocate a buffer for the swiotlb. It does so by calling
memblock_alloc_low(PAGE_ALIGN(bytes), PAGE_SIZE);
If the allocation must fail, no_iotlb_memory is set.
Later during initialization swiotlb-xen comes in (drivers/xen/swiotlb-xen.c:xen_swiotlb_init) and given that io_tlb_start is != 0, it thinks the memory is ready to use when actually it is not.
When the swiotlb is actually needed, swiotlb_tbl_map_single gets called and since no_iotlb_memory is set the kernel panics.
Instead, if swiotlb-xen.c:xen_swiotlb_init knew the swiotlb hadn't been initialized, it would do the initialization itself, which might still succeed.
Fix the panic by setting io_tlb_start to 0 on swiotlb initialization failure, and also by setting no_iotlb_memory to false on swiotlb initialization success.
--- kernel/dma/swiotlb.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
kernel/dma/swiotlb.c +5 -1
@@ -231,6 +231,7 @@ int __init swiotlb_init_with_tbl(char *t io_tlb_orig_addr[i] =INVALID_PHYS_ADDR ; } io_tlb_index =0 ; + no_iotlb_memory = false;if (verbose)swiotlb_print_info ();
@@ -262,9 +263,11 @@ swiotlb_init(int verbose)if (vstart && !swiotlb_init_with_tbl (vstart, io_tlb_nslabs, verbose))return ; -if (io_tlb_start) +if (io_tlb_start) {memblock_free_early (io_tlb_start,PAGE_ALIGN (io_tlb_nslabs <<IO_TLB_SHIFT )); + io_tlb_start =0 ; + }pr_warn ("Cannot allocate buffer" ); no_iotlb_memory = true; }
@@ -362,6 +365,7 @@ swiotlb_late_init_with_tbl(char *tlb, un io_tlb_orig_addr[i] =INVALID_PHYS_ADDR ; } io_tlb_index =0 ; + no_iotlb_memory = false;swiotlb_print_info ();
Greg Kroah-Hartman
maintainerPATCH 235/255 cpufreq: Introduce governor flags
In reply to Greg Kroah-HartmanFrom: Rafael J. Wysocki <[email protected]>
commit 9a2a9ebc0a758d887ee06e067e9f7f0b36ff7574 upstream.
A new cpufreq governor flag will be added subsequently, so replace the bool dynamic_switching fleid in struct cpufreq_governor with a flags field and introduce CPUFREQ_GOV_DYNAMIC_SWITCHING to set for the "dynamic switching" governors instead of it.
No intentional functional impact.
--- drivers/cpufreq/cpufreq.c | 2 +- drivers/cpufreq/cpufreq_governor.h | 2 +- include/linux/cpufreq.h | 9 +++++++-- kernel/sched/cpufreq_schedutil.c | 2 +- 4 files changed, 10 insertions(+), 5 deletions(-)
drivers/cpufreq/cpufreq.c +1 -1
@@ -2233,7 +2233,7 @@ static int cpufreq_init_governor(structreturn -EINVAL ;/* Platform doesn't want dynamic frequency switching ? */ -if (policy->governor->dynamic_switching && +if (policy->governor->flags &CPUFREQ_GOV_DYNAMIC_SWITCHING && cpufreq_driver->flags &CPUFREQ_NO_AUTO_DYNAMIC_SWITCHING ) {struct cpufreq_governor *gov =cpufreq_fallback_governor ();
drivers/cpufreq/cpufreq_governor.h +1 -1
@@ -156,7 +156,7 @@ void cpufreq_dbs_governor_limits(struct#define CPUFREQ_DBS_GOVERNOR_INITIALIZER (_name_) \ { \ .name = _name_, \ - .dynamic_switching = true, \ + .flags = CPUFREQ_GOV_DYNAMIC_SWITCHING, \ .owner = THIS_MODULE, \ .init = cpufreq_dbs_governor_init, \ .exit = cpufreq_dbs_governor_exit, \
include/linux/cpufreq.h +7 -2
@@ -565,12 +565,17 @@ struct cpufreq_governor { char *buf);int (*store_setspeed) (struct cpufreq_policy *policy,unsigned int freq); -/* For governors which change frequency dynamically by themselves */ -bool dynamic_switching;struct list_head governor_list;struct module *owner; +u8 flags; }; +/* Governor flags */ + +/* For governors which change frequency dynamically by themselves */ +#define CPUFREQ_GOV_DYNAMIC_SWITCHING BIT(0) + +/* Pass a target to the cpufreq driver */ unsigned int cpufreq_driver_fast_switch (struct cpufreq_policy *policy,unsigned int target_freq);
kernel/sched/cpufreq_schedutil.c +1 -1
@@ -896,7 +896,7 @@ static void sugov_limits(struct cpufreq_struct cpufreq_governor schedutil_gov = { .name ="schedutil" , .owner =THIS_MODULE , - .dynamic_switching = true, + .flags =CPUFREQ_GOV_DYNAMIC_SWITCHING , .init = sugov_init, .exit = sugov_exit, .start = sugov_start,
Greg Kroah-Hartman
maintainerPATCH 236/255 cpufreq: Introduce CPUFREQ_GOV_STRICT_TARGET
In reply to Greg Kroah-HartmanFrom: Rafael J. Wysocki <[email protected]>
commit 218f66870181bec7aaa6e3c72f346039c590c3c2 upstream.
Introduce a new governor flag, CPUFREQ_GOV_STRICT_TARGET, for the governors that want the target frequency to be set exactly to the given value without leaving any room for adjustments on the hardware side and set this flag for the powersave and performance governors.
--- drivers/cpufreq/cpufreq_performance.c | 1 + drivers/cpufreq/cpufreq_powersave.c | 1 + include/linux/cpufreq.h | 3 +++ 3 files changed, 5 insertions(+)
drivers/cpufreq/cpufreq_performance.c +1 -0
@@ -20,6 +20,7 @@ static void cpufreq_gov_performance_limistatic struct cpufreq_governor cpufreq_gov_performance = { .name ="performance" , .owner =THIS_MODULE , + .flags =CPUFREQ_GOV_STRICT_TARGET , .limits = cpufreq_gov_performance_limits, };
drivers/cpufreq/cpufreq_powersave.c +1 -0
@@ -21,6 +21,7 @@ static struct cpufreq_governor cpufreq_g .name = "powersave", .limits = cpufreq_gov_powersave_limits, .owner = THIS_MODULE, + .flags = CPUFREQ_GOV_STRICT_TARGET, };MODULE_AUTHOR ("Dominik Brodowski <[email protected]>" );
include/linux/cpufreq.h +3 -0
@@ -575,6 +575,9 @@ struct cpufreq_governor {/* For governors which change frequency dynamically by themselves */ #define CPUFREQ_GOV_DYNAMIC_SWITCHING BIT(0) +/* For governors wanting the target frequency to be set exactly */ +#define CPUFREQ_GOV_STRICT_TARGET BIT(1) +/* Pass a target to the cpufreq driver */ unsigned int cpufreq_driver_fast_switch(struct cpufreq_policy *policy,
Greg Kroah-Hartman
maintainerPATCH 237/255 cpufreq: Add strict_target to struct cpufreq_policy
In reply to Greg Kroah-HartmanFrom: Rafael J. Wysocki <[email protected]>
commit ea9364bbadf11f0c55802cf11387d74f524cee84 upstream.
Add a new field to be set when the CPUFREQ_GOV_STRICT_TARGET flag is set for the current governor to struct cpufreq_policy, so that the drivers needing to check CPUFREQ_GOV_STRICT_TARGET do not have to access the governor object during every frequency transition.
--- drivers/cpufreq/cpufreq.c | 2 ++ include/linux/cpufreq.h | 6 ++++++ 2 files changed, 8 insertions(+)
drivers/cpufreq/cpufreq.c +2 -0
@@ -2259,6 +2259,8 @@ static int cpufreq_init_governor(struct } } + policy->strict_target = !!(policy->governor->flags &CPUFREQ_GOV_STRICT_TARGET ); +return 0 ; }
include/linux/cpufreq.h +6 -0
@@ -110,6 +110,12 @@ struct cpufreq_policy {bool fast_switch_enabled;/* +* Set if the CPUFREQ_GOV_STRICT_TARGET flag is set for the current +* governor. +*/ +bool strict_target; + +/* * Preferred average time interval between consecutive invocations of * the driver to set the frequency for this policy. To be set by the * scaling driver (0, which is the default, means no preference).
Greg Kroah-Hartman
maintainerPATCH 238/255 cpufreq: intel_pstate: Take CPUFREQ_GOV_STRICT_TARGET into account
In reply to Greg Kroah-HartmanFrom: Rafael J. Wysocki <[email protected]>
commit fcb3a1ab79904d54499db77017793ccca665eb7e upstream.
Make intel_pstate take the new CPUFREQ_GOV_STRICT_TARGET governor flag into account when it operates in the passive mode with HWP enabled, so as to fix the "powersave" governor behavior in that case (currently, HWP is allowed to scale the performance all the way up to the policy max limit when the "powersave" governor is used, but it should be constrained to the policy min limit then).
--- drivers/cpufreq/intel_pstate.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)
drivers/cpufreq/intel_pstate.c +9 -7
@@ -2509,7 +2509,7 @@ static void intel_cpufreq_trace(struct c }static void intel_cpufreq_adjust_hwp (struct cpudata *cpu,u32 target_pstate, -bool fast_switch) +bool strict,bool fast_switch) {u64 prev =READ_ONCE (cpu->hwp_req_cached), value = prev;
@@ -2521,7 +2521,7 @@ static void intel_cpufreq_adjust_hwp(str* field in it, so opportunistically update the max too if needed. */ value &= ~HWP_MAX_PERF (~0L ); - value |=HWP_MAX_PERF (cpu->max_perf_ratio); + value |=HWP_MAX_PERF (strict ? target_pstate : cpu->max_perf_ratio);if (value == prev)return ;
@@ -2544,14 +2544,16 @@ static void intel_cpufreq_adjust_perf_ct pstate_funcs.get_val(cpu, target_pstate)); } -static int intel_cpufreq_update_pstate (struct cpudata *cpu,int target_pstate, -bool fast_switch) +static int intel_cpufreq_update_pstate (struct cpufreq_policy *policy, +int target_pstate,bool fast_switch) { +struct cpudata *cpu = all_cpu_data[policy->cpu];int old_pstate = cpu->pstate.current_pstate; target_pstate =intel_pstate_prepare_request (cpu, target_pstate);if (hwp_active) { -intel_cpufreq_adjust_hwp (cpu, target_pstate, fast_switch); +intel_cpufreq_adjust_hwp (cpu, target_pstate, + policy->strict_target, fast_switch); cpu->pstate.current_pstate = target_pstate; }else if (target_pstate != old_pstate) {intel_cpufreq_adjust_perf_ctl (cpu, target_pstate, fast_switch);
@@ -2591,7 +2593,7 @@ static int intel_cpufreq_target(struct cbreak ; } - target_pstate =intel_cpufreq_update_pstate (cpu, target_pstate, false); + target_pstate =intel_cpufreq_update_pstate (policy, target_pstate, false); freqs.new = target_pstate * cpu->pstate.scaling;
@@ -2610,7 +2612,7 @@ static unsigned int intel_cpufreq_fast_s target_pstate =DIV_ROUND_UP (target_freq, cpu->pstate.scaling); - target_pstate =intel_cpufreq_update_pstate (cpu, target_pstate, true); + target_pstate =intel_cpufreq_update_pstate (policy, target_pstate, true);return target_pstate * cpu->pstate.scaling; }
Greg Kroah-Hartman
maintainerPATCH 239/255 ethtool: netlink: add missing netdev_features_change() call
In reply to Greg Kroah-HartmanFrom: Alexander Lobakin <[email protected]>
[ Upstream commit 413691384a37fe27f43460226c4160e33140e638 ]
After updating userspace Ethtool from 5.7 to 5.9, I noticed that NETDEV_FEAT_CHANGE is no more raised when changing netdev features through Ethtool.
That's because the old Ethtool ioctl interface always calls netdev_features_change() at the end of user request processing to inform the kernel that our netdevice has some features changed, but the new Netlink interface does not. Instead, it just notifies itself with ETHTOOL_MSG_FEATURES_NTF.
Replace this ethtool_notify() call with netdev_features_change(), so the kernel will be aware of any features changes, just like in case with the ioctl interface. This does not omit Ethtool notifications, as Ethtool itself listens to NETDEV_FEAT_CHANGE and drops ETHTOOL_MSG_FEATURES_NTF on it (net/ethtool/netlink.c:ethnl_netdev_event()).
Quoted 1 line
From v1 [1]:
- dropped extra new line as advised by Jakub;
- no functional changes.
[1] https://lore.kernel.org/netdev/[email protected]
--- net/ethtool/features.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/ethtool/features.c +1 -1
@@ -296,7 +296,7 @@ int ethnl_set_features(struct sk_buff *s active_diff_mask, compact); }if (mod) -ethtool_notify (dev,ETHTOOL_MSG_FEATURES_NTF ,NULL ); +netdev_features_change (dev); out_rtnl:rtnl_unlock ();
Greg Kroah-Hartman
maintainerPATCH 240/255 IPv6: Set SIT tunnel hard_header_len to zero
In reply to Greg Kroah-HartmanFrom: Oliver Herms <[email protected]>
[ Upstream commit 8ef9ba4d666614497a057d09b0a6eafc1e34eadf ]
Due to the legacy usage of hard_header_len for SIT tunnels while already using infrastructure from net/ipv4/ip_tunnel.c the calculation of the path MTU in tnl_update_pmtu is incorrect. This leads to unnecessary creation of MTU exceptions for any flow going over a SIT tunnel.
As SIT tunnels do not have a header themsevles other than their transport (L3, L2) headers we're leaving hard_header_len set to zero as tnl_update_pmtu is already taking care of the transport headers sizes.
This will also help avoiding unnecessary IPv6 GC runs and spinlock contention seen when using SIT tunnels and for more than net.ipv6.route.gc_thresh flows.
--- net/ipv6/sit.c | 2 -- 1 file changed, 2 deletions(-)
net/ipv6/sit.c +0 -2
@@ -1128,7 +1128,6 @@ static void ipip6_tunnel_bind_dev(structif (tdev && !netif_is_l3_master (tdev)) {int t_hlen = tunnel->hlen +sizeof (struct iphdr ); - dev->hard_header_len = tdev->hard_header_len +sizeof (struct iphdr ); dev->mtu = tdev->mtu - t_hlen;if (dev->mtu <IPV6_MIN_MTU ) dev->mtu =IPV6_MIN_MTU ;
@@ -1426,7 +1425,6 @@ static void ipip6_tunnel_setup(struct ne dev->priv_destructor = ipip6_dev_free; dev->type =ARPHRD_SIT ; - dev->hard_header_len =LL_MAX_HEADER + t_hlen; dev->mtu =ETH_DATA_LEN - t_hlen; dev->min_mtu =IPV6_MIN_MTU ; dev->max_mtu =IP6_MAX_MTU - t_hlen;
Greg Kroah-Hartman
maintainerPATCH 241/255 net/af_iucv: fix null pointer dereference on shutdown
In reply to Greg Kroah-HartmanFrom: Ursula Braun <[email protected]>
[ Upstream commit 4031eeafa71eaf22ae40a15606a134ae86345daf ]
syzbot reported the following KASAN finding:
BUG: KASAN: nullptr-dereference in iucv_send_ctrl+0x390/0x3f0 net/iucv/af_iucv.c:385 Read of size 2 at addr 000000000000021e by task syz-executor907/519 CPU: 0 PID: 519 Comm: syz-executor907 Not tainted 5.9.0-syzkaller-07043-gbcf9877ad213 #0 Hardware name: IBM 3906 M04 701 (KVM/Linux) Call Trace: [<00000000c576af60>] unwind_start arch/s390/include/asm/unwind.h:65 [inline] [<00000000c576af60>] show_stack+0x180/0x228 arch/s390/kernel/dumpstack.c:135 [<00000000c9dcd1f8>] __dump_stack lib/dump_stack.c:77 [inline] [<00000000c9dcd1f8>] dump_stack+0x268/0x2f0 lib/dump_stack.c:118 [<00000000c5fed016>] print_address_description.constprop.0+0x5e/0x218 mm/kasan/report.c:383 [<00000000c5fec82a>] __kasan_report mm/kasan/report.c:517 [inline] [<00000000c5fec82a>] kasan_report+0x11a/0x168 mm/kasan/report.c:534 [<00000000c98b5b60>] iucv_send_ctrl+0x390/0x3f0 net/iucv/af_iucv.c:385 [<00000000c98b6262>] iucv_sock_shutdown+0x44a/0x4c0 net/iucv/af_iucv.c:1457 [<00000000c89d3a54>] __sys_shutdown+0x12c/0x1c8 net/socket.c:2204 [<00000000c89d3b70>] __do_sys_shutdown net/socket.c:2212 [inline] [<00000000c89d3b70>] __s390x_sys_shutdown+0x38/0x48 net/socket.c:2210 [<00000000c9e36eac>] system_call+0xe0/0x28c arch/s390/kernel/entry.S:415
There is nothing to shutdown if a connection has never been established. Besides that iucv->hs_dev is not yet initialized if a socket is in IUCV_OPEN state and iucv->path is not yet initialized if socket is in IUCV_BOUND state.
So, just skip the shutdown calls for a socket in these states.
--- net/iucv/af_iucv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
net/iucv/af_iucv.c +2 -1
@@ -1434,7 +1434,8 @@ static int iucv_sock_shutdown(struct socbreak ; } -if (how ==SEND_SHUTDOWN || how ==SHUTDOWN_MASK ) { +if ((how ==SEND_SHUTDOWN || how ==SHUTDOWN_MASK ) && + sk->sk_state ==IUCV_CONNECTED ) {if (iucv->transport ==AF_IUCV_TRANS_IUCV ) { txmsg.class =0 ; txmsg.tag =0 ;
Greg Kroah-Hartman
maintainerPATCH 242/255 net: udp: fix IP header access and skb lookup on Fast/frag0 UDP GRO
In reply to Greg Kroah-HartmanFrom: Alexander Lobakin <[email protected]>
[ Upstream commit 55e729889bb07d68ab071660ce3f5e7a7872ebe8 ]
udp{4,6}_lib_lookup_skb() use ip{,v6}_hdr() to get IP header of the packet. While it's probably OK for non-frag0 paths, this helpers will also point to junk on Fast/frag0 GRO when all headers are located in frags. As a result, sk/skb lookup may fail or give wrong results. To support both GRO modes, skb_gro_network_header() might be used. To not modify original functions, add private versions of udp{4,6}_lib_lookup_skb() only to perform correct sk lookups on GRO.
Present since the introduction of "application-level" UDP GRO in 4.7-rc1.
Misc: replace totally unneeded ternaries with plain ifs.
--- net/ipv4/udp_offload.c | 17 +++++++++++++++-- net/ipv6/udp_offload.c | 17 +++++++++++++++-- 2 files changed, 30 insertions(+), 4 deletions(-)
net/ipv4/udp_offload.c +15 -2
@@ -500,12 +500,22 @@ out: }EXPORT_SYMBOL (udp_gro_receive); +static struct sock *udp4_gro_lookup_skb (struct sk_buff *skb,__be16 sport, +__be16 dport) +{ +const struct iphdr *iph =skb_gro_network_header (skb); + +return __udp4_lib_lookup (dev_net (skb->dev), iph->saddr, sport, + iph->daddr, dport,inet_iif (skb), +inet_sdif (skb), &udp_table,NULL ); +} +INDIRECT_CALLABLE_SCOPE struct sk_buff *udp4_gro_receive(struct list_head *head, struct sk_buff *skb) {struct udphdr *uh =udp_gro_udphdr (skb); +struct sock *sk =NULL ;struct sk_buff *pp; -struct sock *sk;if (unlikely (!uh)) goto flush;
@@ -523,7 +533,10 @@ struct sk_buff *udp4_gro_receive(struct skip:NAPI_GRO_CB (skb)->is_ipv6 =0 ;rcu_read_lock (); - sk =static_branch_unlikely (&udp_encap_needed_key) ?udp4_lib_lookup_skb (skb, uh->source, uh->dest) :NULL ; + +if (static_branch_unlikely (&udp_encap_needed_key)) + sk =udp4_gro_lookup_skb (skb, uh->source, uh->dest); + pp =udp_gro_receive (head, skb, uh, sk);rcu_read_unlock ();return pp;
net/ipv6/udp_offload.c +15 -2
@@ -111,12 +111,22 @@ out:return segs; } +static struct sock *udp6_gro_lookup_skb (struct sk_buff *skb,__be16 sport, +__be16 dport) +{ +const struct ipv6hdr *iph =skb_gro_network_header (skb); + +return __udp6_lib_lookup (dev_net (skb->dev), &iph->saddr, sport, + &iph->daddr, dport,inet6_iif (skb), +inet6_sdif (skb), &udp_table,NULL ); +} +INDIRECT_CALLABLE_SCOPE struct sk_buff *udp6_gro_receive(struct list_head *head, struct sk_buff *skb) {struct udphdr *uh =udp_gro_udphdr (skb); +struct sock *sk =NULL ;struct sk_buff *pp; -struct sock *sk;if (unlikely (!uh)) goto flush;
@@ -135,7 +145,10 @@ struct sk_buff *udp6_gro_receive(struct skip:NAPI_GRO_CB (skb)->is_ipv6 =1 ;rcu_read_lock (); - sk =static_branch_unlikely (&udpv6_encap_needed_key) ?udp6_lib_lookup_skb (skb, uh->source, uh->dest) :NULL ; + +if (static_branch_unlikely (&udpv6_encap_needed_key)) + sk =udp6_gro_lookup_skb (skb, uh->source, uh->dest); + pp =udp_gro_receive (head, skb, uh, sk);rcu_read_unlock ();return pp;
Greg Kroah-Hartman
maintainerPATCH 243/255 net: udp: fix UDP header access on Fast/frag0 UDP GRO
In reply to Greg Kroah-HartmanFrom: Alexander Lobakin <[email protected]>
[ Upstream commit 4b1a86281cc1d0de46df3ad2cb8c1f86ac07681c ]
UDP GRO uses udp_hdr(skb) in its .gro_receive() callback. While it's probably OK for non-frag0 paths (when all headers or even the entire frame are already in skb head), this inline points to junk when using Fast GRO (napi_gro_frags() or napi_gro_receive() with only Ethernet header in skb head and all the rest in the frags) and breaks GRO packet compilation and the packet flow itself.
To support both modes, skb_gro_header_fast() + skb_gro_header_slow() are typically used. UDP even has an inline helper that makes use of them, udp_gro_udphdr(). Use that instead of troublemaking udp_hdr() to get rid of the out-of-order delivers.
Present since the introduction of plain UDP GRO in 5.0-rc1.
--- net/ipv4/udp_offload.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/ipv4/udp_offload.c +1 -1
@@ -366,7 +366,7 @@ out:static struct sk_buff *udp_gro_receive_segment (struct list_head *head,struct sk_buff *skb) { -struct udphdr *uh =udp_hdr (skb); +struct udphdr *uh =udp_gro_udphdr (skb);struct sk_buff *pp =NULL ;struct udphdr *uh2;struct sk_buff *p;
Greg Kroah-Hartman
maintainerPATCH 244/255 net: Update window_clamp if SOCK_RCVBUF is set
In reply to Greg Kroah-HartmanFrom: Mao Wenan <[email protected]>
[ Upstream commit 909172a149749242990a6e64cb55d55460d4e417 ]
When net.ipv4.tcp_syncookies=1 and syn flood is happened, cookie_v4_check or cookie_v6_check tries to redo what tcp_v4_send_synack or tcp_v6_send_synack did, rsk_window_clamp will be changed if SOCK_RCVBUF is set, which will make rcv_wscale is different, the client still operates with initial window scale and can overshot granted window, the client use the initial scale but local server use new scale to advertise window value, and session work abnormally.
--- net/ipv4/syncookies.c | 9 +++++++-- net/ipv6/syncookies.c | 10 ++++++++-- 2 files changed, 15 insertions(+), 4 deletions(-)
net/ipv4/syncookies.c +7 -2
@@ -331,7 +331,7 @@ struct sock *cookie_v4_check(struct sock__u32 cookie =ntohl (th->ack_seq) -1 ;struct sock *ret = sk;struct request_sock *req; -int mss; +int full_space, mss;struct rtable *rt;__u8 rcv_wscale;struct flowi4 fl4;
@@ -427,8 +427,13 @@ struct sock *cookie_v4_check(struct sock/* Try to redo what tcp_v4_send_synack did. */ req->rsk_window_clamp = tp->window_clamp ? :dst_metric (&rt->dst,RTAX_WINDOW ); +/* limit the window selection if the user enforce a smaller rx buffer */ + full_space =tcp_full_space (sk); +if (sk->sk_userlocks &SOCK_RCVBUF_LOCK && + (req->rsk_window_clamp > full_space || req->rsk_window_clamp ==0 )) + req->rsk_window_clamp = full_space; -tcp_select_initial_window (sk,tcp_full_space (sk), req->mss, +tcp_select_initial_window (sk, full_space, req->mss, &req->rsk_rcv_wnd, &req->rsk_window_clamp, ireq->wscale_ok, &rcv_wscale,dst_metric (&rt->dst,RTAX_INITRWND ));
net/ipv6/syncookies.c +8 -2
@@ -136,7 +136,7 @@ struct sock *cookie_v6_check(struct sock__u32 cookie =ntohl (th->ack_seq) -1 ;struct sock *ret = sk;struct request_sock *req; -int mss; +int full_space, mss;struct dst_entry *dst;__u8 rcv_wscale;u32 tsoff =0 ;
@@ -241,7 +241,13 @@ struct sock *cookie_v6_check(struct sock } req->rsk_window_clamp = tp->window_clamp ? :dst_metric (dst,RTAX_WINDOW ); -tcp_select_initial_window (sk,tcp_full_space (sk), req->mss, +/* limit the window selection if the user enforce a smaller rx buffer */ + full_space =tcp_full_space (sk); +if (sk->sk_userlocks &SOCK_RCVBUF_LOCK && + (req->rsk_window_clamp > full_space || req->rsk_window_clamp ==0 )) + req->rsk_window_clamp = full_space; + +tcp_select_initial_window (sk, full_space, req->mss, &req->rsk_rcv_wnd, &req->rsk_window_clamp, ireq->wscale_ok, &rcv_wscale,dst_metric (dst,RTAX_INITRWND ));
Greg Kroah-Hartman
maintainerPATCH 245/255 net/x25: Fix null-ptr-deref in x25_connect
In reply to Greg Kroah-HartmanFrom: Martin Schiller <[email protected]>
[ Upstream commit 361182308766a265b6c521879b34302617a8c209 ]
This fixes a regression for blocking connects introduced by commit 4becb7ee5b3d ("net/x25: Fix x25_neigh refcnt leak when x25 disconnect").
The x25->neighbour is already set to "NULL" by x25_disconnect() now, while a blocking connect is waiting in x25_wait_for_connection_establishment(). Therefore x25->neighbour must not be accessed here again and x25->state is also already set to X25_STATE_0 by x25_disconnect().
--- net/x25/af_x25.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/x25/af_x25.c +1 -1
@@ -825,7 +825,7 @@ static int x25_connect(struct socket *so sock->state =SS_CONNECTED ; rc =0 ; out_put_neigh: -if (rc) { +if (rc && x25->neighbour) {read_lock_bh (&x25_list_lock);x25_neigh_put (x25->neighbour); x25->neighbour =NULL ;
Greg Kroah-Hartman
maintainerPATCH 246/255 tipc: fix memory leak in tipc_topsrv_start()
In reply to Greg Kroah-HartmanFrom: Wang Hai <[email protected]>
[ Upstream commit fa6882c63621821f73cc806f291208e1c6ea6187 ]
kmemleak report a memory leak as follows:
unreferenced object 0xffff88810a596800 (size 512):
comm "ip", pid 21558, jiffies 4297568990 (age 112.120s) hex dump (first 32 bytes):
00 00 00 00 ad 4e ad de ff ff ff ff 00 00 00 00 .....N..........
ff ff ff ff ff ff ff ff 00 83 60 b0 ff ff ff ff ..........`.....
backtrace:
[<0000000022bbe21f>] tipc_topsrv_init_net+0x1f3/0xa70
[<00000000fe15ddf7>] ops_init+0xa8/0x3c0
[<00000000138af6f2>] setup_net+0x2de/0x7e0
[<000000008c6807a3>] copy_net_ns+0x27d/0x530
[<000000006b21adbd>] create_new_namespaces+0x382/0xa30
[<00000000bb169746>] unshare_nsproxy_namespaces+0xa1/0x1d0
[<00000000fe2e42bc>] ksys_unshare+0x39c/0x780
[<0000000009ba3b19>] __x64_sys_unshare+0x2d/0x40
[<00000000614ad866>] do_syscall_64+0x56/0xa0
[<00000000a1b5ca3c>] entry_SYSCALL_64_after_hwframe+0x44/0xa9'srv' is malloced in tipc_topsrv_start() but not free before leaving from the error handling cases. We need to free it.
--- net/tipc/topsrv.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
net/tipc/topsrv.c +8 -2
@@ -665,12 +665,18 @@ static int tipc_topsrv_start(struct net ret =tipc_topsrv_work_start (srv);if (ret <0 ) -return ret; + goto err_start; ret =tipc_topsrv_create_listener (srv);if (ret <0 ) -tipc_topsrv_work_stop (srv); + goto err_create; +return 0 ; + +err_create: +tipc_topsrv_work_stop (srv); +err_start: +kfree (srv);return ret; }
Greg Kroah-Hartman
maintainerPATCH 247/255 devlink: Avoid overwriting port attributes of registered port
In reply to Greg Kroah-HartmanFrom: Parav Pandit <[email protected]>
[ Upstream commit 9f73bd1c2c4c304b238051fc92b3f807326f0a89 ]
Cited commit in fixes tag overwrites the port attributes for the registered port.
Avoid such error by checking registered flag before setting attributes.
--- net/core/devlink.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
net/core/devlink.c +6 -2
@@ -7675,8 +7675,6 @@ static int __devlink_port_attrs_set(stru {struct devlink_port_attrs *attrs = &devlink_port->attrs; -if (WARN_ON (devlink_port->registered)) -return -EEXIST ; devlink_port->attrs_set = true; attrs->flavour = flavour;if (attrs->switch_id.id_len) {
@@ -7700,6 +7698,8 @@ void devlink_port_attrs_set(struct devli {int ret; +if (WARN_ON (devlink_port->registered)) +return ; devlink_port->attrs = *attrs; ret =__devlink_port_attrs_set (devlink_port, attrs->flavour);if (ret)
@@ -7719,6 +7719,8 @@ void devlink_port_attrs_pci_pf_set(strucstruct devlink_port_attrs *attrs = &devlink_port->attrs;int ret; +if (WARN_ON (devlink_port->registered)) +return ; ret =__devlink_port_attrs_set (devlink_port,DEVLINK_PORT_FLAVOUR_PCI_PF );if (ret)
@@ -7741,6 +7743,8 @@ void devlink_port_attrs_pci_vf_set(strucstruct devlink_port_attrs *attrs = &devlink_port->attrs;int ret; +if (WARN_ON (devlink_port->registered)) +return ; ret =__devlink_port_attrs_set (devlink_port,DEVLINK_PORT_FLAVOUR_PCI_VF );if (ret)
Greg Kroah-Hartman
maintainerPATCH 248/255 mptcp: provide rmem[0] limit
In reply to Greg Kroah-HartmanFrom: Paolo Abeni <[email protected]>
[ Upstream commit 989ef49bdf100cc772b3a8737089df36b1ab1e30 ]
The mptcp proto struct currently does not provide the required limit for forward memory scheduling. Under pressure sk_rmem_schedule() will unconditionally try to use such field and will oops.
Address the issue inheriting the tcp limit, as we already do for the wmem one.
--- net/mptcp/protocol.c | 1 + 1 file changed, 1 insertion(+)
net/mptcp/protocol.c +1 -0
@@ -2122,6 +2122,7 @@ static struct proto mptcp_prot = { .memory_pressure = &tcp_memory_pressure, .stream_memory_free = mptcp_memory_free, .sysctl_wmem_offset = offsetof(struct net, ipv4.sysctl_tcp_wmem), + .sysctl_rmem_offset = offsetof(struct net, ipv4.sysctl_tcp_rmem), .sysctl_mem = sysctl_tcp_mem, .obj_size = sizeof(struct mptcp_sock), .slab_flags = SLAB_TYPESAFE_BY_RCU,
Greg Kroah-Hartman
maintainerPATCH 249/255 tunnels: Fix off-by-one in lower MTU bounds for ICMP/ICMPv6 replies
In reply to Greg Kroah-HartmanFrom: Stefano Brivio <[email protected]>
[ Upstream commit 77a2d673d5c9d1d359b5652ff75043273c5dea28 ]
Jianlin reports that a bridged IPv6 VXLAN endpoint, carrying IPv6 packets over a link with a PMTU estimation of exactly 1350 bytes, won't trigger ICMPv6 Packet Too Big replies when the encapsulated datagrams exceed said PMTU value. VXLAN over IPv6 adds 70 bytes of overhead, so an ICMPv6 reply indicating 1280 bytes as inner MTU would be legitimate and expected.
This comes from an off-by-one error I introduced in checks added as part of commit 4cb47a8644cc ("tunnels: PMTU discovery support for directly bridged IP packets"), whose purpose was to prevent sending ICMPv6 Packet Too Big messages with an MTU lower than the smallest permissible IPv6 link MTU, i.e. 1280 bytes.
In iptunnel_pmtud_check_icmpv6(), avoid triggering a reply only if the advertised MTU would be less than, and not equal to, 1280 bytes.
Also fix the analogous comparison for IPv4, that is, skip the ICMP reply only if the resulting MTU is strictly less than 576 bytes.
This becomes apparent while running the net/pmtu.sh bridged VXLAN or GENEVE selftests with adjusted lower-link MTU values. Using e.g. GENEVE, setting ll_mtu to the values reported below, in the test_pmtu_ipvX_over_bridged_vxlanY_or_geneveY_exception() test function, we can see failures on the following tests:
test | ll_mtu -------------------------------|-------- pmtu_ipv4_br_geneve4_exception | 626 pmtu_ipv6_br_geneve4_exception | 1330 pmtu_ipv6_br_geneve6_exception | 1350
owing to the different tunneling overheads implied by the corresponding configurations.
--- net/ipv4/ip_tunnel_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
net/ipv4/ip_tunnel_core.c +2 -2
@@ -263,7 +263,7 @@ static int iptunnel_pmtud_check_icmp(strconst struct icmphdr *icmph =icmp_hdr (skb);const struct iphdr *iph =ip_hdr (skb); -if (mtu <=576 || iph->frag_off !=htons (IP_DF )) +if (mtu <576 || iph->frag_off !=htons (IP_DF ))return 0 ; if (ipv4_is_lbcast(iph->daddr) || ipv4_is_multicast(iph->daddr) ||
@@ -359,7 +359,7 @@ static int iptunnel_pmtud_check_icmpv6(s__be16 frag_off;int offset; -if (mtu <=IPV6_MIN_MTU ) +if (mtu <IPV6_MIN_MTU )return 0 ; if (stype == IPV6_ADDR_ANY || stype == IPV6_ADDR_MULTICAST ||
Greg Kroah-Hartman
maintainerPATCH 250/255 powerpc/603: Always fault when _PAGE_ACCESSED is not set
In reply to Greg Kroah-HartmanFrom: Christophe Leroy <[email protected]>
commit 11522448e641e8f1690c9db06e01985e8e19b401 upstream.
The kernel expects pte_young() to work regardless of CONFIG_SWAP.
Make sure a minor fault is taken to set _PAGE_ACCESSED when it is not already set, regardless of the selection of CONFIG_SWAP.
--- arch/powerpc/kernel/head_32.S | 12 ------------ 1 file changed, 12 deletions(-)
arch/powerpc/kernel/head_32.S +0 -12
@@ -472,11 +472,7 @@ InstructionTLBMiss: cmplw 0,r1,r3 #endif mfspr r2, SPRN_SPRG_PGDIR -#ifdef CONFIG_SWAP li r1,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC -#else - li r1,_PAGE_PRESENT | _PAGE_EXEC -#endif #if defined(CONFIG_MODULES) || defined(CONFIG_DEBUG_PAGEALLOC) bgt- 112f lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */
@@ -538,11 +534,7 @@ DataLoadTLBMiss: lis r1, TASK_SIZE@h /* check if kernel address */ cmplw 0,r1,r3 mfspr r2, SPRN_SPRG_PGDIR -#ifdef CONFIG_SWAP li r1, _PAGE_PRESENT | _PAGE_ACCESSED -#else - li r1, _PAGE_PRESENT -#endif bgt- 112f lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */ addi r2, r2, (swapper_pg_dir - PAGE_OFFSET)@l /* kernel page table */
@@ -618,11 +610,7 @@ DataStoreTLBMiss: lis r1, TASK_SIZE@h /* check if kernel address */ cmplw 0,r1,r3 mfspr r2, SPRN_SPRG_PGDIR -#ifdef CONFIG_SWAP li r1, _PAGE_RW | _PAGE_DIRTY | _PAGE_PRESENT | _PAGE_ACCESSED -#else - li r1, _PAGE_RW | _PAGE_DIRTY | _PAGE_PRESENT -#endif bgt- 112f lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */ addi r2, r2, (swapper_pg_dir - PAGE_OFFSET)@l /* kernel page table */
Greg Kroah-Hartman
maintainerPATCH 251/255 null_blk: Fix scheduling in atomic with zoned mode
In reply to Greg Kroah-HartmanFrom: Damien Le Moal <[email protected]>
commit e1777d099728a76a8f8090f89649aac961e7e530 upstream.
Commit aa1c09cb65e2 ("null_blk: Fix locking in zoned mode") changed zone locking to using the potentially sleeping wait_on_bit_io() function. This is acceptable when memory backing is enabled as the device queue is in that case marked as blocking, but this triggers a scheduling while in atomic context with memory backing disabled.
Fix this by relying solely on the device zone spinlock for zone information protection without temporarily releasing this lock around null_process_cmd() execution in null_zone_write(). This is OK to do since when memory backing is disabled, command processing does not block and the memory backing lock nullb->lock is unused. This solution avoids the overhead of having to mark a zoned null_blk device queue as blocking when memory backing is unused.
This patch also adds comments to the zone locking code to explain the unusual locking scheme.
--- drivers/block/null_blk.h | 1 + drivers/block/null_blk_zoned.c | 31 +++++++++++++++++++++++++------ 2 files changed, 26 insertions(+), 6 deletions(-)
drivers/block/null_blk.h +1 -0
@@ -44,6 +44,7 @@ struct nullb_device {unsigned int nr_zones;struct blk_zone *zones;sector_t zone_size_sects; +spinlock_t zone_lock;unsigned long *zone_locks;unsigned long size;/* device size in MB */
drivers/block/null_blk_zoned.c +25 -6
@@ -46,10 +46,20 @@ int null_init_zoned_dev(struct nullb_devif (!dev->zones)return -ENOMEM ; - dev->zone_locks =bitmap_zalloc (dev->nr_zones,GFP_KERNEL ); -if (!dev->zone_locks) { -kvfree (dev->zones); -return -ENOMEM ; +/* +* With memory backing, the zone_lock spinlock needs to be temporarily +* released to avoid scheduling in atomic context. To guarantee zone +* information protection, use a bitmap to lock zones with +* wait_on_bit_lock_io(). Sleeping on the lock is OK as memory backing +* implies that the queue is marked with BLK_MQ_F_BLOCKING. +*/ +spin_lock_init (&dev->zone_lock); +if (dev->memory_backed) { + dev->zone_locks =bitmap_zalloc (dev->nr_zones,GFP_KERNEL ); +if (!dev->zone_locks) { +kvfree (dev->zones); +return -ENOMEM ; + } }if (dev->zone_nr_conv >= dev->nr_zones) {
@@ -118,12 +128,16 @@ void null_free_zoned_dev(struct nullb_destatic inline void null_lock_zone (struct nullb_device *dev,unsigned int zno) { -wait_on_bit_lock_io (dev->zone_locks, zno,TASK_UNINTERRUPTIBLE ); +if (dev->memory_backed) +wait_on_bit_lock_io (dev->zone_locks, zno,TASK_UNINTERRUPTIBLE ); +spin_lock_irq (&dev->zone_lock); }static inline void null_unlock_zone (struct nullb_device *dev,unsigned int zno) { -clear_and_wake_up_bit (zno, dev->zone_locks); +spin_unlock_irq (&dev->zone_lock); +if (dev->memory_backed) +clear_and_wake_up_bit (zno, dev->zone_locks); } int null_report_zones(struct gendisk *disk, sector_t sector,
@@ -233,7 +247,12 @@ static blk_status_t null_zone_write(struif (zone->cond !=BLK_ZONE_COND_EXP_OPEN ) zone->cond =BLK_ZONE_COND_IMP_OPEN ; +if (dev->memory_backed) +spin_unlock_irq (&dev->zone_lock); ret =null_process_cmd (cmd,REQ_OP_WRITE , sector, nr_sectors); +if (dev->memory_backed) +spin_lock_irq (&dev->zone_lock); +if (ret !=BLK_STS_OK )break ;
Greg Kroah-Hartman
maintainerPATCH 252/255 perf scripting python: Avoid declaring function pointers with a visibility attribute
In reply to Greg Kroah-HartmanFrom: Arnaldo Carvalho de Melo <[email protected]>
commit d0e7b0c71fbb653de90a7163ef46912a96f0bdaf upstream.
To avoid this:
util/scripting-engines/trace-event-python.c: In function 'python_start_script':
util/scripting-engines/trace-event-python.c:1595:2: error: 'visibility' attribute ignored [-Werror=attributes]
1595 | PyMODINIT_FUNC (*initfunc)(void);
| ^~~~~~~~~~~~~~That started breaking when building with PYTHON=python3 and these gcc versions (I haven't checked with the clang ones, maybe it breaks there as well):
# export PERF_TARBALL=http://192.168.86.5/perf/perf-5.9.0.tar.xz # dm fedora:33 fedora:rawhide 1 107.80 fedora:33 : Ok gcc (GCC) 10.2.1 20201005 (Red Hat 10.2.1-5), clang version 11.0.0 (Fedora 11.0.0-1.fc33) 2 92.47 fedora:rawhide : Ok gcc (GCC) 10.2.1 20201016 (Red Hat 10.2.1-6), clang version 11.0.0 (Fedora 11.0.0-1.fc34) #
Avoid that by ditching that 'initfunc' function pointer with its:
#define Py_EXPORTED_SYMBOL _attribute_ ((visibility ("default")))
#define PyMODINIT_FUNC Py_EXPORTED_SYMBOL PyObject*And just call PyImport_AppendInittab() at the end of the ifdef python3 block with the functions that were being attributed to that initfunc.
--- tools/perf/util/scripting-engines/trace-event-python.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
tools/perf/util/scripting-engines/trace-event-python.c +2 -5
@@ -1592,7 +1592,6 @@ static void _free_command_line(wchar_t *static int python_start_script (const char *script,int argc,const char **argv) {struct tables *tables = &tables_global; -PyMODINIT_FUNC (*initfunc)(void);#if PY_MAJOR_VERSION <3 const char **command_line;#else
@@ -1607,20 +1606,18 @@ static int python_start_script(const chaFILE *fp;#if PY_MAJOR_VERSION <3 - initfunc = initperf_trace_context; command_line =malloc ((argc +1 ) *sizeof (const char *)); command_line[0 ] = script;for (i =1 ; i < argc +1 ; i++) command_line[i] = argv[i -1 ]; +PyImport_AppendInittab (name, initperf_trace_context);#else - initfunc = PyInit_perf_trace_context; command_line =malloc ((argc +1 ) *sizeof (wchar_t *)); command_line[0 ] =Py_DecodeLocale (script,NULL );for (i =1 ; i < argc +1 ; i++) command_line[i] =Py_DecodeLocale (argv[i -1 ],NULL ); +PyImport_AppendInittab (name, PyInit_perf_trace_context);#endif - -PyImport_AppendInittab (name, initfunc);Py_Initialize ();#if PY_MAJOR_VERSION <3
Greg Kroah-Hartman
maintainerPATCH 253/255 coresight: etm: perf: Sink selection using sysfs is deprecated
In reply to Greg Kroah-HartmanFrom: Linu Cherian <[email protected]>
commit bb1860efc817c18fce4112f25f51043e44346d1b upstream.
When using the perf interface, sink selection using sysfs is deprecated.
--- drivers/hwtracing/coresight/coresight-etm-perf.c | 2 -- 1 file changed, 2 deletions(-)
drivers/hwtracing/coresight/coresight-etm-perf.c +0 -2
@@ -222,8 +222,6 @@ static void *etm_setup_aux(struct perf_eif (event->attr.config2) { id = (u32 )event->attr.config2; sink =coresight_get_sink_by_id (id); - }else { - sink =coresight_get_enabled_sink (true); } mask = &event_data->mask;
Greg Kroah-Hartman
maintainerPATCH 254/255 coresight: Fix uninitialised pointer bug in etm_setup_aux()
In reply to Greg Kroah-HartmanFrom: Mike Leach <[email protected]>
commit 39a7661dcf655c8198fd5d72412f5030a8e58444 upstream.
Commit [bb1860efc817] changed the sink handling code introducing an uninitialised pointer bug. This results in the default sink selection failing.
Prior to commit:
static void etm_setup_aux(...)
<snip>
struct coresight_device *sink;
<snip>
/* First get the selected sink from user space. */
if (event->attr.config2) {
id = (u32)event->attr.config2;
sink = coresight_get_sink_by_id(id);
} else {
sink = coresight_get_enabled_sink(true);
}<ctd>
*sink always initialised - possibly to NULL which triggers the automatic sink selection.
After commit:
static void etm_setup_aux(...)
<snip>
struct coresight_device *sink;
<snip>
/* First get the selected sink from user space. */
if (event->attr.config2) {
id = (u32)event->attr.config2;
sink = coresight_get_sink_by_id(id);
}<ctd>
*sink pointer uninitialised when not providing a sink on the perf command line. This breaks later checks to enable automatic sink selection.
--- drivers/hwtracing/coresight/coresight-etm-perf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/hwtracing/coresight/coresight-etm-perf.c +1 -1
@@ -210,7 +210,7 @@ static void *etm_setup_aux(struct perf_eu32 id;int cpu = event->cpu;cpumask_t *mask; -struct coresight_device *sink; +struct coresight_device *sink =NULL ;struct etm_event_data *event_data =NULL ; event_data =alloc_event_data (cpu);
Greg Kroah-Hartman
maintainerPATCH 255/255 Convert trailing spaces and periods in path components
In reply to Greg Kroah-HartmanFrom: Boris Protopopov <[email protected]>
commit 57c176074057531b249cf522d90c22313fa74b0b upstream.
When converting trailing spaces and periods in paths, do so for every component of the path, not just the last component. If the conversion is not done for every path component, then subsequent operations in directories with trailing spaces or periods (e.g. create(), mkdir()) will fail with ENOENT. This is because on the server, the directory will have a special symbol in its name, and the client needs to provide the same.
--- fs/cifs/cifs_unicode.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
fs/cifs/cifs_unicode.c +7 -1
@@ -488,7 +488,13 @@ cifsConvertToUTF16(__le16 *target, constelse if (map_chars ==SFM_MAP_UNI_RSVD ) {bool end_of_string; -if (i == srclen -1 ) +/** +* Remap spaces and periods found at the end of every +* component of the path. The special cases of '.' and +* '..' do not need to be dealt with explicitly because +* they are addressed in namei.c:link_path_walk(). +**/ +if ((i == srclen -1 ) || (source[i+1 ] =='\\' )) end_of_string = true;else end_of_string = false;
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.9.9 release. There are 255 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 19 Nov 2020 12:20:51 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.9.9-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.9.y
and the diffstat can be found below.thanks,
greg k-h
All tests passing for Tegra ...
Test results for stable-v5.9:
15 builds: 15 pass, 0 fail
26 boots: 26 pass, 0 fail
64 tests: 64 pass, 0 failLinux version: 5.9.9-rc1-gfb1622495321
Boards tested: tegra124-jetson-tk1, tegra186-p2771-0000,
tegra194-p2972-0000, tegra20-ventana,
tegra210-p2371-2180, tegra210-p3450-0000,
tegra30-cardhu-a04Jon
Greg Kroah-Hartman
maintainerQuoted 26 lines · Jon Hunter
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.9.9 release. There are 255 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 19 Nov 2020 12:20:51 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.9.9-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.9.y
and the diffstat can be found below.thanks,
greg k-h
All tests passing for Tegra ...
Test results for stable-v5.9:
15 builds: 15 pass, 0 fail 26 boots: 26 pass, 0 fail 64 tests: 64 pass, 0 fail
Quoted 7 lines
Linux version: 5.9.9-rc1-gfb1622495321
Boards tested: tegra124-jetson-tk1, tegra186-p2771-0000,tegra194-p2972-0000, tegra20-ventana, tegra210-p2371-2180, tegra210-p3450-0000, tegra30-cardhu-a04Tested-by Jon Hunter <[email protected]>
Thanks for testing all of them and letting me know.
greg k-h
Quoted 18 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.9.9 release. There are 255 patches in this series, all will be posted as a response
to this one. If anyone has any issues with these being applied, please
let me know.Responses should be made by Thu, 19 Nov 2020 12:20:51 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.9.9-rc1.gz
or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-
stable-rc.git linux-5.9.y
and the diffstat can be found below.
Quoted 5 lines
thanks,
greg k-h
Compiled and booted 5.9.9-rc1+. No typical dmesg regression or regressions.
Signature · 2 lines
software engineer rajagiri school of engineering and technology - autonomous
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.9.9 release. There are 255 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 19 Nov 2020 12:20:51 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 9 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.9.9-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.9.y
and the diffstat can be found below.thanks,
greg k-h
Compiled and booted on my test system. No dmesg regressions.
thanks,
-- Shuah
Greg Kroah-Hartman
maintainerQuoted 15 lines · Shuah Khan
Quoted 14 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.9.9 release. There are 255 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 19 Nov 2020 12:20:51 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.9.9-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.9.y
and the diffstat can be found below.
Quoted 8 lines
Quoted 4 lines
thanks,
greg k-h
Compiled and booted on my test system. No dmesg regressions.
Tested-by Shuah Khan <[email protected]>
Thanks for testing them all and letting me know.
greg k-h
Quoted 10 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.9.9 release. There are 255 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 19 Nov 2020 12:20:51 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.9.9-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.9.y
and the diffstat can be found below.thanks,
greg k-h
Results from Linaro’s test farm.
No regressions on arm64, arm, x86_64, and i386.
NOTE:
1)
BUG: Invalid wait context on arm64 db410c device while booting.
This issue has not reproduced after several testing loops.
https://lore.kernel.org/stable/CA+G9fYsk54r9Re4E9BWpqsoxLjpCvxRKFWRgdiKVcPoYE5z0Hw@mail.gmail.com/T/#u
2)
kselftest test suite version upgrade to v5.9
3)
While running kselftest netfilter on x86, i386, arm64 and arm devices the following kernel warning was noticed.
WARNING: at net/netfilter/nf_tables_api.c:622 lockdep_nfnl_nft_mutex_not_held+0x19/0x20 [nf_tables]
4)
From this release we have started building kernels with clang-10 toolchain and testing LTP testsuite on qemu_arm64, qemu_arm, qemu_x86_64 and qemu_i386.
Summary
------------------------------------------------------------------------
kernel: 5.9.9-rc1
git repo: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git
git branch: linux-5.9.y
git commit: fb1622495321923cbb1ae2c6cf2da1e9ca286800
git describe: v5.9.8-256-gfb1622495321
Test details: https://qa-reports.linaro.org/lkft/linux-stable-rc-linux-5.9.y/build/v5.9.8-256-gfb1622495321
No regressions (compared to build v5.9.8)
No fixes (compared to build v5.9.8)
Ran 52946 total tests in the following environments and test suites.
Environments
--------------
- dragonboard-410c
- hi6220-hikey
- i386
- juno-r2
- juno-r2-compat
- juno-r2-kasan
- nxp-ls2088
- qemu-arm-clang
- qemu-arm64-clang
- qemu-arm64-kasan
- qemu-i386-clang
- qemu-x86_64-clang
- qemu-x86_64-kasan
- qemu_arm
- qemu_arm64
- qemu_arm64-compat
- qemu_i386
- qemu_x86_64
- qemu_x86_64-compat
- x15
- x86
- x86-kasan
Test Suites
-----------
* build
* install-android-platform-tools-r2600
* libhugetlbfs
* linux-log-parser
* ltp-cap_bounds-tests
* ltp-commands-tests
* ltp-containers-tests
* ltp-cpuhotplug-tests
* ltp-crypto-tests
* ltp-dio-tests
* ltp-fcntl-locktests-tests
* ltp-filecaps-tests
* ltp-fs-tests
* ltp-fs_bind-tests
* ltp-fs_perms_simple-tests
* ltp-fsx-tests
* ltp-hugetlb-tests
* ltp-io-tests
* ltp-ipc-tests
* ltp-math-tests
* ltp-mm-tests
* ltp-nptl-tests
* ltp-pty-tests
* ltp-sched-tests
* ltp-securebits-tests
* ltp-syscalls-tests
* ltp-tracing-tests
* perf
* v4l2-compliance
* ltp-controllers-tests
* ltp-cve-tests
* network-basic-tests
* kselftest
* ltp-open-posix-tests
* kvm-unit-tests
* kunit
* kselftest-vsyscall-mode-native
* kselftest-vsyscall-mode-none
Signature · 2 lines
Linaro LKFT https://lkft.linaro.org
Greg Kroah-Hartman
maintainerQuoted 17 lines · Naresh Kamboju
Quoted 15 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.9.9 release. There are 255 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 19 Nov 2020 12:20:51 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.9.9-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.9.y
and the diffstat can be found below.
Quoted 8 lines
Quoted 3 lines
thanks,
greg k-h
Results from Linaro’s test farm.
No regressions on arm64, arm,x86_64, and i386.
Thanks for testing all of these and letting me know.
greg k-h
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.9.9 release. There are 255 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 19 Nov 2020 12:20:51 +0000. Anything received after that time might be too late.
Build results:
total: 154 pass: 154 fail: 0 Qemu test results: total: 426 pass: 426 fail: 0
Guenter
Greg Kroah-Hartman
maintainerQuoted 10 lines · Guenter Roeck
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.9.9 release. There are 255 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 19 Nov 2020 12:20:51 +0000. Anything received after that time might be too late.
Quoted 6 lines
Build results:
total: 154 pass: 154 fail: 0 Qemu test results: total: 426 pass: 426 fail: 0Reviewed-by Guenter Roeck <[email protected]>
Thanks for testing all of these and letting me know.
gre gk-h
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.9.9 release. There are 255 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 19 Nov 2020 12:20:51 +0000. Anything received after that time might be too late.
Build results:
total: 154 pass: 154 fail: 0 Qemu test results: total: 426 pass: 426 fail: 0
Guenter