5.15.168-rc1 review
Greg Kroah-Hartman
maintainerPATCH 277/691 interconnect: qcom: sm8250: Enable sync_state
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Konrad Dybcio <[email protected]>
[ Upstream commit bfc7db1cb94ad664546d70212699f8cc6c539e8c ]
Add the generic icc sync_state callback to ensure interconnect votes are taken into account, instead of being pegged at maximum values.
--- drivers/interconnect/qcom/sm8250.c | 1 + 1 file changed, 1 insertion(+)
drivers/interconnect/qcom/sm8250.c +1 -0
@@ -551,6 +551,7 @@ static struct platform_driver qnoc_driver = { .driver = { .name = "qnoc-sm8250", .of_match_table = qnoc_of_match, + .sync_state = icc_sync_state, }, };module_platform_driver (qnoc_driver);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 278/691 vdpa: Add eventfd for the vdpa callback
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xie Yongji <[email protected]>
[ Upstream commit 5e68470f4e80a4120e9ecec408f6ab4ad386bd4a ]
Add eventfd for the vdpa callback so that user
can signal it directly instead of triggering the
callback. It will be used for vhost-vdpa case.
Message-Id: <[email protected]>
Stable-dep-of: 02e9e9366fef ("vhost_vdpa: assign irq bypass producer token correctly")
--- drivers/vhost/vdpa.c | 2 ++ drivers/virtio/virtio_vdpa.c | 1 + include/linux/vdpa.h | 6 ++++++ 3 files changed, 9 insertions(+)
drivers/vhost/vdpa.c +2 -0
@@ -432,9 +432,11 @@ static long vhost_vdpa_vring_ioctl(struct vhost_vdpa *v, unsigned int cmd,if (vq->call_ctx.ctx) { cb.callback = vhost_vdpa_virtqueue_cb; cb.private = vq; + cb.trigger = vq->call_ctx.ctx; }else { cb.callback =NULL ; cb.private =NULL ; + cb.trigger =NULL ; } ops->set_vq_cb (vdpa, idx, &cb);vhost_vdpa_setup_vq_irq (v, idx);
drivers/virtio/virtio_vdpa.c +1 -0
@@ -182,6 +182,7 @@ virtio_vdpa_setup_vq(struct virtio_device *vdev, unsigned int index,/* Setup virtqueue callback */ cb.callback = virtio_vdpa_virtqueue_cb; cb.private = info; + cb.trigger =NULL ; ops->set_vq_cb (vdpa, index, &cb); ops->set_vq_num (vdpa, index,virtqueue_get_vring_size (vq));
include/linux/vdpa.h +6 -0
@@ -11,10 +11,16 @@* struct vdpa_calllback - vDPA callback definition. * @callback: interrupt callback function * @private: the data passed to the callback function +* @trigger: the eventfd for the callback (Optional). +* When it is set, the vDPA driver must guarantee that +* signaling it is functional equivalent to triggering +* the callback. Then vDPA parent can signal it directly +* instead of triggering the callback. */ struct vdpa_callback {irqreturn_t (*callback)(void *data);void *private; +struct eventfd_ctx *trigger; };/**
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 279/691 vhost_vdpa: assign irq bypass producer token correctly
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jason Wang <[email protected]>
[ Upstream commit 02e9e9366fefe461719da5d173385b6685f70319 ]
We used to call irq_bypass_unregister_producer() in vhost_vdpa_setup_vq_irq() which is problematic as we don't know if the token pointer is still valid or not.
Actually, we use the eventfd_ctx as the token so the life cycle of the token should be bound to the VHOST_SET_VRING_CALL instead of vhost_vdpa_setup_vq_irq() which could be called by set_status().
Fixing this by setting up irq bypass producer's token when handling VHOST_SET_VRING_CALL and un-registering the producer before calling vhost_vring_ioctl() to prevent a possible use after free as eventfd could have been released in vhost_vring_ioctl(). And such registering and unregistering will only be done if DRIVER_OK is set.
Message-Id: <[email protected]>
--- drivers/vhost/vdpa.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-)
drivers/vhost/vdpa.c +13 -3
@@ -100,11 +100,9 @@ static void vhost_vdpa_setup_vq_irq(struct vhost_vdpa *v, u16 qid)if (irq <0 )return ; -irq_bypass_unregister_producer (&vq->call_ctx.producer);if (!vq->call_ctx.ctx)return ; - vq->call_ctx.producer.token = vq->call_ctx.ctx; vq->call_ctx.producer.irq = irq; ret =irq_bypass_register_producer (&vq->call_ctx.producer);if (unlikely (ret))
@@ -401,6 +399,14 @@ static long vhost_vdpa_vring_ioctl(struct vhost_vdpa *v, unsigned int cmd, vq->last_avail_idx = vq_state.split.avail_index; }break ; +case VHOST_SET_VRING_CALL : +if (vq->call_ctx.ctx) { +if (ops->get_status (vdpa) & +VIRTIO_CONFIG_S_DRIVER_OK ) +vhost_vdpa_unsetup_vq_irq (v, idx); + vq->call_ctx.producer.token =NULL ; + } +break ; } r =vhost_vring_ioctl (&v->vdev, cmd, argp);
@@ -433,13 +439,16 @@ static long vhost_vdpa_vring_ioctl(struct vhost_vdpa *v, unsigned int cmd, cb.callback = vhost_vdpa_virtqueue_cb; cb.private = vq; cb.trigger = vq->call_ctx.ctx; + vq->call_ctx.producer.token = vq->call_ctx.ctx; +if (ops->get_status (vdpa) & +VIRTIO_CONFIG_S_DRIVER_OK ) +vhost_vdpa_setup_vq_irq (v, idx); }else { cb.callback =NULL ; cb.private =NULL ; cb.trigger =NULL ; } ops->set_vq_cb (vdpa, idx, &cb); -vhost_vdpa_setup_vq_irq (v, idx);break ;case VHOST_SET_VRING_NUM :
@@ -990,6 +999,7 @@ static int vhost_vdpa_open(struct inode *inode, struct file *filep)for (i =0 ; i < nvqs; i++) { vqs[i] = &v->vqs[i]; vqs[i]->handle_kick = handle_vq_kick; + vqs[i]->call_ctx.ctx =NULL ; }vhost_dev_init (dev, vqs, nvqs,0 ,0 ,0 , false, vhost_vdpa_process_iotlb_msg);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 280/691 Revert "dm: requeue IO if mapping table not yet available"
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mikulas Patocka <[email protected]>
[ Upstream commit c8691cd0fc11197515ed148de0780d927bfca38b ]
This reverts commit fa247089de9936a46e290d4724cb5f0b845600f5.
The following sequence of commands causes a livelock - there will be workqueue process looping and consuming 100% CPU:
dmsetup create --notable test
truncate -s 1MiB testdata
losetup /dev/loop0 testdata
dmsetup load test --table '0 2048 linear /dev/loop0 0' dd if=/dev/zero of=/dev/dm-0 bs=16k count=1 conv=fdatasync
The livelock is caused by the commit fa247089de99. The commit claims that it fixes a race condition, however, it is unknown what the actual race condition is and what program is involved in the race condition.
When the inactive table is loaded, the nodes /dev/dm-0 and /sys/block/dm-0 are created. /dev/dm-0 has zero size at this point. When the device is suspended and resumed, the nodes /dev/mapper/test and /dev/disk/* are created.
If some program opens a block device before it is created by dmsetup or lvm, the program is buggy, so dm could just report an error as it used to do before.
--- drivers/md/dm-rq.c | 4 +++- drivers/md/dm.c | 11 ++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-)
drivers/md/dm-rq.c +3 -1
@@ -504,8 +504,10 @@ static blk_status_t dm_mq_queue_rq(struct blk_mq_hw_ctx *hctx, map =dm_get_live_table (md, &srcu_idx);if (unlikely (!map)) { +DMERR_LIMIT ("%s: mapping table unavailable, erroring io" , +dm_device_name (md));dm_put_live_table (md, srcu_idx); -return BLK_STS_RESOURCE ; +return BLK_STS_IOERR ; } ti =dm_table_find_target (map,0 );dm_put_live_table (md, srcu_idx);
drivers/md/dm.c +8 -3
@@ -1593,10 +1593,15 @@ static blk_qc_t dm_submit_bio(struct bio *bio)struct dm_table *map; map =dm_get_live_table (md, &srcu_idx); +if (unlikely (!map)) { +DMERR_LIMIT ("%s: mapping table unavailable, erroring io" , +dm_device_name (md)); +bio_io_error (bio); + goto out; + } -/* If suspended, or map not yet available, queue this IO for later */ -if (unlikely (test_bit (DMF_BLOCK_IO_FOR_SUSPEND , &md->flags)) || -unlikely (!map)) { +/* If suspended, queue this IO for later */ +if (unlikely (test_bit (DMF_BLOCK_IO_FOR_SUSPEND , &md->flags))) {if (bio->bi_opf &REQ_NOWAIT )bio_wouldblock_error (bio);else if (bio->bi_opf &REQ_RAHEAD )
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 281/691 net: axienet: Clean up device used for DMA calls
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Robert Hancock <[email protected]>
[ Upstream commit 17882fd4256721451457ee57532bbae0cd5cacfe ]
Instead of using lp->ndev.parent to find the correct device to use for DMA API calls, just use the dev attribute in the device structure.
Stable-dep-of: 5a6caa2cfabb ("net: xilinx: axienet: Fix packet counting")
--- .../net/ethernet/xilinx/xilinx_axienet_main.c | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-)
drivers/net/ethernet/xilinx/xilinx_axienet_main.c +16 -16
@@ -190,7 +190,7 @@ static void axienet_dma_bd_release(struct net_device *ndev)struct axienet_local *lp =netdev_priv (ndev);/* If we end up here, tx_bd_v must have been DMA allocated. */ -dma_free_coherent (ndev->dev.parent, +dma_free_coherent (lp->dev,sizeof (*lp->tx_bd_v) * lp->tx_bd_num, lp->tx_bd_v, lp->tx_bd_p);
@@ -215,12 +215,12 @@ static void axienet_dma_bd_release(struct net_device *ndev)*/ if (lp->rx_bd_v[i].cntrl) { phys =desc_get_phys_addr (lp, &lp->rx_bd_v[i]); -dma_unmap_single (ndev->dev.parent, phys, +dma_unmap_single (lp->dev, phys, lp->max_frm_size,DMA_FROM_DEVICE ); } } -dma_free_coherent (ndev->dev.parent, +dma_free_coherent (lp->dev,sizeof (*lp->rx_bd_v) * lp->rx_bd_num, lp->rx_bd_v, lp->rx_bd_p);
@@ -249,13 +249,13 @@ static int axienet_dma_bd_init(struct net_device *ndev) lp->rx_bd_ci =0 ;/* Allocate the Tx and Rx buffer descriptors. */ - lp->tx_bd_v =dma_alloc_coherent (ndev->dev.parent, + lp->tx_bd_v =dma_alloc_coherent (lp->dev,sizeof (*lp->tx_bd_v) * lp->tx_bd_num, &lp->tx_bd_p,GFP_KERNEL );if (!lp->tx_bd_v)return -ENOMEM ; - lp->rx_bd_v =dma_alloc_coherent (ndev->dev.parent, + lp->rx_bd_v =dma_alloc_coherent (lp->dev,sizeof (*lp->rx_bd_v) * lp->rx_bd_num, &lp->rx_bd_p,GFP_KERNEL );if (!lp->rx_bd_v)
@@ -285,9 +285,9 @@ static int axienet_dma_bd_init(struct net_device *ndev) goto out; lp->rx_bd_v[i].skb = skb; - addr =dma_map_single (ndev->dev.parent, skb->data, + addr =dma_map_single (lp->dev, skb->data, lp->max_frm_size,DMA_FROM_DEVICE ); -if (dma_mapping_error (ndev->dev.parent, addr)) { +if (dma_mapping_error (lp->dev, addr)) {netdev_err (ndev,"DMA mapping error\n" ); goto out; }
@@ -637,7 +637,7 @@ static int axienet_free_tx_chain(struct net_device *ndev, u32 first_bd,/* Ensure we see complete descriptor update */ dma_rmb (); phys =desc_get_phys_addr (lp, cur_p); -dma_unmap_single (ndev->dev.parent, phys, +dma_unmap_single (lp->dev, phys, (cur_p->cntrl &XAXIDMA_BD_CTRL_LENGTH_MASK ),DMA_TO_DEVICE );
@@ -775,9 +775,9 @@ axienet_start_xmit(struct sk_buff *skb, struct net_device *ndev) cur_p->app0 |=2 ;/* Tx Full Checksum Offload Enabled */ } - phys =dma_map_single (ndev->dev.parent, skb->data, + phys =dma_map_single (lp->dev, skb->data,skb_headlen (skb),DMA_TO_DEVICE ); -if (unlikely (dma_mapping_error (ndev->dev.parent, phys))) { +if (unlikely (dma_mapping_error (lp->dev, phys))) {if (net_ratelimit ())netdev_err (ndev,"TX DMA mapping error\n" ); ndev->stats.tx_dropped++;
@@ -791,11 +791,11 @@ axienet_start_xmit(struct sk_buff *skb, struct net_device *ndev) lp->tx_bd_tail =0 ; cur_p = &lp->tx_bd_v[lp->tx_bd_tail]; frag = &skb_shinfo (skb)->frags[ii]; - phys =dma_map_single (ndev->dev.parent, + phys =dma_map_single (lp->dev,skb_frag_address (frag),skb_frag_size (frag),DMA_TO_DEVICE ); -if (unlikely (dma_mapping_error (ndev->dev.parent, phys))) { +if (unlikely (dma_mapping_error (lp->dev, phys))) {if (net_ratelimit ())netdev_err (ndev,"TX DMA mapping error\n" ); ndev->stats.tx_dropped++;
@@ -873,7 +873,7 @@ static void axienet_recv(struct net_device *ndev) length = cur_p->app4 &0x0000FFFF ; phys =desc_get_phys_addr (lp, cur_p); -dma_unmap_single (ndev->dev.parent, phys, lp->max_frm_size, +dma_unmap_single (lp->dev, phys, lp->max_frm_size,DMA_FROM_DEVICE );skb_put (skb, length);
@@ -906,10 +906,10 @@ static void axienet_recv(struct net_device *ndev)if (!new_skb)break ; - phys =dma_map_single (ndev->dev.parent, new_skb->data, + phys =dma_map_single (lp->dev, new_skb->data, lp->max_frm_size,DMA_FROM_DEVICE ); -if (unlikely (dma_mapping_error (ndev->dev.parent, phys))) { +if (unlikely (dma_mapping_error (lp->dev, phys))) {if (net_ratelimit ())netdev_err (ndev,"RX DMA mapping error\n" );dev_kfree_skb (new_skb);
@@ -1770,7 +1770,7 @@ static void axienet_dma_err_handler(struct work_struct *work)if (cur_p->cntrl) {dma_addr_t addr =desc_get_phys_addr (lp, cur_p); -dma_unmap_single (ndev->dev.parent, addr, +dma_unmap_single (lp->dev, addr, (cur_p->cntrl &XAXIDMA_BD_CTRL_LENGTH_MASK ),DMA_TO_DEVICE );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 282/691 net: axienet: Clean up DMA start/stop and error handling
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Robert Hancock <[email protected]>
[ Upstream commit 84b9ccc0749a7036bcaf707f02273dcbd4756fbf ]
Simplify the DMA error handling process, and remove some duplicated code between the DMA error handling and the stop function.
Stable-dep-of: 5a6caa2cfabb ("net: xilinx: axienet: Fix packet counting")
--- .../net/ethernet/xilinx/xilinx_axienet_main.c | 280 +++++++----------- 1 file changed, 105 insertions(+), 175 deletions(-)
drivers/net/ethernet/xilinx/xilinx_axienet_main.c +105 -175
@@ -226,6 +226,44 @@ static void axienet_dma_bd_release(struct net_device *ndev) lp->rx_bd_p); } +/** +* axienet_dma_start - Set up DMA registers and start DMA operation +* @lp: Pointer to the axienet_local structure +*/ +static void axienet_dma_start (struct axienet_local *lp) +{ +u32 rx_cr, tx_cr; + +/* Start updating the Rx channel control register */ + rx_cr = (lp->coalesce_count_rx <<XAXIDMA_COALESCE_SHIFT ) | + (XAXIDMA_DFT_RX_WAITBOUND <<XAXIDMA_DELAY_SHIFT ) | +XAXIDMA_IRQ_ALL_MASK ; +axienet_dma_out32 (lp,XAXIDMA_RX_CR_OFFSET , rx_cr); + +/* Start updating the Tx channel control register */ + tx_cr = (lp->coalesce_count_tx <<XAXIDMA_COALESCE_SHIFT ) | + (XAXIDMA_DFT_TX_WAITBOUND <<XAXIDMA_DELAY_SHIFT ) | +XAXIDMA_IRQ_ALL_MASK ; +axienet_dma_out32 (lp,XAXIDMA_TX_CR_OFFSET , tx_cr); + +/* Populate the tail pointer and bring the Rx Axi DMA engine out of +* halted state. This will make the Rx side ready for reception. +*/ +axienet_dma_out_addr (lp,XAXIDMA_RX_CDESC_OFFSET , lp->rx_bd_p); + rx_cr |=XAXIDMA_CR_RUNSTOP_MASK ; +axienet_dma_out32 (lp,XAXIDMA_RX_CR_OFFSET , rx_cr); +axienet_dma_out_addr (lp,XAXIDMA_RX_TDESC_OFFSET , lp->rx_bd_p + + (sizeof (*lp->rx_bd_v) * (lp->rx_bd_num -1 ))); + +/* Write to the RS (Run-stop) bit in the Tx channel control register. +* Tx channel is now ready to run. But only after we write to the +* tail pointer register that the Tx channel will start transmitting. +*/ +axienet_dma_out_addr (lp,XAXIDMA_TX_CDESC_OFFSET , lp->tx_bd_p); + tx_cr |=XAXIDMA_CR_RUNSTOP_MASK ; +axienet_dma_out32 (lp,XAXIDMA_TX_CR_OFFSET , tx_cr); +} +/** * axienet_dma_bd_init - Setup buffer descriptor rings for Axi DMA * @ndev: Pointer to the net_device structure
@@ -238,7 +276,6 @@ static void axienet_dma_bd_release(struct net_device *ndev)*/ static int axienet_dma_bd_init (struct net_device *ndev) { -u32 cr;int i;struct sk_buff *skb;struct axienet_local *lp =netdev_priv (ndev);
@@ -296,50 +333,7 @@ static int axienet_dma_bd_init(struct net_device *ndev) lp->rx_bd_v[i].cntrl = lp->max_frm_size; } -/* Start updating the Rx channel control register */ - cr =axienet_dma_in32 (lp,XAXIDMA_RX_CR_OFFSET ); -/* Update the interrupt coalesce count */ - cr = ((cr & ~XAXIDMA_COALESCE_MASK ) | - ((lp->coalesce_count_rx) <<XAXIDMA_COALESCE_SHIFT )); -/* Update the delay timer count */ - cr = ((cr & ~XAXIDMA_DELAY_MASK ) | - (XAXIDMA_DFT_RX_WAITBOUND <<XAXIDMA_DELAY_SHIFT )); -/* Enable coalesce, delay timer and error interrupts */ - cr |=XAXIDMA_IRQ_ALL_MASK ; -/* Write to the Rx channel control register */ -axienet_dma_out32 (lp,XAXIDMA_RX_CR_OFFSET , cr); - -/* Start updating the Tx channel control register */ - cr =axienet_dma_in32 (lp,XAXIDMA_TX_CR_OFFSET ); -/* Update the interrupt coalesce count */ - cr = (((cr & ~XAXIDMA_COALESCE_MASK )) | - ((lp->coalesce_count_tx) <<XAXIDMA_COALESCE_SHIFT )); -/* Update the delay timer count */ - cr = (((cr & ~XAXIDMA_DELAY_MASK )) | - (XAXIDMA_DFT_TX_WAITBOUND <<XAXIDMA_DELAY_SHIFT )); -/* Enable coalesce, delay timer and error interrupts */ - cr |=XAXIDMA_IRQ_ALL_MASK ; -/* Write to the Tx channel control register */ -axienet_dma_out32 (lp,XAXIDMA_TX_CR_OFFSET , cr); - -/* Populate the tail pointer and bring the Rx Axi DMA engine out of -* halted state. This will make the Rx side ready for reception. -*/ -axienet_dma_out_addr (lp,XAXIDMA_RX_CDESC_OFFSET , lp->rx_bd_p); - cr =axienet_dma_in32 (lp,XAXIDMA_RX_CR_OFFSET ); -axienet_dma_out32 (lp,XAXIDMA_RX_CR_OFFSET , - cr |XAXIDMA_CR_RUNSTOP_MASK ); -axienet_dma_out_addr (lp,XAXIDMA_RX_TDESC_OFFSET , lp->rx_bd_p + - (sizeof (*lp->rx_bd_v) * (lp->rx_bd_num -1 ))); - -/* Write to the RS (Run-stop) bit in the Tx channel control register. -* Tx channel is now ready to run. But only after we write to the -* tail pointer register that the Tx channel will start transmitting. -*/ -axienet_dma_out_addr (lp,XAXIDMA_TX_CDESC_OFFSET , lp->tx_bd_p); - cr =axienet_dma_in32 (lp,XAXIDMA_TX_CR_OFFSET ); -axienet_dma_out32 (lp,XAXIDMA_TX_CR_OFFSET , - cr |XAXIDMA_CR_RUNSTOP_MASK ); +axienet_dma_start (lp);return 0 ; out:
@@ -531,6 +525,44 @@ static int __axienet_device_reset(struct axienet_local *lp)return 0 ; } +/** +* axienet_dma_stop - Stop DMA operation +* @lp: Pointer to the axienet_local structure +*/ +static void axienet_dma_stop (struct axienet_local *lp) +{ +int count; +u32 cr, sr; + + cr =axienet_dma_in32 (lp,XAXIDMA_RX_CR_OFFSET ); + cr &= ~(XAXIDMA_CR_RUNSTOP_MASK |XAXIDMA_IRQ_ALL_MASK ); +axienet_dma_out32 (lp,XAXIDMA_RX_CR_OFFSET , cr); +synchronize_irq (lp->rx_irq); + + cr =axienet_dma_in32 (lp,XAXIDMA_TX_CR_OFFSET ); + cr &= ~(XAXIDMA_CR_RUNSTOP_MASK |XAXIDMA_IRQ_ALL_MASK ); +axienet_dma_out32 (lp,XAXIDMA_TX_CR_OFFSET , cr); +synchronize_irq (lp->tx_irq); + +/* Give DMAs a chance to halt gracefully */ + sr =axienet_dma_in32 (lp,XAXIDMA_RX_SR_OFFSET ); +for (count =0 ; !(sr &XAXIDMA_SR_HALT_MASK ) && count <5 ; ++count) { +msleep (20 ); + sr =axienet_dma_in32 (lp,XAXIDMA_RX_SR_OFFSET ); + } + + sr =axienet_dma_in32 (lp,XAXIDMA_TX_SR_OFFSET ); +for (count =0 ; !(sr &XAXIDMA_SR_HALT_MASK ) && count <5 ; ++count) { +msleep (20 ); + sr =axienet_dma_in32 (lp,XAXIDMA_TX_SR_OFFSET ); + } + +/* Do a reset to ensure DMA is really stopped */ +axienet_lock_mii (lp); +__axienet_device_reset (lp); +axienet_unlock_mii (lp); +} +/** * axienet_device_reset - Reset and initialize the Axi Ethernet hardware. * @ndev: Pointer to the net_device structure
@@ -950,41 +982,27 @@ static void axienet_recv(struct net_device *ndev)*/ static irqreturn_t axienet_tx_irq (int irq,void *_ndev) { -u32 cr;unsigned int status;struct net_device *ndev = _ndev;struct axienet_local *lp =netdev_priv (ndev); status =axienet_dma_in32 (lp,XAXIDMA_TX_SR_OFFSET ); -if (status & (XAXIDMA_IRQ_IOC_MASK |XAXIDMA_IRQ_DELAY_MASK )) { -axienet_dma_out32 (lp,XAXIDMA_TX_SR_OFFSET , status); -axienet_start_xmit_done (lp->ndev); - goto out; - } +if (!(status &XAXIDMA_IRQ_ALL_MASK ))return IRQ_NONE ; -if (status &XAXIDMA_IRQ_ERROR_MASK ) { -dev_err (&ndev->dev,"DMA Tx error 0x%x\n" , status); -dev_err (&ndev->dev,"Current BD is at: 0x%x%08x\n" , - (lp->tx_bd_v[lp->tx_bd_ci]).phys_msb, - (lp->tx_bd_v[lp->tx_bd_ci]).phys); - - cr =axienet_dma_in32 (lp,XAXIDMA_TX_CR_OFFSET ); -/* Disable coalesce, delay timer and error interrupts */ - cr &= (~XAXIDMA_IRQ_ALL_MASK ); -/* Write to the Tx channel control register */ -axienet_dma_out32 (lp,XAXIDMA_TX_CR_OFFSET , cr); - - cr =axienet_dma_in32 (lp,XAXIDMA_RX_CR_OFFSET ); -/* Disable coalesce, delay timer and error interrupts */ - cr &= (~XAXIDMA_IRQ_ALL_MASK ); -/* Write to the Rx channel control register */ -axienet_dma_out32 (lp,XAXIDMA_RX_CR_OFFSET , cr); +axienet_dma_out32 (lp,XAXIDMA_TX_SR_OFFSET , status); + +if (unlikely (status &XAXIDMA_IRQ_ERROR_MASK )) { +netdev_err (ndev,"DMA Tx error 0x%x\n" , status); +netdev_err (ndev,"Current BD is at: 0x%x%08x\n" , + (lp->tx_bd_v[lp->tx_bd_ci]).phys_msb, + (lp->tx_bd_v[lp->tx_bd_ci]).phys);schedule_work (&lp->dma_err_task); -axienet_dma_out32 (lp,XAXIDMA_TX_SR_OFFSET , status); + }else { +axienet_start_xmit_done (lp->ndev); } -out: +return IRQ_HANDLED ; }
@@ -1000,41 +1018,27 @@ static irqreturn_t axienet_tx_irq(int irq, void *_ndev)*/ static irqreturn_t axienet_rx_irq (int irq,void *_ndev) { -u32 cr;unsigned int status;struct net_device *ndev = _ndev;struct axienet_local *lp =netdev_priv (ndev); status =axienet_dma_in32 (lp,XAXIDMA_RX_SR_OFFSET ); -if (status & (XAXIDMA_IRQ_IOC_MASK |XAXIDMA_IRQ_DELAY_MASK )) { -axienet_dma_out32 (lp,XAXIDMA_RX_SR_OFFSET , status); -axienet_recv (lp->ndev); - goto out; - } +if (!(status &XAXIDMA_IRQ_ALL_MASK ))return IRQ_NONE ; -if (status &XAXIDMA_IRQ_ERROR_MASK ) { -dev_err (&ndev->dev,"DMA Rx error 0x%x\n" , status); -dev_err (&ndev->dev,"Current BD is at: 0x%x%08x\n" , - (lp->rx_bd_v[lp->rx_bd_ci]).phys_msb, - (lp->rx_bd_v[lp->rx_bd_ci]).phys); - - cr =axienet_dma_in32 (lp,XAXIDMA_TX_CR_OFFSET ); -/* Disable coalesce, delay timer and error interrupts */ - cr &= (~XAXIDMA_IRQ_ALL_MASK ); -/* Finally write to the Tx channel control register */ -axienet_dma_out32 (lp,XAXIDMA_TX_CR_OFFSET , cr); - - cr =axienet_dma_in32 (lp,XAXIDMA_RX_CR_OFFSET ); -/* Disable coalesce, delay timer and error interrupts */ - cr &= (~XAXIDMA_IRQ_ALL_MASK ); -/* write to the Rx channel control register */ -axienet_dma_out32 (lp,XAXIDMA_RX_CR_OFFSET , cr); +axienet_dma_out32 (lp,XAXIDMA_RX_SR_OFFSET , status); + +if (unlikely (status &XAXIDMA_IRQ_ERROR_MASK )) { +netdev_err (ndev,"DMA Rx error 0x%x\n" , status); +netdev_err (ndev,"Current BD is at: 0x%x%08x\n" , + (lp->rx_bd_v[lp->rx_bd_ci]).phys_msb, + (lp->rx_bd_v[lp->rx_bd_ci]).phys);schedule_work (&lp->dma_err_task); -axienet_dma_out32 (lp,XAXIDMA_RX_SR_OFFSET , status); + }else { +axienet_recv (lp->ndev); } -out: +return IRQ_HANDLED ; }
@@ -1152,8 +1156,6 @@ static int axienet_open(struct net_device *ndev)*/ static int axienet_stop (struct net_device *ndev) { -u32 cr, sr; -int count;struct axienet_local *lp =netdev_priv (ndev);dev_dbg (&ndev->dev,"axienet_close()\n" );
@@ -1164,34 +1166,10 @@ static int axienet_stop(struct net_device *ndev)axienet_setoptions (ndev, lp->options & ~(XAE_OPTION_TXEN |XAE_OPTION_RXEN )); - cr =axienet_dma_in32 (lp,XAXIDMA_RX_CR_OFFSET ); - cr &= ~(XAXIDMA_CR_RUNSTOP_MASK |XAXIDMA_IRQ_ALL_MASK ); -axienet_dma_out32 (lp,XAXIDMA_RX_CR_OFFSET , cr); - - cr =axienet_dma_in32 (lp,XAXIDMA_TX_CR_OFFSET ); - cr &= ~(XAXIDMA_CR_RUNSTOP_MASK |XAXIDMA_IRQ_ALL_MASK ); -axienet_dma_out32 (lp,XAXIDMA_TX_CR_OFFSET , cr); +axienet_dma_stop (lp);axienet_iow (lp,XAE_IE_OFFSET ,0 ); -/* Give DMAs a chance to halt gracefully */ - sr =axienet_dma_in32 (lp,XAXIDMA_RX_SR_OFFSET ); -for (count =0 ; !(sr &XAXIDMA_SR_HALT_MASK ) && count <5 ; ++count) { -msleep (20 ); - sr =axienet_dma_in32 (lp,XAXIDMA_RX_SR_OFFSET ); - } - - sr =axienet_dma_in32 (lp,XAXIDMA_TX_SR_OFFSET ); -for (count =0 ; !(sr &XAXIDMA_SR_HALT_MASK ) && count <5 ; ++count) { -msleep (20 ); - sr =axienet_dma_in32 (lp,XAXIDMA_TX_SR_OFFSET ); - } - -/* Do a reset to ensure DMA is really stopped */ -axienet_lock_mii (lp); -__axienet_device_reset (lp); -axienet_unlock_mii (lp); -cancel_work_sync (&lp->dma_err_task);if (lp->eth_irq >0 )
@@ -1748,22 +1726,17 @@ static const struct phylink_mac_ops axienet_phylink_ops = {*/ static void axienet_dma_err_handler (struct work_struct *work) { +u32 i;u32 axienet_status; -u32 cr, i; +struct axidma_bd *cur_p; struct axienet_local *lp = container_of(work, struct axienet_local, dma_err_task);struct net_device *ndev = lp->ndev; -struct axidma_bd *cur_p;axienet_setoptions (ndev, lp->options & ~(XAE_OPTION_TXEN |XAE_OPTION_RXEN )); -/* When we do an Axi Ethernet reset, it resets the complete core -* including the MDIO. MDIO must be disabled before resetting. -* Hold MDIO bus lock to avoid MDIO accesses during the reset. -*/ -axienet_lock_mii (lp); -__axienet_device_reset (lp); -axienet_unlock_mii (lp); + +axienet_dma_stop (lp);for (i =0 ; i < lp->tx_bd_num; i++) { cur_p = &lp->tx_bd_v[i];
@@ -1803,50 +1776,7 @@ static void axienet_dma_err_handler(struct work_struct *work) lp->tx_bd_tail =0 ; lp->rx_bd_ci =0 ; -/* Start updating the Rx channel control register */ - cr =axienet_dma_in32 (lp,XAXIDMA_RX_CR_OFFSET ); -/* Update the interrupt coalesce count */ - cr = ((cr & ~XAXIDMA_COALESCE_MASK ) | - (XAXIDMA_DFT_RX_THRESHOLD <<XAXIDMA_COALESCE_SHIFT )); -/* Update the delay timer count */ - cr = ((cr & ~XAXIDMA_DELAY_MASK ) | - (XAXIDMA_DFT_RX_WAITBOUND <<XAXIDMA_DELAY_SHIFT )); -/* Enable coalesce, delay timer and error interrupts */ - cr |=XAXIDMA_IRQ_ALL_MASK ; -/* Finally write to the Rx channel control register */ -axienet_dma_out32 (lp,XAXIDMA_RX_CR_OFFSET , cr); - -/* Start updating the Tx channel control register */ - cr =axienet_dma_in32 (lp,XAXIDMA_TX_CR_OFFSET ); -/* Update the interrupt coalesce count */ - cr = (((cr & ~XAXIDMA_COALESCE_MASK )) | - (XAXIDMA_DFT_TX_THRESHOLD <<XAXIDMA_COALESCE_SHIFT )); -/* Update the delay timer count */ - cr = (((cr & ~XAXIDMA_DELAY_MASK )) | - (XAXIDMA_DFT_TX_WAITBOUND <<XAXIDMA_DELAY_SHIFT )); -/* Enable coalesce, delay timer and error interrupts */ - cr |=XAXIDMA_IRQ_ALL_MASK ; -/* Finally write to the Tx channel control register */ -axienet_dma_out32 (lp,XAXIDMA_TX_CR_OFFSET , cr); - -/* Populate the tail pointer and bring the Rx Axi DMA engine out of -* halted state. This will make the Rx side ready for reception. -*/ -axienet_dma_out_addr (lp,XAXIDMA_RX_CDESC_OFFSET , lp->rx_bd_p); - cr =axienet_dma_in32 (lp,XAXIDMA_RX_CR_OFFSET ); -axienet_dma_out32 (lp,XAXIDMA_RX_CR_OFFSET , - cr |XAXIDMA_CR_RUNSTOP_MASK ); -axienet_dma_out_addr (lp,XAXIDMA_RX_TDESC_OFFSET , lp->rx_bd_p + - (sizeof (*lp->rx_bd_v) * (lp->rx_bd_num -1 ))); - -/* Write to the RS (Run-stop) bit in the Tx channel control register. -* Tx channel is now ready to run. But only after we write to the -* tail pointer register that the Tx channel will start transmitting -*/ -axienet_dma_out_addr (lp,XAXIDMA_TX_CDESC_OFFSET , lp->tx_bd_p); - cr =axienet_dma_in32 (lp,XAXIDMA_TX_CR_OFFSET ); -axienet_dma_out32 (lp,XAXIDMA_TX_CR_OFFSET , - cr |XAXIDMA_CR_RUNSTOP_MASK ); +axienet_dma_start (lp); axienet_status =axienet_ior (lp,XAE_RCW1_OFFSET ); axienet_status &= ~XAE_RCW1_RX_MASK ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 283/691 net: axienet: dont set IRQ timer when IRQ delay not used
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Robert Hancock <[email protected]>
[ Upstream commit 0155ae6eb84dbeecb7199a2fd9dee72e046ac875 ]
When the RX or TX coalesce count is set to 1, there's no point in setting the delay timer value since an interrupt will already be raised on every packet, and the delay interrupt just causes extra pointless interrupts.
Stable-dep-of: 5a6caa2cfabb ("net: xilinx: axienet: Fix packet counting")
--- .../net/ethernet/xilinx/xilinx_axienet_main.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-)
drivers/net/ethernet/xilinx/xilinx_axienet_main.c +14 -4
@@ -236,14 +236,24 @@ static void axienet_dma_start(struct axienet_local *lp)/* Start updating the Rx channel control register */ rx_cr = (lp->coalesce_count_rx <<XAXIDMA_COALESCE_SHIFT ) | - (XAXIDMA_DFT_RX_WAITBOUND <<XAXIDMA_DELAY_SHIFT ) | -XAXIDMA_IRQ_ALL_MASK ; +XAXIDMA_IRQ_IOC_MASK |XAXIDMA_IRQ_ERROR_MASK ; +/* Only set interrupt delay timer if not generating an interrupt on +* the first RX packet. Otherwise leave at 0 to disable delay interrupt. +*/ +if (lp->coalesce_count_rx >1 ) + rx_cr |= (XAXIDMA_DFT_RX_WAITBOUND <<XAXIDMA_DELAY_SHIFT ) | +XAXIDMA_IRQ_DELAY_MASK ;axienet_dma_out32 (lp,XAXIDMA_RX_CR_OFFSET , rx_cr);/* Start updating the Tx channel control register */ tx_cr = (lp->coalesce_count_tx <<XAXIDMA_COALESCE_SHIFT ) | - (XAXIDMA_DFT_TX_WAITBOUND <<XAXIDMA_DELAY_SHIFT ) | -XAXIDMA_IRQ_ALL_MASK ; +XAXIDMA_IRQ_IOC_MASK |XAXIDMA_IRQ_ERROR_MASK ; +/* Only set interrupt delay timer if not generating an interrupt on +* the first TX packet. Otherwise leave at 0 to disable delay interrupt. +*/ +if (lp->coalesce_count_tx >1 ) + tx_cr |= (XAXIDMA_DFT_TX_WAITBOUND <<XAXIDMA_DELAY_SHIFT ) | +XAXIDMA_IRQ_DELAY_MASK ;axienet_dma_out32 (lp,XAXIDMA_TX_CR_OFFSET , tx_cr);/* Populate the tail pointer and bring the Rx Axi DMA engine out of
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 284/691 net: axienet: implement NAPI and GRO receive
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Robert Hancock <[email protected]>
[ Upstream commit cc37610caaf8d13a6ecb8afd1fe2ebc2424ff622 ]
Implement NAPI and GRO receive. In addition to better performance, this also avoids handling RX packets in hard IRQ context, which reduces the IRQ latency impact to other devices.
Stable-dep-of: 5a6caa2cfabb ("net: xilinx: axienet: Fix packet counting")
--- drivers/net/ethernet/xilinx/xilinx_axienet.h | 6 ++ .../net/ethernet/xilinx/xilinx_axienet_main.c | 81 ++++++++++++------- 2 files changed, 59 insertions(+), 28 deletions(-)
drivers/net/ethernet/xilinx/xilinx_axienet.h +6 -0
@@ -386,6 +386,7 @@ struct axidma_bd {* @phy_node: Pointer to device node structure * @phylink: Pointer to phylink instance * @phylink_config: phylink configuration settings +* @napi: NAPI control structure * @pcs_phy: Reference to PCS/PMA PHY if used * @switch_x_sgmii: Whether switchable 1000BaseX/SGMII mode is enabled in the core * @axi_clk: AXI4-Lite bus clock
@@ -395,6 +396,7 @@ struct axidma_bd {* @regs_start: Resource start for axienet device addresses * @regs: Base address for the axienet_local device address space * @dma_regs: Base address for the axidma device address space +* @rx_dma_cr: Nominal content of RX DMA control register * @dma_err_task: Work structure to process Axi DMA errors * @tx_irq: Axidma TX IRQ number * @rx_irq: Axidma RX IRQ number
@@ -434,6 +436,8 @@ struct axienet_local {struct phylink *phylink;struct phylink_config phylink_config; +struct napi_struct napi; +struct mdio_device *pcs_phy;bool switch_x_sgmii;
@@ -448,6 +452,8 @@ struct axienet_local {void __iomem *regs;void __iomem *dma_regs; +u32 rx_dma_cr; +struct work_struct dma_err_task;int tx_irq;
drivers/net/ethernet/xilinx/xilinx_axienet_main.c +53 -28
202 lines not on this page · raw message
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 285/691 net: axienet: reduce default RX interrupt threshold to 1
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Robert Hancock <[email protected]>
[ Upstream commit 40da5d680e02ca8d61237192db4b5833d3c9639f ]
Now that NAPI has been implemented, the hardware interrupt mitigation mechanism is not needed to avoid excessive interrupt load in most cases. Reduce the default RX interrupt threshold to 1 to reduce introduced latency. This can be increased with ethtool if desired if some applications still want to reduce interrupts.
Stable-dep-of: 5a6caa2cfabb ("net: xilinx: axienet: Fix packet counting")
--- drivers/net/ethernet/xilinx/xilinx_axienet.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/xilinx/xilinx_axienet.h +1 -1
@@ -122,7 +122,7 @@/* Default TX/RX Threshold and waitbound values for SGDMA mode */ #define XAXIDMA_DFT_TX_THRESHOLD 24#define XAXIDMA_DFT_TX_WAITBOUND 254 -#define XAXIDMA_DFT_RX_THRESHOLD 24 +#define XAXIDMA_DFT_RX_THRESHOLD 1#define XAXIDMA_DFT_RX_WAITBOUND 254#define XAXIDMA_BD_CTRL_TXSOF_MASK 0x08000000/* First tx packet */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 286/691 net: axienet: add coalesce timer ethtool configuration
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Robert Hancock <[email protected]>
[ Upstream commit 0b79b8dc97b9df4f873f63161e3050bafc4c4237 ]
Add the ability to configure the RX/TX coalesce timer with ethtool. Change default setting to scale with the clock rate rather than being a fixed number of clock cycles.
Stable-dep-of: 5a6caa2cfabb ("net: xilinx: axienet: Fix packet counting")
--- drivers/net/ethernet/xilinx/xilinx_axienet.h | 10 ++-- .../net/ethernet/xilinx/xilinx_axienet_main.c | 51 +++++++++++++++---- 2 files changed, 47 insertions(+), 14 deletions(-)
drivers/net/ethernet/xilinx/xilinx_axienet.h +7 -3
@@ -119,11 +119,11 @@#define XAXIDMA_IRQ_ERROR_MASK 0x00004000/* Error interrupt */ #define XAXIDMA_IRQ_ALL_MASK 0x00007000/* All interrupts */ -/* Default TX/RX Threshold and waitbound values for SGDMA mode */ +/* Default TX/RX Threshold and delay timer values for SGDMA mode */ #define XAXIDMA_DFT_TX_THRESHOLD 24 -#define XAXIDMA_DFT_TX_WAITBOUND 254 +#define XAXIDMA_DFT_TX_USEC 50#define XAXIDMA_DFT_RX_THRESHOLD 1 -#define XAXIDMA_DFT_RX_WAITBOUND 254 +#define XAXIDMA_DFT_RX_USEC 50#define XAXIDMA_BD_CTRL_TXSOF_MASK 0x08000000/* First tx packet */ #define XAXIDMA_BD_CTRL_TXEOF_MASK 0x04000000/* Last tx packet */
@@ -425,7 +425,9 @@ struct axidma_bd {* @csum_offload_on_tx_path: Stores the checksum selection on TX side. * @csum_offload_on_rx_path: Stores the checksum selection on RX side. * @coalesce_count_rx: Store the irq coalesce on RX side. +* @coalesce_usec_rx: IRQ coalesce delay for RX * @coalesce_count_tx: Store the irq coalesce on TX side. +* @coalesce_usec_tx: IRQ coalesce delay for TX */ struct axienet_local {struct net_device *ndev;
@@ -481,7 +483,9 @@ struct axienet_local {int csum_offload_on_rx_path;u32 coalesce_count_rx; +u32 coalesce_usec_rx;u32 coalesce_count_tx; +u32 coalesce_usec_tx; };/**
drivers/net/ethernet/xilinx/xilinx_axienet_main.c +40 -11
103 lines not on this page · raw message
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 287/691 net: axienet: Be more careful about updating tx_bd_tail
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Robert Hancock <[email protected]>
[ Upstream commit f0cf4000f5867ec4325d19d32bd83cf583065667 ]
The axienet_start_xmit function was updating the tx_bd_tail variable multiple times, with potential rollbacks on error or invalid intermediate positions, even though this variable is also used in the TX completion path. Use READ_ONCE where this variable is read and WRITE_ONCE where it is written to make this update more atomic, and move the write before the MMIO write to start the transfer, so it is protected by that implicit write barrier.
Stable-dep-of: 5a6caa2cfabb ("net: xilinx: axienet: Fix packet counting")
--- .../net/ethernet/xilinx/xilinx_axienet_main.c | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-)
drivers/net/ethernet/xilinx/xilinx_axienet_main.c +15 -11
@@ -747,7 +747,8 @@ static inline int axienet_check_tx_bd_space(struct axienet_local *lp,/* Ensure we see all descriptor updates from device or TX IRQ path */ rmb (); - cur_p = &lp->tx_bd_v[(lp->tx_bd_tail + num_frag) % lp->tx_bd_num]; + cur_p = &lp->tx_bd_v[(READ_ONCE (lp->tx_bd_tail) + num_frag) % + lp->tx_bd_num];if (cur_p->cntrl)return NETDEV_TX_BUSY ;return 0 ;
@@ -808,12 +809,15 @@ axienet_start_xmit(struct sk_buff *skb, struct net_device *ndev)u32 csum_index_off;skb_frag_t *frag;dma_addr_t tail_p, phys; +u32 orig_tail_ptr, new_tail_ptr;struct axienet_local *lp =netdev_priv (ndev);struct axidma_bd *cur_p; -u32 orig_tail_ptr = lp->tx_bd_tail; + + orig_tail_ptr = lp->tx_bd_tail; + new_tail_ptr = orig_tail_ptr; num_frag =skb_shinfo (skb)->nr_frags; - cur_p = &lp->tx_bd_v[lp->tx_bd_tail]; + cur_p = &lp->tx_bd_v[orig_tail_ptr];if (axienet_check_tx_bd_space (lp, num_frag +1 )) {/* Should not happen as last start_xmit call should have
@@ -853,9 +857,9 @@ axienet_start_xmit(struct sk_buff *skb, struct net_device *ndev) cur_p->cntrl =skb_headlen (skb) |XAXIDMA_BD_CTRL_TXSOF_MASK ;for (ii =0 ; ii < num_frag; ii++) { -if (++lp->tx_bd_tail >= lp->tx_bd_num) - lp->tx_bd_tail =0 ; - cur_p = &lp->tx_bd_v[lp->tx_bd_tail]; +if (++new_tail_ptr >= lp->tx_bd_num) + new_tail_ptr =0 ; + cur_p = &lp->tx_bd_v[new_tail_ptr]; frag = &skb_shinfo (skb)->frags[ii]; phys = dma_map_single(lp->dev, skb_frag_address(frag),
@@ -867,8 +871,6 @@ axienet_start_xmit(struct sk_buff *skb, struct net_device *ndev) ndev->stats.tx_dropped++;axienet_free_tx_chain (ndev, orig_tail_ptr, ii +1 ,NULL ); - lp->tx_bd_tail = orig_tail_ptr; -return NETDEV_TX_OK ; }desc_set_phys_addr (lp, phys, cur_p);
@@ -878,11 +880,13 @@ axienet_start_xmit(struct sk_buff *skb, struct net_device *ndev) cur_p->cntrl |=XAXIDMA_BD_CTRL_TXEOF_MASK ; cur_p->skb = skb; - tail_p = lp->tx_bd_p +sizeof (*lp->tx_bd_v) * lp->tx_bd_tail; + tail_p = lp->tx_bd_p +sizeof (*lp->tx_bd_v) * new_tail_ptr; +if (++new_tail_ptr >= lp->tx_bd_num) + new_tail_ptr =0 ; +WRITE_ONCE (lp->tx_bd_tail, new_tail_ptr); +/* Start the transfer */ axienet_dma_out_addr (lp,XAXIDMA_TX_TDESC_OFFSET , tail_p); -if (++lp->tx_bd_tail >= lp->tx_bd_num) - lp->tx_bd_tail =0 ;/* Stop queue if next transmit may not have space */ if (axienet_check_tx_bd_space (lp,MAX_SKB_FRAGS +1 )) {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 288/691 net: axienet: Use NAPI for TX completion path
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Robert Hancock <[email protected]>
[ Upstream commit 9e2bc267e78068b512d4409b884662f425adb1ec ]
This driver was using the TX IRQ handler to perform all TX completion tasks. Under heavy TX network load, this can cause significant irqs-off latencies (found to be in the hundreds of microseconds using ftrace). This can cause other issues, such as overrunning serial UART FIFOs when using high baud rates with limited UART FIFO sizes.
Switch to using a NAPI poll handler to perform the TX completion work to get this out of hard IRQ context and avoid the IRQ latency impact. A separate poll handler is used for TX and RX since they have separate IRQs on this controller, so that the completion work for each of them stays on the same CPU as the interrupt.
Testing on a Xilinx MPSoC ZU9EG platform using iperf3 from a Linux PC through a switch at 1G link speed showed no significant change in TX or RX throughput, with approximately 941 Mbps before and after. Hard IRQ time in the TX throughput test was significantly reduced from 12% to below 1% on the CPU handling TX interrupts, with total hard+soft IRQ CPU usage dropping from about 56% down to 48%.
Stable-dep-of: 5a6caa2cfabb ("net: xilinx: axienet: Fix packet counting")
--- drivers/net/ethernet/xilinx/xilinx_axienet.h | 54 +++---- .../net/ethernet/xilinx/xilinx_axienet_main.c | 142 ++++++++++-------- 2 files changed, 111 insertions(+), 85 deletions(-)
drivers/net/ethernet/xilinx/xilinx_axienet.h +28 -26
@@ -386,7 +386,6 @@ struct axidma_bd {* @phy_node: Pointer to device node structure * @phylink: Pointer to phylink instance * @phylink_config: phylink configuration settings -* @napi: NAPI control structure * @pcs_phy: Reference to PCS/PMA PHY if used * @switch_x_sgmii: Whether switchable 1000BaseX/SGMII mode is enabled in the core * @axi_clk: AXI4-Lite bus clock
@@ -396,7 +395,22 @@ struct axidma_bd {* @regs_start: Resource start for axienet device addresses * @regs: Base address for the axienet_local device address space * @dma_regs: Base address for the axidma device address space +* @napi_rx: NAPI RX control structure * @rx_dma_cr: Nominal content of RX DMA control register +* @rx_bd_v: Virtual address of the RX buffer descriptor ring +* @rx_bd_p: Physical address(start address) of the RX buffer descr. ring +* @rx_bd_num: Size of RX buffer descriptor ring +* @rx_bd_ci: Stores the index of the Rx buffer descriptor in the ring being +* accessed currently. +* @napi_tx: NAPI TX control structure +* @tx_dma_cr: Nominal content of TX DMA control register +* @tx_bd_v: Virtual address of the TX buffer descriptor ring +* @tx_bd_p: Physical address(start address) of the TX buffer descr. ring +* @tx_bd_num: Size of TX buffer descriptor ring +* @tx_bd_ci: Stores the next Tx buffer descriptor in the ring that may be +* complete. Only updated at runtime by TX NAPI poll. +* @tx_bd_tail: Stores the index of the next Tx buffer descriptor in the ring +* to be populated. * @dma_err_task: Work structure to process Axi DMA errors * @tx_irq: Axidma TX IRQ number * @rx_irq: Axidma RX IRQ number
@@ -404,19 +418,6 @@ struct axidma_bd {* @phy_mode: Phy type to identify between MII/GMII/RGMII/SGMII/1000 Base-X * @options: AxiEthernet option word * @features: Stores the extended features supported by the axienet hw -* @tx_bd_v: Virtual address of the TX buffer descriptor ring -* @tx_bd_p: Physical address(start address) of the TX buffer descr. ring -* @tx_bd_num: Size of TX buffer descriptor ring -* @rx_bd_v: Virtual address of the RX buffer descriptor ring -* @rx_bd_p: Physical address(start address) of the RX buffer descr. ring -* @rx_bd_num: Size of RX buffer descriptor ring -* @tx_bd_ci: Stores the index of the Tx buffer descriptor in the ring being -* accessed currently. Used while alloc. BDs before a TX starts -* @tx_bd_tail: Stores the index of the Tx buffer descriptor in the ring being -* accessed currently. Used while processing BDs after the TX -* completed. -* @rx_bd_ci: Stores the index of the Rx buffer descriptor in the ring being -* accessed currently. * @max_frm_size: Stores the maximum size of the frame that can be that * Txed/Rxed in the existing hardware. If jumbo option is * supported, the maximum frame size would be 9k. Else it is
@@ -438,8 +439,6 @@ struct axienet_local {struct phylink *phylink;struct phylink_config phylink_config; -struct napi_struct napi; -struct mdio_device *pcs_phy;bool switch_x_sgmii;
@@ -454,7 +453,20 @@ struct axienet_local {void __iomem *regs;void __iomem *dma_regs; +struct napi_struct napi_rx;u32 rx_dma_cr; +struct axidma_bd *rx_bd_v; +dma_addr_t rx_bd_p; +u32 rx_bd_num; +u32 rx_bd_ci; + +struct napi_struct napi_tx; +u32 tx_dma_cr; +struct axidma_bd *tx_bd_v; +dma_addr_t tx_bd_p; +u32 tx_bd_num; +u32 tx_bd_ci; +u32 tx_bd_tail;struct work_struct dma_err_task;
@@ -466,16 +478,6 @@ struct axienet_local {u32 options;u32 features; -struct axidma_bd *tx_bd_v; -dma_addr_t tx_bd_p; -u32 tx_bd_num; -struct axidma_bd *rx_bd_v; -dma_addr_t rx_bd_p; -u32 rx_bd_num; -u32 tx_bd_ci; -u32 tx_bd_tail; -u32 rx_bd_ci; -u32 max_frm_size;u32 rxmem;
drivers/net/ethernet/xilinx/xilinx_axienet_main.c +83 -59
308 lines not on this page · raw message
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 289/691 net: axienet: Switch to 64-bit RX/TX statistics
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Robert Hancock <[email protected]>
[ Upstream commit cb45a8bf4693965e89d115cd2c510f12bc127c37 ]
The RX and TX byte/packet statistics in this driver could be overflowed relatively quickly on a 32-bit platform. Switch these stats to use the u64_stats infrastructure to avoid this.
Stable-dep-of: 5a6caa2cfabb ("net: xilinx: axienet: Fix packet counting")
--- drivers/net/ethernet/xilinx/xilinx_axienet.h | 12 ++++++ .../net/ethernet/xilinx/xilinx_axienet_main.c | 37 +++++++++++++++++-- 2 files changed, 45 insertions(+), 4 deletions(-)
drivers/net/ethernet/xilinx/xilinx_axienet.h +12 -0
@@ -402,6 +402,9 @@ struct axidma_bd {* @rx_bd_num: Size of RX buffer descriptor ring * @rx_bd_ci: Stores the index of the Rx buffer descriptor in the ring being * accessed currently. +* @rx_packets: RX packet count for statistics +* @rx_bytes: RX byte count for statistics +* @rx_stat_sync: Synchronization object for RX stats * @napi_tx: NAPI TX control structure * @tx_dma_cr: Nominal content of TX DMA control register * @tx_bd_v: Virtual address of the TX buffer descriptor ring
@@ -411,6 +414,9 @@ struct axidma_bd {* complete. Only updated at runtime by TX NAPI poll. * @tx_bd_tail: Stores the index of the next Tx buffer descriptor in the ring * to be populated. +* @tx_packets: TX packet count for statistics +* @tx_bytes: TX byte count for statistics +* @tx_stat_sync: Synchronization object for TX stats * @dma_err_task: Work structure to process Axi DMA errors * @tx_irq: Axidma TX IRQ number * @rx_irq: Axidma RX IRQ number
@@ -459,6 +465,9 @@ struct axienet_local {dma_addr_t rx_bd_p;u32 rx_bd_num;u32 rx_bd_ci; +u64_stats_t rx_packets; +u64_stats_t rx_bytes; +struct u64_stats_sync rx_stat_sync;struct napi_struct napi_tx;u32 tx_dma_cr;
@@ -467,6 +476,9 @@ struct axienet_local {u32 tx_bd_num;u32 tx_bd_ci;u32 tx_bd_tail; +u64_stats_t tx_packets; +u64_stats_t tx_bytes; +struct u64_stats_sync tx_stat_sync;struct work_struct dma_err_task;
drivers/net/ethernet/xilinx/xilinx_axienet_main.c +33 -4
@@ -777,8 +777,10 @@ static int axienet_tx_poll(struct napi_struct *napi, int budget)if (lp->tx_bd_ci >= lp->tx_bd_num) lp->tx_bd_ci %= lp->tx_bd_num; - ndev->stats.tx_packets += packets; - ndev->stats.tx_bytes += size; +u64_stats_update_begin (&lp->tx_stat_sync); +u64_stats_add (&lp->tx_packets, packets); +u64_stats_add (&lp->tx_bytes, size); +u64_stats_update_end (&lp->tx_stat_sync);/* Matches barrier in axienet_start_xmit */ smp_mb ();
@@ -1009,8 +1011,10 @@ static int axienet_rx_poll(struct napi_struct *napi, int budget) cur_p = &lp->rx_bd_v[lp->rx_bd_ci]; } - lp->ndev->stats.rx_packets += packets; - lp->ndev->stats.rx_bytes += size; +u64_stats_update_begin (&lp->rx_stat_sync); +u64_stats_add (&lp->rx_packets, packets); +u64_stats_add (&lp->rx_bytes, size); +u64_stats_update_end (&lp->rx_stat_sync);if (tail_p)axienet_dma_out_addr (lp,XAXIDMA_RX_TDESC_OFFSET , tail_p);
@@ -1317,10 +1321,32 @@ static int axienet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)return phylink_mii_ioctl (lp->phylink, rq, cmd); } +static void +axienet_get_stats64 (struct net_device *dev,struct rtnl_link_stats64 *stats) +{ +struct axienet_local *lp =netdev_priv (dev); +unsigned int start; + +netdev_stats_to_stats64 (stats, &dev->stats); + +do { + start =u64_stats_fetch_begin_irq (&lp->rx_stat_sync); + stats->rx_packets =u64_stats_read (&lp->rx_packets); + stats->rx_bytes =u64_stats_read (&lp->rx_bytes); + }while (u64_stats_fetch_retry_irq (&lp->rx_stat_sync, start)); + +do { + start =u64_stats_fetch_begin_irq (&lp->tx_stat_sync); + stats->tx_packets =u64_stats_read (&lp->tx_packets); + stats->tx_bytes =u64_stats_read (&lp->tx_bytes); + }while (u64_stats_fetch_retry_irq (&lp->tx_stat_sync, start)); +} +static const struct net_device_ops axienet_netdev_ops = { .ndo_open = axienet_open, .ndo_stop = axienet_stop, .ndo_start_xmit = axienet_start_xmit, + .ndo_get_stats64 = axienet_get_stats64, .ndo_change_mtu = axienet_change_mtu, .ndo_set_mac_address = netdev_set_mac_address, .ndo_validate_addr = eth_validate_addr,
@@ -1932,6 +1958,9 @@ static int axienet_probe(struct platform_device *pdev) lp->rx_bd_num =RX_BD_NUM_DEFAULT ; lp->tx_bd_num =TX_BD_NUM_DEFAULT ; +u64_stats_init (&lp->rx_stat_sync); +u64_stats_init (&lp->tx_stat_sync); +netif_napi_add (ndev, &lp->napi_rx, axienet_rx_poll,NAPI_POLL_WEIGHT );netif_napi_add (ndev, &lp->napi_tx, axienet_tx_poll,NAPI_POLL_WEIGHT );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 290/691 net: xilinx: axienet: Fix packet counting
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Anderson <[email protected]>
[ Upstream commit 5a6caa2cfabb559309b5ce29ee7c8e9ce1a9a9df ]
axienet_free_tx_chain returns the number of DMA descriptors it's handled. However, axienet_tx_poll treats the return as the number of packets. When scatter-gather SKBs are enabled, a single packet may use multiple DMA descriptors, which causes incorrect packet counts. Fix this by explicitly keepting track of the number of packets processed as separate from the DMA descriptors.
Budget does not affect the number of Tx completions we can process for NAPI, so we use the ring size as the limit instead of budget. As we no longer return the number of descriptors processed to axienet_tx_poll, we now update tx_bd_ci in axienet_free_tx_chain.
--- .../net/ethernet/xilinx/xilinx_axienet_main.c | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-)
drivers/net/ethernet/xilinx/xilinx_axienet_main.c +14 -9
@@ -675,15 +675,15 @@ static int axienet_device_reset(struct net_device *ndev)* * Would either be called after a successful transmit operation, or after * there was an error when setting up the chain. -* Returns the number of descriptors handled. +* Returns the number of packets handled. */ static int axienet_free_tx_chain (struct axienet_local *lp,u32 first_bd,int nr_bds,bool force,u32 *sizep,int budget) {struct axidma_bd *cur_p;unsigned int status; +int i, packets =0 ;dma_addr_t phys; -int i;for (i =0 ; i < nr_bds; i++) { cur_p = &lp->tx_bd_v[(first_bd + i) % lp->tx_bd_num];
@@ -702,8 +702,10 @@ static int axienet_free_tx_chain(struct axienet_local *lp, u32 first_bd, (cur_p->cntrl &XAXIDMA_BD_CTRL_LENGTH_MASK ), DMA_TO_DEVICE); -if (cur_p->skb && (status &XAXIDMA_BD_STS_COMPLETE_MASK )) +if (cur_p->skb && (status &XAXIDMA_BD_STS_COMPLETE_MASK )) {napi_consume_skb (cur_p->skb, budget); + packets++; + } cur_p->app0 =0 ; cur_p->app1 =0 ;
@@ -719,7 +721,13 @@ static int axienet_free_tx_chain(struct axienet_local *lp, u32 first_bd, *sizep += status &XAXIDMA_BD_STS_ACTUAL_LEN_MASK ; } -return i; +if (!force) { + lp->tx_bd_ci += i; +if (lp->tx_bd_ci >= lp->tx_bd_num) + lp->tx_bd_ci %= lp->tx_bd_num; + } + +return packets; }/**
@@ -770,13 +778,10 @@ static int axienet_tx_poll(struct napi_struct *napi, int budget)u32 size =0 ;int packets; - packets =axienet_free_tx_chain (lp, lp->tx_bd_ci, budget, false, &size, budget); + packets =axienet_free_tx_chain (lp, lp->tx_bd_ci, lp->tx_bd_num, false, + &size, budget);if (packets) { - lp->tx_bd_ci += packets; -if (lp->tx_bd_ci >= lp->tx_bd_num) - lp->tx_bd_ci %= lp->tx_bd_num; -u64_stats_update_begin (&lp->tx_stat_sync);u64_stats_add (&lp->tx_packets, packets);u64_stats_add (&lp->tx_bytes, size);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 291/691 netfilter: nf_reject_ipv6: fix nf_reject_ip6_tcphdr_put()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit 9c778fe48d20ef362047e3376dee56d77f8500d4 ]
syzbot reported that nf_reject_ip6_tcphdr_put() was possibly sending garbage on the four reserved tcp bits (th->res1)
Use skb_put_zero() to clear the whole TCP header,
as done in nf_reject_ip_tcphdr_put()
BUG: KMSAN: uninit-value in nf_reject_ip6_tcphdr_put+0x688/0x6c0 net/ipv6/netfilter/nf_reject_ipv6.c:255 nf_reject_ip6_tcphdr_put+0x688/0x6c0 net/ipv6/netfilter/nf_reject_ipv6.c:255 nf_send_reset6+0xd84/0x15b0 net/ipv6/netfilter/nf_reject_ipv6.c:344 nft_reject_inet_eval+0x3c1/0x880 net/netfilter/nft_reject_inet.c:48 expr_call_ops_eval net/netfilter/nf_tables_core.c:240 [inline] nft_do_chain+0x438/0x22a0 net/netfilter/nf_tables_core.c:288 nft_do_chain_inet+0x41a/0x4f0 net/netfilter/nft_chain_filter.c:161 nf_hook_entry_hookfn include/linux/netfilter.h:154 [inline] nf_hook_slow+0xf4/0x400 net/netfilter/core.c:626 nf_hook include/linux/netfilter.h:269 [inline] NF_HOOK include/linux/netfilter.h:312 [inline] ipv6_rcv+0x29b/0x390 net/ipv6/ip6_input.c:310 __netif_receive_skb_one_core net/core/dev.c:5661 [inline] __netif_receive_skb+0x1da/0xa00 net/core/dev.c:5775 process_backlog+0x4ad/0xa50 net/core/dev.c:6108 __napi_poll+0xe7/0x980 net/core/dev.c:6772 napi_poll net/core/dev.c:6841 [inline] net_rx_action+0xa5a/0x19b0 net/core/dev.c:6963 handle_softirqs+0x1ce/0x800 kernel/softirq.c:554 __do_softirq+0x14/0x1a kernel/softirq.c:588 do_softirq+0x9a/0x100 kernel/softirq.c:455 __local_bh_enable_ip+0x9f/0xb0 kernel/softirq.c:382 local_bh_enable include/linux/bottom_half.h:33 [inline] rcu_read_unlock_bh include/linux/rcupdate.h:908 [inline] __dev_queue_xmit+0x2692/0x5610 net/core/dev.c:4450 dev_queue_xmit include/linux/netdevice.h:3105 [inline] neigh_resolve_output+0x9ca/0xae0 net/core/neighbour.c:1565 neigh_output include/net/neighbour.h:542 [inline] ip6_finish_output2+0x2347/0x2ba0 net/ipv6/ip6_output.c:141 __ip6_finish_output net/ipv6/ip6_output.c:215 [inline] ip6_finish_output+0xbb8/0x14b0 net/ipv6/ip6_output.c:226 NF_HOOK_COND include/linux/netfilter.h:303 [inline] ip6_output+0x356/0x620 net/ipv6/ip6_output.c:247 dst_output include/net/dst.h:450 [inline] NF_HOOK include/linux/netfilter.h:314 [inline] ip6_xmit+0x1ba6/0x25d0 net/ipv6/ip6_output.c:366 inet6_csk_xmit+0x442/0x530 net/ipv6/inet6_connection_sock.c:135 __tcp_transmit_skb+0x3b07/0x4880 net/ipv4/tcp_output.c:1466 tcp_transmit_skb net/ipv4/tcp_output.c:1484 [inline] tcp_connect+0x35b6/0x7130 net/ipv4/tcp_output.c:4143 tcp_v6_connect+0x1bcc/0x1e40 net/ipv6/tcp_ipv6.c:333 __inet_stream_connect+0x2ef/0x1730 net/ipv4/af_inet.c:679 inet_stream_connect+0x6a/0xd0 net/ipv4/af_inet.c:750 __sys_connect_file net/socket.c:2061 [inline] __sys_connect+0x606/0x690 net/socket.c:2078 __do_sys_connect net/socket.c:2088 [inline] __se_sys_connect net/socket.c:2085 [inline] __x64_sys_connect+0x91/0xe0 net/socket.c:2085 x64_sys_call+0x27a5/0x3ba0 arch/x86/include/generated/asm/syscalls_64.h:43 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xcd/0x1e0 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x77/0x7f
Uninit was stored to memory at:
nf_reject_ip6_tcphdr_put+0x60c/0x6c0 net/ipv6/netfilter/nf_reject_ipv6.c:249 nf_send_reset6+0xd84/0x15b0 net/ipv6/netfilter/nf_reject_ipv6.c:344 nft_reject_inet_eval+0x3c1/0x880 net/netfilter/nft_reject_inet.c:48 expr_call_ops_eval net/netfilter/nf_tables_core.c:240 [inline] nft_do_chain+0x438/0x22a0 net/netfilter/nf_tables_core.c:288 nft_do_chain_inet+0x41a/0x4f0 net/netfilter/nft_chain_filter.c:161 nf_hook_entry_hookfn include/linux/netfilter.h:154 [inline] nf_hook_slow+0xf4/0x400 net/netfilter/core.c:626 nf_hook include/linux/netfilter.h:269 [inline] NF_HOOK include/linux/netfilter.h:312 [inline] ipv6_rcv+0x29b/0x390 net/ipv6/ip6_input.c:310 __netif_receive_skb_one_core net/core/dev.c:5661 [inline] __netif_receive_skb+0x1da/0xa00 net/core/dev.c:5775 process_backlog+0x4ad/0xa50 net/core/dev.c:6108 __napi_poll+0xe7/0x980 net/core/dev.c:6772 napi_poll net/core/dev.c:6841 [inline] net_rx_action+0xa5a/0x19b0 net/core/dev.c:6963 handle_softirqs+0x1ce/0x800 kernel/softirq.c:554 __do_softirq+0x14/0x1a kernel/softirq.c:588
Uninit was stored to memory at:
nf_reject_ip6_tcphdr_put+0x2ca/0x6c0 net/ipv6/netfilter/nf_reject_ipv6.c:231 nf_send_reset6+0xd84/0x15b0 net/ipv6/netfilter/nf_reject_ipv6.c:344 nft_reject_inet_eval+0x3c1/0x880 net/netfilter/nft_reject_inet.c:48 expr_call_ops_eval net/netfilter/nf_tables_core.c:240 [inline] nft_do_chain+0x438/0x22a0 net/netfilter/nf_tables_core.c:288 nft_do_chain_inet+0x41a/0x4f0 net/netfilter/nft_chain_filter.c:161 nf_hook_entry_hookfn include/linux/netfilter.h:154 [inline] nf_hook_slow+0xf4/0x400 net/netfilter/core.c:626 nf_hook include/linux/netfilter.h:269 [inline] NF_HOOK include/linux/netfilter.h:312 [inline] ipv6_rcv+0x29b/0x390 net/ipv6/ip6_input.c:310 __netif_receive_skb_one_core net/core/dev.c:5661 [inline] __netif_receive_skb+0x1da/0xa00 net/core/dev.c:5775 process_backlog+0x4ad/0xa50 net/core/dev.c:6108 __napi_poll+0xe7/0x980 net/core/dev.c:6772 napi_poll net/core/dev.c:6841 [inline] net_rx_action+0xa5a/0x19b0 net/core/dev.c:6963 handle_softirqs+0x1ce/0x800 kernel/softirq.c:554 __do_softirq+0x14/0x1a kernel/softirq.c:588
Uninit was created at:
slab_post_alloc_hook mm/slub.c:3998 [inline] slab_alloc_node mm/slub.c:4041 [inline] kmem_cache_alloc_node_noprof+0x6bf/0xb80 mm/slub.c:4084 kmalloc_reserve+0x13d/0x4a0 net/core/skbuff.c:583 __alloc_skb+0x363/0x7b0 net/core/skbuff.c:674 alloc_skb include/linux/skbuff.h:1320 [inline] nf_send_reset6+0x98d/0x15b0 net/ipv6/netfilter/nf_reject_ipv6.c:327 nft_reject_inet_eval+0x3c1/0x880 net/netfilter/nft_reject_inet.c:48 expr_call_ops_eval net/netfilter/nf_tables_core.c:240 [inline] nft_do_chain+0x438/0x22a0 net/netfilter/nf_tables_core.c:288 nft_do_chain_inet+0x41a/0x4f0 net/netfilter/nft_chain_filter.c:161 nf_hook_entry_hookfn include/linux/netfilter.h:154 [inline] nf_hook_slow+0xf4/0x400 net/netfilter/core.c:626 nf_hook include/linux/netfilter.h:269 [inline] NF_HOOK include/linux/netfilter.h:312 [inline] ipv6_rcv+0x29b/0x390 net/ipv6/ip6_input.c:310 __netif_receive_skb_one_core net/core/dev.c:5661 [inline] __netif_receive_skb+0x1da/0xa00 net/core/dev.c:5775 process_backlog+0x4ad/0xa50 net/core/dev.c:6108 __napi_poll+0xe7/0x980 net/core/dev.c:6772 napi_poll net/core/dev.c:6841 [inline] net_rx_action+0xa5a/0x19b0 net/core/dev.c:6963 handle_softirqs+0x1ce/0x800 kernel/softirq.c:554 __do_softirq+0x14/0x1a kernel/softirq.c:588
--- net/ipv6/netfilter/nf_reject_ipv6.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-)
net/ipv6/netfilter/nf_reject_ipv6.c +2 -12
@@ -223,33 +223,23 @@ void nf_reject_ip6_tcphdr_put(struct sk_buff *nskb, const struct tcphdr *oth, unsigned int otcplen) { struct tcphdr *tcph; -int needs_ack;skb_reset_transport_header (nskb); - tcph =skb_put (nskb,sizeof (struct tcphdr )); + tcph =skb_put_zero (nskb,sizeof (struct tcphdr ));/* Truncate to length (no data) */ tcph->doff =sizeof (struct tcphdr )/4 ; tcph->source = oth->dest; tcph->dest = oth->source;if (oth->ack) { - needs_ack =0 ; tcph->seq = oth->ack_seq; - tcph->ack_seq =0 ; }else { - needs_ack =1 ; tcph->ack_seq =htonl (ntohl (oth->seq) + oth->syn + oth->fin + otcplen - (oth->doff<<2 )); - tcph->seq =0 ; + tcph->ack =1 ; } -/* Reset flags */ - ((u_int8_t *)tcph)[13 ] =0 ; tcph->rst =1 ; - tcph->ack = needs_ack; - tcph->window =0 ; - tcph->urg_ptr =0 ; - tcph->check =0 ;/* Adjust TCP checksum */ tcph->check = csum_ipv6_magic(&ipv6_hdr(nskb)->saddr,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 292/691 net: seeq: Fix use after free vulnerability in ether3 Driver Due to Race Condition
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kaixin Wang <[email protected]>
[ Upstream commit b5109b60ee4fcb2f2bb24f589575e10cc5283ad4 ]
In the ether3_probe function, a timer is initialized with a callback function ether3_ledoff, bound to &prev(dev)->timer. Once the timer is started, there is a risk of a race condition if the module or device is removed, triggering the ether3_remove function to perform cleanup. The sequence of operations that may lead to a UAF bug is as follows:
CPU0 CPU1
| ether3_ledoff
ether3_remove |
free_netdev(dev); |
put_devic |
kfree(dev); |
| ether3_outw(priv(dev)->regs.config2 |= CFG2_CTRLO, REG_CONFIG2);
| // use devFix it by ensuring that the timer is canceled before proceeding with the cleanup in ether3_remove.
--- drivers/net/ethernet/seeq/ether3.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/ethernet/seeq/ether3.c +2 -0
@@ -845,9 +845,11 @@ static void ether3_remove(struct expansion_card *ec) {struct net_device *dev =ecard_get_drvdata (ec); +ether3_outw (priv (dev)->regs.config2 |=CFG2_CTRLO ,REG_CONFIG2 );ecard_set_drvdata (ec,NULL );unregister_netdev (dev); +del_timer_sync (&priv (dev)->timer);free_netdev (dev);ecard_release_resources (ec); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 293/691 net: ipv6: select DST_CACHE from IPV6_RPL_LWTUNNEL
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Weißschuh <[email protected]>
[ Upstream commit 93c21077bb9ba08807c459982d440dbbee4c7af3 ]
The rpl sr tunnel code contains calls to dst_cache_*() which are only present when the dst cache is built.
Select DST_CACHE to build the dst cache, similar to other kconfig options in the same file.
Compiling the rpl sr tunnel without DST_CACHE will lead to linker errors.
--- net/ipv6/Kconfig | 1 + 1 file changed, 1 insertion(+)
net/ipv6/Kconfig +1 -0
@@ -322,6 +322,7 @@ config IPV6_RPL_LWTUNNEL bool "IPv6: RPL Source Routing Header support" depends on IPV6 select LWTUNNEL + select DST_CACHE help Support for RFC6554 RPL Source Routing Header using the lightweight tunnels mechanism.
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 294/691 tcp: check skb is non-NULL in tcp_rto_delta_us()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josh Hunt <[email protected]>
[ Upstream commit c8770db2d54437a5f49417ae7b46f7de23d14db6 ]
We have some machines running stock Ubuntu 20.04.6 which is their 5.4.0-174-generic kernel that are running ceph and recently hit a null ptr dereference in tcp_rearm_rto(). Initially hitting it from the TLP path, but then later we also saw it getting hit from the RACK case as well. Here are examples of the oops messages we saw in each of those cases:
Jul 26 15:05:02 rx [11061395.780353] BUG: kernel NULL pointer dereference, address: 0000000000000020 Jul 26 15:05:02 rx [11061395.787572] #PF: supervisor read access in kernel mode Jul 26 15:05:02 rx [11061395.792971] #PF: error_code(0x0000) - not-present page Jul 26 15:05:02 rx [11061395.798362] PGD 0 P4D 0 Jul 26 15:05:02 rx [11061395.801164] Oops: 0000 [#1] SMP NOPTI Jul 26 15:05:02 rx [11061395.805091] CPU: 0 PID: 9180 Comm: msgr-worker-1 Tainted: G W 5.4.0-174-generic #193-Ubuntu Jul 26 15:05:02 rx [11061395.814996] Hardware name: Supermicro SMC 2x26 os-gen8 64C NVME-Y 256G/H12SSW-NTR, BIOS 2.5.V1.2U.NVMe.UEFI 05/09/2023 Jul 26 15:05:02 rx [11061395.825952] RIP: 0010:tcp_rearm_rto+0xe4/0x160 Jul 26 15:05:02 rx [11061395.830656] Code: 87 ca 04 00 00 00 5b 41 5c 41 5d 5d c3 c3 49 8b bc 24 40 06 00 00 eb 8d 48 bb cf f7 53 e3 a5 9b c4 20 4c 89 ef e8 0c fe 0e 00 <48> 8b 78 20 48 c1 ef 03 48 89 f8 41 8b bc 24 80 04 00 00 48 f7 e3 Jul 26 15:05:02 rx [11061395.849665] RSP: 0018:ffffb75d40003e08 EFLAGS: 00010246 Jul 26 15:05:02 rx [11061395.855149] RAX: 0000000000000000 RBX: 20c49ba5e353f7cf RCX: 0000000000000000 Jul 26 15:05:02 rx [11061395.862542] RDX: 0000000062177c30 RSI: 000000000000231c RDI: ffff9874ad283a60 Jul 26 15:05:02 rx [11061395.869933] RBP: ffffb75d40003e20 R08: 0000000000000000 R09: ffff987605e20aa8 Jul 26 15:05:02 rx [11061395.877318] R10: ffffb75d40003f00 R11: ffffb75d4460f740 R12: ffff9874ad283900 Jul 26 15:05:02 rx [11061395.884710] R13: ffff9874ad283a60 R14: ffff9874ad283980 R15: ffff9874ad283d30 Jul 26 15:05:02 rx [11061395.892095] FS: 00007f1ef4a2e700(0000) GS:ffff987605e00000(0000) knlGS:0000000000000000 Jul 26 15:05:02 rx [11061395.900438] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 Jul 26 15:05:02 rx [11061395.906435] CR2: 0000000000000020 CR3: 0000003e450ba003 CR4: 0000000000760ef0 Jul 26 15:05:02 rx [11061395.913822] PKRU: 55555554 Jul 26 15:05:02 rx [11061395.916786] Call Trace: Jul 26 15:05:02 rx [11061395.919488] Jul 26 15:05:02 rx [11061395.921765] ? show_regs.cold+0x1a/0x1f Jul 26 15:05:02 rx [11061395.925859] ? __die+0x90/0xd9 Jul 26 15:05:02 rx [11061395.929169] ? no_context+0x196/0x380 Jul 26 15:05:02 rx [11061395.933088] ? ip6_protocol_deliver_rcu+0x4e0/0x4e0 Jul 26 15:05:02 rx [11061395.938216] ? ip6_sublist_rcv_finish+0x3d/0x50 Jul 26 15:05:02 rx [11061395.943000] ? __bad_area_nosemaphore+0x50/0x1a0 Jul 26 15:05:02 rx [11061395.947873] ? bad_area_nosemaphore+0x16/0x20 Jul 26 15:05:02 rx [11061395.952486] ? do_user_addr_fault+0x267/0x450 Jul 26 15:05:02 rx [11061395.957104] ? ipv6_list_rcv+0x112/0x140 Jul 26 15:05:02 rx [11061395.961279] ? __do_page_fault+0x58/0x90 Jul 26 15:05:02 rx [11061395.965458] ? do_page_fault+0x2c/0xe0 Jul 26 15:05:02 rx [11061395.969465] ? page_fault+0x34/0x40 Jul 26 15:05:02 rx [11061395.973217] ? tcp_rearm_rto+0xe4/0x160 Jul 26 15:05:02 rx [11061395.977313] ? tcp_rearm_rto+0xe4/0x160 Jul 26 15:05:02 rx [11061395.981408] tcp_send_loss_probe+0x10b/0x220 Jul 26 15:05:02 rx [11061395.985937] tcp_write_timer_handler+0x1b4/0x240 Jul 26 15:05:02 rx [11061395.990809] tcp_write_timer+0x9e/0xe0 Jul 26 15:05:02 rx [11061395.994814] ? tcp_write_timer_handler+0x240/0x240 Jul 26 15:05:02 rx [11061395.999866] call_timer_fn+0x32/0x130 Jul 26 15:05:02 rx [11061396.003782] __run_timers.part.0+0x180/0x280 Jul 26 15:05:02 rx [11061396.008309] ? recalibrate_cpu_khz+0x10/0x10 Jul 26 15:05:02 rx [11061396.012841] ? native_x2apic_icr_write+0x30/0x30 Jul 26 15:05:02 rx [11061396.017718] ? lapic_next_event+0x21/0x30 Jul 26 15:05:02 rx [11061396.021984] ? clockevents_program_event+0x8f/0xe0 Jul 26 15:05:02 rx [11061396.027035] run_timer_softirq+0x2a/0x50 Jul 26 15:05:02 rx [11061396.031212] __do_softirq+0xd1/0x2c1 Jul 26 15:05:02 rx [11061396.035044] do_softirq_own_stack+0x2a/0x40 Jul 26 15:05:02 rx [11061396.039480] Jul 26 15:05:02 rx [11061396.041840] do_softirq.part.0+0x46/0x50 Jul 26 15:05:02 rx [11061396.046022] __local_bh_enable_ip+0x50/0x60 Jul 26 15:05:02 rx [11061396.050460] _raw_spin_unlock_bh+0x1e/0x20 Jul 26 15:05:02 rx [11061396.054817] nf_conntrack_tcp_packet+0x29e/0xbe0 [nf_conntrack] Jul 26 15:05:02 rx [11061396.060994] ? get_l4proto+0xe7/0x190 [nf_conntrack] Jul 26 15:05:02 rx [11061396.066220] nf_conntrack_in+0xe9/0x670 [nf_conntrack] Jul 26 15:05:02 rx [11061396.071618] ipv6_conntrack_local+0x14/0x20 [nf_conntrack] Jul 26 15:05:02 rx [11061396.077356] nf_hook_slow+0x45/0xb0 Jul 26 15:05:02 rx [11061396.081098] ip6_xmit+0x3f0/0x5d0 Jul 26 15:05:02 rx [11061396.084670] ? ipv6_anycast_cleanup+0x50/0x50 Jul 26 15:05:02 rx [11061396.089282] ? __sk_dst_check+0x38/0x70 Jul 26 15:05:02 rx [11061396.093381] ? inet6_csk_route_socket+0x13b/0x200 Jul 26 15:05:02 rx [11061396.098346] inet6_csk_xmit+0xa7/0xf0 Jul 26 15:05:02 rx [11061396.102263] __tcp_transmit_skb+0x550/0xb30 Jul 26 15:05:02 rx [11061396.106701] tcp_write_xmit+0x3c6/0xc20 Jul 26 15:05:02 rx [11061396.110792] ? __alloc_skb+0x98/0x1d0 Jul 26 15:05:02 rx [11061396.114708] __tcp_push_pending_frames+0x37/0x100 Jul 26 15:05:02 rx [11061396.119667] tcp_push+0xfd/0x100 Jul 26 15:05:02 rx [11061396.123150] tcp_sendmsg_locked+0xc70/0xdd0 Jul 26 15:05:02 rx [11061396.127588] tcp_sendmsg+0x2d/0x50 Jul 26 15:05:02 rx [11061396.131245] inet6_sendmsg+0x43/0x70 Jul 26 15:05:02 rx [11061396.135075] __sock_sendmsg+0x48/0x70 Jul 26 15:05:02 rx [11061396.138994] ____sys_sendmsg+0x212/0x280 Jul 26 15:05:02 rx [11061396.143172] ___sys_sendmsg+0x88/0xd0 Jul 26 15:05:02 rx [11061396.147098] ? __seccomp_filter+0x7e/0x6b0 Jul 26 15:05:02 rx [11061396.151446] ? __switch_to+0x39c/0x460 Jul 26 15:05:02 rx [11061396.155453] ? __switch_to_asm+0x42/0x80 Jul 26 15:05:02 rx [11061396.159636] ? __switch_to_asm+0x5a/0x80 Jul 26 15:05:02 rx [11061396.163816] __sys_sendmsg+0x5c/0xa0 Jul 26 15:05:02 rx [11061396.167647] __x64_sys_sendmsg+0x1f/0x30 Jul 26 15:05:02 rx [11061396.171832] do_syscall_64+0x57/0x190 Jul 26 15:05:02 rx [11061396.175748] entry_SYSCALL_64_after_hwframe+0x5c/0xc1 Jul 26 15:05:02 rx [11061396.181055] RIP: 0033:0x7f1ef692618d Jul 26 15:05:02 rx [11061396.184893] Code: 28 89 54 24 1c 48 89 74 24 10 89 7c 24 08 e8 ca ee ff ff 8b 54 24 1c 48 8b 74 24 10 41 89 c0 8b 7c 24 08 b8 2e 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 2f 44 89 c7 48 89 44 24 08 e8 fe ee ff ff 48 Jul 26 15:05:02 rx [11061396.203889] RSP: 002b:00007f1ef4a26aa0 EFLAGS: 00000293 ORIG_RAX: 000000000000002e Jul 26 15:05:02 rx [11061396.211708] RAX: ffffffffffffffda RBX: 000000000000084b RCX: 00007f1ef692618d Jul 26 15:05:02 rx [11061396.219091] RDX: 0000000000004000 RSI: 00007f1ef4a26b10 RDI: 0000000000000275 Jul 26 15:05:02 rx [11061396.226475] RBP: 0000000000004000 R08: 0000000000000000 R09: 0000000000000020 Jul 26 15:05:02 rx [11061396.233859] R10: 0000000000000000 R11: 0000000000000293 R12: 000000000000084b Jul 26 15:05:02 rx [11061396.241243] R13: 00007f1ef4a26b10 R14: 0000000000000275 R15: 000055592030f1e8 Jul 26 15:05:02 rx [11061396.248628] Modules linked in: vrf bridge stp llc vxlan ip6_udp_tunnel udp_tunnel nls_iso8859_1 amd64_edac_mod edac_mce_amd kvm_amd kvm crct10dif_pclmul ghash_clmulni_intel aesni_intel crypto_simd cryptd glue_helper wmi_bmof ipmi_ssif input_leds joydev rndis_host cdc_ether usbnet mii ast drm_vram_helper ttm drm_kms_helper i2c_algo_bit fb_sys_fops syscopyarea sysfillrect sysimgblt ccp mac_hid ipmi_si ipmi_devintf ipmi_msghandler nft_ct sch_fq_codel nf_tables_set nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 nf_tables nfnetlink ramoops reed_solomon efi_pstore drm ip_tables x_tables autofs4 raid10 raid456 async_raid6_recov async_memcpy async_pq async_xor async_tx xor raid6_pq libcrc32c raid0 multipath linear mlx5_ib ib_uverbs ib_core raid1 mlx5_core hid_generic pci_hyperv_intf crc32_pclmul tls usbhid ahci mlxfw bnxt_en libahci hid nvme i2c_piix4 nvme_core wmi Jul 26 15:05:02 rx [11061396.324334] CR2: 0000000000000020 Jul 26 15:05:02 rx [11061396.327944] ---[ end trace 68a2b679d1cfb4f1 ]--- Jul 26 15:05:02 rx [11061396.433435] RIP: 0010:tcp_rearm_rto+0xe4/0x160 Jul 26 15:05:02 rx [11061396.438137] Code: 87 ca 04 00 00 00 5b 41 5c 41 5d 5d c3 c3 49 8b bc 24 40 06 00 00 eb 8d 48 bb cf f7 53 e3 a5 9b c4 20 4c 89 ef e8 0c fe 0e 00 <48> 8b 78 20 48 c1 ef 03 48 89 f8 41 8b bc 24 80 04 00 00 48 f7 e3 Jul 26 15:05:02 rx [11061396.457144] RSP: 0018:ffffb75d40003e08 EFLAGS: 00010246 Jul 26 15:05:02 rx [11061396.462629] RAX: 0000000000000000 RBX: 20c49ba5e353f7cf RCX: 0000000000000000 Jul 26 15:05:02 rx [11061396.470012] RDX: 0000000062177c30 RSI: 000000000000231c RDI: ffff9874ad283a60 Jul 26 15:05:02 rx [11061396.477396] RBP: ffffb75d40003e20 R08: 0000000000000000 R09: ffff987605e20aa8 Jul 26 15:05:02 rx [11061396.484779] R10: ffffb75d40003f00 R11: ffffb75d4460f740 R12: ffff9874ad283900 Jul 26 15:05:02 rx [11061396.492164] R13: ffff9874ad283a60 R14: ffff9874ad283980 R15: ffff9874ad283d30 Jul 26 15:05:02 rx [11061396.499547] FS: 00007f1ef4a2e700(0000) GS:ffff987605e00000(0000) knlGS:0000000000000000 Jul 26 15:05:02 rx [11061396.507886] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 Jul 26 15:05:02 rx [11061396.513884] CR2: 0000000000000020 CR3: 0000003e450ba003 CR4: 0000000000760ef0 Jul 26 15:05:02 rx [11061396.521267] PKRU: 55555554 Jul 26 15:05:02 rx [11061396.524230] Kernel panic - not syncing: Fatal exception in interrupt Jul 26 15:05:02 rx [11061396.530885] Kernel Offset: 0x1b200000 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffffbfffffff) Jul 26 15:05:03 rx [11061396.660181] ---[ end Kernel panic - not syncing: Fatal exception in interrupt ]---
After we hit this we disabled TLP by setting tcp_early_retrans to 0 and then hit the crash in the RACK case:
Aug 7 07:26:16 rx [1006006.265582] BUG: kernel NULL pointer dereference, address: 0000000000000020
Aug 7 07:26:16 rx [1006006.272719] #PF: supervisor read access in kernel mode
Aug 7 07:26:16 rx [1006006.278030] #PF: error_code(0x0000) - not-present page
Aug 7 07:26:16 rx [1006006.283343] PGD 0 P4D 0
Aug 7 07:26:16 rx [1006006.286057] Oops: 0000 [#1] SMP NOPTI
Aug 7 07:26:16 rx [1006006.289896] CPU: 5 PID: 0 Comm: swapper/5 Tainted: G W 5.4.0-174-generic #193-Ubuntu
Aug 7 07:26:16 rx [1006006.299107] Hardware name: Supermicro SMC 2x26 os-gen8 64C NVME-Y 256G/H12SSW-NTR, BIOS 2.5.V1.2U.NVMe.UEFI 05/09/2023
Aug 7 07:26:16 rx [1006006.309970] RIP: 0010:tcp_rearm_rto+0xe4/0x160
Aug 7 07:26:16 rx [1006006.314584] Code: 87 ca 04 00 00 00 5b 41 5c 41 5d 5d c3 c3 49 8b bc 24 40 06 00 00 eb 8d 48 bb cf f7 53 e3 a5 9b c4 20 4c 89 ef e8 0c fe 0e 00 <48> 8b 78 20 48 c1 ef 03 48 89 f8 41 8b bc 24 80 04 00 00 48 f7 e3
Aug 7 07:26:16 rx [1006006.333499] RSP: 0018:ffffb42600a50960 EFLAGS: 00010246
Aug 7 07:26:16 rx [1006006.338895] RAX: 0000000000000000 RBX: 20c49ba5e353f7cf RCX: 0000000000000000
Aug 7 07:26:16 rx [1006006.346193] RDX: 0000000000000000 RSI: 0000000000000001 RDI: ffff92d687ed8160
Aug 7 07:26:16 rx [1006006.353489] RBP: ffffb42600a50978 R08: 0000000000000000 R09: 00000000cd896dcc
Aug 7 07:26:16 rx [1006006.360786] R10: ffff92dc3404f400 R11: 0000000000000001 R12: ffff92d687ed8000
Aug 7 07:26:16 rx [1006006.368084] R13: ffff92d687ed8160 R14: 00000000cd896dcc R15: 00000000cd8fca81
Aug 7 07:26:16 rx [1006006.375381] FS: 0000000000000000(0000) GS:ffff93158ad40000(0000) knlGS:0000000000000000
Aug 7 07:26:16 rx [1006006.383632] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
Aug 7 07:26:16 rx [1006006.389544] CR2: 0000000000000020 CR3: 0000003e775ce006 CR4: 0000000000760ee0
Aug 7 07:26:16 rx [1006006.396839] PKRU: 55555554
Aug 7 07:26:16 rx [1006006.399717] Call Trace:
Aug 7 07:26:16 rx [1006006.402335]
Aug 7 07:26:16 rx [1006006.404525] ? show_regs.cold+0x1a/0x1f
Aug 7 07:26:16 rx [1006006.408532] ? __die+0x90/0xd9
Aug 7 07:26:16 rx [1006006.411760] ? no_context+0x196/0x380
Aug 7 07:26:16 rx [1006006.415599] ? __bad_area_nosemaphore+0x50/0x1a0
Aug 7 07:26:16 rx [1006006.420392] ? _raw_spin_lock+0x1e/0x30
Aug 7 07:26:16 rx [1006006.424401] ? bad_area_nosemaphore+0x16/0x20
Aug 7 07:26:16 rx [1006006.428927] ? do_user_addr_fault+0x267/0x450
Aug 7 07:26:16 rx [1006006.433450] ? __do_page_fault+0x58/0x90
Aug 7 07:26:16 rx [1006006.437542] ? do_page_fault+0x2c/0xe0
Aug 7 07:26:16 rx [1006006.441470] ? page_fault+0x34/0x40
Aug 7 07:26:16 rx [1006006.445134] ? tcp_rearm_rto+0xe4/0x160
Aug 7 07:26:16 rx [1006006.449145] tcp_ack+0xa32/0xb30
Aug 7 07:26:16 rx [1006006.452542] tcp_rcv_established+0x13c/0x670
Aug 7 07:26:16 rx [1006006.456981] ? sk_filter_trim_cap+0x48/0x220
Aug 7 07:26:16 rx [1006006.461419] tcp_v6_do_rcv+0xdb/0x450
Aug 7 07:26:16 rx [1006006.465257] tcp_v6_rcv+0xc2b/0xd10
Aug 7 07:26:16 rx [1006006.468918] ip6_protocol_deliver_rcu+0xd3/0x4e0
Aug 7 07:26:16 rx [1006006.473706] ip6_input_finish+0x15/0x20
Aug 7 07:26:16 rx [1006006.477710] ip6_input+0xa2/0xb0
Aug 7 07:26:16 rx [1006006.481109] ? ip6_protocol_deliver_rcu+0x4e0/0x4e0
Aug 7 07:26:16 rx [1006006.486151] ip6_sublist_rcv_finish+0x3d/0x50
Aug 7 07:26:16 rx [1006006.490679] ip6_sublist_rcv+0x1aa/0x250
Aug 7 07:26:16 rx [1006006.494779] ? ip6_rcv_finish_core.isra.0+0xa0/0xa0
Aug 7 07:26:16 rx [1006006.499828] ipv6_list_rcv+0x112/0x140
Aug 7 07:26:16 rx [1006006.503748] __netif_receive_skb_list_core+0x1a4/0x250
Aug 7 07:26:16 rx [1006006.509057] netif_receive_skb_list_internal+0x1a1/0x2b0
Aug 7 07:26:16 rx [1006006.514538] gro_normal_list.part.0+0x1e/0x40
Aug 7 07:26:16 rx [1006006.519068] napi_complete_done+0x91/0x130
Aug 7 07:26:16 rx [1006006.523352] mlx5e_napi_poll+0x18e/0x610 [mlx5_core]
Aug 7 07:26:16 rx [1006006.528481] net_rx_action+0x142/0x390
Aug 7 07:26:16 rx [1006006.532398] __do_softirq+0xd1/0x2c1
Aug 7 07:26:16 rx [1006006.536142] irq_exit+0xae/0xb0
Aug 7 07:26:16 rx [1006006.539452] do_IRQ+0x5a/0xf0
Aug 7 07:26:16 rx [1006006.542590] common_interrupt+0xf/0xf
Aug 7 07:26:16 rx [1006006.546421]
Aug 7 07:26:16 rx [1006006.548695] RIP: 0010:native_safe_halt+0xe/0x10
Aug 7 07:26:16 rx [1006006.553399] Code: 7b ff ff ff eb bd 90 90 90 90 90 90 e9 07 00 00 00 0f 00 2d 36 2c 50 00 f4 c3 66 90 e9 07 00 00 00 0f 00 2d 26 2c 50 00 fb f4 90 0f 1f 44 00 00 55 48 89 e5 41 55 41 54 53 e8 dd 5e 61 ff 65
Aug 7 07:26:16 rx [1006006.572309] RSP: 0018:ffffb42600177e70 EFLAGS: 00000246 ORIG_RAX: ffffffffffffffc2
Aug 7 07:26:16 rx [1006006.580040] RAX: ffffffff8ed08b20 RBX: 0000000000000005 RCX: 0000000000000001
Aug 7 07:26:16 rx [1006006.587337] RDX: 00000000f48eeca2 RSI: 0000000000000082 RDI: 0000000000000082
Aug 7 07:26:16 rx [1006006.594635] RBP: ffffb42600177e90 R08: 0000000000000000 R09: 000000000000020f
Aug 7 07:26:16 rx [1006006.601931] R10: 0000000000100000 R11: 0000000000000000 R12: 0000000000000005
Aug 7 07:26:16 rx [1006006.609229] R13: ffff93157deb5f00 R14: 0000000000000000 R15: 0000000000000000
Aug 7 07:26:16 rx [1006006.616530] ? __cpuidle_text_start+0x8/0x8
Aug 7 07:26:16 rx [1006006.620886] ? default_idle+0x20/0x140
Aug 7 07:26:16 rx [1006006.624804] arch_cpu_idle+0x15/0x20
Aug 7 07:26:16 rx [1006006.628545] default_idle_call+0x23/0x30
Aug 7 07:26:16 rx [1006006.632640] do_idle+0x1fb/0x270
Aug 7 07:26:16 rx [1006006.636035] cpu_startup_entry+0x20/0x30
Aug 7 07:26:16 rx [1006006.640126] start_secondary+0x178/0x1d0
Aug 7 07:26:16 rx [1006006.644218] secondary_startup_64+0xa4/0xb0
Aug 7 07:26:17 rx [1006006.648568] Modules linked in: vrf bridge stp llc vxlan ip6_udp_tunnel udp_tunnel nls_iso8859_1 nft_ct amd64_edac_mod edac_mce_amd kvm_amd kvm crct10dif_pclmul ghash_clmulni_intel aesni_intel crypto_simd cryptd glue_helper wmi_bmof ipmi_ssif input_leds joydev rndis_host cdc_ether usbnet ast mii drm_vram_helper ttm drm_kms_helper i2c_algo_bit fb_sys_fops syscopyarea sysfillrect sysimgblt ccp mac_hid ipmi_si ipmi_devintf ipmi_msghandler sch_fq_codel nf_tables_set nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 nf_tables nfnetlink ramoops reed_solomon efi_pstore drm ip_tables x_tables autofs4 raid10 raid456 async_raid6_recov async_memcpy async_pq async_xor async_tx xor raid6_pq libcrc32c raid0 multipath linear mlx5_ib ib_uverbs ib_core raid1 hid_generic mlx5_core pci_hyperv_intf crc32_pclmul usbhid ahci tls mlxfw bnxt_en hid libahci nvme i2c_piix4 nvme_core wmi [last unloaded: cpuid] Aug 7 07:26:17 rx [1006006.726180] CR2: 0000000000000020
Aug 7 07:26:17 rx [1006006.729718] ---[ end trace e0e2e37e4e612984 ]---
Prior to seeing the first crash and on other machines we also see the warning in tcp_send_loss_probe() where packets_out is non-zero, but both transmit and retrans queues are empty so we know the box is seeing some accounting issue in this area:
Jul 26 09:15:27 kernel: ------------[ cut here ]------------ Jul 26 09:15:27 kernel: invalid inflight: 2 state 1 cwnd 68 mss 8988 Jul 26 09:15:27 kernel: WARNING: CPU: 16 PID: 0 at net/ipv4/tcp_output.c:2605 tcp_send_loss_probe+0x214/0x220 Jul 26 09:15:27 kernel: Modules linked in: vrf bridge stp llc vxlan ip6_udp_tunnel udp_tunnel nls_iso8859_1 nft_ct amd64_edac_mod edac_mce_amd kvm_amd kvm crct10dif_pclmul ghash_clmulni_intel aesni_intel crypto_simd cryptd glue_helper wmi_bmof ipmi_ssif joydev input_leds rndis_host cdc_ether usbnet mii ast drm_vram_helper ttm drm_kms_he> Jul 26 09:15:27 kernel: CPU: 16 PID: 0 Comm: swapper/16 Not tainted 5.4.0-174-generic #193-Ubuntu Jul 26 09:15:27 kernel: Hardware name: Supermicro SMC 2x26 os-gen8 64C NVME-Y 256G/H12SSW-NTR, BIOS 2.5.V1.2U.NVMe.UEFI 05/09/2023 Jul 26 09:15:27 kernel: RIP: 0010:tcp_send_loss_probe+0x214/0x220 Jul 26 09:15:27 kernel: Code: 08 26 01 00 75 e2 41 0f b6 54 24 12 41 8b 8c 24 c0 06 00 00 45 89 f0 48 c7 c7 e0 b4 20 a7 c6 05 8d 08 26 01 01 e8 4a c0 0f 00 <0f> 0b eb ba 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 55 48 89 e5 41 Jul 26 09:15:27 kernel: RSP: 0018:ffffb7838088ce00 EFLAGS: 00010286 Jul 26 09:15:27 kernel: RAX: 0000000000000000 RBX: ffff9b84b5630430 RCX: 0000000000000006 Jul 26 09:15:27 kernel: RDX: 0000000000000007 RSI: 0000000000000096 RDI: ffff9b8e4621c8c0 Jul 26 09:15:27 kernel: RBP: ffffb7838088ce18 R08: 0000000000000927 R09: 0000000000000004 Jul 26 09:15:27 kernel: R10: 0000000000000000 R11: 0000000000000001 R12: ffff9b84b5630000 Jul 26 09:15:27 kernel: R13: 0000000000000000 R14: 000000000000231c R15: ffff9b84b5630430 Jul 26 09:15:27 kernel: FS: 0000000000000000(0000) GS:ffff9b8e46200000(0000) knlGS:0000000000000000 Jul 26 09:15:27 kernel: CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 Jul 26 09:15:27 kernel: CR2: 000056238cec2380 CR3: 0000003e49ede005 CR4: 0000000000760ee0 Jul 26 09:15:27 kernel: PKRU: 55555554 Jul 26 09:15:27 kernel: Call Trace: Jul 26 09:15:27 kernel: <IRQ> Jul 26 09:15:27 kernel: ? show_regs.cold+0x1a/0x1f Jul 26 09:15:27 kernel: ? __warn+0x98/0xe0 Jul 26 09:15:27 kernel: ? tcp_send_loss_probe+0x214/0x220 Jul 26 09:15:27 kernel: ? report_bug+0xd1/0x100 Jul 26 09:15:27 kernel: ? do_error_trap+0x9b/0xc0 Jul 26 09:15:27 kernel: ? do_invalid_op+0x3c/0x50 Jul 26 09:15:27 kernel: ? tcp_send_loss_probe+0x214/0x220 Jul 26 09:15:27 kernel: ? invalid_op+0x1e/0x30 Jul 26 09:15:27 kernel: ? tcp_send_loss_probe+0x214/0x220 Jul 26 09:15:27 kernel: tcp_write_timer_handler+0x1b4/0x240 Jul 26 09:15:27 kernel: tcp_write_timer+0x9e/0xe0 Jul 26 09:15:27 kernel: ? tcp_write_timer_handler+0x240/0x240 Jul 26 09:15:27 kernel: call_timer_fn+0x32/0x130 Jul 26 09:15:27 kernel: __run_timers.part.0+0x180/0x280 Jul 26 09:15:27 kernel: ? timerqueue_add+0x9b/0xb0 Jul 26 09:15:27 kernel: ? enqueue_hrtimer+0x3d/0x90 Jul 26 09:15:27 kernel: ? do_error_trap+0x9b/0xc0 Jul 26 09:15:27 kernel: ? do_invalid_op+0x3c/0x50 Jul 26 09:15:27 kernel: ? tcp_send_loss_probe+0x214/0x220 Jul 26 09:15:27 kernel: ? invalid_op+0x1e/0x30 Jul 26 09:15:27 kernel: ? tcp_send_loss_probe+0x214/0x220 Jul 26 09:15:27 kernel: tcp_write_timer_handler+0x1b4/0x240 Jul 26 09:15:27 kernel: tcp_write_timer+0x9e/0xe0 Jul 26 09:15:27 kernel: ? tcp_write_timer_handler+0x240/0x240 Jul 26 09:15:27 kernel: call_timer_fn+0x32/0x130 Jul 26 09:15:27 kernel: __run_timers.part.0+0x180/0x280 Jul 26 09:15:27 kernel: ? timerqueue_add+0x9b/0xb0 Jul 26 09:15:27 kernel: ? enqueue_hrtimer+0x3d/0x90 Jul 26 09:15:27 kernel: ? recalibrate_cpu_khz+0x10/0x10 Jul 26 09:15:27 kernel: ? ktime_get+0x3e/0xa0 Jul 26 09:15:27 kernel: ? native_x2apic_icr_write+0x30/0x30 Jul 26 09:15:27 kernel: run_timer_softirq+0x2a/0x50 Jul 26 09:15:27 kernel: __do_softirq+0xd1/0x2c1 Jul 26 09:15:27 kernel: irq_exit+0xae/0xb0 Jul 26 09:15:27 kernel: smp_apic_timer_interrupt+0x7b/0x140 Jul 26 09:15:27 kernel: apic_timer_interrupt+0xf/0x20 Jul 26 09:15:27 kernel: </IRQ> Jul 26 09:15:27 kernel: RIP: 0010:native_safe_halt+0xe/0x10 Jul 26 09:15:27 kernel: Code: 7b ff ff ff eb bd 90 90 90 90 90 90 e9 07 00 00 00 0f 00 2d 36 2c 50 00 f4 c3 66 90 e9 07 00 00 00 0f 00 2d 26 2c 50 00 fb f4 <c3> 90 0f 1f 44 00 00 55 48 89 e5 41 55 41 54 53 e8 dd 5e 61 ff 65 Jul 26 09:15:27 kernel: RSP: 0018:ffffb783801cfe70 EFLAGS: 00000246 ORIG_RAX: ffffffffffffff13 Jul 26 09:15:27 kernel: RAX: ffffffffa6908b20 RBX: 0000000000000010 RCX: 0000000000000001 Jul 26 09:15:27 kernel: RDX: 000000006fc0c97e RSI: 0000000000000082 RDI: 0000000000000082 Jul 26 09:15:27 kernel: RBP: ffffb783801cfe90 R08: 0000000000000000 R09: 0000000000000225 Jul 26 09:15:27 kernel: R10: 0000000000100000 R11: 0000000000000000 R12: 0000000000000010 Jul 26 09:15:27 kernel: R13: ffff9b8e390b0000 R14: 0000000000000000 R15: 0000000000000000 Jul 26 09:15:27 kernel: ? __cpuidle_text_start+0x8/0x8 Jul 26 09:15:27 kernel: ? default_idle+0x20/0x140 Jul 26 09:15:27 kernel: arch_cpu_idle+0x15/0x20 Jul 26 09:15:27 kernel: default_idle_call+0x23/0x30 Jul 26 09:15:27 kernel: do_idle+0x1fb/0x270 Jul 26 09:15:27 kernel: cpu_startup_entry+0x20/0x30 Jul 26 09:15:27 kernel: start_secondary+0x178/0x1d0 Jul 26 09:15:27 kernel: secondary_startup_64+0xa4/0xb0 Jul 26 09:15:27 kernel: ---[ end trace e7ac822987e33be1 ]---
The NULL ptr deref is coming from tcp_rto_delta_us() attempting to pull an skb off the head of the retransmit queue and then dereferencing that skb to get the skb_mstamp_ns value via tcp_skb_timestamp_us(skb).
The crash is the same one that was reported a # of years ago here:
https://lore.kernel.org/netdev/[email protected]/T/#t
and the kernel we're running has the fix which was added to resolve this issue.
Unfortunately we've been unsuccessful so far in reproducing this problem in the lab and do not have the luxury of pushing out a new kernel to try and test if newer kernels resolve this issue at the moment. I realize this is a report against both an Ubuntu kernel and also an older 5.4 kernel. I have reported this issue to Ubuntu here: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/2077657
however I feel like since this issue has possibly cropped up again it makes sense to build in some protection in this path (even on the latest kernel versions) since the code in question just blindly assumes there's a valid skb without testing if it's NULL b/f it looks at the timestamp.
Given we have seen crashes in this path before and now this case it seems like we should protect ourselves for when packets_out accounting is incorrect. While we should fix that root cause we should also just make sure the skb is not NULL before dereferencing it. Also add a warn once here to capture some information if/when the problem case is hit again.
--- include/net/tcp.h | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-)
include/net/tcp.h +19 -2
@@ -2123,9 +2123,26 @@ static inline s64 tcp_rto_delta_us(const struct sock *sk) {const struct sk_buff *skb =tcp_rtx_queue_head (sk);u32 rto =inet_csk (sk)->icsk_rto; -u64 rto_time_stamp_us =tcp_skb_timestamp_us (skb) +jiffies_to_usecs (rto); -return rto_time_stamp_us -tcp_sk (sk)->tcp_mstamp; +if (likely (skb)) { +u64 rto_time_stamp_us =tcp_skb_timestamp_us (skb) +jiffies_to_usecs (rto); + +return rto_time_stamp_us -tcp_sk (sk)->tcp_mstamp; + }else { +WARN_ONCE (1 , +"rtx queue emtpy: " +"out:%u sacked:%u lost:%u retrans:%u " +"tlp_high_seq:%u sk_state:%u ca_state:%u " +"advmss:%u mss_cache:%u pmtu:%u\n" , +tcp_sk (sk)->packets_out,tcp_sk (sk)->sacked_out, +tcp_sk (sk)->lost_out,tcp_sk (sk)->retrans_out, +tcp_sk (sk)->tlp_high_seq, sk->sk_state, +inet_csk (sk)->icsk_ca_state, +tcp_sk (sk)->advmss,tcp_sk (sk)->mss_cache, +inet_csk (sk)->icsk_pmtu_cookie); +return jiffies_to_usecs (rto); + } + }/*
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 295/691 net: qrtr: Update packets cloning when broadcasting
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Youssef Samir <[email protected]>
[ Upstream commit f011b313e8ebd5b7abd8521b5119aecef403de45 ]
When broadcasting data to multiple nodes via MHI, using skb_clone() causes all nodes to receive the same header data. This can result in packets being discarded by endpoints, leading to lost data.
This issue occurs when a socket is closed, and a QRTR_TYPE_DEL_CLIENT packet is broadcasted. All nodes receive the same destination node ID, causing the node connected to the client to discard the packet and remain unaware of the client's deletion.
Replace skb_clone() with pskb_copy(), to create a separate copy of the header for each sk_buff.
--- net/qrtr/af_qrtr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/qrtr/af_qrtr.c +1 -1
@@ -879,7 +879,7 @@ static int qrtr_bcast_enqueue(struct qrtr_node *node, struct sk_buff *skb,mutex_lock (&qrtr_node_lock);list_for_each_entry (node, &qrtr_all_nodes, item) { - skbn =skb_clone (skb,GFP_KERNEL ); + skbn =pskb_copy (skb,GFP_KERNEL );if (!skbn)break ;skb_set_owner_w (skbn, skb->sk);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 296/691 bonding: Fix unnecessary warnings and logs from bond_xdp_get_xmit_slave()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiwon Kim <[email protected]>
[ Upstream commit 0cbfd45fbcf0cb26d85c981b91c62fe73cdee01c ]
syzbot reported a WARNING in bond_xdp_get_xmit_slave. To reproduce this[1], one bond device (bond1) has xdpdrv, which increases bpf_master_redirect_enabled_key. Another bond device (bond0) which is unsupported by XDP but its slave (veth3) has xdpgeneric that returns XDP_TX. This triggers WARN_ON_ONCE() from the xdp_master_redirect(). To reduce unnecessary warnings and improve log management, we need to delete the WARN_ON_ONCE() and add ratelimit to the netdev_err().
[1] Steps to reproduce:
# Needs tx_xdp with return XDP_TX;
ip l add veth0 type veth peer veth1
ip l add veth3 type veth peer veth4
ip l add bond0 type bond mode 6 # BOND_MODE_ALB, unsupported by XDP ip l add bond1 type bond # BOND_MODE_ROUNDROBIN by default ip l set veth0 master bond1
ip l set bond1 up
# Increases bpf_master_redirect_enabled_key
ip l set dev bond1 xdpdrv object tx_xdp.o section xdp_tx ip l set veth3 master bond0
ip l set bond0 up
ip l set veth4 up
# Triggers WARN_ON_ONCE() from the xdp_master_redirect() ip l set veth3 xdpgeneric object tx_xdp.o section xdp_tx
--- drivers/net/bonding/bond_main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/net/bonding/bond_main.c +3 -3
@@ -5191,9 +5191,9 @@ bond_xdp_get_xmit_slave(struct net_device *bond_dev, struct xdp_buff *xdp)break ;default : -/* Should never happen. Mode guarded by bond_xdp_check() */ -netdev_err (bond_dev,"Unknown bonding mode %d for xdp xmit\n" ,BOND_MODE (bond)); -WARN_ON_ONCE (1 ); +if (net_ratelimit ()) +netdev_err (bond_dev,"Unknown bonding mode %d for xdp xmit\n" , +BOND_MODE (bond));return NULL ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 297/691 netfilter: nf_tables: Keep deleted flowtable hooks until after RCU
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Phil Sutter <[email protected]>
[ Upstream commit 642c89c475419b4d0c0d90e29d9c1a0e4351f379 ]
Documentation of list_del_rcu() warns callers to not immediately free the deleted list item. While it seems not necessary to use the RCU-variant of list_del() here in the first place, doing so seems to require calling kfree_rcu() on the deleted item as well.
--- net/netfilter/nf_tables_api.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/netfilter/nf_tables_api.c +1 -1
@@ -8434,7 +8434,7 @@ static void nf_tables_flowtable_destroy(struct nft_flowtable *flowtable) flowtable->data.type->setup (&flowtable->data, hook->ops.dev,FLOW_BLOCK_UNBIND );list_del_rcu (&hook->list); -kfree (hook); +kfree_rcu (hook, rcu); }kfree (flowtable->name);module_put (flowtable->data.type->owner);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 298/691 netfilter: ctnetlink: compile ctnetlink_label_size with CONFIG_NF_CONNTRACK_EVENTS
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Simon Horman <[email protected]>
[ Upstream commit e1f1ee0e9ad8cbe660f5c104e791c5f1a7cf4c31 ]
Only provide ctnetlink_label_size when it is used, which is when CONFIG_NF_CONNTRACK_EVENTS is configured.
Flagged by clang-18 W=1 builds as:
.../nf_conntrack_netlink.c:385:19: warning: unused function 'ctnetlink_label_size' [-Wunused-function]
385 | static inline int ctnetlink_label_size(const struct nf_conn *ct)
| ^~~~~~~~~~~~~~~~~~~~
The condition on CONFIG_NF_CONNTRACK_LABELS being removed by this patch guards compilation of non-trivial implementations of ctnetlink_dump_labels() and ctnetlink_label_size().
However, this is not necessary as each of these functions will always return 0 if CONFIG_NF_CONNTRACK_LABELS is not defined as each function starts with the equivalent of:
struct nf_conn_labels *labels = nf_ct_labels_find(ct); if (!labels) return 0;
And nf_ct_labels_find always returns NULL if CONFIG_NF_CONNTRACK_LABELS is not enabled. So I believe that the compiler optimises the code away in such cases anyway.
Found by inspection.
Compile tested only.
Originally splitted in two patches, Pablo Neira Ayuso collapsed them and added Fixes: tag.
--- net/netfilter/nf_conntrack_netlink.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
net/netfilter/nf_conntrack_netlink.c +2 -5
@@ -370,7 +370,7 @@ static int ctnetlink_dump_secctx(struct sk_buff *skb, const struct nf_conn *ct)#define ctnetlink_dump_secctx (a, b) (0)#endif -#ifdef CONFIG_NF_CONNTRACK_LABELS +#ifdef CONFIG_NF_CONNTRACK_EVENTS static inline int ctnetlink_label_size (const struct nf_conn *ct) {struct nf_conn_labels *labels =nf_ct_labels_find (ct);
@@ -379,6 +379,7 @@ static inline int ctnetlink_label_size(const struct nf_conn *ct)return 0 ; return nla_total_size(sizeof(labels->bits)); } +#endif static int ctnetlink_dump_labels (struct sk_buff *skb,const struct nf_conn *ct)
@@ -399,10 +400,6 @@ ctnetlink_dump_labels(struct sk_buff *skb, const struct nf_conn *ct)return 0 ; } -#else -#define ctnetlink_dump_labels (a, b) (0) -#define ctnetlink_label_size (a) (0) -#endif #define master_tuple (ct) &(ct->master->tuplehash[IP_CT_DIR_ORIGINAL].tuple)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 299/691 drm/amd/display: Fix Synaptics Cascaded Panamera DSC Determination
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fangzhi Zuo <[email protected]>
commit 4437936c6b696b98f3fe1d8679a2788c41b4df77 upstream.
Synaptics Cascaded Panamera topology needs to unconditionally acquire root aux for dsc decoding.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +1 -1
@@ -227,7 +227,7 @@ static bool validate_dsc_caps_on_connect aconnector->dsc_aux = &aconnector->mst_port->dm_dp_aux.aux;/* synaptics cascaded MST hub case */ -if (!aconnector->dsc_aux &&is_synaptics_cascaded_panamera (aconnector->dc_link, port)) +if (is_synaptics_cascaded_panamera (aconnector->dc_link, port)) aconnector->dsc_aux = port->mgr->aux;if (!aconnector->dsc_aux)
Greg Kroah-Hartman
maintainerPATCH 300/691 Input: goodix - use the new soc_intel_is_byt() helper
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans de Goede <[email protected]>
commit d176708ffc20332d1c730098d2b111e0b77ece82 upstream.
Use the new soc_intel_is_byt() helper from linux/platform_data/x86/soc.h.
--- drivers/input/touchscreen/goodix.c | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-)
drivers/input/touchscreen/goodix.c +2 -16
@@ -18,6 +18,7 @@#include <linux/delay.h> #include <linux/irq.h> #include <linux/interrupt.h> +#include <linux/platform_data/x86/soc.h> #include <linux/slab.h> #include <linux/acpi.h> #include <linux/of.h>
@@ -684,21 +685,6 @@ static int goodix_reset(struct goodix_ts }#ifdef ACPI_GPIO_SUPPORT -#include <asm/cpu_device_id.h> -#include <asm/intel-family.h> - -static const struct x86_cpu_id baytrail_cpu_ids[] = { - {X86_VENDOR_INTEL ,6 ,INTEL_FAM6_ATOM_SILVERMONT ,X86_FEATURE_ANY , }, - {} -}; - -static inline bool is_byt (void ) -{ -const struct x86_cpu_id *id =x86_match_cpu (baytrail_cpu_ids); - -return !!id; -} -static const struct acpi_gpio_params first_gpio = {0 ,0 , false };static const struct acpi_gpio_params second_gpio = {1 ,0 , false };
@@ -782,7 +768,7 @@ static int goodix_add_acpi_gpio_mappingsdev_info (dev,"Using ACPI INTI and INTO methods for IRQ pin access\n" ); ts->irq_pin_access_method =IRQ_PIN_ACCESS_ACPI_METHOD ; gpio_mapping = acpi_goodix_reset_only_gpios; - }else if (is_byt () && ts->gpio_count ==2 && ts->gpio_int_idx ==-1 ) { + }else if (soc_intel_is_byt () && ts->gpio_count ==2 && ts->gpio_int_idx ==-1 ) {dev_info (dev,"No ACPI GpioInt resource, assuming that the GPIO order is reset, int\n" ); ts->irq_pin_access_method =IRQ_PIN_ACCESS_ACPI_GPIO ; gpio_mapping = acpi_goodix_int_last_gpios;
Greg Kroah-Hartman
maintainerPATCH 301/691 powercap: RAPL: fix invalid initialization for pl4_supported field
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sumeet Pawnikar <[email protected]>
commit d05b5e0baf424c8c4b4709ac11f66ab726c8deaf upstream.
The current initialization of the struct x86_cpu_id via pl4_support_ids[] is partial and wrong. It is initializing "stepping" field with "X86_FEATURE_ANY" instead of "feature" field.
Use X86_MATCH_INTEL_FAM6_MODEL macro instead of initializing each field of the struct x86_cpu_id for pl4_supported list of CPUs. This X86_MATCH_INTEL_FAM6_MODEL macro internally uses another macro X86_MATCH_VENDOR_FAM_MODEL_FEATURE for X86 based CPU matching with appropriate initialized values.
[ Ricardo: I only kept TIGERLAKE, ALDERLAKE, and ALDERLAKE_L in
pl4_support_ids as only these models are enumerated before this changeset. ]
--- drivers/powercap/intel_rapl_msr.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/powercap/intel_rapl_msr.c +3 -3
@@ -136,9 +136,9 @@ static int rapl_msr_write_raw(int cpu, s/* List of verified CPUs. */ static const struct x86_cpu_id pl4_support_ids[] = { - {X86_VENDOR_INTEL ,6 ,INTEL_FAM6_TIGERLAKE_L ,X86_FEATURE_ANY }, - {X86_VENDOR_INTEL ,6 ,INTEL_FAM6_ALDERLAKE ,X86_FEATURE_ANY }, - {X86_VENDOR_INTEL ,6 ,INTEL_FAM6_ALDERLAKE_L ,X86_FEATURE_ANY }, +X86_MATCH_INTEL_FAM6_MODEL (TIGERLAKE_L ,NULL ), +X86_MATCH_INTEL_FAM6_MODEL (ALDERLAKE ,NULL ), +X86_MATCH_INTEL_FAM6_MODEL (ALDERLAKE_L ,NULL ), {} };
Greg Kroah-Hartman
maintainerPATCH 302/691 x86/mm: Switch to new Intel CPU model defines
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tony Luck <[email protected]>
commit 2eda374e883ad297bd9fe575a16c1dc850346075 upstream.
New CPU #defines encode vendor and family as well as model.
[ dhansen: vertically align 0's in invlpg_miss_ids[] ]
[ Ricardo: I used the old match macro X86_MATCH_INTEL_FAM6_MODEL()
instead of X86_MATCH_VFM() as in the upstream commit.
I also kept the ALDERLAKE_N name instead of ATOM_GRACEMONT. Both refer to the same CPU model. ]
--- arch/x86/mm/init.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-)
arch/x86/mm/init.c +6 -10
@@ -263,21 +263,17 @@ static void __init probe_page_size_mask( } } -#define INTEL_MATCH (_model) { .vendor = X86_VENDOR_INTEL, \ - .family = 6, \ - .model = _model, \ - }/* * INVLPG may not properly flush Global entries * on these CPUs when PCIDs are enabled. */ static const struct x86_cpu_id invlpg_miss_ids[] = { -INTEL_MATCH (INTEL_FAM6_ALDERLAKE ), -INTEL_MATCH (INTEL_FAM6_ALDERLAKE_L ), -INTEL_MATCH (INTEL_FAM6_ALDERLAKE_N ), -INTEL_MATCH (INTEL_FAM6_RAPTORLAKE ), -INTEL_MATCH (INTEL_FAM6_RAPTORLAKE_P ), -INTEL_MATCH (INTEL_FAM6_RAPTORLAKE_S ), +X86_MATCH_INTEL_FAM6_MODEL (ALDERLAKE ,0 ), +X86_MATCH_INTEL_FAM6_MODEL (ALDERLAKE_L ,0 ), +X86_MATCH_INTEL_FAM6_MODEL (ALDERLAKE_N ,0 ), +X86_MATCH_INTEL_FAM6_MODEL (RAPTORLAKE ,0 ), +X86_MATCH_INTEL_FAM6_MODEL (RAPTORLAKE_P ,0 ), +X86_MATCH_INTEL_FAM6_MODEL (RAPTORLAKE_S ,0 ), {} };
Greg Kroah-Hartman
maintainerPATCH 303/691 vfio/pci: fix potential memory leak in vfio_intx_enable()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ye Bin <[email protected]>
commit 82b951e6fbd31d85ae7f4feb5f00ddd4c5d256e2 upstream.
If vfio_irq_ctx_alloc() failed will lead to 'name' memory leak.
--- drivers/vfio/pci/vfio_pci_intrs.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/vfio/pci/vfio_pci_intrs.c +3 -1
@@ -181,8 +181,10 @@ static int vfio_intx_enable(struct vfio_return -ENOMEM ; vdev->ctx =kzalloc (sizeof (struct vfio_pci_irq_ctx ),GFP_KERNEL ); -if (!vdev->ctx) +if (!vdev->ctx) { +kfree (name);return -ENOMEM ; + } vdev->num_ctx =1 ;
Greg Kroah-Hartman
maintainerPATCH 304/691 selinux,smack: dont bypass permissions check in inode_setsecctx hook
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Scott Mayhew <[email protected]>
commit 76a0e79bc84f466999fa501fce5bf7a07641b8a7 upstream.
Marek Gresko reports that the root user on an NFS client is able to change the security labels on files on an NFS filesystem that is exported with root squashing enabled.
The end of the kerneldoc comment for __vfs_setxattr_noperm() states:
* This function requires the caller to lock the inode's i_mutex before it * is executed. It also assumes that the caller will make the appropriate * permission checks.
nfsd_setattr() does do permissions checking via fh_verify() and nfsd_permission(), but those don't do all the same permissions checks that are done by security_inode_setxattr() and its related LSM hooks do.
Since nfsd_setattr() is the only consumer of security_inode_setsecctx(), simplest solution appears to be to replace the call to __vfs_setxattr_noperm() with a call to __vfs_setxattr_locked(). This fixes the above issue and has the added benefit of causing nfsd to recall conflicting delegations on a file when a client tries to change its security label.
--- security/selinux/hooks.c | 4 ++-- security/smack/smack_lsm.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-)
security/selinux/hooks.c +2 -2
@@ -6727,8 +6727,8 @@ static int selinux_inode_notifysecctx(st*/ static int selinux_inode_setsecctx (struct dentry *dentry,void *ctx,u32 ctxlen) { -return __vfs_setxattr_noperm (&init_user_ns, dentry,XATTR_NAME_SELINUX , - ctx, ctxlen,0 ); +return __vfs_setxattr_locked (&init_user_ns, dentry,XATTR_NAME_SELINUX , + ctx, ctxlen,0 ,NULL ); }static int selinux_inode_getsecctx (struct inode *inode,void **ctx,u32 *ctxlen)
security/smack/smack_lsm.c +2 -2
@@ -4649,8 +4649,8 @@ static int smack_inode_notifysecctx(strustatic int smack_inode_setsecctx (struct dentry *dentry,void *ctx,u32 ctxlen) { -return __vfs_setxattr_noperm (&init_user_ns, dentry,XATTR_NAME_SMACK , - ctx, ctxlen,0 ); +return __vfs_setxattr_locked (&init_user_ns, dentry,XATTR_NAME_SMACK , + ctx, ctxlen,0 ,NULL ); }static int smack_inode_getsecctx (struct inode *inode,void **ctx,u32 *ctxlen)
Greg Kroah-Hartman
maintainerPATCH 305/691 Remove *.orig pattern from .gitignore
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Laurent Pinchart <[email protected]>
commit 76be4f5a784533c71afbbb1b8f2963ef9e2ee258 upstream.
Commit 3f1b0e1f2875 (".gitignore update") added *.orig and *.rej patterns to .gitignore in v2.6.23. The commit message didn't give a rationale. Later on, commit 1f5d3a6b6532 ("Remove *.rej pattern from .gitignore") removed the *.rej pattern in v2.6.26, on the rationale that *.rej files indicated something went really wrong and should not be ignored.
The *.rej files are now shown by git status, which helps located conflicts when applying patches and lowers the probability that they will go unnoticed. It is however still easy to overlook the *.orig files which slowly polute the source tree. That's not as big of a deal as not noticing a conflict, but it's still not nice.
Drop the *.orig pattern from .gitignore to avoid this and help keep the source tree clean.
[[email protected]:
I do not have a strong opinion about this. Perhaps some people may have a different opinion.
If you are someone who wants to ignore *.orig, it is likely you would want to do so across all projects. Then, $XDG_CONFIG_HOME/git/ignore would be more suitable for your needs. gitignore(5) suggests, "Patterns which a user wants Git to ignore in all situations generally go into a file specified by core.excludesFile in the user's ~/.gitconfig".
Please note that you cannot do the opposite; if *.orig is ignored by the project's .gitignore, you cannot override the decision because $XDG_CONFIG_HOME/git/ignore has a lower priority.
If *.orig is sitting on the fence, I'd leave it to the users. ]
--- .gitignore | 1 - 1 file changed, 1 deletion(-)
.gitignore +0 -1
@@ -129,7 +129,6 @@ GTAGS # id-utils files ID -*.orig *~ \#*#
Greg Kroah-Hartman
maintainerPATCH 306/691 PCI: xilinx-nwl: Fix off-by-one in INTx IRQ handler
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Anderson <[email protected]>
commit 0199d2f2bd8cd97b310f7ed82a067247d7456029 upstream.
MSGF_LEG_MASK is laid out with INTA in bit 0, INTB in bit 1, INTC in bit 2, and INTD in bit 3. Hardware IRQ numbers start at 0, and we register PCI_NUM_INTX IRQs. So to enable INTA (aka hwirq 0) we should set bit 0. Remove the subtraction of one.
This bug would cause INTx interrupts not to be delivered, as enabling INTB would actually enable INTA, and enabling INTA wouldn't enable anything at all. It is likely that this got overlooked for so long since most PCIe hardware uses MSIs. This fixes the following UBSAN error:
UBSAN: shift-out-of-bounds in ../drivers/pci/controller/pcie-xilinx-nwl.c:389:11 shift exponent 18446744073709551615 is too large for 32-bit type 'int' CPU: 1 PID: 61 Comm: kworker/u10:1 Not tainted 6.6.20+ #268 Hardware name: xlnx,zynqmp (DT) Workqueue: events_unbound deferred_probe_work_func Call trace: dump_backtrace (arch/arm64/kernel/stacktrace.c:235) show_stack (arch/arm64/kernel/stacktrace.c:242) dump_stack_lvl (lib/dump_stack.c:107) dump_stack (lib/dump_stack.c:114) __ubsan_handle_shift_out_of_bounds (lib/ubsan.c:218 lib/ubsan.c:387) nwl_unmask_leg_irq (drivers/pci/controller/pcie-xilinx-nwl.c:389 (discriminator 1)) irq_enable (kernel/irq/internals.h:234 kernel/irq/chip.c:170 kernel/irq/chip.c:439 kernel/irq/chip.c:432 kernel/irq/chip.c:345) __irq_startup (kernel/irq/internals.h:239 kernel/irq/chip.c:180 kernel/irq/chip.c:250) irq_startup (kernel/irq/chip.c:270) __setup_irq (kernel/irq/manage.c:1800) request_threaded_irq (kernel/irq/manage.c:2206) pcie_pme_probe (include/linux/interrupt.h:168 drivers/pci/pcie/pme.c:348)
--- drivers/pci/controller/pcie-xilinx-nwl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/pci/controller/pcie-xilinx-nwl.c +2 -2
@@ -376,7 +376,7 @@ static void nwl_mask_leg_irq(struct irq_u32 mask;u32 val; - mask =1 << (data->hwirq -1 ); + mask =1 << data->hwirq;raw_spin_lock_irqsave (&pcie->leg_mask_lock, flags); val =nwl_bridge_readl (pcie,MSGF_LEG_MASK );nwl_bridge_writel (pcie, (val & (~mask)),MSGF_LEG_MASK );
@@ -390,7 +390,7 @@ static void nwl_unmask_leg_irq(struct iru32 mask;u32 val; - mask =1 << (data->hwirq -1 ); + mask =1 << data->hwirq;raw_spin_lock_irqsave (&pcie->leg_mask_lock, flags); val =nwl_bridge_readl (pcie,MSGF_LEG_MASK );nwl_bridge_writel (pcie, (val | mask),MSGF_LEG_MASK );
Greg Kroah-Hartman
maintainerPATCH 307/691 ASoC: rt5682: Return devm_of_clk_add_hw_provider to transfer the error
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ma Ke <[email protected]>
commit fcca6d05ef49d5650514ea1dcfd12e4ae3ff2be6 upstream.
Return devm_of_clk_add_hw_provider() in order to transfer the error, if it fails due to resource allocation failure or device tree clock provider registration failure.
--- sound/soc/codecs/rt5682.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
sound/soc/codecs/rt5682.c +3 -1
@@ -2893,8 +2893,10 @@ int rt5682_register_dai_clks(struct rt56 }if (dev->of_node) { -devm_of_clk_add_hw_provider (dev, of_clk_hw_simple_get, + ret =devm_of_clk_add_hw_provider (dev, of_clk_hw_simple_get, dai_clk_hw); +if (ret) +return ret; }else { ret = devm_clk_hw_register_clkdev(dev, dai_clk_hw, init.name,
Greg Kroah-Hartman
maintainerPATCH 308/691 soc: versatile: integrator: fix OF node leak in probe() error path
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Kozlowski <[email protected]>
commit 874c5b601856adbfda10846b9770a6c66c41e229 upstream.
Driver is leaking OF node reference obtained fromof_find_matching_node().
--- drivers/soc/versatile/soc-integrator.c | 1 + 1 file changed, 1 insertion(+)
drivers/soc/versatile/soc-integrator.c +1 -0
@@ -113,6 +113,7 @@ static int __init integrator_soc_init(voreturn -ENODEV ; syscon_regmap =syscon_node_to_regmap (np); +of_node_put (np);if (IS_ERR (syscon_regmap))return PTR_ERR (syscon_regmap);
Greg Kroah-Hartman
maintainerPATCH 309/691 Revert "media: tuners: fix error return code of hybrid_tuner_request_state()"
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Roman Smirnov <[email protected]>
commit e25cc4be4616fcf5689622b3226d648aab253cdb upstream.
This reverts commit b9302fa7ed979e84b454e4ca92192cf485a4ed41.
As Fedor Pchelkin pointed out, this commit violates the convention of using the macro return value, which causes errors. For example, in functions tda18271_attach(), xc5000_attach(), simple_tuner_attach().
--- drivers/media/tuners/tuner-i2c.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
drivers/media/tuners/tuner-i2c.h +1 -3
@@ -133,10 +133,8 @@ static inline int tuner_i2c_xfer_send_re } \if (0 == __ret) { \ state =kzalloc (sizeof (type),GFP_KERNEL ); \ -if (!state) { \ - __ret = -ENOMEM ; \ +if (NULL == state) \ goto __fail; \ - } \ state->i2c_props.addr = i2caddr; \ state->i2c_props.adap = i2cadap; \ state->i2c_props.name = devname; \
Greg Kroah-Hartman
maintainerPATCH 310/691 Input: i8042 - add TUXEDO Stellaris 16 Gen5 AMD to i8042 quirk table
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Werner Sembach <[email protected]>
commit e06edf96dea065dd1d9df695bf8b92784992333e upstream.
Some TongFang barebones have touchpad and/or keyboard issues after suspend, fixable with nomux + reset + noloop + nopnp. Luckily, none of them have an external PS/2 port so this can safely be set for all of them.
I'm not entirely sure if every device listed really needs all four quirks, but after testing and production use, no negative effects could be observed when setting all four.
--- drivers/input/serio/i8042-acpipnpio.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
drivers/input/serio/i8042-acpipnpio.h +23 -0
@@ -1111,6 +1111,29 @@ static const struct dmi_system_id i8042_ .driver_data = (void *)(SERIO_QUIRK_NOLOOP) },/* +* Some TongFang barebones have touchpad and/or keyboard issues after +* suspend fixable with nomux + reset + noloop + nopnp. Luckily, none of +* them have an external PS/2 port so this can safely be set for all of +* them. +* TongFang barebones come with board_vendor and/or system_vendor set to +* a different value for each individual reseller. The only somewhat +* universal way to identify them is by board_name. +*/ + { + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "GM6XGxX"), + }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX |SERIO_QUIRK_RESET_ALWAYS | +SERIO_QUIRK_NOLOOP |SERIO_QUIRK_NOPNP ) + }, + { + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "GMxXGxX"), + }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX |SERIO_QUIRK_RESET_ALWAYS | +SERIO_QUIRK_NOLOOP |SERIO_QUIRK_NOPNP ) + }, +/* * A lot of modern Clevo barebones have touchpad and/or keyboard issues * after suspend fixable with nomux + reset + noloop + nopnp. Luckily, * none of them have an external PS/2 port so this can safely be set for
Greg Kroah-Hartman
maintainerPATCH 311/691 Input: i8042 - add TUXEDO Stellaris 15 Slim Gen6 AMD to i8042 quirk table
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Werner Sembach <[email protected]>
commit 3870e2850b56306d1d1e435c5a1ccbccd7c59291 upstream.
The Gen6 devices have the same problem and the same Solution as the Gen5 ones.
Some TongFang barebones have touchpad and/or keyboard issues after suspend, fixable with nomux + reset + noloop + nopnp. Luckily, none of them have an external PS/2 port so this can safely be set for all of them.
I'm not entirely sure if every device listed really needs all four quirks, but after testing and production use, no negative effects could be observed when setting all four.
--- drivers/input/serio/i8042-acpipnpio.h | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/input/serio/i8042-acpipnpio.h +7 -0
@@ -1133,6 +1133,13 @@ static const struct dmi_system_id i8042_ .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) }, + { + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "GMxHGxx"), + }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | + SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) + }, /* * A lot of modern Clevo barebones have touchpad and/or keyboard issues * after suspend fixable with nomux + reset + noloop + nopnp. Luckily,
Greg Kroah-Hartman
maintainerPATCH 312/691 Input: i8042 - add another board name for TUXEDO Stellaris Gen5 AMD line
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Werner Sembach <[email protected]>
commit 01eed86d50af9fab27d876fd677b86259ebe9de3 upstream.
There might be devices out in the wild where the board name is GMxXGxx instead of GMxXGxX.
Adding both to be on the safe side.
--- drivers/input/serio/i8042-acpipnpio.h | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/input/serio/i8042-acpipnpio.h +7 -0
@@ -1128,6 +1128,13 @@ static const struct dmi_system_id i8042_ }, { .matches = { + DMI_MATCH(DMI_BOARD_NAME, "GMxXGxx"), + }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX |SERIO_QUIRK_RESET_ALWAYS | +SERIO_QUIRK_NOLOOP |SERIO_QUIRK_NOPNP ) + }, + { + .matches = { DMI_MATCH(DMI_BOARD_NAME, "GMxXGxX"), }, .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
Greg Kroah-Hartman
maintainerPATCH 313/691 drm/amd/display: Round calculated vtotal
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Robin Chen <[email protected]>
commit c03fca619fc687338a3b6511fdbed94096abdf79 upstream.
[WHY]
The calculated vtotal may has 1 line deviation. To get precisely vtotal number, round the vtotal result.
--- drivers/gpu/drm/amd/display/modules/freesync/freesync.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/display/modules/freesync/freesync.c +1 -1
@@ -131,7 +131,7 @@ unsigned int mod_freesync_calc_v_total_f v_total =div64_u64 (div64_u64 (((unsigned long long )( frame_duration_in_ns) * (stream->timing.pix_clk_100hz /10 )), - stream->timing.h_total),1000000 ); + stream->timing.h_total) +500000 ,1000000 );/* v_total cannot be less than nominal */ if (v_total < stream->timing.v_total) {
Greg Kroah-Hartman
maintainerPATCH 314/691 drm/amd/display: Validate backlight caps are sane
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mario Limonciello <[email protected]>
commit 327e62f47eb57ae5ff63de82b0815557104e439a upstream.
Currently amdgpu takes backlight caps provided by the ACPI tables on systems as is. If the firmware sets maximums that are too low this means that users don't get a good experience.
To avoid having to maintain a quirk list of such systems, do a sanity check on the values. Check that the spread is at least half of the values that amdgpu would use if no ACPI table was found and if not use the amdgpu defaults.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +16 -0
@@ -3906,6 +3906,7 @@ static int amdgpu_dm_mode_config_init(st#define AMDGPU_DM_DEFAULT_MIN_BACKLIGHT 12#define AMDGPU_DM_DEFAULT_MAX_BACKLIGHT 255 +#define AMDGPU_DM_MIN_SPREAD ((AMDGPU_DM_DEFAULT_MAX_BACKLIGHT - AMDGPU_DM_DEFAULT_MIN_BACKLIGHT) / 2)#define AUX_BL_DEFAULT_TRANSITION_TIME_MS 50 #if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) ||\
@@ -3923,6 +3924,21 @@ static void amdgpu_dm_update_backlight_creturn ;amdgpu_acpi_get_backlight_caps (&caps); + +/* validate the firmware value is sane */ +if (caps.caps_valid) { +int spread = caps.max_input_signal - caps.min_input_signal; + +if (caps.max_input_signal >AMDGPU_DM_DEFAULT_MAX_BACKLIGHT || + caps.min_input_signal <AMDGPU_DM_DEFAULT_MIN_BACKLIGHT || + spread >AMDGPU_DM_DEFAULT_MAX_BACKLIGHT || + spread <AMDGPU_DM_MIN_SPREAD ) { +DRM_DEBUG_KMS ("DM: Invalid backlight caps: min=%d, max=%d\n" , + caps.min_input_signal, caps.max_input_signal); + caps.caps_valid = false; + } + } +if (caps.caps_valid) { dm->backlight_caps[bl_idx].caps_valid = true;if (caps.aux_support)
Greg Kroah-Hartman
maintainerPATCH 315/691 scsi: mac_scsi: Revise printk(KERN_DEBUG ...) messages
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Finn Thain <[email protected]>
commit 5ec4f820cb9766e4583df947150a6febce8da794 upstream.
After a bus fault, capture and log the chip registers immediately, if the NDEBUG_PSEUDO_DMA macro is defined. Remove some printk(KERN_DEBUG ...) messages that aren't needed any more. Don't skip the debug message when bytes == 0. Show all of the byte counters in the debug messages.
--- drivers/scsi/mac_scsi.c | 42 +++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-)
drivers/scsi/mac_scsi.c +22 -20
@@ -286,13 +286,14 @@ static inline int macscsi_pread(struct NCR5380_hostdata *hostdata,while (!NCR5380_poll_politely (hostdata,BUS_AND_STATUS_REG ,BASR_DRQ |BASR_PHASE_MATCH ,BASR_DRQ |BASR_PHASE_MATCH ,0 )) { -int bytes; +int bytes, chunk_bytes;if (macintosh_config->ident ==MAC_MODEL_IIFX )write_ctrl_reg (hostdata,CTRL_HANDSHAKE_MODE |CTRL_INTERRUPTS_ENABLE ); - bytes =mac_pdma_recv (s, d,min (hostdata->pdma_residual,512 )); + chunk_bytes =min (hostdata->pdma_residual,512 ); + bytes =mac_pdma_recv (s, d, chunk_bytes);if (bytes >0 ) { d += bytes;
@@ -302,23 +303,23 @@ static inline int macscsi_pread(struct NCR5380_hostdata *hostdata,if (hostdata->pdma_residual ==0 ) goto out; -if (NCR5380_poll_politely2 (hostdata,STATUS_REG ,SR_REQ ,SR_REQ , -BUS_AND_STATUS_REG ,BASR_ACK , -BASR_ACK ,0 ) <0 ) -scmd_printk (KERN_DEBUG , hostdata->connected, -"%s: !REQ and !ACK\n" , __func__);if (!(NCR5380_read (BUS_AND_STATUS_REG ) &BASR_PHASE_MATCH )) goto out;if (bytes ==0 )udelay (MAC_PDMA_DELAY ); -if (bytes >=0 ) +if (bytes >0 )continue ; -dsprintk (NDEBUG_PSEUDO_DMA , hostdata->host, -"%s: bus error (%d/%d)\n" , __func__, d - dst, len);NCR5380_dprint (NDEBUG_PSEUDO_DMA , hostdata->host); +dsprintk (NDEBUG_PSEUDO_DMA , hostdata->host, +"%s: bus error [%d/%d] (%d/%d)\n" , + __func__, d - dst, len, bytes, chunk_bytes); + +if (bytes ==0 ) +continue ; + result =-1 ; goto out; }
@@ -345,13 +346,14 @@ static inline int macscsi_pwrite(struct NCR5380_hostdata *hostdata,while (!NCR5380_poll_politely (hostdata,BUS_AND_STATUS_REG ,BASR_DRQ |BASR_PHASE_MATCH ,BASR_DRQ |BASR_PHASE_MATCH ,0 )) { -int bytes; +int bytes, chunk_bytes;if (macintosh_config->ident ==MAC_MODEL_IIFX )write_ctrl_reg (hostdata,CTRL_HANDSHAKE_MODE |CTRL_INTERRUPTS_ENABLE ); - bytes =mac_pdma_send (s, d,min (hostdata->pdma_residual,512 )); + chunk_bytes =min (hostdata->pdma_residual,512 ); + bytes =mac_pdma_send (s, d, chunk_bytes);if (bytes >0 ) { s += bytes;
@@ -370,23 +372,23 @@ static inline int macscsi_pwrite(struct NCR5380_hostdata *hostdata, goto out; } -if (NCR5380_poll_politely2 (hostdata,STATUS_REG ,SR_REQ ,SR_REQ , -BUS_AND_STATUS_REG ,BASR_ACK , -BASR_ACK ,0 ) <0 ) -scmd_printk (KERN_DEBUG , hostdata->connected, -"%s: !REQ and !ACK\n" , __func__);if (!(NCR5380_read (BUS_AND_STATUS_REG ) &BASR_PHASE_MATCH )) goto out;if (bytes ==0 )udelay (MAC_PDMA_DELAY ); -if (bytes >=0 ) +if (bytes >0 )continue ; -dsprintk (NDEBUG_PSEUDO_DMA , hostdata->host, -"%s: bus error (%d/%d)\n" , __func__, s - src, len);NCR5380_dprint (NDEBUG_PSEUDO_DMA , hostdata->host); +dsprintk (NDEBUG_PSEUDO_DMA , hostdata->host, +"%s: bus error [%d/%d] (%d/%d)\n" , + __func__, s - src, len, bytes, chunk_bytes); + +if (bytes ==0 ) +continue ; + result =-1 ; goto out; }
Signature · 1 line
2.46.2
Greg Kroah-Hartman
maintainerPATCH 316/691 scsi: mac_scsi: Refactor polling loop
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Finn Thain <[email protected]>
commit 5545c3165cbc98615fe65a44f41167cbb557e410 upstream.
Before the error handling can be revised, some preparation is needed. Refactor the polling loop with a new function, macscsi_wait_for_drq(). This function will gain more call sites in the next patch.
--- drivers/scsi/mac_scsi.c | 80 +++++++++++++++++++++-------------------- 1 file changed, 42 insertions(+), 38 deletions(-)
drivers/scsi/mac_scsi.c +42 -38
@@ -208,8 +208,6 @@ __setup("mac5380=", mac_scsi_setup);".previous \n" \ : "+a" (addr), "+r" (n), "+r" (result) : "a" (io)) -#define MAC_PDMA_DELAY 32 - static inline int mac_pdma_recv(void __iomem *io, unsigned char *start, int n) {unsigned char *addr = start;
@@ -274,6 +272,36 @@ static inline void write_ctrl_reg(struct NCR5380_hostdata *hostdata, u32 value)out_be32 (hostdata->io + (CTRL_REG <<4 ), value); } +static inline int macscsi_wait_for_drq (struct NCR5380_hostdata *hostdata) +{ +unsigned int n =1 ;/* effectively multiplies NCR5380_REG_POLL_TIME */ +unsigned char basr; + +again: + basr =NCR5380_read (BUS_AND_STATUS_REG ); + +if (!(basr &BASR_PHASE_MATCH )) +return 1 ; + +if (basr &BASR_IRQ ) +return -1 ; + +if (basr &BASR_DRQ ) +return 0 ; + +if (n-- ==0 ) { +NCR5380_dprint (NDEBUG_PSEUDO_DMA , hostdata->host); +dsprintk (NDEBUG_PSEUDO_DMA , hostdata->host, +"%s: DRQ timeout\n" , __func__); +return -1 ; + } + +NCR5380_poll_politely2 (hostdata, +BUS_AND_STATUS_REG ,BASR_DRQ ,BASR_DRQ , +BUS_AND_STATUS_REG ,BASR_PHASE_MATCH ,0 ,0 ); + goto again; +} +static inline int macscsi_pread (struct NCR5380_hostdata *hostdata,unsigned char *dst,int len) {
@@ -283,9 +311,7 @@ static inline int macscsi_pread(struct NCR5380_hostdata *hostdata, hostdata->pdma_residual = len; -while (!NCR5380_poll_politely (hostdata,BUS_AND_STATUS_REG , -BASR_DRQ |BASR_PHASE_MATCH , -BASR_DRQ |BASR_PHASE_MATCH ,0 )) { +while (macscsi_wait_for_drq (hostdata) ==0 ) {int bytes, chunk_bytes;if (macintosh_config->ident ==MAC_MODEL_IIFX )
@@ -295,19 +321,16 @@ static inline int macscsi_pread(struct NCR5380_hostdata *hostdata, chunk_bytes =min (hostdata->pdma_residual,512 ); bytes =mac_pdma_recv (s, d, chunk_bytes); +if (macintosh_config->ident ==MAC_MODEL_IIFX ) +write_ctrl_reg (hostdata,CTRL_INTERRUPTS_ENABLE ); +if (bytes >0 ) { d += bytes; hostdata->pdma_residual -= bytes; }if (hostdata->pdma_residual ==0 ) - goto out; - -if (!(NCR5380_read (BUS_AND_STATUS_REG ) &BASR_PHASE_MATCH )) - goto out; - -if (bytes ==0 ) -udelay (MAC_PDMA_DELAY ); +break ;if (bytes >0 )continue ;
@@ -321,16 +344,9 @@ static inline int macscsi_pread(struct NCR5380_hostdata *hostdata,continue ; result =-1 ; - goto out; +break ; } -scmd_printk (KERN_ERR , hostdata->connected, -"%s: phase mismatch or !DRQ\n" , __func__); -NCR5380_dprint (NDEBUG_PSEUDO_DMA , hostdata->host); - result =-1 ; -out: -if (macintosh_config->ident ==MAC_MODEL_IIFX ) -write_ctrl_reg (hostdata,CTRL_INTERRUPTS_ENABLE );return result; }
@@ -343,9 +359,7 @@ static inline int macscsi_pwrite(struct NCR5380_hostdata *hostdata, hostdata->pdma_residual = len; -while (!NCR5380_poll_politely (hostdata,BUS_AND_STATUS_REG , -BASR_DRQ |BASR_PHASE_MATCH , -BASR_DRQ |BASR_PHASE_MATCH ,0 )) { +while (macscsi_wait_for_drq (hostdata) ==0 ) {int bytes, chunk_bytes;if (macintosh_config->ident ==MAC_MODEL_IIFX )
@@ -355,6 +369,9 @@ static inline int macscsi_pwrite(struct NCR5380_hostdata *hostdata, chunk_bytes =min (hostdata->pdma_residual,512 ); bytes =mac_pdma_send (s, d, chunk_bytes); +if (macintosh_config->ident ==MAC_MODEL_IIFX ) +write_ctrl_reg (hostdata,CTRL_INTERRUPTS_ENABLE ); +if (bytes >0 ) { s += bytes; hostdata->pdma_residual -= bytes;
@@ -369,15 +386,9 @@ static inline int macscsi_pwrite(struct NCR5380_hostdata *hostdata, "%s: Last Byte Sent timeout\n", __func__); result =-1 ; } - goto out; +break ; } -if (!(NCR5380_read (BUS_AND_STATUS_REG ) &BASR_PHASE_MATCH )) - goto out; - -if (bytes ==0 ) -udelay (MAC_PDMA_DELAY ); -if (bytes >0 )continue ;
@@ -390,16 +401,9 @@ static inline int macscsi_pwrite(struct NCR5380_hostdata *hostdata,continue ; result =-1 ; - goto out; +break ; } -scmd_printk (KERN_ERR , hostdata->connected, -"%s: phase mismatch or !DRQ\n" , __func__); -NCR5380_dprint (NDEBUG_PSEUDO_DMA , hostdata->host); - result =-1 ; -out: -if (macintosh_config->ident ==MAC_MODEL_IIFX ) -write_ctrl_reg (hostdata,CTRL_INTERRUPTS_ENABLE );return result; }
Signature · 1 line
2.46.2
Greg Kroah-Hartman
maintainerPATCH 317/691 scsi: mac_scsi: Disallow bus errors during PDMA send
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Finn Thain <[email protected]>
commit 5551bc30e4a69ad86d0d008e2f56cd59b6583476 upstream.
SD cards can produce write latency spikes on the order of a hundred milliseconds. If the target firmware does not hide that latency during DATA IN and OUT phases it can cause the PDMA circuitry to raise a processor bus fault which in turn leads to an unreliable byte count and a DMA overrun.
The Last Byte Sent flag is used to detect the overrun but this mechanism is unreliable on some systems. Instead, set a DID_ERROR result whenever there is a bus fault during a PDMA send, unless the cause was a phase mismatch.
--- drivers/scsi/mac_scsi.c | 44 +++++++++++++++++++------------------------- 1 file changed, 19 insertions(+), 25 deletions(-)
drivers/scsi/mac_scsi.c +19 -25
@@ -102,11 +102,15 @@ __setup("mac5380=", mac_scsi_setup);* Linux SCSI drivers lack knowledge of the timing behaviour of SCSI targets * so bus errors are unavoidable. * -* If a MOVE.B instruction faults, we assume that zero bytes were transferred -* and simply retry. That assumption probably depends on target behaviour but -* seems to hold up okay. The NOP provides synchronization: without it the -* fault can sometimes occur after the program counter has moved past the -* offending instruction. Post-increment addressing can't be used. +* If a MOVE.B instruction faults during a receive operation, we assume the +* target sent nothing and try again. That assumption probably depends on +* target firmware but it seems to hold up okay. If a fault happens during a +* send operation, the target may or may not have seen /ACK and got the byte. +* It's uncertain so the whole SCSI command gets retried. +* +* The NOP is needed for synchronization because the fault address in the +* exception stack frame may or may not be the instruction that actually +* caused the bus error. Post-increment addressing can't be used. */ #define MOVE_BYTE (operands) \
@@ -243,22 +247,21 @@ static inline int mac_pdma_send(unsignedif (n >=1 ) {MOVE_BYTE ("%0@,%3@" );if (result) - goto out; +return -1 ; }if (n >=1 && ((unsigned long )addr &1 )) {MOVE_BYTE ("%0@,%3@" );if (result) - goto out; +return -2 ; }while (n >=32 )MOVE_16_WORDS ("%0@+,%3@" );while (n >=2 )MOVE_WORD ("%0@+,%3@" );if (result) -return start - addr;/* Negated to indicate uncertain length */ +return start - addr -1 ;/* Negated to indicate uncertain length */ if (n ==1 )MOVE_BYTE ("%0@,%3@" ); -out:return addr - start; }
@@ -307,7 +310,6 @@ static inline int macscsi_pread(struct N {u8 __iomem *s = hostdata->pdma_io + (INPUT_DATA_REG <<4 );unsigned char *d = dst; -int result =0 ; hostdata->pdma_residual = len;
@@ -343,11 +345,12 @@ static inline int macscsi_pread(struct Nif (bytes ==0 )continue ; - result =-1 ; +if (macscsi_wait_for_drq (hostdata) <=0 ) +set_host_byte (hostdata->connected,DID_ERROR );break ; } -return result; +return 0 ; } static inline int macscsi_pwrite(struct NCR5380_hostdata *hostdata,
@@ -355,7 +358,6 @@ static inline int macscsi_pwrite(struct {unsigned char *s = src;u8 __iomem *d = hostdata->pdma_io + (OUTPUT_DATA_REG <<4 ); -int result =0 ; hostdata->pdma_residual = len;
@@ -377,17 +379,8 @@ static inline int macscsi_pwrite(struct hostdata->pdma_residual -= bytes; } -if (hostdata->pdma_residual ==0 ) { -if (NCR5380_poll_politely (hostdata,TARGET_COMMAND_REG , -TCR_LAST_BYTE_SENT , -TCR_LAST_BYTE_SENT , -0 ) <0 ) { -scmd_printk (KERN_ERR , hostdata->connected, -"%s: Last Byte Sent timeout\n" , __func__); - result =-1 ; - } +if (hostdata->pdma_residual ==0 )break ; - }if (bytes >0 )continue ;
@@ -400,11 +393,12 @@ static inline int macscsi_pwrite(structif (bytes ==0 )continue ; - result =-1 ; +if (macscsi_wait_for_drq (hostdata) <=0 ) +set_host_byte (hostdata->connected,DID_ERROR );break ; } -return result; +return 0 ; } static int macscsi_dma_xfer_len(struct NCR5380_hostdata *hostdata,
Greg Kroah-Hartman
maintainerPATCH 318/691 usbnet: fix cyclical race on disconnect with work queue
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Neukum <[email protected]>
commit 04e906839a053f092ef53f4fb2d610983412b904 upstream.
The work can submit URBs and the URBs can schedule the work. This cycle needs to be broken, when a device is to be stopped. Use a flag to do so.
This is a design issue as old as the driver.
--- drivers/net/usb/usbnet.c | 37 ++++++++++++++++++++++++++++--------- include/linux/usb/usbnet.h | 15 +++++++++++++++ 2 files changed, 43 insertions(+), 9 deletions(-)
drivers/net/usb/usbnet.c +28 -9
@@ -467,10 +467,15 @@ static enum skb_state defer_bh(struct usvoid usbnet_defer_kevent (struct usbnet *dev,int work) {set_bit (work, &dev->flags); -if (!schedule_work (&dev->kevent)) -netdev_dbg (dev->net,"kevent %s may have been dropped\n" , usbnet_event_names[work]); -else -netdev_dbg (dev->net,"kevent %s scheduled\n" , usbnet_event_names[work]); +if (!usbnet_going_away (dev)) { +if (!schedule_work (&dev->kevent)) +netdev_dbg (dev->net, +"kevent %s may have been dropped\n" , + usbnet_event_names[work]); +else +netdev_dbg (dev->net, +"kevent %s scheduled\n" , usbnet_event_names[work]); + } }EXPORT_SYMBOL_GPL (usbnet_defer_kevent);
@@ -538,7 +543,8 @@ static int rx_submit (struct usbnet *devtasklet_schedule (&dev->bh);break ;case 0 : -__usbnet_queue_skb (&dev->rxq, skb, rx_start); +if (!usbnet_going_away (dev)) +__usbnet_queue_skb (&dev->rxq, skb, rx_start); } }else {netif_dbg (dev, ifdown, dev->net,"rx: stopped\n" );
@@ -848,9 +854,18 @@ int usbnet_stop (struct net_device *net)/* deferred work (timer, softirq, task) must also stop */ dev->flags =0 ; -del_timer_sync (&dev->delay); -tasklet_kill (&dev->bh); +del_timer_sync (&dev->delay); +tasklet_kill (&dev->bh);cancel_work_sync (&dev->kevent); + +/* We have cyclic dependencies. Those calls are needed +* to break a cycle. We cannot fall into the gaps because +* we have a flag +*/ +tasklet_kill (&dev->bh); +del_timer_sync (&dev->delay); +cancel_work_sync (&dev->kevent); +if (!pm)usb_autopm_put_interface (dev->intf);
@@ -1176,7 +1191,8 @@ fail_halt: status); }else {clear_bit (EVENT_RX_HALT , &dev->flags); -tasklet_schedule (&dev->bh); +if (!usbnet_going_away (dev)) +tasklet_schedule (&dev->bh); } }
@@ -1201,7 +1217,8 @@ fail_halt:usb_autopm_put_interface (dev->intf); fail_lowmem:if (resched) -tasklet_schedule (&dev->bh); +if (!usbnet_going_away (dev)) +tasklet_schedule (&dev->bh); } }
@@ -1557,6 +1574,7 @@ static void usbnet_bh (struct timer_list }else if (netif_running (dev->net) &&netif_device_present (dev->net) &&netif_carrier_ok (dev->net) && + !usbnet_going_away (dev) && !timer_pending (&dev->delay) && !test_bit (EVENT_RX_PAUSED , &dev->flags) && !test_bit (EVENT_RX_HALT , &dev->flags)) {
@@ -1604,6 +1622,7 @@ void usbnet_disconnect (struct usb_interusb_set_intfdata (intf,NULL );if (!dev)return ; +usbnet_mark_going_away (dev); xdev =interface_to_usbdev (intf);
include/linux/usb/usbnet.h +15 -0
@@ -84,8 +84,23 @@ struct usbnet {# define EVENT_LINK_CHANGE 11# define EVENT_SET_RX_MODE 12# define EVENT_NO_IP_ALIGN 13 +/* This one is special, as it indicates that the device is going away +* there are cyclic dependencies between tasklet, timer and bh +* that must be broken +*/ +# define EVENT_UNPLUG 31 }; +static inline bool usbnet_going_away (struct usbnet *ubn) +{ +return test_bit (EVENT_UNPLUG , &ubn->flags); +} + +static inline void usbnet_mark_going_away (struct usbnet *ubn) +{ +set_bit (EVENT_UNPLUG , &ubn->flags); +} +static inline struct usb_driver *driver_of (struct usb_interface *intf) {return to_usb_driver (intf->dev.driver);
Greg Kroah-Hartman
maintainerPATCH 319/691 USB: appledisplay: close race between probe and completion handler
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Neukum <[email protected]>
commit 8265d06b7794493d82c5c21a12d7ba43eccc30cb upstream.
There is a small window during probing when IO is running but the backlight is not registered. Processing events during that time will crash. The completion handler needs to check for a backlight before scheduling work.
The bug is as old as the driver.
--- drivers/usb/misc/appledisplay.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-)
drivers/usb/misc/appledisplay.c +11 -4
@@ -107,7 +107,12 @@ static void appledisplay_complete(structcase ACD_BTN_BRIGHT_UP :case ACD_BTN_BRIGHT_DOWN : pdata->button_pressed =1 ; -schedule_delayed_work (&pdata->work,0 ); +/* +* there is a window during which no device +* is registered +*/ +if (pdata->bd ) +schedule_delayed_work (&pdata->work,0 );break ;case ACD_BTN_NONE :default :
@@ -202,6 +207,7 @@ static int appledisplay_probe(struct usb const struct usb_device_id *id) {struct backlight_properties props; +struct backlight_device *backlight;struct appledisplay *pdata;struct usb_device *udev =interface_to_usbdev (iface);struct usb_endpoint_descriptor *endpoint;
@@ -272,13 +278,14 @@ static int appledisplay_probe(struct usbmemset (&props,0 ,sizeof (struct backlight_properties )); props.type =BACKLIGHT_RAW ; props.max_brightness =0xff ; - pdata->bd =backlight_device_register (bl_name,NULL , pdata, + backlight =backlight_device_register (bl_name,NULL , pdata, &appledisplay_bl_data, &props); -if (IS_ERR (pdata->bd)) { +if (IS_ERR (backlight)) {dev_err (&iface->dev,"Backlight registration failed\n" ); - retval =PTR_ERR (pdata->bd); + retval =PTR_ERR (backlight); goto error; } + pdata->bd = backlight;/* Try to get brightness */ brightness =appledisplay_bl_get_brightness (pdata->bd);
Greg Kroah-Hartman
maintainerPATCH 320/691 USB: misc: cypress_cy7c63: check for short transfer
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Neukum <[email protected]>
commit 49cd2f4d747eeb3050b76245a7f72aa99dbd3310 upstream.
As we process the second byte of a control transfer, transfers of less than 2 bytes must be discarded.
This bug is as old as the driver.
--- drivers/usb/misc/cypress_cy7c63.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/usb/misc/cypress_cy7c63.c +4 -0
@@ -88,6 +88,9 @@ static int vendor_command(struct cypressUSB_DIR_IN |USB_TYPE_VENDOR |USB_RECIP_OTHER , address, data, iobuf,CYPRESS_MAX_REQSIZE , USB_CTRL_GET_TIMEOUT); +/* we must not process garbage */ +if (retval <2 ) + goto err_buf;/* store returned data (more READs to be added) */ switch (request) {
@@ -107,6 +110,7 @@ static int vendor_command(struct cypressbreak ; } +err_buf:kfree (iobuf); error:return retval;
Greg Kroah-Hartman
maintainerPATCH 321/691 USB: class: CDC-ACM: fix race between get_serial and set_serial
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Neukum <[email protected]>
commit b41c1fa155ba56d125885b0191aabaf3c508d0a3 upstream.
TIOCGSERIAL is an ioctl. Thus it must be atomic. It returns two values. Racing with set_serial it can return an inconsistent result. The mutex must be taken.
In terms of logic the bug is as old as the driver. In terms of code it goes back to the conversion to the get_serial and set_serial methods.
--- drivers/usb/class/cdc-acm.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/usb/class/cdc-acm.c +2 -0
@@ -942,10 +942,12 @@ static int get_serial_info(struct tty_ststruct acm *acm = tty->driver_data; ss->line = acm->minor; +mutex_lock (&acm->port.mutex); ss->close_delay =jiffies_to_msecs (acm->port.close_delay) /10 ; ss->closing_wait = acm->port.closing_wait ==ASYNC_CLOSING_WAIT_NONE ?ASYNC_CLOSING_WAIT_NONE :jiffies_to_msecs (acm->port.closing_wait) /10 ; +mutex_unlock (&acm->port.mutex);return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 322/691 usb: cdnsp: Fix incorrect usb_request status
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pawel Laszczak <[email protected]>
commit 1702bec4477cc7d31adb4a760d14d33fac928b7a upstream.
Fix changes incorrect usb_request->status returned during disabling endpoints. Before fix the status returned during dequeuing requests while disabling endpoint was ECONNRESET.
Patch change it to ESHUTDOWN.
Patch fixes issue detected during testing UVC gadget.
During stopping streaming the class starts dequeuing usb requests and controller driver returns the -ECONNRESET status. After completion requests the class or application "uvc-gadget" try to queue this request again. Changing this status to ESHUTDOWN cause that UVC assumes that endpoint is disabled, or device is disconnected and stops re-queuing usb requests.
--- drivers/usb/cdns3/cdnsp-ring.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/usb/cdns3/cdnsp-ring.c +4 -2
@@ -718,7 +718,8 @@ int cdnsp_remove_request(struct cdnsp_de seg =cdnsp_trb_in_td (pdev, cur_td->start_seg, cur_td->first_trb, cur_td->last_trb, hw_deq); -if (seg && (pep->ep_state &EP_ENABLED )) +if (seg && (pep->ep_state &EP_ENABLED ) && + !(pep->ep_state &EP_DIS_IN_RROGRESS ))cdnsp_find_new_dequeue_state (pdev, pep, preq->request.stream_id, cur_td, &deq_state);else
@@ -736,7 +737,8 @@ int cdnsp_remove_request(struct cdnsp_de* During disconnecting all endpoint will be disabled so we don't * have to worry about updating dequeue pointer. */ -if (pdev->cdnsp_state &CDNSP_STATE_DISCONNECT_PENDING ) { +if (pdev->cdnsp_state &CDNSP_STATE_DISCONNECT_PENDING || + pep->ep_state &EP_DIS_IN_RROGRESS ) { status = -ESHUTDOWN ; ret =cdnsp_cmd_set_deq (pdev, pep, &deq_state); }
Greg Kroah-Hartman
maintainerPATCH 323/691 usb: dwc2: drd: fix clock gating on USB role switch
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tomas Marek <[email protected]>
commit 2c6b6afa59e78bebcb65bbc8a76b3459f139547c upstream.
The dwc2_handle_usb_suspend_intr() function disables gadget clocks in USB peripheral mode when no other power-down mode is available (introduced by commit 0112b7ce68ea ("usb: dwc2: Update dwc2_handle_usb_suspend_intr function.")). However, the dwc2_drd_role_sw_set() USB role update handler attempts to read DWC2 registers if the USB role has changed while the USB is in suspend mode (when the clocks are gated). This causes the system to hang.
Release the gadget clocks before handling the USB role update.
--- drivers/usb/dwc2/drd.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/usb/dwc2/drd.c +9 -0
@@ -105,6 +105,15 @@ static int dwc2_drd_role_sw_set(struct uspin_lock_irqsave (&hsotg->lock, flags); +if ((IS_ENABLED (CONFIG_USB_DWC2_PERIPHERAL ) || +IS_ENABLED (CONFIG_USB_DWC2_DUAL_ROLE )) && +dwc2_is_device_mode (hsotg) && + hsotg->lx_state ==DWC2_L2 && + hsotg->params.power_down ==DWC2_POWER_DOWN_PARAM_NONE && + hsotg->bus_suspended && + !hsotg->params.no_clock_gating) +dwc2_gadget_exit_clock_gating (hsotg,0 ); +if (role ==USB_ROLE_HOST ) { already =dwc2_ovr_avalid (hsotg, true); }else if (role ==USB_ROLE_DEVICE ) {
Greg Kroah-Hartman
maintainerPATCH 324/691 bus: integrator-lm: fix OF node leak in probe()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Kozlowski <[email protected]>
commit 15a62b81175885b5adfcaf49870466e3603f06c7 upstream.
Driver code is leaking OF node reference from of_find_matching_node() in probe().
--- drivers/bus/arm-integrator-lm.c | 1 + 1 file changed, 1 insertion(+)
drivers/bus/arm-integrator-lm.c +1 -0
@@ -85,6 +85,7 @@ static int integrator_ap_lm_probe(structreturn -ENODEV ; } map =syscon_node_to_regmap (syscon); +of_node_put (syscon);if (IS_ERR (map)) {dev_err (dev,"could not find Integrator/AP system controller\n" );
Greg Kroah-Hartman
maintainerPATCH 325/691 firmware_loader: Block path traversal
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jann Horn <[email protected]>
commit f0e5311aa8022107d63c54e2f03684ec097d1394 upstream.
Most firmware names are hardcoded strings, or are constructed from fairly constrained format strings where the dynamic parts are just some hex numbers or such.
However, there are a couple codepaths in the kernel where firmware file names contain string components that are passed through from a device or semi-privileged userspace; the ones I could find (not counting interfaces that require root privileges) are:
- lpfc_sli4_request_firmware_update() seems to construct the firmware filename from "ModelName", a string that was previously parsed out of some descriptor ("Vital Product Data") in lpfc_fill_vpd()
- nfp_net_fw_find() seems to construct a firmware filename from a model name coming from nfp_hwinfo_lookup(pf->hwinfo, "nffw.partno"), which I think parses some descriptor that was read from the device. (But this case likely isn't exploitable because the format string looks like "netronome/nic_%s", and there shouldn't be any *folders* starting with "netronome/nic_". The previous case was different because there, the "%s" is *at the start* of the format string.)
- module_flash_fw_schedule() is reachable from the ETHTOOL_MSG_MODULE_FW_FLASH_ACT netlink command, which is marked as GENL_UNS_ADMIN_PERM (meaning CAP_NET_ADMIN inside a user namespace is enough to pass the privilege check), and takes a userspace-provided firmware name.
(But I think to reach this case, you need to have CAP_NET_ADMIN over a network namespace that a special kind of ethernet device is mapped into, so I think this is not a viable attack path in practice.)
Fix it by rejecting any firmware names containing ".." path components.
For what it's worth, I went looking and haven't found any USB device drivers that use the firmware loader dangerously.
--- drivers/base/firmware_loader/main.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+)
drivers/base/firmware_loader/main.c +30 -0
@@ -788,6 +788,26 @@ static void fw_abort_batch_reqs(struct fmutex_unlock (&fw_lock); } +/* +* Reject firmware file names with ".." path components. +* There are drivers that construct firmware file names from device-supplied +* strings, and we don't want some device to be able to tell us "I would like to +* be sent my firmware from ../../../etc/shadow, please". +* +* Search for ".." surrounded by either '/' or start/end of string. +* +* This intentionally only looks at the firmware name, not at the firmware base +* directory or at symlink contents. +*/ +static bool name_contains_dotdot (const char *name) +{ +size_t name_len =strlen (name); + +return strcmp (name,".." ) ==0 ||strncmp (name,"../" ,3 ) ==0 || +strstr (name,"/../" ) !=NULL || + (name_len >=3 &&strcmp (name+name_len-3 ,"/.." ) ==0 ); +} +/* called from request_firmware() and request_firmware_work_func() */ static int _request_firmware(const struct firmware **firmware_p, const char *name,
@@ -808,6 +828,14 @@ _request_firmware(const struct firmware goto out; } +if (name_contains_dotdot (name)) { +dev_warn (device, +"Firmware load for '%s' refused, path contains '..' component\n" , + name); + ret = -EINVAL ; + goto out; + } + ret =_request_firmware_prepare (&fw, name, device, buf, size, offset, opt_flags);if (ret <=0 )/* error or already assigned */
@@ -878,6 +906,8 @@ _request_firmware(const struct firmware* @name will be used as $FIRMWARE in the uevent environment and * should be distinctive enough not to be confused with any other * firmware image for this or any other device. +* It must not contain any ".." path components - "foo/bar..bin" is +* allowed, but "foo/../bar.bin" is not. * * Caller must hold the reference count of @device. *
Greg Kroah-Hartman
maintainerPATCH 326/691 tty: rp2: Fix reset with non forgiving PCIe host bridges
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Fainelli <[email protected]>
commit f16dd10ba342c429b1e36ada545fb36d4d1f0e63 upstream.
The write to RP2_GLOBAL_CMD followed by an immediate read of RP2_GLOBAL_CMD in rp2_reset_asic() is intented to flush out the write, however by then the device is already in reset and cannot respond to a memory cycle access.
On platforms such as the Raspberry Pi 4 and others using the pcie-brcmstb.c driver, any memory access to a device that cannot respond is met with a fatal system error, rather than being substituted with all 1s as is usually the case on PC platforms.
Swapping the delay and the read ensures that the device has finished resetting before we attempt to read from it.
--- drivers/tty/serial/rp2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/tty/serial/rp2.c +1 -1
@@ -598,8 +598,8 @@ static void rp2_reset_asic(struct rp2_cau32 clk_cfg;writew (1 , base +RP2_GLOBAL_CMD ); -readw (base +RP2_GLOBAL_CMD );msleep (100 ); +readw (base +RP2_GLOBAL_CMD );writel (0 , base +RP2_CLK_PRESCALER );/* TDM clock configuration */
Greg Kroah-Hartman
maintainerPATCH 327/691 xhci: Set quirky xHC PCI hosts to D3 _after_ stopping and freeing them.
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mathias Nyman <[email protected]>
commit f81dfa3b57c624c56f2bff171c431bc7f5b558f2 upstream.
PCI xHC host should be stopped and xhci driver memory freed before putting host to PCI D3 state during PCI remove callback.
Hosts with XHCI_SPURIOUS_WAKEUP quirk did this the wrong way around and set the host to D3 before calling usb_hcd_pci_remove(dev), which will access the host to stop it, and then free xhci.
--- drivers/usb/host/xhci-pci.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
drivers/usb/host/xhci-pci.c +5 -3
@@ -535,8 +535,10 @@ put_runtime_pm:static void xhci_pci_remove (struct pci_dev *dev) {struct xhci_hcd *xhci; +bool set_power_d3; xhci =hcd_to_xhci (pci_get_drvdata (dev)); + set_power_d3 = xhci->quirks &XHCI_SPURIOUS_WAKEUP ; xhci->xhc_state |=XHCI_STATE_REMOVING ;
@@ -549,11 +551,11 @@ static void xhci_pci_remove(struct pci_d xhci->shared_hcd =NULL ; } +usb_hcd_pci_remove (dev); +/* Workaround for spurious wakeups at shutdown with HSW */ -if (xhci->quirks &XHCI_SPURIOUS_WAKEUP ) +if (set_power_d3)pci_set_power_state (dev, PCI_D3hot); - -usb_hcd_pci_remove (dev); }#ifdef CONFIG_PM
Greg Kroah-Hartman
maintainerPATCH 328/691 crypto: ccp - Properly unregister /dev/sev on sev PLATFORM_STATUS failure
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pavan Kumar Paluri <[email protected]>
commit ce3d2d6b150ba8528f3218ebf0cee2c2c572662d upstream.
In case of sev PLATFORM_STATUS failure, sev_get_api_version() fails resulting in sev_data field of psp_master nulled out. This later becomes a problem when unloading the ccp module because the device has not been unregistered (via misc_deregister()) before clearing the sev_data field of psp_master. As a result, on reloading the ccp module, a duplicate device issue is encountered as can be seen from the dmesg log below.
on reloading ccp module via modprobe ccp
Call Trace: <TASK> dump_stack_lvl+0xd7/0xf0 dump_stack+0x10/0x20 sysfs_warn_dup+0x5c/0x70 sysfs_create_dir_ns+0xbc/0xd kobject_add_internal+0xb1/0x2f0 kobject_add+0x7a/0xe0 ? srso_alias_return_thunk+0x5/0xfbef5 ? get_device_parent+0xd4/0x1e0 ? __pfx_klist_children_get+0x10/0x10 device_add+0x121/0x870 ? srso_alias_return_thunk+0x5/0xfbef5 device_create_groups_vargs+0xdc/0x100 device_create_with_groups+0x3f/0x60 misc_register+0x13b/0x1c0 sev_dev_init+0x1d4/0x290 [ccp] psp_dev_init+0x136/0x300 [ccp] sp_init+0x6f/0x80 [ccp] sp_pci_probe+0x2a6/0x310 [ccp] ? srso_alias_return_thunk+0x5/0xfbef5 local_pci_probe+0x4b/0xb0 work_for_cpu_fn+0x1a/0x30 process_one_work+0x203/0x600 worker_thread+0x19e/0x350 ? __pfx_worker_thread+0x10/0x10 kthread+0xeb/0x120 ? __pfx_kthread+0x10/0x10 ret_from_fork+0x3c/0x60 ? __pfx_kthread+0x10/0x10 ret_from_fork_asm+0x1a/0x30 </TASK> kobject: kobject_add_internal failed for sev with -EEXIST, don't try to register things with the same name in the same directory. ccp 0000:22:00.1: sev initialization failed ccp 0000:22:00.1: psp initialization failed ccp 0000:a2:00.1: no command queues available ccp 0000:a2:00.1: psp enabled
Address this issue by unregistering the /dev/sev before clearing out sev_data in case of PLATFORM_STATUS failure.
--- drivers/crypto/ccp/sev-dev.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/crypto/ccp/sev-dev.c +2 -0
@@ -1141,6 +1141,8 @@ void sev_pci_init(void)return ; err: +sev_dev_destroy (psp_master); + psp_master->sev_data =NULL ; }
Greg Kroah-Hartman
maintainerPATCH 329/691 drbd: Fix atomicity violation in drbd_uuid_set_bm()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qiu-ji Chen <[email protected]>
commit 2f02b5af3a4482b216e6a466edecf6ba8450fa45 upstream.
The violation of atomicity occurs when the drbd_uuid_set_bm function is executed simultaneously with modifying the value of device->ldev->md.uuid[UI_BITMAP]. Consider a scenario where, while device->ldev->md.uuid[UI_BITMAP] passes the validity check when its value is not zero, the value of device->ldev->md.uuid[UI_BITMAP] is written to zero. In this case, the check in drbd_uuid_set_bm might refer to the old value of device->ldev->md.uuid[UI_BITMAP] (before locking), which allows an invalid value to pass the validity check, resulting in inconsistency.
To address this issue, it is recommended to include the data validity check within the locked section of the function. This modification ensures that the value of device->ldev->md.uuid[UI_BITMAP] does not change during the validation process, thereby maintaining its integrity.
This possible bug is found by an experimental static analysis tool developed by our team. This tool analyzes the locking APIs to extract function pairs that can be concurrently executed, and then analyzes the instructions in the paired functions to identify possible concurrency bugs including data races and atomicity violations.
--- drivers/block/drbd/drbd_main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/block/drbd/drbd_main.c +4 -2
@@ -3406,10 +3406,12 @@ void drbd_uuid_new_current(struct drbd_dvoid drbd_uuid_set_bm (struct drbd_device *device,u64 val)__must_hold (local) {unsigned long flags; -if (device->ldev->md.uuid[UI_BITMAP ] ==0 && val ==0 ) +spin_lock_irqsave (&device->ldev->md.uuid_lock, flags); +if (device->ldev->md.uuid[UI_BITMAP ] ==0 && val ==0 ) { +spin_unlock_irqrestore (&device->ldev->md.uuid_lock, flags);return ; + } -spin_lock_irqsave (&device->ldev->md.uuid_lock, flags);if (val ==0 ) {drbd_uuid_move_history (device); device->ldev->md.uuid[UI_HISTORY_START ] = device->ldev->md.uuid[UI_BITMAP ];
Greg Kroah-Hartman
maintainerPATCH 330/691 drbd: Add NULL check for net_conf to prevent dereference in state validation
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mikhail Lobanov <[email protected]>
commit a5e61b50c9f44c5edb6e134ede6fee8806ffafa9 upstream.
If the net_conf pointer is NULL and the code attempts to access its fields without a check, it will lead to a null pointer dereference. Add a NULL check before dereferencing the pointer.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
--- drivers/block/drbd/drbd_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/block/drbd/drbd_state.c +1 -1
@@ -876,7 +876,7 @@ is_valid_state(struct drbd_device *devic ns.disk == D_OUTDATED) rv =SS_CONNECTED_OUTDATES ; - else if ((ns.conn == C_VERIFY_S || ns.conn == C_VERIFY_T) && + else if (nc && (ns.conn == C_VERIFY_S || ns.conn == C_VERIFY_T) && (nc->verify_alg[0] == 0)) rv =SS_NO_VERIFY_ALG ;
Greg Kroah-Hartman
maintainerPATCH 331/691 ACPI: sysfs: validate return type of _STR method
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Weißschuh <[email protected]>
commit 4bb1e7d027413835b086aed35bc3f0713bc0f72b upstream.
Only buffer objects are valid return values of _STR.
If something else is returned description_show() will access invalid memory.
--- drivers/acpi/device_sysfs.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/acpi/device_sysfs.c +3 -2
@@ -543,8 +543,9 @@ int acpi_device_setup_files(struct acpi_* If device has _STR, 'description' file is created */ if (acpi_has_method (dev->handle,"_STR" )) { - status =acpi_evaluate_object (dev->handle,"_STR" , -NULL , &buffer); + status =acpi_evaluate_object_typed (dev->handle,"_STR" , +NULL , &buffer, +ACPI_TYPE_BUFFER );if (ACPI_FAILURE (status)) buffer.pointer =NULL ; dev->pnp.str_obj = buffer.pointer;
Greg Kroah-Hartman
maintainerPATCH 332/691 ACPI: resource: Add another DMI match for the TongFang GMxXGxx
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Werner Sembach <[email protected]>
commit a98cfe6ff15b62f94a44d565607a16771c847bc6 upstream.
Internal documentation suggest that the TUXEDO Polaris 15 Gen5 AMD might have GMxXGxX as the board name instead of GMxXGxx.
Adding both to be on the safe side.
--- drivers/acpi/resource.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/acpi/resource.c +6 -0
@@ -516,6 +516,12 @@ static const struct dmi_system_id mainge }, }, { +/* TongFang GMxXGxX/TUXEDO Polaris 15 Gen5 AMD */ + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "GMxXGxX"), + }, + }, + {/* TongFang GMxXGxx sold as Eluktronics Inc. RP-15 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Eluktronics Inc."),
Greg Kroah-Hartman
maintainerPATCH 333/691 efistub/tpm: Use ACPI reclaim memory for event log to avoid corruption
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ard Biesheuvel <[email protected]>
commit 77d48d39e99170b528e4f2e9fc5d1d64cdedd386 upstream.
The TPM event log table is a Linux specific construct, where the data produced by the GetEventLog() boot service is cached in memory, and passed on to the OS using an EFI configuration table.
The use of EFI_LOADER_DATA here results in the region being left unreserved in the E820 memory map constructed by the EFI stub, and this is the memory description that is passed on to the incoming kernel by kexec, which is therefore unaware that the region should be reserved.
Even though the utility of the TPM2 event log after a kexec is questionable, any corruption might send the parsing code off into the weeds and crash the kernel. So let's use EFI_ACPI_RECLAIM_MEMORY instead, which is always treated as reserved by the E820 conversion logic.
--- drivers/firmware/efi/libstub/tpm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/firmware/efi/libstub/tpm.c +1 -1
@@ -115,7 +115,7 @@ void efi_retrieve_tpm2_eventlog(void) }/* Allocate space for the logs and copy them. */ - status =efi_bs_call (allocate_pool,EFI_LOADER_DATA , + status =efi_bs_call (allocate_pool,EFI_ACPI_RECLAIM_MEMORY ,sizeof (*log_tbl) + log_size, (void **)&log_tbl);if (status !=EFI_SUCCESS ) {
Greg Kroah-Hartman
maintainerPATCH 334/691 perf/x86/intel/pt: Fix sampling synchronization
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Adrian Hunter <[email protected]>
commit d92792a4b26e50b96ab734cbe203d8a4c932a7a9 upstream.
pt_event_snapshot_aux() uses pt->handle_nmi to determine if tracing needs to be stopped, however tracing can still be going because pt->handle_nmi is set to zero before tracing is stopped in pt_event_stop, whereas pt_event_snapshot_aux() requires that tracing must be stopped in order to copy a sample of trace from the buffer.
Instead call pt_config_stop() always, which anyway checks config for RTIT_CTL_TRACEEN and does nothing if it is already clear.
Note pt_event_snapshot_aux() can continue to use pt->handle_nmi to determine if the trace needs to be restarted afterwards.
--- arch/x86/events/intel/pt.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-)
arch/x86/events/intel/pt.c +7 -8
@@ -1586,6 +1586,7 @@ static void pt_event_stop(struct perf_ev* see comment in intel_pt_interrupt(). */ WRITE_ONCE (pt->handle_nmi,0 ); +barrier ();pt_config_stop (event);
@@ -1637,11 +1638,10 @@ static long pt_event_snapshot_aux(structreturn 0 ;/* -* Here, handle_nmi tells us if the tracing is on +* There is no PT interrupt in this mode, so stop the trace and it will +* remain stopped while the buffer is copied. */ -if (READ_ONCE (pt->handle_nmi)) -pt_config_stop (event); - +pt_config_stop (event);pt_read_offset (buf);pt_update_head (pt);
@@ -1653,11 +1653,10 @@ static long pt_event_snapshot_aux(struct ret =perf_output_copy_aux (&pt->handle, handle, from, to);/* -* If the tracing was on when we turned up, restart it. -* Compiler barrier not needed as we couldn't have been -* preempted by anything that touches pt->handle_nmi. +* Here, handle_nmi tells us if the tracing was on. +* If the tracing was on, restart it. */ -if (pt->handle_nmi) +if (READ_ONCE (pt->handle_nmi))pt_config_start (event);return ret;
Greg Kroah-Hartman
maintainerPATCH 335/691 wifi: rtw88: 8822c: Fix reported RX band width
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bitterblue Smith <[email protected]>
commit a71ed5898dfae68262f79277915d1dfe34586bc6 upstream.
"iw dev wlp2s0 station dump" shows incorrect rx bitrate:
tx bitrate: 866.7 MBit/s VHT-MCS 9 80MHz short GI VHT-NSS 2 rx bitrate: 86.7 MBit/s VHT-MCS 9 VHT-NSS 1
This is because the RX band width is calculated incorrectly. Fix the calculation according to the phydm_rxsc_2_bw() function from the official drivers.
After:
tx bitrate: 866.7 MBit/s VHT-MCS 9 80MHz short GI VHT-NSS 2 rx bitrate: 390.0 MBit/s VHT-MCS 9 80MHz VHT-NSS 1
It also works correctly with the AP configured for 20 MHz and 40 MHz.
Tested with RTL8822CE.
--- drivers/net/wireless/realtek/rtw88/rtw8822c.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
drivers/net/wireless/realtek/rtw88/rtw8822c.c +6 -4
@@ -2584,12 +2584,14 @@ static void query_phy_status_page1(strucelse rxsc =GET_PHY_STAT_P1_HT_RXSC (phy_status); -if (rxsc >=9 && rxsc <=12 ) +if (rxsc ==0 ) + bw = rtwdev->hal.current_band_width; +else if (rxsc >=1 && rxsc <=8 ) + bw =RTW_CHANNEL_WIDTH_20 ; +else if (rxsc >=9 && rxsc <=12 ) bw =RTW_CHANNEL_WIDTH_40 ; -else if (rxsc >=13 ) - bw =RTW_CHANNEL_WIDTH_80 ;else - bw =RTW_CHANNEL_WIDTH_20 ; + bw =RTW_CHANNEL_WIDTH_80 ; pkt_stat->rx_power[RF_PATH_A ] =GET_PHY_STAT_P1_PWDB_A (phy_status) -110 ; pkt_stat->rx_power[RF_PATH_B ] =GET_PHY_STAT_P1_PWDB_B (phy_status) -110 ;
Greg Kroah-Hartman
maintainerPATCH 336/691 wifi: mt76: mt7615: check devm_kasprintf() returned value
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ma Ke <[email protected]>
commit 5acdc432f832d810e0d638164c393b877291d9b4 upstream.
devm_kasprintf() can return a NULL pointer on failure but this returned value is not checked. Fix this lack and check the returned value.
Found by code review.
--- drivers/net/wireless/mediatek/mt76/mt7615/init.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/wireless/mediatek/mt76/mt7615/init.c +3 -0
@@ -56,6 +56,9 @@ int mt7615_thermal_init(struct mt7615_de name =devm_kasprintf (&wiphy->dev,GFP_KERNEL ,"mt7615_%s" ,wiphy_name (wiphy)); +if (!name) +return -ENOMEM ; + hwmon =devm_hwmon_device_register_with_groups (&wiphy->dev, name, dev, mt7615_hwmon_groups);if (IS_ERR (hwmon))
Greg Kroah-Hartman
maintainerPATCH 337/691 debugobjects: Fix conditions in fill_pool()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhen Lei <[email protected]>
commit 684d28feb8546d1e9597aa363c3bfcf52fe250b7 upstream.
fill_pool() uses 'obj_pool_min_free' to decide whether objects should be handed back to the kmem cache. But 'obj_pool_min_free' records the lowest historical value of the number of objects in the object pool and not the minimum number of objects which should be kept in the pool.
Use 'debug_objects_pool_min_level' instead, which holds the minimum number which was scaled to the number of CPUs at boot time.
[ tglx: Massage change log ]
--- lib/debugobjects.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
lib/debugobjects.c +3 -2
@@ -144,13 +144,14 @@ static void fill_pool(void)* READ_ONCE()s pair with the WRITE_ONCE()s in pool_lock critical * sections. */ -while (READ_ONCE (obj_nr_tofree) && (READ_ONCE (obj_pool_free) < obj_pool_min_free)) { +while (READ_ONCE (obj_nr_tofree) && +READ_ONCE (obj_pool_free) < debug_objects_pool_min_level) {raw_spin_lock_irqsave (&pool_lock, flags);/* * Recheck with the lock held as the worker thread might have * won the race and freed the global free list already. */ -while (obj_nr_tofree && (obj_pool_free < obj_pool_min_free)) { +while (obj_nr_tofree && (obj_pool_free < debug_objects_pool_min_level)) { obj =hlist_entry (obj_to_free.first,typeof (*obj), node);hlist_del (&obj->node);WRITE_ONCE (obj_nr_tofree, obj_nr_tofree -1 );
Greg Kroah-Hartman
maintainerPATCH 338/691 f2fs: prevent possible int overflow in dir_block_index()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nikita Zhandarovich <[email protected]>
commit 47f268f33dff4a5e31541a990dc09f116f80e61c upstream.
The result of multiplication between values derived from functions dir_buckets() and bucket_blocks() *could* technically reach 2^30 * 2^2 = 2^32.
While unlikely to happen, it is prudent to ensure that it will not lead to integer overflow. Thus, use mul_u32_u32() as it's more appropriate to mitigate the issue.
Found by Linux Verification Center (linuxtesting.org) with static analysis tool SVACE.
--- fs/f2fs/dir.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
fs/f2fs/dir.c +2 -1
@@ -190,7 +190,8 @@ static unsigned long dir_block_index(unsunsigned long bidx =0 ;for (i =0 ; i < level; i++) - bidx +=dir_buckets (i, dir_level) *bucket_blocks (i); + bidx +=mul_u32_u32 (dir_buckets (i, dir_level), +bucket_blocks (i)); bidx += idx *bucket_blocks (level);return bidx; }
Greg Kroah-Hartman
maintainerPATCH 339/691 f2fs: avoid potential int overflow in sanity_check_area_boundary()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nikita Zhandarovich <[email protected]>
commit 50438dbc483ca6a133d2bce9d5d6747bcee38371 upstream.
While calculating the end addresses of main area and segment 0, u32 may be not enough to hold the result without the danger of int overflow.
Just in case, play it safe and cast one of the operands to a wider type (u64).
Found by Linux Verification Center (linuxtesting.org) with static analysis tool SVACE.
--- fs/f2fs/super.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
fs/f2fs/super.c +2 -2
@@ -3181,9 +3181,9 @@ static inline bool sanity_check_area_bouu32 segment_count =le32_to_cpu (raw_super->segment_count);u32 log_blocks_per_seg =le32_to_cpu (raw_super->log_blocks_per_seg);u64 main_end_blkaddr = main_blkaddr + - (segment_count_main << log_blocks_per_seg); + ((u64 )segment_count_main << log_blocks_per_seg);u64 seg_end_blkaddr = segment0_blkaddr + - (segment_count << log_blocks_per_seg); + ((u64 )segment_count << log_blocks_per_seg);if (segment0_blkaddr != cp_blkaddr) { f2fs_info(sbi, "Mismatch start address, segment0(%u) cp_blkaddr(%u)",
Greg Kroah-Hartman
maintainerPATCH 340/691 hwrng: mtk - Use devm_pm_runtime_enable
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guoqing Jiang <[email protected]>
commit 78cb66caa6ab5385ac2090f1aae5f3c19e08f522 upstream.
Replace pm_runtime_enable with the devres-enabled version which can trigger pm_runtime_disable.
Otherwise, the below appears during reload driver.
mtk_rng 1020f000.rng: Unbalanced pm_runtime_enable!
--- drivers/char/hw_random/mtk-rng.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/char/hw_random/mtk-rng.c +1 -1
@@ -142,7 +142,7 @@ static int mtk_rng_probe(struct platformdev_set_drvdata (&pdev->dev, priv);pm_runtime_set_autosuspend_delay (&pdev->dev,RNG_AUTOSUSPEND_TIMEOUT );pm_runtime_use_autosuspend (&pdev->dev); -pm_runtime_enable (&pdev->dev); +devm_pm_runtime_enable (&pdev->dev);dev_info (&pdev->dev,"registered RNG driver\n" );
Greg Kroah-Hartman
maintainerPATCH 341/691 hwrng: bcm2835 - Add missing clk_disable_unprepare in bcm2835_rng_init
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gaosheng Cui <[email protected]>
commit d57e2f7cffd57fe2800332dec768ec1b67a4159f upstream.
Add the missing clk_disable_unprepare() before return in bcm2835_rng_init().
--- drivers/char/hw_random/bcm2835-rng.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/char/hw_random/bcm2835-rng.c +3 -1
@@ -95,8 +95,10 @@ static int bcm2835_rng_init(struct hwrngreturn ret; ret =reset_control_reset (priv->reset); -if (ret) +if (ret) { +clk_disable_unprepare (priv->clk);return ret; + }if (priv->mask_interrupts) {/* mask the interrupt */
Greg Kroah-Hartman
maintainerPATCH 342/691 hwrng: cctrng - Add missing clk_disable_unprepare in cctrng_resume
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gaosheng Cui <[email protected]>
commit 4b7acc85de14ee8a2236f54445dc635d47eceac0 upstream.
Add the missing clk_disable_unprepare() before return in cctrng_resume().
--- drivers/char/hw_random/cctrng.c | 1 + 1 file changed, 1 insertion(+)
drivers/char/hw_random/cctrng.c +1 -0
@@ -665,6 +665,7 @@ static int __maybe_unused cctrng_resume(/* wait for Cryptocell reset completion */ if (!cctrng_wait_for_reset_completion (drvdata)) {dev_err (dev,"Cryptocell reset not completed" ); +clk_disable_unprepare (drvdata->clk);return -EBUSY ; }
Greg Kroah-Hartman
maintainerPATCH 343/691 arm64: dts: rockchip: Raise Pinebook Pros panel backlight PWM frequency
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dragan Simic <[email protected]>
commit 8c51521de18755d4112a77a598a348b38d0af370 upstream.
Increase the frequency of the PWM signal that drives the LED backlight of the Pinebook Pro's panel, from about 1.35 KHz (which equals to the PWM period of 740,740 ns), to exactly 8 kHz (which equals to the PWM period of 125,000 ns). Using a higher PWM frequency for the panel backlight, which reduces the flicker, can only be beneficial to the end users' eyes.
On top of that, increasing the backlight PWM signal frequency reportedly eliminates the buzzing emitted from the Pinebook Pro's built-in speakers when certain backlight levels are set, which cause some weird interference with some of the components of the Pinebook Pro's audio chain.
The old value for the backlight PWM period, i.e. 740,740 ns, is pretty much an arbitrary value that was selected during the very early bring-up of the Pinebook Pro, only because that value seemed to minimize horizontal line distortion on the display, which resulted from the old X.org drivers causing screen tearing when dragging windows around. That's no longer an issue, so there are no reasons to stick with the old PWM period value.
The lower and the upper backlight PWM frequency limits for the Pinebook Pro's panel, according to its datasheet, are 200 Hz and 10 kHz, respectively. [1] These changes still leave some headroom, which may have some positive effects on the lifetime expectancy of the panel's backlight LEDs.
[1] https://files.pine64.org/doc/datasheet/PinebookPro/NV140FHM-N49_Rev.P0_20160804_201710235838.pdf
--- arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts +1 -1
@@ -31,7 +31,7 @@ backlight: edp-backlight { compatible = "pwm-backlight"; power-supply = <&vcc_12v>; - pwms = <&pwm0 0 740740 0>; + pwms = <&pwm0 0 125000 0>; }; bat: battery {
Greg Kroah-Hartman
maintainerPATCH 344/691 arm64: dts: rockchip: Correct the Pinebook Pro battery design capacity
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dragan Simic <[email protected]>
commit def33fb1191207f5afa6dcb681d71fef2a6c1293 upstream.
All batches of the Pine64 Pinebook Pro, except the latest batch (as of 2024) whose hardware design was revised due to the component shortage, use a 1S lithium battery whose nominal/design capacity is 10,000 mAh, according to the battery datasheet. [1][2] Let's correct the design full-charge value in the Pinebook Pro board dts, to improve the accuracy of the hardware description, and to hopefully improve the accuracy of the fuel gauge a bit on all units that don't belong to the latest batch.
The above-mentioned latest batch uses a different 1S lithium battery with a slightly lower capacity, more precisely 9,600 mAh. To make the fuel gauge work reliably on the latest batch, a sample battery would need to be sent to CellWise, to obtain its proprietary battery profile, whose data goes into "cellwise,battery-profile" in the Pinebook Pro board dts. Without that data, the fuel gauge reportedly works unreliably, so changing the design capacity won't have any negative effects on the already unreliable operation of the fuel gauge in the Pinebook Pros that belong to the latest batch.
According to the battery datasheet, its voltage can go as low as 2.75 V while discharging, but it's better to leave the current 3.0 V value in the dts file, because of the associated Pinebook Pro's voltage regulation issues.
[1] https://wiki.pine64.org/index.php/Pinebook_Pro#Battery
[2] https://files.pine64.org/doc/datasheet/pinebook/40110175P%203.8V%2010000mAh%E8%A7%84%E6%A0%BC%E4%B9%A6-14.pdf
--- arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts +1 -1
@@ -36,7 +36,7 @@ bat: battery { compatible = "simple-battery"; - charge-full-design-microamp-hours = <9800000>; + charge-full-design-microamp-hours = <10000000>; voltage-max-design-microvolt = <4350000>; voltage-min-design-microvolt = <3000000>; };
Greg Kroah-Hartman
maintainerPATCH 345/691 vfs: fix race between evice_inodes() and find_inode()&iput()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Julian Sun <[email protected]>
commit 88b1afbf0f6b221f6c5bb66cc80cd3b38d696687 upstream.
Hi, all
Recently I noticed a bug[1] in btrfs, after digged it into and I believe it'a race in vfs.
Let's assume there's a inode (ie ino 261) with i_count 1 is called by iput(), and there's a concurrent thread calling generic_shutdown_super().
cpu0: cpu1:iput() // i_count is 1
->spin_lock(inode)
->dec i_count to 0
->iput_final() generic_shutdown_super()
->__inode_add_lru() ->evict_inodes()
// cause some reason[2] ->if (atomic_read(inode->i_count)) continue;
// return before // inode 261 passed the above check
// list_lru_add_obj() // and then schedule out ->spin_unlock()
// note here: the inode 261
// was still at sb list and hash list,
// and I_FREEING|I_WILL_FREE was not been set
btrfs_iget()
// after some function calls
->find_inode()
// found the above inode 261
->spin_lock(inode)
// check I_FREEING|I_WILL_FREE
// and passed
->__iget()
->spin_unlock(inode) // schedule back
->spin_lock(inode)
// check (I_NEW|I_FREEING|I_WILL_FREE) flags,
// passed and set I_FREEINGiput() ->spin_unlock(inode)
->spin_lock(inode) ->evict()
// dec i_count to 0
->iput_final()
->spin_unlock()
->evict()Now, we have two threads simultaneously evicting
the same inode, which may trigger the BUG(inode->i_state & I_CLEAR) statement both within clear_inode() and iput().
To fix the bug, recheck the inode->i_count after holding i_lock. Because in the most scenarios, the first check is valid, and the overhead of spin_lock() can be reduced.
If there is any misunderstanding, please let me know, thanks.
[1]: https://lore.kernel.org/linux-btrfs/[email protected]/
[2]: The reason might be 1. SB_ACTIVE was removed or 2. mapping_shrinkable() return false when I reproduced the bug.
--- fs/inode.c | 4 ++++ 1 file changed, 4 insertions(+)
fs/inode.c +4 -0
@@ -678,6 +678,10 @@ again:continue ;spin_lock (&inode->i_lock); +if (atomic_read (&inode->i_count)) { +spin_unlock (&inode->i_lock); +continue ; + }if (inode->i_state & (I_NEW |I_FREEING |I_WILL_FREE )) {spin_unlock (&inode->i_lock);continue ;
Greg Kroah-Hartman
maintainerPATCH 346/691 fs: Fix file_set_fowner LSM hook inconsistencies
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mickaël Salaün <[email protected]>
commit 26f204380a3c182e5adf1a798db0724d6111b597 upstream.
The fcntl's F_SETOWN command sets the process that handle SIGIO/SIGURG for the related file descriptor. Before this change, the file_set_fowner LSM hook was always called, ignoring the VFS logic which may not actually change the process that handles SIGIO (e.g. TUN, TTY, dnotify), nor update the related UID/EUID.
Moreover, because security_file_set_fowner() was called without lock (e.g. f_owner.lock), concurrent F_SETOWN commands could result to a race condition and inconsistent LSM states (e.g. SELinux's fown_sid) compared to struct fown_struct's UID/EUID.
This change makes sure the LSM states are always in sync with the VFS state by moving the security_file_set_fowner() call close to the UID/EUID updates and using the same f_owner.lock .
Rename f_modown() to __f_setown() to simplify code.
--- fs/fcntl.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-)
fs/fcntl.c +4 -10
@@ -85,8 +85,8 @@ static int setfl(int fd, struct file * freturn error; } -static void f_modown (struct file *filp,struct pid *pid,enum pid_type type, -int force) +void __f_setown (struct file *filp,struct pid *pid,enum pid_type type, +int force) {write_lock_irq (&filp->f_owner.lock);if (force || !filp->f_owner.pid) {
@@ -96,19 +96,13 @@ static void f_modown(struct file *filp,if (pid) {const struct cred *cred =current_cred (); +security_file_set_fowner (filp); filp->f_owner.uid = cred->uid; filp->f_owner.euid = cred->euid; } }write_unlock_irq (&filp->f_owner.lock); } - -void __f_setown (struct file *filp,struct pid *pid,enum pid_type type, -int force) -{ -security_file_set_fowner (filp); -f_modown (filp, pid, type, force); -}EXPORT_SYMBOL (__f_setown);int f_setown (struct file *filp,unsigned long arg,int force)
@@ -144,7 +138,7 @@ EXPORT_SYMBOL(f_setown);void f_delown (struct file *filp) { -f_modown (filp,NULL ,PIDTYPE_TGID ,1 ); +__f_setown (filp,NULL ,PIDTYPE_TGID ,1 ); }pid_t f_getown (struct file *filp)
Greg Kroah-Hartman
maintainerPATCH 347/691 nfs: fix memory leak in error path of nfs4_do_reclaim
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Li Lingfeng <[email protected]>
commit 8f6a7c9467eaf39da4c14e5474e46190ab3fb529 upstream.
Commit c77e22834ae9 ("NFSv4: Fix a potential sleep while atomic in nfs4_do_reclaim()") separate out the freeing of the state owners from nfs4_purge_state_owners() and finish it outside the rcu lock. However, the error path is omitted. As a result, the state owners in "freeme" will not be released.
Fix it by adding freeing in the error path.
--- fs/nfs/nfs4state.c | 1 + 1 file changed, 1 insertion(+)
fs/nfs/nfs4state.c +1 -0
@@ -1949,6 +1949,7 @@ restart:set_bit (ops->owner_flag_bit, &sp->so_flags);nfs4_put_state_owner (sp); status =nfs4_recovery_handle_error (clp, status); +nfs4_free_state_owners (&freeme);return (status !=0 ) ? status : -EAGAIN ; }
Greg Kroah-Hartman
maintainerPATCH 348/691 EDAC/igen6: Fix conversion of system address to physical memory address
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qiuxu Zhuo <[email protected]>
commit 0ad875f442e95d69a1145a38aabac2fd29984fe3 upstream.
The conversion of system address to physical memory address (as viewed by the memory controller) by igen6_edac is incorrect when the system address is above the TOM (Total amount Of populated physical Memory) for Elkhart Lake and Ice Lake (Neural Network Processor). Fix this conversion.
--- drivers/edac/igen6_edac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/edac/igen6_edac.c +1 -1
@@ -245,7 +245,7 @@ static u64 ehl_err_addr_to_imc_addr(u64if (igen6_tom <= _4GB)return eaddr + igen6_tolud - _4GB; -if (eaddr < _4GB) +if (eaddr >= igen6_tom)return eaddr + igen6_tolud - igen6_tom;return eaddr;
Greg Kroah-Hartman
maintainerPATCH 349/691 padata: use integer wrap around to prevent deadlock on seq_nr overflow
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: VanGiang Nguyen <[email protected]>
commit 9a22b2812393d93d84358a760c347c21939029a6 upstream.
When submitting more than 2^32 padata objects to padata_do_serial, the current sorting implementation incorrectly sorts padata objects with overflowed seq_nr, causing them to be placed before existing objects in the reorder list. This leads to a deadlock in the serialization process as padata_find_next cannot match padata->seq_nr and pd->processed because the padata instance with overflowed seq_nr will be selected next.
To fix this, we use an unsigned integer wrap around to correctly sort padata objects in scenarios with integer overflow.
--- kernel/padata.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
kernel/padata.c +2 -1
@@ -396,7 +396,8 @@ void padata_do_serial(struct padata_priv/* Sort in ascending order of sequence number. */ list_for_each_prev (pos, &reorder->list) { cur = list_entry(pos, struct padata_priv, list); -if (cur->seq_nr < padata->seq_nr) +/* Compare by difference to consider integer wrap around */ +if ((signed int )(cur->seq_nr - padata->seq_nr) <0 )break ; }list_add (&padata->list, pos);
Greg Kroah-Hartman
maintainerPATCH 350/691 soc: versatile: realview: fix memory leak during device remove
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Kozlowski <[email protected]>
[ Upstream commit 1c4f26a41f9d052f334f6ae629e01f598ed93508 ]
If device is unbound, the memory allocated for soc_dev_attr should be freed to prevent leaks.
Stable-dep-of: c774f2564c00 ("soc: versatile: realview: fix soc_dev leak during device remove")
--- drivers/soc/versatile/soc-realview.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
drivers/soc/versatile/soc-realview.c +3 -4
@@ -93,7 +93,7 @@ static int realview_soc_probe(struct platform_device *pdev)if (IS_ERR (syscon_regmap))return PTR_ERR (syscon_regmap); - soc_dev_attr =kzalloc (sizeof (*soc_dev_attr),GFP_KERNEL ); + soc_dev_attr =devm_kzalloc (&pdev->dev,sizeof (*soc_dev_attr),GFP_KERNEL );if (!soc_dev_attr)return -ENOMEM ;
@@ -106,10 +106,9 @@ static int realview_soc_probe(struct platform_device *pdev) soc_dev_attr->family ="Versatile" ; soc_dev_attr->custom_attr_group = realview_groups[0 ]; soc_dev =soc_device_register (soc_dev_attr); -if (IS_ERR (soc_dev)) { -kfree (soc_dev_attr); +if (IS_ERR (soc_dev))return -ENODEV ; - } + ret =regmap_read (syscon_regmap,REALVIEW_SYS_ID_OFFSET , &realview_coreid);if (ret)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 351/691 soc: versatile: realview: fix soc_dev leak during device remove
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Kozlowski <[email protected]>
[ Upstream commit c774f2564c0086c23f5269fd4691f233756bf075 ]
If device is unbound, the soc_dev should be unregistered to prevent memory leak.
--- drivers/soc/versatile/soc-realview.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
drivers/soc/versatile/soc-realview.c +13 -0
@@ -4,6 +4,7 @@* * Author: Linus Walleij <[email protected]> */ +#include <linux/device.h> #include <linux/init.h> #include <linux/io.h> #include <linux/slab.h>
@@ -81,6 +82,13 @@ static struct attribute *realview_attrs[] = {ATTRIBUTE_GROUPS (realview); +static void realview_soc_socdev_release (void *data) +{ +struct soc_device *soc_dev = data; + +soc_device_unregister (soc_dev); +} +static int realview_soc_probe (struct platform_device *pdev) {struct regmap *syscon_regmap;
@@ -109,6 +117,11 @@ static int realview_soc_probe(struct platform_device *pdev)if (IS_ERR (soc_dev))return -ENODEV ; + ret =devm_add_action_or_reset (&pdev->dev, realview_soc_socdev_release, + soc_dev); +if (ret) +return ret; + ret =regmap_read (syscon_regmap,REALVIEW_SYS_ID_OFFSET , &realview_coreid);if (ret)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 352/691 usb: yurex: Replace snprintf() with the safer scnprintf() variant
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lee Jones <[email protected]>
[ Upstream commit 86b20af11e84c26ae3fde4dcc4f490948e3f8035 ]
There is a general misunderstanding amongst engineers that {v}snprintf() returns the length of the data *actually* encoded into the destination array. However, as per the C99 standard {v}snprintf() really returns the length of the data that *would have been* written if there were enough space for it. This misunderstanding has led to buffer-overruns in the past. It's generally considered safer to use the {v}scnprintf() variants in their place (or even sprintf() in simple cases). So let's do that.
Whilst we're at it, let's define some magic numbers to increase readability and ease of maintenance.
Stable-dep-of: 93907620b308 ("USB: misc: yurex: fix race between read and write")
--- drivers/usb/misc/yurex.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
drivers/usb/misc/yurex.c +7 -5
@@ -34,6 +34,8 @@#define YUREX_BUF_SIZE 8#define YUREX_WRITE_TIMEOUT (HZ*2) +#define MAX_S64_STRLEN 20/* {-}922337203685477580{7,8} */ +/* table of devices that work with this driver */ static struct usb_device_id yurex_table[] = { {USB_DEVICE (YUREX_VENDOR_ID ,YUREX_PRODUCT_ID ) },
@@ -401,7 +403,7 @@ static ssize_t yurex_read(struct file *file, char __user *buffer, size_t count, {struct usb_yurex *dev;int len =0 ; -char in_buffer[20 ]; +char in_buffer[MAX_S64_STRLEN ];unsigned long flags; dev = file->private_data;
@@ -412,14 +414,14 @@ static ssize_t yurex_read(struct file *file, char __user *buffer, size_t count,return -ENODEV ; } +if (WARN_ON_ONCE (dev->bbu >S64_MAX || dev->bbu <S64_MIN )) +return -EIO ; +spin_lock_irqsave (&dev->lock, flags); - len =snprintf (in_buffer,20 ,"%lld\n" , dev->bbu); +scnprintf (in_buffer,MAX_S64_STRLEN ,"%lld\n" , dev->bbu);spin_unlock_irqrestore (&dev->lock, flags);mutex_unlock (&dev->io_mutex); -if (WARN_ON_ONCE (len >=sizeof (in_buffer))) -return -EIO ; -return simple_read_from_buffer (buffer, count, ppos, in_buffer, len); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 353/691 USB: misc: yurex: fix race between read and write
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Neukum <[email protected]>
[ Upstream commit 93907620b308609c72ba4b95b09a6aa2658bb553 ]
The write code path touches the bbu member in a non atomic manner without taking the spinlock. Fix it.
The bug is as old as the driver.
--- drivers/usb/misc/yurex.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
drivers/usb/misc/yurex.c +6 -4
@@ -404,7 +404,6 @@ static ssize_t yurex_read(struct file *file, char __user *buffer, size_t count,struct usb_yurex *dev;int len =0 ;char in_buffer[MAX_S64_STRLEN ]; -unsigned long flags; dev = file->private_data;
@@ -417,9 +416,9 @@ static ssize_t yurex_read(struct file *file, char __user *buffer, size_t count,if (WARN_ON_ONCE (dev->bbu >S64_MAX || dev->bbu <S64_MIN ))return -EIO ; -spin_lock_irqsave (&dev->lock, flags); +spin_lock_irq (&dev->lock);scnprintf (in_buffer,MAX_S64_STRLEN ,"%lld\n" , dev->bbu); -spin_unlock_irqrestore (&dev->lock, flags); +spin_unlock_irq (&dev->lock);mutex_unlock (&dev->io_mutex);return simple_read_from_buffer (buffer, count, ppos, in_buffer, len);
@@ -509,8 +508,11 @@ static ssize_t yurex_write(struct file *file, const char __user *user_buffer, __func__, retval); goto error; } -if (set && timeout) +if (set && timeout) { +spin_lock_irq (&dev->lock); dev->bbu = c2; +spin_unlock_irq (&dev->lock); + }return timeout ? count : -EIO ; error:
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 354/691 xhci: fix event ring segment table related masks and variables in header
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mathias Nyman <[email protected]>
[ Upstream commit 8c1cbec9db1ab044167a7594c88bb5906c9d3ee4 ]
xHC controller can supports up to 1024 interrupters. To fit these change the max_interrupters varable from u8 to u16.
Add a separate mask for the reserve and preserve bits [5:0] in the erst base register and use it instead of the ERST_PRT_MASK. ERSR_PTR_MASK [3:0] is intended for masking bits in the event ring dequeue pointer register.
Stable-dep-of: e5fa8db0be3e ("usb: xhci: fix loss of data on Cadence xHC")
--- drivers/usb/host/xhci-mem.c | 4 ++-- drivers/usb/host/xhci.h | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-)
drivers/usb/host/xhci-mem.c +2 -2
@@ -2572,8 +2572,8 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)"// Set ERST base address for ir_set 0 = 0x%llx" , (unsigned long long)xhci->erst.erst_dma_addr); val_64 =xhci_read_64 (xhci, &xhci->ir_set->erst_base); - val_64 &=ERST_PTR_MASK ; - val_64 |= (xhci->erst.erst_dma_addr & (u64 ) ~ERST_PTR_MASK ); + val_64 &=ERST_BASE_RSVDP ; + val_64 |= (xhci->erst.erst_dma_addr & (u64 ) ~ERST_BASE_RSVDP );xhci_write_64 (xhci, val_64, &xhci->ir_set->erst_base);/* Set the event ring dequeue address */
drivers/usb/host/xhci.h +4 -1
@@ -513,6 +513,9 @@ struct xhci_intr_reg {/* Preserve bits 16:31 of erst_size */ #define ERST_SIZE_MASK (0xffff << 16) +/* erst_base bitmasks */ +#define ERST_BASE_RSVDP (0x3f) +/* erst_dequeue bitmasks */ /* Dequeue ERST Segment Index (DESI) - Segment number (or alias) * where the current dequeue pointer lies. This is an optional HW hint.
@@ -1777,7 +1780,7 @@ struct xhci_hcd {u8 sbrn;u16 hci_version;u8 max_slots; -u8 max_interrupters; +u16 max_interrupters;u8 max_ports;u8 isoc_threshold;/* imod_interval in ns (I * 250ns) */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 355/691 xhci: remove xhci_test_trb_in_td_math early development check
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mathias Nyman <[email protected]>
[ Upstream commit 54f9927dfe2266402a226d5f51d38236bdca0590 ]
Time to remove this test trb in td math check that was added in early stage of xhci driver development.
It verified that the size, alignment and boundaries of the event and command rings allocated by the driver itself are correct.
Stable-dep-of: e5fa8db0be3e ("usb: xhci: fix loss of data on Cadence xHC")
--- drivers/usb/host/xhci-mem.c | 160 ------------------------------------ 1 file changed, 160 deletions(-)
drivers/usb/host/xhci-mem.c +0 -160
@@ -1941,164 +1941,6 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) xhci->usb3_rhub.bus_state.bus_suspended =0 ; } -static int xhci_test_trb_in_td (struct xhci_hcd *xhci, -struct xhci_segment *input_seg, -union xhci_trb *start_trb, -union xhci_trb *end_trb, -dma_addr_t input_dma, -struct xhci_segment *result_seg, -char *test_name,int test_number) -{ -unsigned long long start_dma; -unsigned long long end_dma; -struct xhci_segment *seg; - - start_dma =xhci_trb_virt_to_dma (input_seg, start_trb); - end_dma =xhci_trb_virt_to_dma (input_seg, end_trb); - - seg =trb_in_td (xhci, input_seg, start_trb, end_trb, input_dma, false); -if (seg != result_seg) { -xhci_warn (xhci,"WARN: %s TRB math test %d failed!\n" , - test_name, test_number); -xhci_warn (xhci,"Tested TRB math w/ seg %p and " -"input DMA 0x%llx\n" , - input_seg, - (unsigned long long ) input_dma); -xhci_warn (xhci,"starting TRB %p (0x%llx DMA), " -"ending TRB %p (0x%llx DMA)\n" , - start_trb, start_dma, - end_trb, end_dma); -xhci_warn (xhci,"Expected seg %p, got seg %p\n" , - result_seg, seg); -trb_in_td (xhci, input_seg, start_trb, end_trb, input_dma, - true); -return -1 ; - } -return 0 ; -} - -/* TRB math checks for xhci_trb_in_td(), using the command and event rings. */ -static int xhci_check_trb_in_td_math (struct xhci_hcd *xhci) -{ -struct { -dma_addr_t input_dma; -struct xhci_segment *result_seg; - } simple_test_vector [] = { -/* A zeroed DMA field should fail */ - {0 ,NULL }, -/* One TRB before the ring start should fail */ - { xhci->event_ring->first_seg->dma -16 ,NULL }, -/* One byte before the ring start should fail */ - { xhci->event_ring->first_seg->dma -1 ,NULL }, -/* Starting TRB should succeed */ - { xhci->event_ring->first_seg->dma, xhci->event_ring->first_seg }, -/* Ending TRB should succeed */ - { xhci->event_ring->first_seg->dma + (TRBS_PER_SEGMENT -1 )*16 , - xhci->event_ring->first_seg }, -/* One byte after the ring end should fail */ - { xhci->event_ring->first_seg->dma + (TRBS_PER_SEGMENT -1 )*16 +1 ,NULL }, -/* One TRB after the ring end should fail */ - { xhci->event_ring->first_seg->dma + (TRBS_PER_SEGMENT )*16 ,NULL }, -/* An address of all ones should fail */ - { (dma_addr_t) (~0 ),NULL }, - }; -struct { -struct xhci_segment *input_seg; -union xhci_trb *start_trb; -union xhci_trb *end_trb; -dma_addr_t input_dma; -struct xhci_segment *result_seg; - } complex_test_vector [] = { -/* Test feeding a valid DMA address from a different ring */ - { .input_seg = xhci->event_ring->first_seg, - .start_trb = xhci->event_ring->first_seg->trbs, - .end_trb = &xhci->event_ring->first_seg->trbs[TRBS_PER_SEGMENT -1 ], - .input_dma = xhci->cmd_ring->first_seg->dma, - .result_seg =NULL , - }, -/* Test feeding a valid end TRB from a different ring */ - { .input_seg = xhci->event_ring->first_seg, - .start_trb = xhci->event_ring->first_seg->trbs, - .end_trb = &xhci->cmd_ring->first_seg->trbs[TRBS_PER_SEGMENT -1 ], - .input_dma = xhci->cmd_ring->first_seg->dma, - .result_seg =NULL , - }, -/* Test feeding a valid start and end TRB from a different ring */ - { .input_seg = xhci->event_ring->first_seg, - .start_trb = xhci->cmd_ring->first_seg->trbs, - .end_trb = &xhci->cmd_ring->first_seg->trbs[TRBS_PER_SEGMENT -1 ], - .input_dma = xhci->cmd_ring->first_seg->dma, - .result_seg =NULL , - }, -/* TRB in this ring, but after this TD */ - { .input_seg = xhci->event_ring->first_seg, - .start_trb = &xhci->event_ring->first_seg->trbs[0 ], - .end_trb = &xhci->event_ring->first_seg->trbs[3 ], - .input_dma = xhci->event_ring->first_seg->dma +4 *16 , - .result_seg =NULL , - }, -/* TRB in this ring, but before this TD */ - { .input_seg = xhci->event_ring->first_seg, - .start_trb = &xhci->event_ring->first_seg->trbs[3 ], - .end_trb = &xhci->event_ring->first_seg->trbs[6 ], - .input_dma = xhci->event_ring->first_seg->dma +2 *16 , - .result_seg =NULL , - }, -/* TRB in this ring, but after this wrapped TD */ - { .input_seg = xhci->event_ring->first_seg, - .start_trb = &xhci->event_ring->first_seg->trbs[TRBS_PER_SEGMENT -3 ], - .end_trb = &xhci->event_ring->first_seg->trbs[1 ], - .input_dma = xhci->event_ring->first_seg->dma +2 *16 , - .result_seg =NULL , - }, -/* TRB in this ring, but before this wrapped TD */ - { .input_seg = xhci->event_ring->first_seg, - .start_trb = &xhci->event_ring->first_seg->trbs[TRBS_PER_SEGMENT -3 ], - .end_trb = &xhci->event_ring->first_seg->trbs[1 ], - .input_dma = xhci->event_ring->first_seg->dma + (TRBS_PER_SEGMENT -4 )*16 , - .result_seg =NULL , - }, -/* TRB not in this ring, and we have a wrapped TD */ - { .input_seg = xhci->event_ring->first_seg, - .start_trb = &xhci->event_ring->first_seg->trbs[TRBS_PER_SEGMENT -3 ], - .end_trb = &xhci->event_ring->first_seg->trbs[1 ], - .input_dma = xhci->cmd_ring->first_seg->dma +2 *16 , - .result_seg =NULL , - }, - }; - -unsigned int num_tests; -int i, ret; - - num_tests =ARRAY_SIZE (simple_test_vector); -for (i =0 ; i < num_tests; i++) { - ret =xhci_test_trb_in_td (xhci, - xhci->event_ring->first_seg, - xhci->event_ring->first_seg->trbs, - &xhci->event_ring->first_seg->trbs[TRBS_PER_SEGMENT -1 ], - simple_test_vector[i].input_dma, - simple_test_vector[i].result_seg, -"Simple" , i); -if (ret <0 ) -return ret; - } - - num_tests =ARRAY_SIZE (complex_test_vector); -for (i =0 ; i < num_tests; i++) { - ret =xhci_test_trb_in_td (xhci, - complex_test_vector[i].input_seg, - complex_test_vector[i].start_trb, - complex_test_vector[i].end_trb, - complex_test_vector[i].input_dma, - complex_test_vector[i].result_seg, -"Complex" , i); -if (ret <0 ) -return ret; - } -xhci_dbg (xhci,"TRB math tests passed.\n" ); -return 0 ; -} -static void xhci_set_hc_event_deq (struct xhci_hcd *xhci) {u64 temp;
@@ -2549,8 +2391,6 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) 0, flags);if (!xhci->event_ring) goto fail; -if (xhci_check_trb_in_td_math (xhci) <0 ) - goto fail; ret =xhci_alloc_erst (xhci, xhci->event_ring, &xhci->erst, flags);if (ret)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 356/691 xhci: Refactor interrupter code for initial multi interrupter support.
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mathias Nyman <[email protected]>
[ Upstream commit b17a57f89f69069458d0a9d9b04281ce48da7ebb ]
xHC supports several interrupters, each with its own mmio register set, event ring and MSI/MSI-X vector. Transfers can be assigned different interrupters when queued. See xhci 4.17 for details.
Current driver only supports one interrupter.
Create a xhci_interrupter structure containing an event ring, pointer to mmio registers for this interrupter, variables to store registers over s3 suspend, erst, etc. Add functions to create and free an interrupter, and pass an interrupter pointer to functions that deal with events.
Secondary interrupters are also useful without having an interrupt vector. One use case is the xHCI audio sideband offloading where a DSP can take care of specific audio endpoints.
When all transfer events of an offloaded endpoint can be mapped to a separate interrupter event ring the DSP can poll this ring, and we can mask these events preventing waking up the CPU.
Only minor functional changes such as clearing some of the interrupter registers when freeing the interrupter.
Still create only one primary interrupter.
Stable-dep-of: e5fa8db0be3e ("usb: xhci: fix loss of data on Cadence xHC")
--- drivers/usb/host/xhci-debugfs.c | 2 +- drivers/usb/host/xhci-mem.c | 168 +++++++++++++++++++++----------- drivers/usb/host/xhci-ring.c | 68 +++++++------ drivers/usb/host/xhci.c | 54 ++++++---- drivers/usb/host/xhci.h | 24 +++-- 5 files changed, 196 insertions(+), 120 deletions(-)
drivers/usb/host/xhci-debugfs.c +1 -1
@@ -693,7 +693,7 @@ void xhci_debugfs_init(struct xhci_hcd *xhci)"command-ring" , xhci->debugfs_root); -xhci_debugfs_create_ring_dir (xhci, &xhci->event_ring, +xhci_debugfs_create_ring_dir (xhci, &xhci->interrupter->event_ring,"event-ring" , xhci->debugfs_root);
drivers/usb/host/xhci-mem.c +110 -58
223 lines not on this page · raw message
drivers/usb/host/xhci-ring.c +37 -31
192 lines not on this page · raw message
drivers/usb/host/xhci.c +34 -20
122 lines not on this page · raw message
drivers/usb/host/xhci.h +14 -10
@@ -1691,11 +1691,6 @@ struct s3_save {u32 dev_nt;u64 dcbaa_ptr;u32 config_reg; -u32 irq_pending; -u32 irq_control; -u32 erst_size; -u64 erst_base; -u64 erst_dequeue; };/* Use for lpm */
@@ -1717,7 +1712,18 @@ struct xhci_bus_state {unsigned long resuming_ports; }; - +struct xhci_interrupter { +struct xhci_ring *event_ring; +struct xhci_erst erst; +struct xhci_intr_reg __iomem *ir_set; +unsigned int intr_num; +/* For interrupter registers save and restore over suspend/resume */ +u32 s3_irq_pending; +u32 s3_irq_control; +u32 s3_erst_size; +u64 s3_erst_base; +u64 s3_erst_dequeue; +};/* * It can take up to 20 ms to transition from RExit to U0 on the * Intel Lynx Point LP xHCI host.
@@ -1764,8 +1770,6 @@ struct xhci_hcd {struct xhci_op_regs __iomem *op_regs;struct xhci_run_regs __iomem *run_regs;struct xhci_doorbell_array __iomem *dba; -/* Our HCD's current interrupter register set */ -struct xhci_intr_reg __iomem *ir_set;/* Cached register copies of read-only HC data */ __u32 hcs_params1;
@@ -1800,6 +1804,7 @@ struct xhci_hcd {struct reset_control *reset;/* data structures */ struct xhci_device_context_array *dcbaa; +struct xhci_interrupter *interrupter;struct xhci_ring *cmd_ring;unsigned int cmd_ring_state;#define CMD_RING_STATE_RUNNING (1 << 0)
@@ -1810,8 +1815,7 @@ struct xhci_hcd {struct delayed_work cmd_timer;struct completion cmd_ring_stop_completion;struct xhci_command *current_cmd; -struct xhci_ring *event_ring; -struct xhci_erst erst; +/* Scratchpad */ struct xhci_scratchpad *scratchpad;/* Store LPM test failed devices' information */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 357/691 xhci: Preserve RsvdP bits in ERSTBA register correctly
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lukas Wunner <[email protected]>
[ Upstream commit cf97c5e0f7dda2edc15ecd96775fe6c355823784 ]
xhci_add_interrupter() erroneously preserves only the lowest 4 bits when writing the ERSTBA register, not the lowest 6 bits. Fix it.
Migrate the ERST_BASE_RSVDP macro to the modern GENMASK_ULL() syntax to avoid a u64 cast.
This was previously fixed by commit 8c1cbec9db1a ("xhci: fix event ring segment table related masks and variables in header"), but immediately undone by commit b17a57f89f69 ("xhci: Refactor interrupter code for initial multi interrupter support.").
Stable-dep-of: e5fa8db0be3e ("usb: xhci: fix loss of data on Cadence xHC")
--- drivers/usb/host/xhci-mem.c | 4 ++-- drivers/usb/host/xhci.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-)
drivers/usb/host/xhci-mem.c +2 -2
@@ -2316,8 +2316,8 @@ xhci_alloc_interrupter(struct xhci_hcd *xhci, unsigned int intr_num, gfp_t flagswritel (erst_size, &ir->ir_set->erst_size); erst_base =xhci_read_64 (xhci, &ir->ir_set->erst_base); - erst_base &=ERST_PTR_MASK ; - erst_base |= (ir->erst.erst_dma_addr & (u64 ) ~ERST_PTR_MASK ); + erst_base &=ERST_BASE_RSVDP ; + erst_base |= ir->erst.erst_dma_addr & ~ERST_BASE_RSVDP ;xhci_write_64 (xhci, erst_base, &ir->ir_set->erst_base);/* Set the event ring dequeue address of this interrupter */
drivers/usb/host/xhci.h +1 -1
@@ -514,7 +514,7 @@ struct xhci_intr_reg {#define ERST_SIZE_MASK (0xffff << 16)/* erst_base bitmasks */ -#define ERST_BASE_RSVDP (0x3f) +#define ERST_BASE_RSVDP (GENMASK_ULL(5, 0))/* erst_dequeue bitmasks */ /* Dequeue ERST Segment Index (DESI) - Segment number (or alias)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 358/691 xhci: Add a quirk for writing ERST in high-low order
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daehwan Jung <[email protected]>
[ Upstream commit bc162403e33e1d57e40994977acaf19f1434e460 ]
This quirk is for the controller that has a limitation in supporting separate ERSTBA_HI and ERSTBA_LO programming. It's supported when the ERSTBA is programmed ERSTBA_HI before ERSTBA_LO. That's because the internal initialization of event ring fetches the "Event Ring Segment Table Entry" based on the indication of ERSTBA_LO written.
Stable-dep-of: e5fa8db0be3e ("usb: xhci: fix loss of data on Cadence xHC")
--- drivers/usb/host/xhci-mem.c | 5 ++++- drivers/usb/host/xhci.h | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-)
drivers/usb/host/xhci-mem.c +4 -1
@@ -2318,7 +2318,10 @@ xhci_alloc_interrupter(struct xhci_hcd *xhci, unsigned int intr_num, gfp_t flags erst_base =xhci_read_64 (xhci, &ir->ir_set->erst_base); erst_base &=ERST_BASE_RSVDP ; erst_base |= ir->erst.erst_dma_addr & ~ERST_BASE_RSVDP ; -xhci_write_64 (xhci, erst_base, &ir->ir_set->erst_base); +if (xhci->quirks &XHCI_WRITE_64_HI_LO ) +hi_lo_writeq (erst_base, &ir->ir_set->erst_base); +else +xhci_write_64 (xhci, erst_base, &ir->ir_set->erst_base);/* Set the event ring dequeue address of this interrupter */ xhci_set_hc_event_deq (xhci, ir);
drivers/usb/host/xhci.h +2 -0
@@ -17,6 +17,7 @@#include <linux/kernel.h> #include <linux/usb/hcd.h> #include <linux/io-64-nonatomic-lo-hi.h> +#include <linux/io-64-nonatomic-hi-lo.h> /* Code sharing between pci-quirks and xhci hcd */ #include "xhci-ext-caps.h"
@@ -1916,6 +1917,7 @@ struct xhci_hcd {#define XHCI_RESET_TO_DEFAULT BIT_ULL(44)#define XHCI_ZHAOXIN_TRB_FETCH BIT_ULL(45)#define XHCI_ZHAOXIN_HOST BIT_ULL(46) +#define XHCI_WRITE_64_HI_LO BIT_ULL(47)unsigned int num_active_eps;unsigned int limit_active_eps;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 359/691 usb: xhci: fix loss of data on Cadence xHC
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pawel Laszczak <[email protected]>
[ Upstream commit e5fa8db0be3e8757e8641600c518425a4589b85c ]
Streams should flush their TRB cache, re-read TRBs, and start executing TRBs from the beginning of the new dequeue pointer after a 'Set TR Dequeue Pointer' command.
Cadence controllers may fail to start from the beginning of the dequeue TRB as it doesn't clear the Opaque 'RsvdO' field of the stream context during 'Set TR Dequeue' command. This stream context area is where xHC stores information about the last partially executed TD when a stream is stopped. xHC uses this information to resume the transfer where it left mid TD, when the stream is restarted.
Patch fixes this by clearing out all RsvdO fields before initializing new Stream transfer using a 'Set TR Dequeue Pointer' command.
--- drivers/usb/cdns3/host.c | 4 +++- drivers/usb/host/xhci-pci.c | 7 +++++++ drivers/usb/host/xhci-ring.c | 14 ++++++++++++++ drivers/usb/host/xhci.h | 1 + 4 files changed, 25 insertions(+), 1 deletion(-)
drivers/usb/cdns3/host.c +3 -1
@@ -61,7 +61,9 @@ static const struct xhci_plat_priv xhci_plat_cdns3_xhci = { .resume_quirk = xhci_cdns3_resume_quirk, }; -static const struct xhci_plat_priv xhci_plat_cdnsp_xhci; +static const struct xhci_plat_priv xhci_plat_cdnsp_xhci = { + .quirks =XHCI_CDNS_SCTX_QUIRK , +};static int __cdns_host_init (struct cdns *cdns) {
drivers/usb/host/xhci-pci.c +7 -0
@@ -75,6 +75,9 @@#define PCI_DEVICE_ID_ASMEDIA_2142_XHCI 0x2142#define PCI_DEVICE_ID_ASMEDIA_3242_XHCI 0x3242 +#define PCI_DEVICE_ID_CADENCE 0x17CD +#define PCI_DEVICE_ID_CADENCE_SSP 0x0200 +static const char hcd_name[] ="xhci_hcd" ;static struct hc_driver __read_mostly xhci_pci_hc_driver;
@@ -353,6 +356,10 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) xhci->quirks |=XHCI_ZHAOXIN_TRB_FETCH ; } +if (pdev->vendor ==PCI_DEVICE_ID_CADENCE && + pdev->device ==PCI_DEVICE_ID_CADENCE_SSP ) + xhci->quirks |=XHCI_CDNS_SCTX_QUIRK ; +/* xHC spec requires PCI devices to support D3hot and D3cold */ if (xhci->hci_version >=0x120 ) xhci->quirks |=XHCI_DEFAULT_PM_RUNTIME_ALLOW ;
drivers/usb/host/xhci-ring.c +14 -0
@@ -1446,6 +1446,20 @@ static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci, int slot_id,struct xhci_stream_ctx *ctx = &ep->stream_info->stream_ctx_array[stream_id]; deq =le64_to_cpu (ctx->stream_ring) &SCTX_DEQ_MASK ; + +/* +* Cadence xHCI controllers store some endpoint state +* information within Rsvd0 fields of Stream Endpoint +* context. This field is not cleared during Set TR +* Dequeue Pointer command which causes XDMA to skip +* over transfer ring and leads to data loss on stream +* pipe. +* To fix this issue driver must clear Rsvd0 field. +*/ +if (xhci->quirks &XHCI_CDNS_SCTX_QUIRK ) { + ctx->reserved[0 ] =0 ; + ctx->reserved[1 ] =0 ; + } }else { deq =le64_to_cpu (ep_ctx->deq) & ~EP_CTX_CYCLE_MASK ; }
drivers/usb/host/xhci.h +1 -0
@@ -1918,6 +1918,7 @@ struct xhci_hcd {#define XHCI_ZHAOXIN_TRB_FETCH BIT_ULL(45)#define XHCI_ZHAOXIN_HOST BIT_ULL(46)#define XHCI_WRITE_64_HI_LO BIT_ULL(47) +#define XHCI_CDNS_SCTX_QUIRK BIT_ULL(48)unsigned int num_active_eps;unsigned int limit_active_eps;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 360/691 pps: remove usage of the deprecated ida_simple_xx() API
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christophe JAILLET <[email protected]>
[ Upstream commit 55dbc5b5174d0e7d1fa397d05aa4cb145e8b887e ]
ida_alloc() and ida_free() should be preferred to the deprecated ida_simple_get() and ida_simple_remove().
This is less verbose.
Stable-dep-of: 62c5a01a5711 ("pps: add an error check in parport_attach")
--- drivers/pps/clients/pps_parport.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/pps/clients/pps_parport.c +3 -3
@@ -148,7 +148,7 @@ static void parport_attach(struct parport *port)return ; } - index =ida_simple_get (&pps_client_index,0 ,0 ,GFP_KERNEL ); + index =ida_alloc (&pps_client_index,GFP_KERNEL );memset (&pps_client_cb,0 ,sizeof (pps_client_cb)); pps_client_cb.private = device; pps_client_cb.irq_func = parport_irq;
@@ -188,7 +188,7 @@ static void parport_attach(struct parport *port) err_unregister_dev:parport_unregister_device (device->pardev); err_free: -ida_simple_remove (&pps_client_index, index); +ida_free (&pps_client_index, index);kfree (device); }
@@ -208,7 +208,7 @@ static void parport_detach(struct parport *port)pps_unregister_source (device->pps);parport_release (pardev);parport_unregister_device (pardev); -ida_simple_remove (&pps_client_index, device->index); +ida_free (&pps_client_index, device->index);kfree (device); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 361/691 pps: add an error check in parport_attach
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ma Ke <[email protected]>
[ Upstream commit 62c5a01a5711c8e4be8ae7b6f0db663094615d48 ]
In parport_attach, the return value of ida_alloc is unchecked, witch leads to the use of an invalid index value.
To address this issue, index should be checked. When the index value is abnormal, the device should be freed.
Found by code review, compile tested only.
--- drivers/pps/clients/pps_parport.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/pps/clients/pps_parport.c +6 -2
@@ -149,6 +149,9 @@ static void parport_attach(struct parport *port) } index =ida_alloc (&pps_client_index,GFP_KERNEL ); +if (index <0 ) + goto err_free_device; +memset (&pps_client_cb,0 ,sizeof (pps_client_cb)); pps_client_cb.private = device; pps_client_cb.irq_func = parport_irq;
@@ -159,7 +162,7 @@ static void parport_attach(struct parport *port) index);if (!device->pardev) {pr_err ("couldn't register with %s\n" , port->name); - goto err_free; + goto err_free_ida; }if (parport_claim_or_block (device->pardev) <0 ) {
@@ -187,8 +190,9 @@ static void parport_attach(struct parport *port)parport_release (device->pardev); err_unregister_dev:parport_unregister_device (device->pardev); -err_free: +err_free_ida:ida_free (&pps_client_index, index); +err_free_device:kfree (device); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 362/691 x86/idtentry: Incorporate definitions/declarations of the FRED entries
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xin Li <[email protected]>
[ Upstream commit 90f357208200a941e90e75757123326684d715d0 ]
FRED and IDT can share most of the definitions and declarations so that in the majority of cases the actual handler implementation is the same.
The differences are the exceptions where FRED stores exception related information on the stack and the sysvec implementations as FRED can handle irqentry/exit() in the dispatcher instead of having it in each handler.
Also add stub defines for vectors which are not used due to Kconfig decisions to spare the ifdeffery in the actual FRED dispatch code.
Stable-dep-of: 477d81a1c47a ("x86/entry: Remove unwanted instrumentation in common_interrupt()")
--- arch/x86/include/asm/idtentry.h | 71 +++++++++++++++++++++++++++++---- 1 file changed, 63 insertions(+), 8 deletions(-)
arch/x86/include/asm/idtentry.h +63 -8
@@ -11,15 +11,18 @@#include <asm/irq_stack.h> +typedef void (*idtentry_t )(struct pt_regs *regs); +/** * DECLARE_IDTENTRY - Declare functions for simple IDT entry points * No error code pushed by hardware * @vector: Vector number (ignored for C) * @func: Function name of the entry point * -* Declares three functions: +* Declares four functions: * - The ASM entry point: asm_##func * - The XEN PV trap entry point: xen_##func (maybe unused) +* - The C handler called from the FRED event dispatcher (maybe unused) * - The C handler called from the ASM entry point * * Note: This is the C variant of DECLARE_IDTENTRY(). As the name says it
@@ -29,6 +32,7 @@#define DECLARE_IDTENTRY (vector, func) \ asmlinkage void asm_##func(void); \ asmlinkage void xen_asm_##func(void); \ + void fred_##func(struct pt_regs *regs); \ __visible void func(struct pt_regs *regs)/**
@@ -135,6 +139,17 @@ static __always_inline void __##func(struct pt_regs *regs, \#define DEFINE_IDTENTRY_RAW (func) \ __visible noinstr void func(struct pt_regs *regs) +/** +* DEFINE_FREDENTRY_RAW - Emit code for raw FRED entry points +* @func: Function name of the entry point +* +* @func is called from the FRED event dispatcher with interrupts disabled. +* +* See @DEFINE_IDTENTRY_RAW for further details. +*/ +#define DEFINE_FREDENTRY_RAW (func) \ +noinstr void fred_##func(struct pt_regs *regs) +/** * DECLARE_IDTENTRY_RAW_ERRORCODE - Declare functions for raw IDT entry points * Error code pushed by hardware
@@ -231,17 +246,27 @@ static noinline void __##func(struct pt_regs *regs, u32 vector)#define DEFINE_IDTENTRY_SYSVEC (func) \ static void __##func(struct pt_regs *regs); \ \ +static __always_inline void instr_##func(struct pt_regs *regs) \ +{ \ + kvm_set_cpu_l1tf_flush_l1d(); \ + run_sysvec_on_irqstack_cond(__##func, regs); \ +} \ + \ __visible noinstr void func(struct pt_regs *regs) \ { \ irqentry_state_t state = irqentry_enter(regs); \ \ instrumentation_begin(); \ - kvm_set_cpu_l1tf_flush_l1d(); \ - run_sysvec_on_irqstack_cond(__##func, regs); \ + instr_##func (regs); \ instrumentation_end(); \ irqentry_exit(regs, state); \ } \ \ +void fred_##func(struct pt_regs *regs) \ +{ \ + instr_##func (regs); \ +} \ + \ static noinline void __##func(struct pt_regs *regs)/**
@@ -258,19 +283,29 @@ static noinline void __##func(struct pt_regs *regs)#define DEFINE_IDTENTRY_SYSVEC_SIMPLE (func) \ static __always_inline void __##func(struct pt_regs *regs); \ \ -__visible noinstr void func(struct pt_regs *regs) \ +static __always_inline void instr_##func(struct pt_regs *regs) \ { \ - irqentry_state_t state = irqentry_enter(regs); \ - \ - instrumentation_begin(); \ __irq_enter_raw(); \ kvm_set_cpu_l1tf_flush_l1d(); \ __##func (regs); \ __irq_exit_raw(); \ +} \ + \ +__visible noinstr void func(struct pt_regs *regs) \ +{ \ + irqentry_state_t state = irqentry_enter(regs); \ + \ + instrumentation_begin(); \ + instr_##func (regs); \ instrumentation_end(); \ irqentry_exit(regs, state); \ } \ \ +void fred_##func(struct pt_regs *regs) \ +{ \ + instr_##func (regs); \ +} \ + \ static __always_inline void __##func(struct pt_regs *regs)/**
@@ -408,15 +443,18 @@ __visible noinstr void func(struct pt_regs *regs, \/* C-Code mapping */ #define DECLARE_IDTENTRY_NMI DECLARE_IDTENTRY_RAW#define DEFINE_IDTENTRY_NMI DEFINE_IDTENTRY_RAW +#define DEFINE_FREDENTRY_NMI DEFINE_FREDENTRY_RAW#ifdef CONFIG_X86_64 #define DECLARE_IDTENTRY_MCE DECLARE_IDTENTRY_IST#define DEFINE_IDTENTRY_MCE DEFINE_IDTENTRY_IST#define DEFINE_IDTENTRY_MCE_USER DEFINE_IDTENTRY_NOIST +#define DEFINE_FREDENTRY_MCE DEFINE_FREDENTRY_RAW#define DECLARE_IDTENTRY_DEBUG DECLARE_IDTENTRY_IST#define DEFINE_IDTENTRY_DEBUG DEFINE_IDTENTRY_IST#define DEFINE_IDTENTRY_DEBUG_USER DEFINE_IDTENTRY_NOIST +#define DEFINE_FREDENTRY_DEBUG DEFINE_FREDENTRY_RAW#endif #else /* !__ASSEMBLY__ */
@@ -645,23 +683,36 @@ DECLARE_IDTENTRY_SYSVEC(IRQ_MOVE_CLEANUP_VECTOR, sysvec_irq_move_cleanup);DECLARE_IDTENTRY_SYSVEC (REBOOT_VECTOR , sysvec_reboot);DECLARE_IDTENTRY_SYSVEC (CALL_FUNCTION_SINGLE_VECTOR , sysvec_call_function_single);DECLARE_IDTENTRY_SYSVEC (CALL_FUNCTION_VECTOR , sysvec_call_function); +#else +# define fred_sysvec_reschedule_ipi NULL +# define fred_sysvec_reboot NULL +# define fred_sysvec_call_function_single NULL +# define fred_sysvec_call_function NULL#endif #ifdef CONFIG_X86_LOCAL_APIC # ifdef CONFIG_X86_MCE_THRESHOLD DECLARE_IDTENTRY_SYSVEC (THRESHOLD_APIC_VECTOR , sysvec_threshold); +# else +# define fred_sysvec_threshold NULL# endif # ifdef CONFIG_X86_MCE_AMD DECLARE_IDTENTRY_SYSVEC (DEFERRED_ERROR_VECTOR , sysvec_deferred_error); +# else +# define fred_sysvec_deferred_error NULL# endif # ifdef CONFIG_X86_THERMAL_VECTOR DECLARE_IDTENTRY_SYSVEC (THERMAL_APIC_VECTOR , sysvec_thermal); +# else +# define fred_sysvec_thermal NULL# endif # ifdef CONFIG_IRQ_WORK DECLARE_IDTENTRY_SYSVEC (IRQ_WORK_VECTOR , sysvec_irq_work); +# else +# define fred_sysvec_irq_work NULL# endif #endif
@@ -669,12 +720,16 @@ DECLARE_IDTENTRY_SYSVEC(IRQ_WORK_VECTOR, sysvec_irq_work);DECLARE_IDTENTRY_SYSVEC (POSTED_INTR_VECTOR , sysvec_kvm_posted_intr_ipi);DECLARE_IDTENTRY_SYSVEC (POSTED_INTR_WAKEUP_VECTOR , sysvec_kvm_posted_intr_wakeup_ipi);DECLARE_IDTENTRY_SYSVEC (POSTED_INTR_NESTED_VECTOR , sysvec_kvm_posted_intr_nested_ipi); +#else +# define fred_sysvec_kvm_posted_intr_ipi NULL +# define fred_sysvec_kvm_posted_intr_wakeup_ipi NULL +# define fred_sysvec_kvm_posted_intr_nested_ipi NULL#endif #if IS_ENABLED (CONFIG_HYPERV )DECLARE_IDTENTRY_SYSVEC (HYPERVISOR_CALLBACK_VECTOR , sysvec_hyperv_callback);DECLARE_IDTENTRY_SYSVEC (HYPERV_REENLIGHTENMENT_VECTOR , sysvec_hyperv_reenlightenment); -DECLARE_IDTENTRY_SYSVEC (HYPERV_STIMER0_VECTOR , sysvec_hyperv_stimer0); +DECLARE_IDTENTRY_SYSVEC (HYPERV_STIMER0_VECTOR , sysvec_hyperv_stimer0);#endif #if IS_ENABLED (CONFIG_ACRN_GUEST )
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 363/691 x86/entry: Remove unwanted instrumentation in common_interrupt()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Vyukov <[email protected]>
[ Upstream commit 477d81a1c47a1b79b9c08fc92b5dea3c5143800b ]
common_interrupt() and related variants call kvm_set_cpu_l1tf_flush_l1d(), which is neither marked noinstr nor __always_inline.
So compiler puts it out of line and adds instrumentation to it. Since the call is inside of instrumentation_begin/end(), objtool does not warn about it.
The manifestation is that KCOV produces spurious coverage in kvm_set_cpu_l1tf_flush_l1d() in random places because the call happens when preempt count is not yet updated to say that the kernel is in an interrupt.
Mark kvm_set_cpu_l1tf_flush_l1d() as __always_inline and move it out of the instrumentation_begin/end() section. It only calls __this_cpu_write() which is already safe to call in noinstr contexts.
--- arch/x86/include/asm/hardirq.h | 8 ++++++-- arch/x86/include/asm/idtentry.h | 6 +++--- 2 files changed, 9 insertions(+), 5 deletions(-)
arch/x86/include/asm/hardirq.h +6 -2
@@ -62,7 +62,11 @@ extern u64 arch_irq_stat(void);#if IS_ENABLED (CONFIG_KVM_INTEL ) -static inline void kvm_set_cpu_l1tf_flush_l1d (void ) +/* +* This function is called from noinstr interrupt contexts +* and must be inlined to not get instrumentation. +*/ +static __always_inline void kvm_set_cpu_l1tf_flush_l1d(void) {__this_cpu_write (irq_stat.kvm_cpu_l1tf_flush_l1d,1 ); }
@@ -77,7 +81,7 @@ static __always_inline bool kvm_get_cpu_l1tf_flush_l1d(void)return __this_cpu_read (irq_stat.kvm_cpu_l1tf_flush_l1d); }#else /* !IS_ENABLED(CONFIG_KVM_INTEL) */ -static inline void kvm_set_cpu_l1tf_flush_l1d (void ) { } +static __always_inline void kvm_set_cpu_l1tf_flush_l1d(void) { }#endif /* IS_ENABLED(CONFIG_KVM_INTEL) */ #endif /* _ASM_X86_HARDIRQ_H */
arch/x86/include/asm/idtentry.h +3 -3
@@ -210,8 +210,8 @@ __visible noinstr void func(struct pt_regs *regs, \irqentry_state_t state =irqentry_enter (regs); \u32 vector = (u32 )(u8 )error_code; \ \ +kvm_set_cpu_l1tf_flush_l1d (); \instrumentation_begin (); \ -kvm_set_cpu_l1tf_flush_l1d (); \ run_irq_on_irqstack_cond(__##func, regs, vector); \ instrumentation_end(); \ irqentry_exit(regs, state); \
@@ -248,7 +248,6 @@ static void __##func(struct pt_regs *regs); \ \ static __always_inline void instr_##func(struct pt_regs *regs) \ { \ - kvm_set_cpu_l1tf_flush_l1d(); \ run_sysvec_on_irqstack_cond(__##func, regs); \ } \ \
@@ -256,6 +255,7 @@ __visible noinstr void func(struct pt_regs *regs) \ { \irqentry_state_t state =irqentry_enter (regs); \ \ +kvm_set_cpu_l1tf_flush_l1d (); \instrumentation_begin (); \ instr_##func (regs); \instrumentation_end (); \
@@ -286,7 +286,6 @@ static __always_inline void __##func(struct pt_regs *regs); \ static __always_inline void instr_##func(struct pt_regs *regs) \ { \ __irq_enter_raw(); \ - kvm_set_cpu_l1tf_flush_l1d(); \ __##func (regs); \ __irq_exit_raw(); \ } \
@@ -295,6 +294,7 @@ __visible noinstr void func(struct pt_regs *regs) \ { \irqentry_state_t state =irqentry_enter (regs); \ \ +kvm_set_cpu_l1tf_flush_l1d (); \instrumentation_begin (); \ instr_##func (regs); \instrumentation_end (); \
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 364/691 io_uring/sqpoll: do not allow pinning outside of cpuset
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Felix Moessbauer <[email protected]>
The submit queue polling threads are userland threads that just never exit to the userland. When creating the thread with IORING_SETUP_SQ_AFF, the affinity of the poller thread is set to the cpu specified in sq_thread_cpu. However, this CPU can be outside of the cpuset defined by the cgroup cpuset controller. This violates the rules defined by the cpuset controller and is a potential issue for realtime applications.
In b7ed6d8ffd6 we fixed the default affinity of the poller thread, in case no explicit pinning is required by inheriting the one of the creating task. In case of explicit pinning, the check is more complicated, as also a cpu outside of the parent cpumask is allowed. We implemented this by using cpuset_cpus_allowed (that has support for cgroup cpusets) and testing if the requested cpu is in the set.
--- io_uring/io_uring.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
io_uring/io_uring.c +4 -1
@@ -56,6 +56,7 @@#include <linux/mm.h> #include <linux/mman.h> #include <linux/percpu.h> +#include <linux/cpuset.h> #include <linux/slab.h> #include <linux/blkdev.h> #include <linux/bvec.h>
@@ -8746,10 +8747,12 @@ static int io_sq_offload_create(struct ireturn 0 ;if (p->flags &IORING_SETUP_SQ_AFF ) { +struct cpumask allowed_mask;int cpu = p->sq_thread_cpu; ret = -EINVAL ; -if (cpu >= nr_cpu_ids || !cpu_online (cpu)) +cpuset_cpus_allowed (current, &allowed_mask); +if (!cpumask_test_cpu (cpu, &allowed_mask)) goto err_sqpoll; sqd->sq_cpu = cpu; }else {
Re: [PATCH 5.15 364/691] io_uring/sqpoll: do not allow pinning outside of cpuset
Quoted 2 lines · Greg Kroah-Hartman
5.15-stable review patch. If anyone has any objections, please let me know.
This patch is buggy and must not be cherry-picked without also having:
a09c17240bd ("io_uring/sqpoll: retain test for whether the CPU is valid")7f44beadcc1 ("io_uring/sqpoll: do not put cpumask on stack")
Best regards,
Felix Moessbauer
Quoted 60 lines
------------------
From: Felix Moessbauer <[email protected]>
The submit queue polling threads are userland threads that just never exit to the userland. When creating the thread with
IORING_SETUP_SQ_AFF,
the affinity of the poller thread is set to the cpu specified insq_thread_cpu. However, this CPU can be outside of the cpuset defined by the cgroup cpuset controller. This violates the rules defined by the
cpuset controller and is a potential issue for realtime applications.In
b7ed6d8ffd6we fixed the default affinity of the poller thread, in case no explicit pinning is required by inheriting the one of the creating task. In case of explicit pinning, the check is more complicated, as also a cpu outside of the parent cpumask is allowed. We implemented this by usingcpuset_cpus_allowed(that has support for
cgroup cpusets) and testing if the requested cpu is in the set.Fixes 37d1e2e3642e ("io_uring: move SQPOLL thread io-wq forkedworker")
Cc [email protected] # 6.1+Signed-off-by Felix Moessbauer <[email protected]>Link:
https://lore.kernel.org/r/[email protected]Signed-off-by Jens Axboe <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>---
io_uring/io_uring.c | 5 ++++-1 file changed, 4 insertions(+), 1 deletion(-)io_uring/io_uring.c +1
-0@@ -56,6 +56,7 @@ #include <linux/mm.h> #include <linux/mman.h> #include <linux/percpu.h> +#include <linux/cpuset.h> #include <linux/slab.h> #include <linux/blkdev.h> #include <linux/bvec.h>@@ -8746,10 +8747,12 @@ static int io_sq_offload_create(struct i return 0;
if (p->flags&IORING_SETUP_SQ_AFF) {
+ struct cpumaskallowed_mask;
int cpu =p->sq_thread_cpu;
ret =-EINVAL;
- if (cpu >=nr_cpu_ids|| !cpu_online(cpu)) + cpuset_cpus_allowed(current,&allowed_mask); + if (!cpumask_test_cpu(cpu,&allowed_mask)) gotoerr_sqpoll;sqd->sq_cpu= cpu;
} else {
Signature · 2 lines
Siemens AG, Technology Linux Expert Center
Greg Kroah-Hartman
maintainerPATCH 365/691 bpf: lsm: Set bpf_lsm_blob_sizes.lbs_task to 0
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Song Liu <[email protected]>
commit 300a90b2cb5d442879e6398920c49aebbd5c8e40 upstream.
bpf task local storage is now using task_struct->bpf_storage, so bpf_lsm_blob_sizes.lbs_task is no longer needed. Remove it to save some memory.
--- security/bpf/hooks.c | 1 - 1 file changed, 1 deletion(-)
security/bpf/hooks.c +0 -1
@@ -24,7 +24,6 @@ static int __init bpf_lsm_init(void) struct lsm_blob_sizes bpf_lsm_blob_sizes __lsm_ro_after_init = { .lbs_inode =sizeof (struct bpf_storage_blob ), - .lbs_task =sizeof (struct bpf_storage_blob ), };DEFINE_LSM (bpf) = {
Greg Kroah-Hartman
maintainerPATCH 366/691 lockdep: fix deadlock issue between lockdep and rcu
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhiguo Niu <[email protected]>
commit a6f88ac32c6e63e69c595bfae220d8641704c9b7 upstream.
There is a deadlock scenario between lockdep and rcu when rcu nocb feature is enabled, just as following call stack:
rcuop/x
-000|queued_spin_lock_slowpath(lock = 0xFFFFFF817F2A8A80, val = ?) -001|queued_spin_lock(inline) // try to hold nocb_gp_lock -001|do_raw_spin_lock(lock = 0xFFFFFF817F2A8A80) -002|__raw_spin_lock_irqsave(inline) -002|_raw_spin_lock_irqsave(lock = 0xFFFFFF817F2A8A80) -003|wake_nocb_gp_defer(inline) -003|__call_rcu_nocb_wake(rdp = 0xFFFFFF817F30B680) -004|__call_rcu_common(inline) -004|call_rcu(head = 0xFFFFFFC082EECC28, func = ?) -005|call_rcu_zapped(inline) -005|free_zapped_rcu(ch = ?)// hold graph lock -006|rcu_do_batch(rdp = 0xFFFFFF817F245680) -007|nocb_cb_wait(inline) -007|rcu_nocb_cb_kthread(arg = 0xFFFFFF817F245680) -008|kthread(_create = 0xFFFFFF80803122C0) -009|ret_from_fork(asm)
rcuop/y
-000|queued_spin_lock_slowpath(lock = 0xFFFFFFC08291BBC8, val = 0) -001|queued_spin_lock() -001|lockdep_lock() -001|graph_lock() // try to hold graph lock -002|lookup_chain_cache_add() -002|validate_chain() -003|lock_acquire -004|_raw_spin_lock_irqsave(lock = 0xFFFFFF817F211D80) -005|lock_timer_base(inline) -006|mod_timer(inline) -006|wake_nocb_gp_defer(inline)// hold nocb_gp_lock -006|__call_rcu_nocb_wake(rdp = 0xFFFFFF817F2A8680) -007|__call_rcu_common(inline) -007|call_rcu(head = 0xFFFFFFC0822E0B58, func = ?) -008|call_rcu_hurry(inline) -008|rcu_sync_call(inline) -008|rcu_sync_func(rhp = 0xFFFFFFC0822E0B58) -009|rcu_do_batch(rdp = 0xFFFFFF817F266680) -010|nocb_cb_wait(inline) -010|rcu_nocb_cb_kthread(arg = 0xFFFFFF817F266680) -011|kthread(_create = 0xFFFFFF8080363740) -012|ret_from_fork(asm)
rcuop/x and rcuop/y are rcu nocb threads with the same nocb gp thread. This patch release the graph lock before lockdep call_rcu.
--- kernel/locking/lockdep.c | 48 +++++++++++++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 16 deletions(-)
kernel/locking/lockdep.c +32 -16
@@ -6028,25 +6028,27 @@ static struct pending_free *get_pending_static void free_zapped_rcu (struct rcu_head *cb);/* -* Schedule an RCU callback if no RCU callback is pending. Must be called with -* the graph lock held. -*/ -static void call_rcu_zapped (struct pending_free *pf) +* See if we need to queue an RCU callback, must called with +* the lockdep lock held, returns false if either we don't have +* any pending free or the callback is already scheduled. +* Otherwise, a call_rcu() must follow this function call. +*/ +static bool prepare_call_rcu_zapped (struct pending_free *pf) {WARN_ON_ONCE (inside_selftest ());if (list_empty (&pf->zapped)) -return ; +return false;if (delayed_free.scheduled) -return ; +return false; delayed_free.scheduled = true;WARN_ON_ONCE (delayed_free.pf + delayed_free.index != pf); delayed_free.index ^=1 ; -call_rcu (&delayed_free.rcu_head, free_zapped_rcu); +return true; }/* The caller must hold the graph lock. May be called from RCU context. */
@@ -6072,6 +6074,7 @@ static void free_zapped_rcu(struct rcu_h {struct pending_free *pf;unsigned long flags; +bool need_callback;if (WARN_ON_ONCE (ch != &delayed_free.rcu_head))return ;
@@ -6083,14 +6086,18 @@ static void free_zapped_rcu(struct rcu_h pf = delayed_free.pf + (delayed_free.index ^1 );__free_zapped_classes (pf); delayed_free.scheduled = false; + need_callback = +prepare_call_rcu_zapped (delayed_free.pf + delayed_free.index); +lockdep_unlock (); +raw_local_irq_restore (flags);/* -* If there's anything on the open list, close and start a new callback. -*/ -call_rcu_zapped (delayed_free.pf + delayed_free.index); +* If there's pending free and its callback has not been scheduled, +* queue an RCU callback. +*/ +if (need_callback) +call_rcu (&delayed_free.rcu_head, free_zapped_rcu); -lockdep_unlock (); -raw_local_irq_restore (flags); }/*
@@ -6130,6 +6137,7 @@ static void lockdep_free_key_range_reg(v {struct pending_free *pf;unsigned long flags; +bool need_callback;init_data_structures_once ();
@@ -6137,10 +6145,11 @@ static void lockdep_free_key_range_reg(vlockdep_lock (); pf =get_pending_free ();__lockdep_free_key_range (pf, start, size); -call_rcu_zapped (pf); + need_callback =prepare_call_rcu_zapped (pf);lockdep_unlock ();raw_local_irq_restore (flags); - +if (need_callback) +call_rcu (&delayed_free.rcu_head, free_zapped_rcu);/* * Wait for any possible iterators from look_up_lock_class() to pass * before continuing to free the memory they refer to.
@@ -6234,6 +6243,7 @@ static void lockdep_reset_lock_reg(strucstruct pending_free *pf;unsigned long flags;int locked; +bool need_callback = false;raw_local_irq_save (flags); locked =graph_lock ();
@@ -6242,11 +6252,13 @@ static void lockdep_reset_lock_reg(struc pf =get_pending_free ();__lockdep_reset_lock (pf, lock); -call_rcu_zapped (pf); + need_callback =prepare_call_rcu_zapped (pf);graph_unlock (); out_irq:raw_local_irq_restore (flags); +if (need_callback) +call_rcu (&delayed_free.rcu_head, free_zapped_rcu); }/*
@@ -6290,6 +6302,7 @@ void lockdep_unregister_key(struct lock_struct pending_free *pf;unsigned long flags;bool found = false; +bool need_callback = false;might_sleep ();
@@ -6310,11 +6323,14 @@ void lockdep_unregister_key(struct lock_if (found) { pf =get_pending_free ();__lockdep_free_key_range (pf, key,1 ); -call_rcu_zapped (pf); + need_callback =prepare_call_rcu_zapped (pf); }lockdep_unlock ();raw_local_irq_restore (flags); +if (need_callback) +call_rcu (&delayed_free.rcu_head, free_zapped_rcu); +/* Wait until is_dynamic_key() has finished accessing k->hash_entry. */ synchronize_rcu (); }
Greg Kroah-Hartman
maintainerPATCH 367/691 mm: only enforce minimum stack gap size if its sensible
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Gow <[email protected]>
commit 69b50d4351ed924f29e3d46b159e28f70dfc707f upstream.
The generic mmap_base code tries to leave a gap between the top of the stack and the mmap base address, but enforces a minimum gap size (MIN_GAP) of 128MB, which is too large on some setups. In particular, on arm tasks without ADDR_LIMIT_32BIT, the STACK_TOP value is less than 128MB, so it's impossible to fit such a gap in.
Only enforce this minimum if MIN_GAP < MAX_GAP, as we'd prefer to honour MAX_GAP, which is defined proportionally, so scales better and always leaves us with both _some_ stack space and some room for mmap.
This fixes the usercopy KUnit test suite on 32-bit arm, as it doesn't set any personality flags so gets the default (in this case 26-bit) task size. This test can be run with: ./tools/testing/kunit/kunit.py run --arch arm usercopy --make_options LLVM=1
--- mm/util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
mm/util.c +1 -1
@@ -430,7 +430,7 @@ static unsigned long mmap_base(unsignedif (gap + pad > gap) gap += pad; -if (gap <MIN_GAP ) +if (gap <MIN_GAP &&MIN_GAP <MAX_GAP ) gap =MIN_GAP ;else if (gap >MAX_GAP ) gap =MAX_GAP ;
Greg Kroah-Hartman
maintainerPATCH 368/691 i2c: aspeed: Update the stop sw state when the bus recovery occurs
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tommy Huang <[email protected]>
commit 93701d3b84ac5f3ea07259d4ced405c53d757985 upstream.
When the i2c bus recovery occurs, driver will send i2c stop command in the scl low condition. In this case the sw state will still keep original situation. Under multi-master usage, i2c bus recovery will be called when i2c transfer timeout occurs. Update the stop command calling with aspeed_i2c_do_stop function to update master_state.
--- drivers/i2c/busses/i2c-aspeed.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
drivers/i2c/busses/i2c-aspeed.c +8 -8
@@ -172,6 +172,13 @@ struct aspeed_i2c_bus {static int aspeed_i2c_reset (struct aspeed_i2c_bus *bus); +/* precondition: bus.lock has been acquired. */ +static void aspeed_i2c_do_stop (struct aspeed_i2c_bus *bus) +{ + bus->master_state =ASPEED_I2C_MASTER_STOP ; +writel (ASPEED_I2CD_M_STOP_CMD , bus->base +ASPEED_I2C_CMD_REG ); +} +static int aspeed_i2c_recover_bus (struct aspeed_i2c_bus *bus) {unsigned long time_left, flags;
@@ -189,7 +196,7 @@ static int aspeed_i2c_recover_bus(struct command);reinit_completion (&bus->cmd_complete); -writel (ASPEED_I2CD_M_STOP_CMD , bus->base +ASPEED_I2C_CMD_REG ); +aspeed_i2c_do_stop (bus);spin_unlock_irqrestore (&bus->lock, flags); time_left = wait_for_completion_timeout(
@@ -386,13 +393,6 @@ static void aspeed_i2c_do_start(struct a }/* precondition: bus.lock has been acquired. */ -static void aspeed_i2c_do_stop (struct aspeed_i2c_bus *bus) -{ - bus->master_state =ASPEED_I2C_MASTER_STOP ; -writel (ASPEED_I2CD_M_STOP_CMD , bus->base +ASPEED_I2C_CMD_REG ); -} - -/* precondition: bus.lock has been acquired. */ static void aspeed_i2c_next_msg_or_stop (struct aspeed_i2c_bus *bus) {if (bus->msgs_index +1 < bus->msgs_count) {
Greg Kroah-Hartman
maintainerPATCH 369/691 i2c: isch: Add missed else
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Shevchenko <[email protected]>
commit 1db4da55070d6a2754efeb3743f5312fc32f5961 upstream.
In accordance with the existing comment and code analysis it is quite likely that there is a missed 'else' when adapter times out. Add it.
--- drivers/i2c/busses/i2c-isch.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/i2c/busses/i2c-isch.c +1 -2
@@ -99,8 +99,7 @@ static int sch_transaction(void)if (retries >MAX_RETRIES ) {dev_err (&sch_adapter.dev,"SMBus Timeout!\n" ); result = -ETIMEDOUT ; - } -if (temp &0x04 ) { + }else if (temp &0x04 ) { result = -EIO ;dev_dbg (&sch_adapter.dev,"Bus collision! SMBus may be " "locked until next hard reset. (sorry!)\n" );
Greg Kroah-Hartman
maintainerPATCH 370/691 usb: yurex: Fix inconsistent locking bug in yurex_read()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Harshit Mogalapalli <[email protected]>
commit e7d3b9f28654dbfce7e09f8028210489adaf6a33 upstream.
Unlock before returning on the error path.
--- drivers/usb/misc/yurex.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/usb/misc/yurex.c +3 -1
@@ -413,8 +413,10 @@ static ssize_t yurex_read(struct file *freturn -ENODEV ; } -if (WARN_ON_ONCE (dev->bbu >S64_MAX || dev->bbu <S64_MIN )) +if (WARN_ON_ONCE (dev->bbu >S64_MAX || dev->bbu <S64_MIN )) { +mutex_unlock (&dev->io_mutex);return -EIO ; + }spin_lock_irq (&dev->lock);scnprintf (in_buffer,MAX_S64_STRLEN ,"%lld\n" , dev->bbu);
Greg Kroah-Hartman
maintainerPATCH 371/691 spi: lpspi: Simplify some error message
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christophe JAILLET <[email protected]>
commit 0df874c6712d9aa8f43c50ec887a21f7b86fc917 upstream.
dev_err_probe() already prints the error code in a human readable way, so there is no need to duplicate it as a numerical value at the end of the message.
--- drivers/spi/spi-fsl-lpspi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/spi/spi-fsl-lpspi.c +1 -1
@@ -919,7 +919,7 @@ static int fsl_lpspi_probe(struct platfo ret =devm_spi_register_controller (&pdev->dev, controller);if (ret <0 ) { -dev_err_probe (&pdev->dev, ret,"spi_register_controller error: %i\n" , ret); +dev_err_probe (&pdev->dev, ret,"spi_register_controller error\n" ); goto free_dma; }
Greg Kroah-Hartman
maintainerPATCH 372/691 static_call: Handle module init failure correctly in static_call_del_module()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Gleixner <[email protected]>
[ Upstream commit 4b30051c4864234ec57290c3d142db7c88f10d8a ]
Module insertion invokes static_call_add_module() to initialize the static calls in a module. static_call_add_module() invokes __static_call_init(), which allocates a struct static_call_mod to either encapsulate the built-in static call sites of the associated key into it so further modules can be added or to append the module to the module chain.
If that allocation fails the function returns with an error code and the module core invokes static_call_del_module() to clean up eventually added static_call_mod entries.
This works correctly, when all keys used by the module were converted over to a module chain before the failure. If not then static_call_del_module() causes a #GP as it blindly assumes that key::mods points to a valid struct static_call_mod.
The problem is that key::mods is not a individual struct member of struct static_call_key, it's part of a union to save space:
union {
/* bit 0: 0 = mods, 1 = sites */
unsigned long type;
struct static_call_mod *mods;
struct static_call_site *sites;
};key::sites is a pointer to the list of built-in usage sites of the static call. The type of the pointer is differentiated by bit 0. A mods pointer has the bit clear, the sites pointer has the bit set.
As static_call_del_module() blidly assumes that the pointer is a valid static_call_mod type, it fails to check for this failure case and dereferences the pointer to the list of built-in call sites, which is obviously bogus.
Cure it by checking whether the key has a sites or a mods pointer.
If it's a sites pointer then the key is not to be touched. As the sites are walked in the same order as in __static_call_init() the site walk can be terminated because all subsequent sites have not been touched by the init code due to the error exit.
If it was converted before the allocation fail, then the inner loop which searches for a module match will find nothing.
A fail in the second allocation in __static_call_init() is harmless and does not require special treatment. The first allocation succeeded and converted the key to a module chain. That first entry has mod::mod == NULL and mod::next == NULL, so the inner loop of static_call_del_module() will neither find a module match nor a module chain. The next site in the walk was either already converted, but can't match the module, or it will exit the outer loop because it has a static_call_site pointer and not a static_call_mod pointer.
--- kernel/static_call_inline.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
kernel/static_call_inline.c +11 -0
@@ -400,6 +400,17 @@ static void static_call_del_module(struct module *mod)for (site = start; site < stop; site++) { key =static_call_key (site); + +/* +* If the key was not updated due to a memory allocation +* failure in __static_call_init() then treating key::sites +* as key::mods in the code below would cause random memory +* access and #GP. In that case all subsequent sites have +* not been touched either, so stop iterating. +*/ +if (!static_call_key_has_mods (key)) +break ; +if (key == prev_key)continue ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 373/691 static_call: Replace pointless WARN_ON() in static_call_module_notify()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Gleixner <[email protected]>
[ Upstream commit fe513c2ef0a172a58f158e2e70465c4317f0a9a2 ]
static_call_module_notify() triggers a WARN_ON(), when memory allocation fails in __static_call_add_module().
That's not really justified, because the failure case must be correctly handled by the well known call chain and the error code is passed through to the initiating userspace application.
A memory allocation fail is not a fatal problem, but the WARN_ON() takes the machine out when panic_on_warn is set.
Replace it with a pr_warn().
--- kernel/static_call_inline.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/static_call_inline.c +1 -1
@@ -442,7 +442,7 @@ static int static_call_module_notify(struct notifier_block *nb,case MODULE_STATE_COMING : ret =static_call_add_module (mod);if (ret) { -WARN (1 ,"Failed to allocate memory for static calls" ); +pr_warn ("Failed to allocate memory for static calls\n" );static_call_del_module (mod); }break ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 374/691 mailbox: rockchip: fix a typo in module autoloading
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Liao Chen <[email protected]>
[ Upstream commit e92d87c9c5d769e4cb1dd7c90faa38dddd7e52e3 ]
MODULE_DEVICE_TABLE(of, rockchip_mbox_of_match) could let the module properly autoloaded based on the alias from of_device_id table. It should be 'rockchip_mbox_of_match' instead of 'rockchp_mbox_of_match', just fix it.
--- drivers/mailbox/rockchip-mailbox.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/mailbox/rockchip-mailbox.c +1 -1
@@ -159,7 +159,7 @@ static const struct of_device_id rockchip_mbox_of_match[] = { { .compatible = "rockchip,rk3368-mailbox", .data = &rk3368_drv_data}, { }, }; -MODULE_DEVICE_TABLE (of, rockchp_mbox_of_match); +MODULE_DEVICE_TABLE (of, rockchip_mbox_of_match);static int rockchip_mbox_probe (struct platform_device *pdev) {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 375/691 mailbox: bcm2835: Fix timeout during suspend mode
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stefan Wahren <[email protected]>
[ Upstream commit dc09f007caed3b2f6a3b6bd7e13777557ae22bfd ]
During noirq suspend phase the Raspberry Pi power driver suffer of firmware property timeouts. The reason is that the IRQ of the underlying BCM2835 mailbox is disabled and rpi_firmware_property_list() will always run into a timeout [1].
Since the VideoCore side isn't consider as a wakeup source, set the IRQF_NO_SUSPEND flag for the mailbox IRQ in order to keep it enabled during suspend-resume cycle.
[1]
PM: late suspend of devices complete after 1.754 msecs
WARNING: CPU: 0 PID: 438 at drivers/firmware/raspberrypi.c:128 rpi_firmware_property_list+0x204/0x22c Firmware transaction 0x00028001 timeout Modules linked in: CPU: 0 PID: 438 Comm: bash Tainted: G C 6.9.3-dirty #17 Hardware name: BCM2835 Call trace: unwind_backtrace from show_stack+0x18/0x1c show_stack from dump_stack_lvl+0x34/0x44 dump_stack_lvl from __warn+0x88/0xec __warn from warn_slowpath_fmt+0x7c/0xb0 warn_slowpath_fmt from rpi_firmware_property_list+0x204/0x22c rpi_firmware_property_list from rpi_firmware_property+0x68/0x8c rpi_firmware_property from rpi_firmware_set_power+0x54/0xc0 rpi_firmware_set_power from _genpd_power_off+0xe4/0x148 _genpd_power_off from genpd_sync_power_off+0x7c/0x11c genpd_sync_power_off from genpd_finish_suspend+0xcc/0xe0 genpd_finish_suspend from dpm_run_callback+0x78/0xd0 dpm_run_callback from device_suspend_noirq+0xc0/0x238 device_suspend_noirq from dpm_suspend_noirq+0xb0/0x168 dpm_suspend_noirq from suspend_devices_and_enter+0x1b8/0x5ac suspend_devices_and_enter from pm_suspend+0x254/0x2e4 pm_suspend from state_store+0xa8/0xd4 state_store from kernfs_fop_write_iter+0x154/0x1a0 kernfs_fop_write_iter from vfs_write+0x12c/0x184 vfs_write from ksys_write+0x78/0xc0 ksys_write from ret_fast_syscall+0x0/0x54 Exception stack(0xcc93dfa8 to 0xcc93dff0)
[...]
PM: noirq suspend of devices complete after 3095.584 msecs
--- drivers/mailbox/bcm2835-mailbox.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/mailbox/bcm2835-mailbox.c +2 -1
@@ -146,7 +146,8 @@ static int bcm2835_mbox_probe(struct platform_device *pdev)spin_lock_init (&mbox->lock); ret =devm_request_irq (dev,irq_of_parse_and_map (dev->of_node,0 ), - bcm2835_mbox_irq,0 ,dev_name (dev), mbox); + bcm2835_mbox_irq,IRQF_NO_SUSPEND ,dev_name (dev), + mbox);if (ret) {dev_err (dev,"Failed to register a mailbox IRQ handler: %d\n" , ret);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 376/691 ceph: remove the incorrect Fw reference check when dirtying pages
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xiubo Li <[email protected]>
[ Upstream commit c08dfb1b49492c09cf13838c71897493ea3b424e ]
When doing the direct-io reads it will also try to mark pages dirty, but for the read path it won't hold the Fw caps and there is case will it get the Fw reference.
--- fs/ceph/addr.c | 1 - 1 file changed, 1 deletion(-)
fs/ceph/addr.c +0 -1
@@ -95,7 +95,6 @@ static int ceph_set_page_dirty(struct page *page)/* dirty the head */ spin_lock (&ci->i_ceph_lock); -BUG_ON (ci->i_wr_ref ==0 );// caller should hold Fw reference if (__ceph_have_pending_cap_snap (ci)) {struct ceph_cap_snap *capsnap = list_last_entry(&ci->i_cap_snaps,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 377/691 ieee802154: Fix build error
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jinjie Ruan <[email protected]>
[ Upstream commit addf89774e48c992316449ffab4f29c2309ebefb ]
If REGMAP_SPI is m and IEEE802154_MCR20A is y,
mcr20a.c:(.text+0x3ed6c5b): undefined reference to `__devm_regmap_init_spi' ld: mcr20a.c:(.text+0x3ed6cb5): undefined reference to `__devm_regmap_init_spi'
Select REGMAP_SPI for IEEE802154_MCR20A to fix it.
--- drivers/net/ieee802154/Kconfig | 1 + 1 file changed, 1 insertion(+)
drivers/net/ieee802154/Kconfig +1 -0
@@ -108,6 +108,7 @@ config IEEE802154_CA8210_DEBUGFS config IEEE802154_MCR20A tristate "MCR20A transceiver driver" + select REGMAP_SPI depends on IEEE802154_DRIVERS && MAC802154 depends on SPI help
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 378/691 net/mlx5: Fix error path in multi-packet WQE transmit
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gerd Bayer <[email protected]>
[ Upstream commit 2bcae12c795f32ddfbf8c80d1b5f1d3286341c32 ]
Remove the erroneous unmap in case no DMA mapping was established
The multi-packet WQE transmit code attempts to obtain a DMA mapping for the skb. This could fail, e.g. under memory pressure, when the IOMMU driver just can't allocate more memory for page tables. While the code tries to handle this in the path below the err_unmap label it erroneously unmaps one entry from the sq's FIFO list of active mappings. Since the current map attempt failed this unmap is removing some random DMA mapping that might still be required. If the PCI function now presents that IOVA, the IOMMU may assumes a rogue DMA access and e.g. on s390 puts the PCI function in error state.
The erroneous behavior was seen in a stress-test environment that created memory pressure.
--- drivers/net/ethernet/mellanox/mlx5/core/en_tx.c | 1 - 1 file changed, 1 deletion(-)
drivers/net/ethernet/mellanox/mlx5/core/en_tx.c +0 -1
@@ -685,7 +685,6 @@ mlx5e_sq_xmit_mpwqe(struct mlx5e_txqsq *sq, struct sk_buff *skb,return ; err_unmap: -mlx5e_dma_unmap_wqe_err (sq,1 ); sq->stats->dropped++;dev_kfree_skb_any (skb);mlx5e_tx_flush (sq);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 379/691 net/mlx5: Added cond_resched() to crdump collection
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mohamed Khalfella <[email protected]>
[ Upstream commit ec793155894140df7421d25903de2e6bc12c695b ]
Collecting crdump involves reading vsc registers from pci config space of mlx device, which can take long time to complete. This might result in starving other threads waiting to run on the cpu.
Numbers I got from testing ConnectX-5 Ex MCX516A-CDAT in the lab:
- mlx5_vsc_gw_read_block_fast() was called with length = 1310716.
- mlx5_vsc_gw_read_fast() reads 4 bytes at a time. It was not used to read the entire 1310716 bytes. It was called 53813 times because there are jumps in read_addr.
- On average mlx5_vsc_gw_read_fast() took 35284.4ns.
- In total mlx5_vsc_wait_on_flag() called vsc_read() 54707 times. The average time for each call was 17548.3ns. In some instances vsc_read() was called more than one time when the flag was not set. As expected the thread released the cpu after 16 iterations in mlx5_vsc_wait_on_flag().
- Total time to read crdump was 35284.4ns * 53813 ~= 1.898s.
It was seen in the field that crdump can take more than 5 seconds to complete. During that time mlx5_vsc_wait_on_flag() did not release the cpu because it did not complete 16 iterations. It is believed that pci config reads were slow. Adding cond_resched() every 128 register read improves the situation. In the common case the, crdump takes ~1.8989s, the thread yields the cpu every ~4.51ms. If crdump takes ~5s, the thread yields the cpu every ~18.0ms.
--- drivers/net/ethernet/mellanox/mlx5/core/lib/pci_vsc.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
drivers/net/ethernet/mellanox/mlx5/core/lib/pci_vsc.c +10 -0
@@ -24,6 +24,11 @@ pci_write_config_dword((dev)->pdev, (dev)->vsc_addr + (offset), (val))#define VSC_MAX_RETRIES 2048 +/* Reading VSC registers can take relatively long time. +* Yield the cpu every 128 registers read. +*/ +#define VSC_GW_READ_BLOCK_COUNT 128 +enum {VSC_CTRL_OFFSET =0x4 ,VSC_COUNTER_OFFSET =0x8 ,
@@ -269,6 +274,7 @@ int mlx5_vsc_gw_read_block_fast(struct mlx5_core_dev *dev, u32 *data, {unsigned int next_read_addr =0 ;unsigned int read_addr =0 ; +unsigned int count =0 ;while (read_addr < length) { if (mlx5_vsc_gw_read_fast(dev, read_addr, &next_read_addr,
@@ -276,6 +282,10 @@ int mlx5_vsc_gw_read_block_fast(struct mlx5_core_dev *dev, u32 *data,return read_addr; read_addr = next_read_addr; +if (++count ==VSC_GW_READ_BLOCK_COUNT ) { +cond_resched (); + count =0 ; + } }return length; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 380/691 net/mlx5e: Fix NULL deref in mlx5e_tir_builder_alloc()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Elena Salomatkina <[email protected]>
[ Upstream commit f25389e779500cf4a59ef9804534237841bce536 ]
In mlx5e_tir_builder_alloc() kvzalloc() may return NULL which is dereferenced on the next line in a reference to the modify field.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
--- drivers/net/ethernet/mellanox/mlx5/core/en/tir.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/ethernet/mellanox/mlx5/core/en/tir.c +3 -0
@@ -23,6 +23,9 @@ struct mlx5e_tir_builder *mlx5e_tir_builder_alloc(bool modify)struct mlx5e_tir_builder *builder; builder =kvzalloc (sizeof (*builder),GFP_KERNEL ); +if (!builder) +return NULL ; + builder->modify = modify;return builder;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 381/691 netfilter: uapi: NFTA_FLOWTABLE_HOOK is NLA_NESTED
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Phil Sutter <[email protected]>
[ Upstream commit 76f1ed087b562a469f2153076f179854b749c09a ]
Fix the comment which incorrectly defines it as NLA_U32.
--- include/uapi/linux/netfilter/nf_tables.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/uapi/linux/netfilter/nf_tables.h +1 -1
@@ -1638,7 +1638,7 @@ enum nft_flowtable_flags {* * @NFTA_FLOWTABLE_TABLE: name of the table containing the expression (NLA_STRING) * @NFTA_FLOWTABLE_NAME: name of this flow table (NLA_STRING) -* @NFTA_FLOWTABLE_HOOK: netfilter hook configuration(NLA_U32) +* @NFTA_FLOWTABLE_HOOK: netfilter hook configuration (NLA_NESTED) * @NFTA_FLOWTABLE_USE: number of references to this flow table (NLA_U32) * @NFTA_FLOWTABLE_HANDLE: object handle (NLA_U64) * @NFTA_FLOWTABLE_FLAGS: flags (NLA_U32)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 382/691 net: ieee802154: mcr20a: Use IRQF_NO_AUTOEN flag in request_irq()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jinjie Ruan <[email protected]>
[ Upstream commit 09573b1cc76e7ff8f056ab29ea1cdc152ec8c653 ]
disable_irq() after request_irq() still has a time gap in which interrupts can come. request_irq() with IRQF_NO_AUTOEN flag will disable IRQ auto-enable when request IRQ.
--- drivers/net/ieee802154/mcr20a.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
drivers/net/ieee802154/mcr20a.c +1 -4
@@ -1311,16 +1311,13 @@ mcr20a_probe(struct spi_device *spi) irq_type =IRQF_TRIGGER_FALLING ; ret =devm_request_irq (&spi->dev, spi->irq, mcr20a_irq_isr, - irq_type,dev_name (&spi->dev), lp); + irq_type |IRQF_NO_AUTOEN ,dev_name (&spi->dev), lp);if (ret) {dev_err (&spi->dev,"could not request_irq for mcr20a\n" ); ret = -ENODEV ; goto free_dev; } -/* disable_irq by default and wait for starting hardware */ -disable_irq (spi->irq); - ret =ieee802154_register_hw (hw);if (ret) {dev_crit (&spi->dev,"ieee802154_register_hw failed\n" );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 383/691 netfilter: nf_tables: prevent nf_skb_duplicated corruption
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit 92ceba94de6fb4cee2bf40b485979c342f44a492 ]
syzbot found that nf_dup_ipv4() or nf_dup_ipv6() could write per-cpu variable nf_skb_duplicated in an unsafe way [1].
Disabling preemption as hinted by the splat is not enough, we have to disable soft interrupts as well.
[1]
BUG: using __this_cpu_write() in preemptible [00000000] code: syz.4.282/6316 caller is nf_dup_ipv4+0x651/0x8f0 net/ipv4/netfilter/nf_dup_ipv4.c:87 CPU: 0 UID: 0 PID: 6316 Comm: syz.4.282 Not tainted 6.11.0-rc7-syzkaller-00104-g7052622fccb1 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 08/06/2024 Call Trace: <TASK> __dump_stack lib/dump_stack.c:93 [inline] dump_stack_lvl+0x241/0x360 lib/dump_stack.c:119 check_preemption_disabled+0x10e/0x120 lib/smp_processor_id.c:49 nf_dup_ipv4+0x651/0x8f0 net/ipv4/netfilter/nf_dup_ipv4.c:87 nft_dup_ipv4_eval+0x1db/0x300 net/ipv4/netfilter/nft_dup_ipv4.c:30 expr_call_ops_eval net/netfilter/nf_tables_core.c:240 [inline] nft_do_chain+0x4ad/0x1da0 net/netfilter/nf_tables_core.c:288 nft_do_chain_ipv4+0x202/0x320 net/netfilter/nft_chain_filter.c:23 nf_hook_entry_hookfn include/linux/netfilter.h:154 [inline] nf_hook_slow+0xc3/0x220 net/netfilter/core.c:626 nf_hook+0x2c4/0x450 include/linux/netfilter.h:269 NF_HOOK_COND include/linux/netfilter.h:302 [inline] ip_output+0x185/0x230 net/ipv4/ip_output.c:433 ip_local_out net/ipv4/ip_output.c:129 [inline] ip_send_skb+0x74/0x100 net/ipv4/ip_output.c:1495 udp_send_skb+0xacf/0x1650 net/ipv4/udp.c:981 udp_sendmsg+0x1c21/0x2a60 net/ipv4/udp.c:1269 sock_sendmsg_nosec net/socket.c:730 [inline] __sock_sendmsg+0x1a6/0x270 net/socket.c:745 ____sys_sendmsg+0x525/0x7d0 net/socket.c:2597 ___sys_sendmsg net/socket.c:2651 [inline] __sys_sendmmsg+0x3b2/0x740 net/socket.c:2737 __do_sys_sendmmsg net/socket.c:2766 [inline] __se_sys_sendmmsg net/socket.c:2763 [inline] __x64_sys_sendmmsg+0xa0/0xb0 net/socket.c:2763 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7f4ce4f7def9 Code: ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 a8 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007f4ce5d4a038 EFLAGS: 00000246 ORIG_RAX: 0000000000000133 RAX: ffffffffffffffda RBX: 00007f4ce5135f80 RCX: 00007f4ce4f7def9 RDX: 0000000000000001 RSI: 0000000020005d40 RDI: 0000000000000006 RBP: 00007f4ce4ff0b76 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 R13: 0000000000000000 R14: 00007f4ce5135f80 R15: 00007ffd4cbc6d68 </TASK>
--- net/ipv4/netfilter/nf_dup_ipv4.c | 7 +++++-- net/ipv6/netfilter/nf_dup_ipv6.c | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-)
net/ipv4/netfilter/nf_dup_ipv4.c +5 -2
@@ -52,8 +52,9 @@ void nf_dup_ipv4(struct net *net, struct sk_buff *skb, unsigned int hooknum, {struct iphdr *iph; +local_bh_disable ();if (this_cpu_read (nf_skb_duplicated)) -return ; + goto out;/* * Copy the skb, and route the copy. Will later return %XT_CONTINUE for * the original skb, which should continue on its way as if nothing has
@@ -61,7 +62,7 @@ void nf_dup_ipv4(struct net *net, struct sk_buff *skb, unsigned int hooknum,*/ skb =pskb_copy (skb,GFP_ATOMIC );if (skb ==NULL ) -return ; + goto out;#if IS_ENABLED (CONFIG_NF_CONNTRACK )/* Avoid counting cloned packets towards the original connection. */
@@ -90,6 +91,8 @@ void nf_dup_ipv4(struct net *net, struct sk_buff *skb, unsigned int hooknum, }else {kfree_skb (skb); } +out: +local_bh_enable (); }EXPORT_SYMBOL_GPL (nf_dup_ipv4);
net/ipv6/netfilter/nf_dup_ipv6.c +5 -2
@@ -47,11 +47,12 @@ static bool nf_dup_ipv6_route(struct net *net, struct sk_buff *skb,void nf_dup_ipv6 (struct net *net,struct sk_buff *skb,unsigned int hooknum,const struct in6_addr *gw,int oif) { +local_bh_disable ();if (this_cpu_read (nf_skb_duplicated)) -return ; + goto out; skb =pskb_copy (skb,GFP_ATOMIC );if (skb ==NULL ) -return ; + goto out;#if IS_ENABLED (CONFIG_NF_CONNTRACK )nf_reset_ct (skb);
@@ -69,6 +70,8 @@ void nf_dup_ipv6(struct net *net, struct sk_buff *skb, unsigned int hooknum, }else {kfree_skb (skb); } +out: +local_bh_enable (); }EXPORT_SYMBOL_GPL (nf_dup_ipv6);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 384/691 Bluetooth: btmrvl: Use IRQF_NO_AUTOEN flag in request_irq()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jinjie Ruan <[email protected]>
[ Upstream commit 7b1ab460592ca818e7b52f27cd3ec86af79220d1 ]
disable_irq() after request_irq() still has a time gap in which interrupts can come. request_irq() with IRQF_NO_AUTOEN flag will disable IRQ auto-enable when request IRQ.
--- drivers/bluetooth/btmrvl_sdio.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/bluetooth/btmrvl_sdio.c +1 -2
@@ -105,7 +105,7 @@ static int btmrvl_sdio_probe_of(struct device *dev, }else { ret =devm_request_irq (dev, cfg->irq_bt, btmrvl_wake_irq_bt, -0 ,"bt_wake" , card); +IRQF_NO_AUTOEN ,"bt_wake" , card);if (ret) { dev_err(dev, "Failed to request irq_bt %d (%d)\n",
@@ -114,7 +114,6 @@ static int btmrvl_sdio_probe_of(struct device *dev,/* Configure wakeup (enabled by default) */ device_init_wakeup (dev, true); -disable_irq (cfg->irq_bt); } }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 385/691 net: ethernet: lantiq_etop: fix memory disclosure
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aleksander Jan Bajkowski <[email protected]>
[ Upstream commit 45c0de18ff2dc9af01236380404bbd6a46502c69 ]
When applying padding, the buffer is not zeroed, which results in memory disclosure. The mentioned data is observed on the wire. This patch uses skb_put_padto() to pad Ethernet frames properly. The mentioned function zeroes the expanded buffer.
In case the packet cannot be padded it is silently dropped. Statistics are also not incremented. This driver does not support statistics in the old 32-bit format or the new 64-bit format. These will be added in the future. In its current form, the patch should be easily backported to stable versions.
Ethernet MACs on Amazon-SE and Danube cannot do padding of the packets in hardware, so software padding must be applied.
--- drivers/net/ethernet/lantiq_etop.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/net/ethernet/lantiq_etop.c +3 -1
@@ -464,7 +464,9 @@ ltq_etop_tx(struct sk_buff *skb, struct net_device *dev)unsigned long flags;u32 byte_offset; - len = skb->len <ETH_ZLEN ?ETH_ZLEN : skb->len; +if (skb_put_padto (skb,ETH_ZLEN )) +return NETDEV_TX_OK ; + len = skb->len;if ((desc->ctl & (LTQ_DMA_OWN |LTQ_DMA_C )) || ch->skb[ch->dma.desc]) {netdev_err (dev,"tx ring full\n" );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 386/691 net: avoid potential underflow in qdisc_pkt_len_init() with UFO
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit c20029db28399ecc50e556964eaba75c43b1e2f1 ]
After commit 7c6d2ecbda83 ("net: be more gentle about silly gso requests coming from user") virtio_net_hdr_to_skb() had sanity check to detect malicious attempts from user space to cook a bad GSO packet.
Then commit cf9acc90c80ec ("net: virtio_net_hdr_to_skb: count transport header in UFO") while fixing one issue, allowed user space to cook a GSO packet with the following characteristic :
IPv4 SKB_GSO_UDP, gso_size=3, skb->len = 28.
When this packet arrives in qdisc_pkt_len_init(), we end up with hdr_len = 28 (IPv4 header + UDP header), matching skb->len
Then the following sets gso_segs to 0 :
gso_segs = DIV_ROUND_UP(skb->len - hdr_len,
shinfo->gso_size);
Then later we set qdisc_skb_cb(skb)->pkt_len to back to zero :/
qdisc_skb_cb(skb)->pkt_len += (gso_segs - 1) * hdr_len;
This leads to the following crash in fq_codel [1]
qdisc_pkt_len_init() is best effort, we only want an estimation of the bytes sent on the wire, not crashing the kernel.
This patch is fixing this particular issue, a following one adds more sanity checks for another potential bug.
[1]
[ 70.724101] BUG: kernel NULL pointer dereference, address: 0000000000000000 [ 70.724561] #PF: supervisor read access in kernel mode [ 70.724561] #PF: error_code(0x0000) - not-present page [ 70.724561] PGD 10ac61067 P4D 10ac61067 PUD 107ee2067 PMD 0 [ 70.724561] Oops: Oops: 0000 [#1] SMP NOPTI [ 70.724561] CPU: 11 UID: 0 PID: 2163 Comm: b358537762 Not tainted 6.11.0-virtme #991 [ 70.724561] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 [ 70.724561] RIP: 0010:fq_codel_enqueue (net/sched/sch_fq_codel.c:120 net/sched/sch_fq_codel.c:168 net/sched/sch_fq_codel.c:230) sch_fq_codel [ 70.724561] Code: 24 08 49 c1 e1 06 44 89 7c 24 18 45 31 ed 45 31 c0 31 ff 89 44 24 14 4c 03 8b 90 01 00 00 eb 04 39 ca 73 37 4d 8b 39 83 c7 01 <49> 8b 17 49 89 11 41 8b 57 28 45 8b 5f 34 49 c7 07 00 00 00 00 49 All code ======== 0: 24 08 and $0x8,%al 2: 49 c1 e1 06 shl $0x6,%r9 6: 44 89 7c 24 18 mov %r15d,0x18(%rsp) b: 45 31 ed xor %r13d,%r13d e: 45 31 c0 xor %r8d,%r8d 11: 31 ff xor %edi,%edi 13: 89 44 24 14 mov %eax,0x14(%rsp) 17: 4c 03 8b 90 01 00 00 add 0x190(%rbx),%r9 1e: eb 04 jmp 0x24 20: 39 ca cmp %ecx,%edx 22: 73 37 jae 0x5b 24: 4d 8b 39 mov (%r9),%r15 27: 83 c7 01 add $0x1,%edi 2a:* 49 8b 17 mov (%r15),%rdx <-- trapping instruction 2d: 49 89 11 mov %rdx,(%r9) 30: 41 8b 57 28 mov 0x28(%r15),%edx 34: 45 8b 5f 34 mov 0x34(%r15),%r11d 38: 49 c7 07 00 00 00 00 movq $0x0,(%r15)
3f: 49 rex.WB
Code starting with the faulting instruction
===========================================
0: 49 8b 17 mov (%r15),%rdx 3: 49 89 11 mov %rdx,(%r9) 6: 41 8b 57 28 mov 0x28(%r15),%edx a: 45 8b 5f 34 mov 0x34(%r15),%r11d e: 49 c7 07 00 00 00 00 movq $0x0,(%r15) 15: 49 rex.WB [ 70.724561] RSP: 0018:ffff95ae85e6fb90 EFLAGS: 00000202 [ 70.724561] RAX: 0000000002000000 RBX: ffff95ae841de000 RCX: 0000000000000000 [ 70.724561] RDX: 0000000000000000 RSI: 0000000000000001 RDI: 0000000000000001 [ 70.724561] RBP: ffff95ae85e6fbf8 R08: 0000000000000000 R09: ffff95b710a30000 [ 70.724561] R10: 0000000000000000 R11: bdf289445ce31881 R12: ffff95ae85e6fc58 [ 70.724561] R13: 0000000000000000 R14: 0000000000000040 R15: 0000000000000000 [ 70.724561] FS: 000000002c5c1380(0000) GS:ffff95bd7fcc0000(0000) knlGS:0000000000000000 [ 70.724561] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 70.724561] CR2: 0000000000000000 CR3: 000000010c568000 CR4: 00000000000006f0 [ 70.724561] Call Trace: [ 70.724561] <TASK> [ 70.724561] ? __die (arch/x86/kernel/dumpstack.c:421 arch/x86/kernel/dumpstack.c:434) [ 70.724561] ? page_fault_oops (arch/x86/mm/fault.c:715) [ 70.724561] ? exc_page_fault (./arch/x86/include/asm/irqflags.h:26 ./arch/x86/include/asm/irqflags.h:87 ./arch/x86/include/asm/irqflags.h:147 arch/x86/mm/fault.c:1489 arch/x86/mm/fault.c:1539) [ 70.724561] ? asm_exc_page_fault (./arch/x86/include/asm/idtentry.h:623) [ 70.724561] ? fq_codel_enqueue (net/sched/sch_fq_codel.c:120 net/sched/sch_fq_codel.c:168 net/sched/sch_fq_codel.c:230) sch_fq_codel [ 70.724561] dev_qdisc_enqueue (net/core/dev.c:3784) [ 70.724561] __dev_queue_xmit (net/core/dev.c:3880 (discriminator 2) net/core/dev.c:4390 (discriminator 2)) [ 70.724561] ? irqentry_enter (kernel/entry/common.c:237) [ 70.724561] ? sysvec_apic_timer_interrupt (./arch/x86/include/asm/hardirq.h:74 (discriminator 2) arch/x86/kernel/apic/apic.c:1043 (discriminator 2) arch/x86/kernel/apic/apic.c:1043 (discriminator 2)) [ 70.724561] ? trace_hardirqs_on (kernel/trace/trace_preemptirq.c:58 (discriminator 4)) [ 70.724561] ? asm_sysvec_apic_timer_interrupt (./arch/x86/include/asm/idtentry.h:702) [ 70.724561] ? virtio_net_hdr_to_skb.constprop.0 (./include/linux/virtio_net.h:129 (discriminator 1)) [ 70.724561] packet_sendmsg (net/packet/af_packet.c:3145 (discriminator 1) net/packet/af_packet.c:3177 (discriminator 1)) [ 70.724561] ? _raw_spin_lock_bh (./arch/x86/include/asm/atomic.h:107 (discriminator 4) ./include/linux/atomic/atomic-arch-fallback.h:2170 (discriminator 4) ./include/linux/atomic/atomic-instrumented.h:1302 (discriminator 4) ./include/asm-generic/qspinlock.h:111 (discriminator 4) ./include/linux/spinlock.h:187 (discriminator 4) ./include/linux/spinlock_api_smp.h:127 (discriminator 4) kernel/locking/spinlock.c:178 (discriminator 4)) [ 70.724561] ? netdev_name_node_lookup_rcu (net/core/dev.c:325 (discriminator 1)) [ 70.724561] __sys_sendto (net/socket.c:730 (discriminator 1) net/socket.c:745 (discriminator 1) net/socket.c:2210 (discriminator 1)) [ 70.724561] ? __sys_setsockopt (./include/linux/file.h:34 net/socket.c:2355) [ 70.724561] __x64_sys_sendto (net/socket.c:2222 (discriminator 1) net/socket.c:2218 (discriminator 1) net/socket.c:2218 (discriminator 1)) [ 70.724561] do_syscall_64 (arch/x86/entry/common.c:52 (discriminator 1) arch/x86/entry/common.c:83 (discriminator 1)) [ 70.724561] entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:130) [ 70.724561] RIP: 0033:0x41ae09
--- net/core/dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/core/dev.c +1 -1
@@ -3787,7 +3787,7 @@ static void qdisc_pkt_len_init(struct sk_buff *skb) sizeof(_tcphdr), &_tcphdr);if (likely (th)) hdr_len +=__tcp_hdrlen (th); - }else { + }else if (shinfo->gso_type &SKB_GSO_UDP_L4 ) {struct udphdr _udphdr; if (skb_header_pointer(skb, skb_transport_offset(skb),
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 387/691 net: add more sanity checks to qdisc_pkt_len_init()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit ab9a9a9e9647392a19e7a885b08000e89c86b535 ]
One path takes care of SKB_GSO_DODGY, assumingskb->len is bigger than hdr_len.
virtio_net_hdr_to_skb() does not fully dissect TCP headers, it only make sure it is at least 20 bytes.
It is possible for an user to provide a malicious 'GSO' packet, total length of 80 bytes.
- 20 bytes of IPv4 header
- 60 bytes TCP header
- a small gso_size like 8
virtio_net_hdr_to_skb() would declare this packet as a normal GSO packet, because it would see 40 bytes of payload, bigger than gso_size.
We need to make detect this case to not underflow
qdisc_skb_cb(skb)->pkt_len.
--- net/core/dev.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
net/core/dev.c +7 -3
@@ -3795,10 +3795,14 @@ static void qdisc_pkt_len_init(struct sk_buff *skb) hdr_len +=sizeof (struct udphdr ); } -if (shinfo->gso_type &SKB_GSO_DODGY ) - gso_segs =DIV_ROUND_UP (skb->len - hdr_len, - shinfo->gso_size); +if (unlikely (shinfo->gso_type &SKB_GSO_DODGY )) { +int payload = skb->len - hdr_len; +/* Malicious packet. */ +if (payload <=0 ) +return ; + gso_segs =DIV_ROUND_UP (payload, shinfo->gso_size); + }qdisc_skb_cb (skb)->pkt_len += (gso_segs -1 ) * hdr_len; } }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 388/691 stmmac_pci: Fix underflow size in stmmac_rx
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zekun Shen <[email protected]>
[ Upstream commit 0f296e782f21dc1c55475a3c107ac68ab09cc1cf ]
This bug report came up when we were testing the device driver by fuzzing. It shows that buf1_len can get underflowed and be 0xfffffffc (4294967292).
This bug is triggerable with a compromised/malfunctioning device. We found the bug through QEMU emulation tested the patch with emulation. We did NOT test it on real hardware.
Attached is the bug report by fuzzing.
BUG: KASAN: use-after-free in stmmac_napi_poll_rx+0x1c08/0x36e0 [stmmac] Read of size 4294967292 at addr ffff888016358000 by task ksoftirqd/0/9 CPU: 0 PID: 9 Comm: ksoftirqd/0 Tainted: G W 5.6.0 #1 Call Trace: dump_stack+0x76/0xa0 print_address_description.constprop.0+0x16/0x200 ? stmmac_napi_poll_rx+0x1c08/0x36e0 [stmmac] ? stmmac_napi_poll_rx+0x1c08/0x36e0 [stmmac] __kasan_report.cold+0x37/0x7c ? stmmac_napi_poll_rx+0x1c08/0x36e0 [stmmac] kasan_report+0xe/0x20 check_memory_region+0x15a/0x1d0 memcpy+0x20/0x50 stmmac_napi_poll_rx+0x1c08/0x36e0 [stmmac] ? stmmac_suspend+0x850/0x850 [stmmac] ? __next_timer_interrupt+0xba/0xf0 net_rx_action+0x363/0xbd0 ? call_timer_fn+0x240/0x240 ? __switch_to_asm+0x40/0x70 ? napi_busy_loop+0x520/0x520 ? __schedule+0x839/0x15a0 __do_softirq+0x18c/0x634 ? takeover_tasklets+0x5f0/0x5f0 run_ksoftirqd+0x15/0x20 smpboot_thread_fn+0x2f1/0x6b0 ? smpboot_unregister_percpu_thread+0x160/0x160 ? __kthread_parkme+0x80/0x100 ? smpboot_unregister_percpu_thread+0x160/0x160 kthread+0x2b5/0x3b0 ? kthread_create_on_node+0xd0/0xd0 ret_from_fork+0x22/0x40
Stable-dep-of: 4c1b56671b68 ("net: stmmac: dwmac4: extend timeout for VLAN Tag register busy bit check")
--- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +5 -4
@@ -5241,12 +5241,13 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)if (likely (!(status & rx_not_ls)) && (likely (priv->synopsys_id >=DWMAC_CORE_4_00 ) ||unlikely (status != llc_snap))) { -if (buf2_len) +if (buf2_len) { buf2_len -=ETH_FCS_LEN ; -else + len -=ETH_FCS_LEN ; + }else if (buf1_len) { buf1_len -=ETH_FCS_LEN ; - - len -=ETH_FCS_LEN ; + len -=ETH_FCS_LEN ; + } }if (!skb) {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 389/691 net: stmmac: Disable automatic FCS/Pad stripping
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kurt Kanzenbach <[email protected]>
[ Upstream commit 929d43421ee526c5a3c4d6f7e2bb1b98b2cb1b1f ]
The stmmac has the possibility to automatically strip the padding/FCS for IEEE 802.3 type frames. This feature is enabled conditionally. Therefore, the stmmac receive path has to have a determination logic whether the FCS has to be stripped in software or not.
In fact, for DSA this ACS feature is disabled and the determination logic doesn't check for it properly. For instance, when using DSA in combination with an older stmmac (pre version 4), the FCS is not stripped by hardware or software which is problematic.
So either add another check for DSA to the fast path or simply disable ACS feature completely. The latter approach has been chosen, because most of the time the FCS is stripped in software anyway and it removes conditionals from the receive fast path.
Stable-dep-of: 4c1b56671b68 ("net: stmmac: dwmac4: extend timeout for VLAN Tag register busy bit check")
--- .../net/ethernet/stmicro/stmmac/dwmac100.h | 2 +- .../net/ethernet/stmicro/stmmac/dwmac1000.h | 2 +- .../ethernet/stmicro/stmmac/dwmac1000_core.c | 9 ------- .../ethernet/stmicro/stmmac/dwmac100_core.c | 8 ------- .../net/ethernet/stmicro/stmmac/dwmac4_core.c | 1 - .../net/ethernet/stmicro/stmmac/stmmac_main.c | 24 ++++--------------- 6 files changed, 6 insertions(+), 40 deletions(-)
drivers/net/ethernet/stmicro/stmmac/dwmac100.h +1 -1
@@ -56,7 +56,7 @@#define MAC_CONTROL_TE 0x00000008/* Transmitter Enable */ #define MAC_CONTROL_RE 0x00000004/* Receiver Enable */ -#define MAC_CORE_INIT (MAC_CONTROL_HBD | MAC_CONTROL_ASTP) +#define MAC_CORE_INIT (MAC_CONTROL_HBD)/* MAC FLOW CTRL defines */ #define MAC_FLOW_CTRL_PT_MASK 0xffff0000/* Pause Time Mask */
drivers/net/ethernet/stmicro/stmmac/dwmac1000.h +1 -1
@@ -126,7 +126,7 @@ enum inter_frame_gap {#define GMAC_CONTROL_TE 0x00000008/* Transmitter Enable */ #define GMAC_CONTROL_RE 0x00000004/* Receiver Enable */ -#define GMAC_CORE_INIT (GMAC_CONTROL_JD | GMAC_CONTROL_PS | GMAC_CONTROL_ACS | \ +#define GMAC_CORE_INIT (GMAC_CONTROL_JD | GMAC_CONTROL_PS | \ GMAC_CONTROL_BE | GMAC_CONTROL_DCRS)/* GMAC Frame Filter defines */
drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c +0 -9
@@ -15,7 +15,6 @@#include <linux/crc32.h> #include <linux/slab.h> #include <linux/ethtool.h> -#include <net/dsa.h> #include <asm/io.h> #include "stmmac.h" #include "stmmac_pcs.h"
@@ -24,7 +23,6 @@static void dwmac1000_core_init (struct mac_device_info *hw,struct net_device *dev) { -struct stmmac_priv *priv =netdev_priv (dev);void __iomem *ioaddr = hw->pcsr;u32 value =readl (ioaddr +GMAC_CONTROL );int mtu = dev->mtu;
@@ -32,13 +30,6 @@ static void dwmac1000_core_init(struct mac_device_info *hw,/* Configure GMAC core */ value |=GMAC_CORE_INIT ; -/* Clear ACS bit because Ethernet switch tagging formats such as -* Broadcom tags can look like invalid LLC/SNAP packets and cause the -* hardware to truncate packets on reception. -*/ -if (netdev_uses_dsa (dev) || !priv->plat->enh_desc) - value &= ~GMAC_CONTROL_ACS ; -if (mtu >1500 ) value |=GMAC_CONTROL_2K ;if (mtu >2000 )
drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c +0 -8
@@ -15,7 +15,6 @@*******************************************************************************/ #include <linux/crc32.h> -#include <net/dsa.h> #include <asm/io.h> #include "stmmac.h" #include "dwmac100.h"
@@ -28,13 +27,6 @@ static void dwmac100_core_init(struct mac_device_info *hw, value |=MAC_CORE_INIT ; -/* Clear ASTP bit because Ethernet switch tagging formats such as -* Broadcom tags can look like invalid LLC/SNAP packets and cause the -* hardware to truncate packets on reception. -*/ -if (netdev_uses_dsa (dev)) - value &= ~MAC_CONTROL_ASTP ; -writel (value, ioaddr +MAC_CONTROL );#ifdef STMMAC_VLAN_TAG_USED
drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c +0 -1
@@ -14,7 +14,6 @@#include <linux/slab.h> #include <linux/ethtool.h> #include <linux/io.h> -#include <net/dsa.h> #include "stmmac.h" #include "stmmac_pcs.h" #include "dwmac4.h"
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +4 -20
@@ -5045,16 +5045,8 @@ static int stmmac_rx_zc(struct stmmac_priv *priv, int limit, u32 queue) buf1_len =stmmac_rx_buf1_len (priv, p, status, len); len += buf1_len; -/* ACS is set; GMAC core strips PAD/FCS for IEEE 802.3 -* Type frames (LLC/LLC-SNAP) -* -* llc_snap is never checked in GMAC >= 4, so this ACS -* feature is always disabled and packets need to be -* stripped manually. -*/ -if (likely (!(status & rx_not_ls)) && - (likely (priv->synopsys_id >=DWMAC_CORE_4_00 ) || -unlikely (status != llc_snap))) { +/* ACS is disabled; strip manually. */ +if (likely (!(status & rx_not_ls))) { buf1_len -=ETH_FCS_LEN ; len -=ETH_FCS_LEN ; }
@@ -5231,16 +5223,8 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue) buf2_len =stmmac_rx_buf2_len (priv, p, status, len); len += buf2_len; -/* ACS is set; GMAC core strips PAD/FCS for IEEE 802.3 -* Type frames (LLC/LLC-SNAP) -* -* llc_snap is never checked in GMAC >= 4, so this ACS -* feature is always disabled and packets need to be -* stripped manually. -*/ -if (likely (!(status & rx_not_ls)) && - (likely (priv->synopsys_id >=DWMAC_CORE_4_00 ) || -unlikely (status != llc_snap))) { +/* ACS is disabled; strip manually. */ +if (likely (!(status & rx_not_ls))) {if (buf2_len) { buf2_len -=ETH_FCS_LEN ; len -=ETH_FCS_LEN ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 390/691 net: stmmac: dwmac4: extend timeout for VLAN Tag register busy bit check
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shenwei Wang <[email protected]>
[ Upstream commit 4c1b56671b68ffcbe6b78308bfdda6bcce6491ae ]
Increase the timeout for checking the busy bit of the VLAN Tag register from 10µs to 500ms. This change is necessary to accommodate scenarios where Energy Efficient Ethernet (EEE) is enabled.
Overnight testing revealed that when EEE is active, the busy bit can remain set for up to approximately 300ms. The new 500ms timeout provides a safety margin.
--- .../net/ethernet/stmicro/stmmac/dwmac4_core.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-)
drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c +9 -9
@@ -14,6 +14,7 @@#include <linux/slab.h> #include <linux/ethtool.h> #include <linux/io.h> +#include <linux/iopoll.h> #include "stmmac.h" #include "stmmac_pcs.h" #include "dwmac4.h"
@@ -469,7 +470,7 @@ static int dwmac4_write_vlan_filter(struct net_device *dev, u8 index, u32 data) { void __iomem *ioaddr = (void __iomem *)dev->base_addr; -int i, timeout =10 ; +int ret;u32 val;if (index >= hw->num_vlan)
@@ -485,16 +486,15 @@ static int dwmac4_write_vlan_filter(struct net_device *dev,writel (val, ioaddr +GMAC_VLAN_TAG ); -for (i =0 ; i < timeout; i++) { - val =readl (ioaddr +GMAC_VLAN_TAG ); -if (!(val &GMAC_VLAN_TAG_CTRL_OB )) -return 0 ; -udelay (1 ); + ret =readl_poll_timeout (ioaddr +GMAC_VLAN_TAG , val, + !(val &GMAC_VLAN_TAG_CTRL_OB ), +1000 ,500000 ); +if (ret) { +netdev_err (dev,"Timeout accessing MAC_VLAN_Tag_Filter\n" ); +return -EBUSY ; } -netdev_err (dev,"Timeout accessing MAC_VLAN_Tag_Filter\n" ); - -return -EBUSY ; +return 0 ; } static int dwmac4_add_hw_vlan_rx_fltr(struct net_device *dev,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 391/691 ipv4: ip_gre: Fix drops of small packets in ipgre_xmit
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Anton Danilov <[email protected]>
[ Upstream commit c4a14f6d9d17ad1e41a36182dd3b8a5fd91efbd7 ]
Regression Description:
Depending on the options specified for the GRE tunnel device, small packets may be dropped. This occurs because the pskb_network_may_pull function fails due to the packet's insufficient length.
For example, if only the okey option is specified for the tunnel device, original (before encapsulation) packets smaller than 28 bytes (including the IPv4 header) will be dropped. This happens because the required length is calculated relative to the network header, not the skb->head.
Here is how the required length is computed and checked:
* The pull_len variable is set to 28 bytes, consisting of:
* IPv4 header: 20 bytes
* GRE header with Key field: 8 bytes
* The pskb_network_may_pull function adds the network offset, shifting the checkable space further to the beginning of the network header and extending it to the beginning of the packet. As a result, the end of the checkable space occurs beyond the actual end of the packet.
Instead of ensuring that 28 bytes are present in skb->head, the function is requesting these 28 bytes starting from the network header. For small packets, this requested length exceeds the actual packet size, causing the check to fail and the packets to be dropped.
This issue affects both locally originated and forwarded packets in DMVPN-like setups.
How to reproduce (for local originated packets):
ip link add dev gre1 type gre ikey 1.9.8.4 okey 1.9.8.4 \
local <your-ip> remote 0.0.0.0 ip link set mtu 1400 dev gre1
ip link set up dev gre1
ip address add 192.168.13.1/24 dev gre1
ip neighbor add 192.168.13.2 lladdr <remote-ip> dev gre1 ping -s 1374 -c 10 192.168.13.2
tcpdump -vni gre1
tcpdump -vni <your-ext-iface> 'ip proto 47'
ip -s -s -d link show dev gre1
Solution:
Use the pskb_may_pull function instead the pskb_network_may_pull.
--- net/ipv4/ip_gre.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
net/ipv4/ip_gre.c +3 -3
@@ -644,11 +644,11 @@ static netdev_tx_t ipgre_xmit(struct sk_buff *skb,if (skb_cow_head (skb,0 )) goto free_skb; - tnl_params = (const struct iphdr *)skb->data; - -if (!pskb_network_may_pull (skb, pull_len)) +if (!pskb_may_pull (skb, pull_len)) goto free_skb; + tnl_params = (const struct iphdr *)skb->data; +/* ip_tunnel_xmit() needs skb->data pointing to gre header. */ skb_pull (skb, pull_len);skb_reset_mac_header (skb);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 392/691 ppp: do not assume bh is held in ppp_channel_bridge_input()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit aec7291003df78cb71fd461d7b672912bde55807 ]
Networking receive path is usually handled from BH handler. However, some protocols need to acquire the socket lock, and packets might be stored in the socket backlog is the socket was owned by a user process.
In this case, release_sock(), __release_sock(), and sk_backlog_rcv() might call the sk->sk_backlog_rcv() handler in process context.
sybot caught ppp was not considering this case inppp_channel_bridge_input() :
WARNING: inconsistent lock state
6.11.0-rc7-syzkaller-g5f5673607153 #0 Not tainted
--------------------------------
inconsistent {SOFTIRQ-ON-W} -> {IN-SOFTIRQ-W} usage.
ksoftirqd/1/24 [HC0[0]:SC1[1]:HE1:SE0] takes:
ffff0000db7f11e0 (&pch->downl){+.?.}-{2:2}, at: spin_lock include/linux/spinlock.h:351 [inline] ffff0000db7f11e0 (&pch->downl){+.?.}-{2:2}, at: ppp_channel_bridge_input drivers/net/ppp/ppp_generic.c:2272 [inline] ffff0000db7f11e0 (&pch->downl){+.?.}-{2:2}, at: ppp_input+0x16c/0x854 drivers/net/ppp/ppp_generic.c:2304
{SOFTIRQ-ON-W} state was registered at:
lock_acquire+0x240/0x728 kernel/locking/lockdep.c:5759 __raw_spin_lock include/linux/spinlock_api_smp.h:133 [inline] _raw_spin_lock+0x48/0x60 kernel/locking/spinlock.c:154 spin_lock include/linux/spinlock.h:351 [inline] ppp_channel_bridge_input drivers/net/ppp/ppp_generic.c:2272 [inline] ppp_input+0x16c/0x854 drivers/net/ppp/ppp_generic.c:2304 pppoe_rcv_core+0xfc/0x314 drivers/net/ppp/pppoe.c:379 sk_backlog_rcv include/net/sock.h:1111 [inline] __release_sock+0x1a8/0x3d8 net/core/sock.c:3004 release_sock+0x68/0x1b8 net/core/sock.c:3558 pppoe_sendmsg+0xc8/0x5d8 drivers/net/ppp/pppoe.c:903 sock_sendmsg_nosec net/socket.c:730 [inline] __sock_sendmsg net/socket.c:745 [inline] __sys_sendto+0x374/0x4f4 net/socket.c:2204 __do_sys_sendto net/socket.c:2216 [inline] __se_sys_sendto net/socket.c:2212 [inline] __arm64_sys_sendto+0xd8/0xf8 net/socket.c:2212 __invoke_syscall arch/arm64/kernel/syscall.c:35 [inline] invoke_syscall+0x98/0x2b8 arch/arm64/kernel/syscall.c:49 el0_svc_common+0x130/0x23c arch/arm64/kernel/syscall.c:132 do_el0_svc+0x48/0x58 arch/arm64/kernel/syscall.c:151 el0_svc+0x54/0x168 arch/arm64/kernel/entry-common.c:712 el0t_64_sync_handler+0x84/0xfc arch/arm64/kernel/entry-common.c:730 el0t_64_sync+0x190/0x194 arch/arm64/kernel/entry.S:598 irq event stamp: 282914 hardirqs last enabled at (282914): [<ffff80008b42e30c>] __raw_spin_unlock_irqrestore include/linux/spinlock_api_smp.h:151 [inline] hardirqs last enabled at (282914): [<ffff80008b42e30c>] _raw_spin_unlock_irqrestore+0x38/0x98 kernel/locking/spinlock.c:194 hardirqs last disabled at (282913): [<ffff80008b42e13c>] __raw_spin_lock_irqsave include/linux/spinlock_api_smp.h:108 [inline] hardirqs last disabled at (282913): [<ffff80008b42e13c>] _raw_spin_lock_irqsave+0x2c/0x7c kernel/locking/spinlock.c:162 softirqs last enabled at (282904): [<ffff8000801f8e88>] softirq_handle_end kernel/softirq.c:400 [inline] softirqs last enabled at (282904): [<ffff8000801f8e88>] handle_softirqs+0xa3c/0xbfc kernel/softirq.c:582 softirqs last disabled at (282909): [<ffff8000801fbdf8>] run_ksoftirqd+0x70/0x158 kernel/softirq.c:928
other info that might help us debug this:
Possible unsafe locking scenario:
CPU0
----
lock(&pch->downl);
<Interrupt>
lock(&pch->downl);*** DEADLOCK ***
1 lock held by ksoftirqd/1/24:
#0: ffff80008f74dfa0 (rcu_read_lock){....}-{1:2}, at: rcu_lock_acquire+0x10/0x4c include/linux/rcupdate.h:325
stack backtrace: CPU: 1 UID: 0 PID: 24 Comm: ksoftirqd/1 Not tainted 6.11.0-rc7-syzkaller-g5f5673607153 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 08/06/2024 Call trace: dump_backtrace+0x1b8/0x1e4 arch/arm64/kernel/stacktrace.c:319 show_stack+0x2c/0x3c arch/arm64/kernel/stacktrace.c:326 __dump_stack lib/dump_stack.c:93 [inline] dump_stack_lvl+0xe4/0x150 lib/dump_stack.c:119 dump_stack+0x1c/0x28 lib/dump_stack.c:128 print_usage_bug+0x698/0x9ac kernel/locking/lockdep.c:4000 mark_lock_irq+0x980/0xd2c mark_lock+0x258/0x360 kernel/locking/lockdep.c:4677 __lock_acquire+0xf48/0x779c kernel/locking/lockdep.c:5096 lock_acquire+0x240/0x728 kernel/locking/lockdep.c:5759 __raw_spin_lock include/linux/spinlock_api_smp.h:133 [inline] _raw_spin_lock+0x48/0x60 kernel/locking/spinlock.c:154 spin_lock include/linux/spinlock.h:351 [inline] ppp_channel_bridge_input drivers/net/ppp/ppp_generic.c:2272 [inline] ppp_input+0x16c/0x854 drivers/net/ppp/ppp_generic.c:2304 ppp_async_process+0x98/0x150 drivers/net/ppp/ppp_async.c:495 tasklet_action_common+0x318/0x3f4 kernel/softirq.c:785 tasklet_action+0x68/0x8c kernel/softirq.c:811 handle_softirqs+0x2e4/0xbfc kernel/softirq.c:554 run_ksoftirqd+0x70/0x158 kernel/softirq.c:928 smpboot_thread_fn+0x4b0/0x90c kernel/smpboot.c:164 kthread+0x288/0x310 kernel/kthread.c:389 ret_from_fork+0x10/0x20 arch/arm64/kernel/entry.S:860
--- drivers/net/ppp/ppp_generic.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/ppp/ppp_generic.c +2 -2
@@ -2268,7 +2268,7 @@ static bool ppp_channel_bridge_input(struct channel *pch, struct sk_buff *skb)if (!pchb) goto out_rcu; -spin_lock (&pchb->downl); +spin_lock_bh (&pchb->downl);if (!pchb->chan) {/* channel got unregistered */ kfree_skb (skb);
@@ -2280,7 +2280,7 @@ static bool ppp_channel_bridge_input(struct channel *pch, struct sk_buff *skb)kfree_skb (skb); outl: -spin_unlock (&pchb->downl); +spin_unlock_bh (&pchb->downl); out_rcu:rcu_read_unlock ();
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 393/691 sctp: set sk_state back to CLOSED if autobind fails in sctp_listen_start
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xin Long <[email protected]>
[ Upstream commit 8beee4d8dee76b67c75dc91fd8185d91e845c160 ]
In sctp_listen_start() invoked by sctp_inet_listen(), it should set the sk_state back to CLOSED if sctp_autobind() fails due to whatever reason.
Otherwise, next time when calling sctp_inet_listen(), if sctp_sk(sk)->reuse is already set via setsockopt(SCTP_REUSE_PORT), sctp_sk(sk)->bind_hash will be dereferenced as sk_state is LISTENING, which causes a crash as bind_hash is NULL.
KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007] RIP: 0010:sctp_inet_listen+0x7f0/0xa20 net/sctp/socket.c:8617 Call Trace: <TASK> __sys_listen_socket net/socket.c:1883 [inline] __sys_listen+0x1b7/0x230 net/socket.c:1894 __do_sys_listen net/socket.c:1902 [inline]
--- net/sctp/socket.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
net/sctp/socket.c +3 -1
@@ -8542,8 +8542,10 @@ static int sctp_listen_start(struct sock *sk, int backlog)*/ inet_sk_set_state (sk,SCTP_SS_LISTENING );if (!ep->base.bind_addr.port) { -if (sctp_autobind (sk)) +if (sctp_autobind (sk)) { +inet_sk_set_state (sk,SCTP_SS_CLOSED );return -EAGAIN ; + } }else {if (sctp_get_port (sk,inet_sk (sk)->inet_num)) {inet_sk_set_state (sk,SCTP_SS_CLOSED );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 394/691 i2c: xiic: Fix broken locking on tx_msg
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marek Vasut <[email protected]>
[ Upstream commit c119e7d00c916881913011e6f4c6ac349a41e4e2 ]
The tx_msg is set from multiple places, sometimes without locking, which fall apart on any SMP system. Only ever access tx_msg inside the driver mutex.
Stable-dep-of: 1d4a1adbed25 ("i2c: xiic: Try re-initialization on bus busy timeout")
--- drivers/i2c/busses/i2c-xiic.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-)
drivers/i2c/busses/i2c-xiic.c +16 -10
@@ -170,7 +170,7 @@ struct xiic_i2c {#define xiic_tx_space (i2c) ((i2c)->tx_msg->len - (i2c)->tx_pos)#define xiic_rx_space (i2c) ((i2c)->rx_msg->len - (i2c)->rx_pos) -static int xiic_start_xfer (struct xiic_i2c *i2c); +static int xiic_start_xfer (struct xiic_i2c *i2c,struct i2c_msg *msgs,int num);static void __xiic_start_xfer (struct xiic_i2c *i2c);/*
@@ -701,15 +701,25 @@ static void __xiic_start_xfer(struct xiic_i2c *i2c) } -static int xiic_start_xfer (struct xiic_i2c *i2c) +static int xiic_start_xfer (struct xiic_i2c *i2c,struct i2c_msg *msgs,int num) {int ret; +mutex_lock (&i2c->lock); + ret =xiic_busy (i2c); +if (ret) + goto out; + + i2c->tx_msg = msgs; + i2c->rx_msg =NULL ; + i2c->nmsgs = num; + ret =xiic_reinit (i2c);if (!ret)__xiic_start_xfer (i2c); +out:mutex_unlock (&i2c->lock);return ret;
@@ -727,14 +737,7 @@ static int xiic_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)if (err <0 )return err; - err =xiic_busy (i2c); -if (err) - goto out; - - i2c->tx_msg = msgs; - i2c->nmsgs = num; - - err =xiic_start_xfer (i2c); + err =xiic_start_xfer (i2c, msgs, num);if (err <0 ) {dev_err (adap->dev.parent,"Error xiic_start_xfer\n" ); goto out;
@@ -742,9 +745,11 @@ static int xiic_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)if (wait_event_timeout (i2c->wait, (i2c->state ==STATE_ERROR ) || (i2c->state ==STATE_DONE ),HZ )) { +mutex_lock (&i2c->lock); err = (i2c->state ==STATE_DONE ) ? num : -EIO ; goto out; }else { +mutex_lock (&i2c->lock); i2c->tx_msg =NULL ; i2c->rx_msg =NULL ; i2c->nmsgs =0 ;
@@ -752,6 +757,7 @@ static int xiic_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) goto out; } out: +mutex_unlock (&i2c->lock);pm_runtime_mark_last_busy (i2c->dev);pm_runtime_put_autosuspend (i2c->dev);return err;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 395/691 i2c: xiic: Switch from waitqueue to completion
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marek Vasut <[email protected]>
[ Upstream commit fdacc3c7405d1fc33c1f2771699a4fc24551e480 ]
There will never be threads queueing up in the xiic_xmit(), use completion synchronization primitive to wait for the interrupt handler thread to complete instead as it is much better fit and there is no need to overload it for this purpose.
Stable-dep-of: 1d4a1adbed25 ("i2c: xiic: Try re-initialization on bus busy timeout")
--- drivers/i2c/busses/i2c-xiic.c | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-)
drivers/i2c/busses/i2c-xiic.c +18 -15
@@ -23,7 +23,7 @@#include <linux/platform_device.h> #include <linux/i2c.h> #include <linux/interrupt.h> -#include <linux/wait.h> +#include <linux/completion.h> #include <linux/platform_data/i2c-xiic.h> #include <linux/io.h> #include <linux/slab.h>
@@ -48,7 +48,7 @@ enum xiic_endian {* struct xiic_i2c - Internal representation of the XIIC I2C bus * @dev: Pointer to device structure * @base: Memory base of the HW registers -* @wait: Wait queue for callers +* @completion: Completion for callers * @adap: Kernel adapter representation * @tx_msg: Messages from above to be sent * @lock: Mutual exclusion
@@ -64,7 +64,7 @@ enum xiic_endian {struct xiic_i2c {struct device *dev;void __iomem *base; -wait_queue_head_t wait; +struct completion completion;struct i2c_adapter adap;struct i2c_msg *tx_msg;struct mutex lock;
@@ -160,6 +160,9 @@ struct xiic_i2c {#define XIIC_PM_TIMEOUT 1000/* ms */ /* timeout waiting for the controller to respond */ #define XIIC_I2C_TIMEOUT (msecs_to_jiffies(1000)) +/* timeout waiting for the controller finish transfers */ +#define XIIC_XFER_TIMEOUT (msecs_to_jiffies(10000)) +/* * The following constant is used for the device global interrupt enable * register, to enable all interrupts for the device, this is the only bit
@@ -367,7 +370,7 @@ static void xiic_wakeup(struct xiic_i2c *i2c, int code) i2c->rx_msg =NULL ; i2c->nmsgs =0 ; i2c->state = code; -wake_up (&i2c->wait); +complete (&i2c->completion); }static irqreturn_t xiic_process (int irq,void *dev_id)
@@ -714,6 +717,7 @@ static int xiic_start_xfer(struct xiic_i2c *i2c, struct i2c_msg *msgs, int num) i2c->tx_msg = msgs; i2c->rx_msg =NULL ; i2c->nmsgs = num; +init_completion (&i2c->completion); ret =xiic_reinit (i2c);if (!ret)
@@ -740,23 +744,23 @@ static int xiic_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) err =xiic_start_xfer (i2c, msgs, num);if (err <0 ) {dev_err (adap->dev.parent,"Error xiic_start_xfer\n" ); - goto out; +return err; } -if (wait_event_timeout (i2c->wait, (i2c->state ==STATE_ERROR ) || - (i2c->state ==STATE_DONE ),HZ )) { -mutex_lock (&i2c->lock); - err = (i2c->state ==STATE_DONE ) ? num : -EIO ; - goto out; - }else { -mutex_lock (&i2c->lock); + err =wait_for_completion_timeout (&i2c->completion,XIIC_XFER_TIMEOUT ); +mutex_lock (&i2c->lock); +if (err ==0 ) {/* Timeout */ i2c->tx_msg =NULL ; i2c->rx_msg =NULL ; i2c->nmsgs =0 ; err = -ETIMEDOUT ; - goto out; + }else if (err <0 ) {/* Completion error */ + i2c->tx_msg =NULL ; + i2c->rx_msg =NULL ; + i2c->nmsgs =0 ; + }else { + err = (i2c->state ==STATE_DONE ) ? num : -EIO ; } -out:mutex_unlock (&i2c->lock);pm_runtime_mark_last_busy (i2c->dev);pm_runtime_put_autosuspend (i2c->dev);
@@ -819,7 +823,6 @@ static int xiic_i2c_probe(struct platform_device *pdev) DRIVER_NAME " %s", pdev->name);mutex_init (&i2c->lock); -init_waitqueue_head (&i2c->wait); i2c->clk =devm_clk_get (&pdev->dev,NULL );if (IS_ERR (i2c->clk))
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 396/691 i2c: xiic: Fix RX IRQ busy check
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marek Vasut <[email protected]>
[ Upstream commit 294b29f15469e90893c2b72a738a962ee02a12eb ]
In case the XIIC does TX/RX transfer, make sure no other kernel thread can start another TX transfer at the same time. This could happen since the driver only checks tx_msg for being non-NULL and returns -EBUSY in that case, however it is necessary to check also rx_msg for the same.
Stable-dep-of: 1d4a1adbed25 ("i2c: xiic: Try re-initialization on bus busy timeout")
--- drivers/i2c/busses/i2c-xiic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/i2c/busses/i2c-xiic.c +1 -1
@@ -545,7 +545,7 @@ static int xiic_busy(struct xiic_i2c *i2c)int tries =3 ;int err; -if (i2c->tx_msg) +if (i2c->tx_msg || i2c->rx_msg)return -EBUSY ;/* In single master mode bus can only be busy, when in use by this
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 397/691 i2c: xiic: xiic_xfer(): Fix runtime PM leak on error path
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lars-Peter Clausen <[email protected]>
[ Upstream commit d663d93bb47e7ab45602b227701022d8aa16040a ]
The xiic_xfer() function gets a runtime PM reference when the function is entered. This reference is released when the function is exited. There is currently one error path where the function exits directly, which leads to a leak of the runtime PM reference.
Make sure that this error path also releases the runtime PM reference.
Stable-dep-of: 1d4a1adbed25 ("i2c: xiic: Try re-initialization on bus busy timeout")
--- drivers/i2c/busses/i2c-xiic.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/i2c/busses/i2c-xiic.c +3 -1
@@ -744,7 +744,7 @@ static int xiic_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) err =xiic_start_xfer (i2c, msgs, num);if (err <0 ) {dev_err (adap->dev.parent,"Error xiic_start_xfer\n" ); -return err; + goto out; } err =wait_for_completion_timeout (&i2c->completion,XIIC_XFER_TIMEOUT );
@@ -762,6 +762,8 @@ static int xiic_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) err = (i2c->state ==STATE_DONE ) ? num : -EIO ; }mutex_unlock (&i2c->lock); + +out:pm_runtime_mark_last_busy (i2c->dev);pm_runtime_put_autosuspend (i2c->dev);return err;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 398/691 i2c: xiic: improve error message when transfer fails to start
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marc Ferland <[email protected]>
[ Upstream commit ee1691d0ae103ba7fd9439800ef454674fadad27 ]
xiic_start_xfer can fail for different reasons:
- EBUSY: bus is busy or i2c messages still in tx_msg or rx_msg
- ETIMEDOUT: timed-out trying to clear the RX fifo
- EINVAL: wrong clock settings
Both EINVAL and ETIMEDOUT will currently print a specific error message followed by a generic one, for example:
Failed to clear rx fifo
Error xiic_start_xfer
however EBUSY will simply output the generic message:
Error xiic_start_xfer
which is not really helpful.
This commit adds a new error message when a busy condition is detected and also removes the generic message since it does not provide any relevant information to the user.
Stable-dep-of: 1d4a1adbed25 ("i2c: xiic: Try re-initialization on bus busy timeout")
--- drivers/i2c/busses/i2c-xiic.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
drivers/i2c/busses/i2c-xiic.c +5 -4
@@ -711,8 +711,11 @@ static int xiic_start_xfer(struct xiic_i2c *i2c, struct i2c_msg *msgs, int num)mutex_lock (&i2c->lock); ret =xiic_busy (i2c); -if (ret) +if (ret) { +dev_err (i2c->adap.dev.parent, +"cannot start a transfer while busy\n" ); goto out; + } i2c->tx_msg = msgs; i2c->rx_msg =NULL ;
@@ -742,10 +745,8 @@ static int xiic_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)return err; err =xiic_start_xfer (i2c, msgs, num); -if (err <0 ) { -dev_err (adap->dev.parent,"Error xiic_start_xfer\n" ); +if (err <0 ) goto out; - } err =wait_for_completion_timeout (&i2c->completion,XIIC_XFER_TIMEOUT );mutex_lock (&i2c->lock);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 399/691 i2c: xiic: Try re-initialization on bus busy timeout
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Robert Hancock <[email protected]>
[ Upstream commit 1d4a1adbed2582444aaf97671858b7d12915bd05 ]
In the event that the I2C bus was powered down when the I2C controller driver loads, or some spurious pulses occur on the I2C bus, it's possible that the controller detects a spurious I2C "start" condition. In this situation it may continue to report the bus is busy indefinitely and block the controller from working.
The "single-master" DT flag can be specified to disable bus busy checks entirely, but this may not be safe to use in situations where other I2C masters may potentially exist.
In the event that the controller reports "bus busy" for too long when starting a transaction, we can try reinitializing the controller to see if the busy condition clears. This allows recovering from this scenario.
--- drivers/i2c/busses/i2c-xiic.c | 41 ++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 15 deletions(-)
drivers/i2c/busses/i2c-xiic.c +26 -15
@@ -540,23 +540,11 @@ static int xiic_bus_busy(struct xiic_i2c *i2c)return (sr &XIIC_SR_BUS_BUSY_MASK ) ? -EBUSY :0 ; } -static int xiic_busy (struct xiic_i2c *i2c) +static int xiic_wait_not_busy (struct xiic_i2c *i2c) {int tries =3 ;int err; -if (i2c->tx_msg || i2c->rx_msg) -return -EBUSY ; - -/* In single master mode bus can only be busy, when in use by this -* driver. If the register indicates bus being busy for some reason we -* should ignore it, since bus will never be released and i2c will be -* stuck forever. -*/ -if (i2c->singlemaster) { -return 0 ; - } -/* for instance if previous transfer was terminated due to TX error * it might be that the bus is on it's way to become available * give it at most 3 ms to wake
@@ -710,13 +698,36 @@ static int xiic_start_xfer(struct xiic_i2c *i2c, struct i2c_msg *msgs, int num)mutex_lock (&i2c->lock); - ret =xiic_busy (i2c); -if (ret) { +if (i2c->tx_msg || i2c->rx_msg) {dev_err (i2c->adap.dev.parent,"cannot start a transfer while busy\n" ); + ret = -EBUSY ; goto out; } +/* In single master mode bus can only be busy, when in use by this +* driver. If the register indicates bus being busy for some reason we +* should ignore it, since bus will never be released and i2c will be +* stuck forever. +*/ +if (!i2c->singlemaster) { + ret =xiic_wait_not_busy (i2c); +if (ret) { +/* If the bus is stuck in a busy state, such as due to spurious low +* pulses on the bus causing a false start condition to be detected, +* then try to recover by re-initializing the controller and check +* again if the bus is still busy. +*/ +dev_warn (i2c->adap.dev.parent,"I2C bus busy timeout, reinitializing\n" ); + ret =xiic_reinit (i2c); +if (ret) + goto out; + ret =xiic_wait_not_busy (i2c); +if (ret) + goto out; + } + } + i2c->tx_msg = msgs; i2c->rx_msg =NULL ; i2c->nmsgs = num;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 400/691 media: usbtv: Remove useless locks in usbtv_video_free()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Benjamin Gaignard <[email protected]>
[ Upstream commit 65e6a2773d655172143cc0b927cdc89549842895 ]
Remove locks calls in usbtv_video_free() because are useless and may led to a deadlock as reported here:
https://syzkaller.appspot.com/x/bisect.txt?x=166dc872180000
Also remove usbtv_stop() call since it will be called when unregistering the device.
Before 'c838530d230b' this issue would only be noticed if you disconnect while streaming and now it is noticeable even when disconnecting while not streaming.
--- drivers/media/usb/usbtv/usbtv-video.c | 7 ------- 1 file changed, 7 deletions(-)
drivers/media/usb/usbtv/usbtv-video.c +0 -7
@@ -959,15 +959,8 @@ int usbtv_video_init(struct usbtv *usbtv)void usbtv_video_free (struct usbtv *usbtv) { -mutex_lock (&usbtv->vb2q_lock); -mutex_lock (&usbtv->v4l2_lock); - -usbtv_stop (usbtv);vb2_video_unregister_device (&usbtv->vdev);v4l2_device_disconnect (&usbtv->v4l2_dev); -mutex_unlock (&usbtv->v4l2_lock); -mutex_unlock (&usbtv->vb2q_lock); -v4l2_device_put (&usbtv->v4l2_dev); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 401/691 ALSA: mixer_oss: Remove some incorrect kfree_const() usages
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christophe JAILLET <[email protected]>
[ Upstream commit 368e4663c557de4a33f321b44e7eeec0a21b2e4e ]
"assigned" and "assigned->name" are allocated in snd_mixer_oss_proc_write() using kmalloc() and kstrdup(), so there is no point in using kfree_const() to free these resources.
Switch to the more standard kfree() to free these resources.
This could avoid a memory leak.
--- sound/core/oss/mixer_oss.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
sound/core/oss/mixer_oss.c +2 -2
@@ -967,8 +967,8 @@ static void snd_mixer_oss_slot_free(struct snd_mixer_oss_slot *chn)struct slot *p = chn->private_data;if (p) {if (p->allocated && p->assigned) { -kfree_const (p->assigned->name); -kfree_const (p->assigned); +kfree (p->assigned->name); +kfree (p->assigned); }kfree (p); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 402/691 ALSA: hda/realtek: Fix the push button function for the ALC257
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oder Chiou <[email protected]>
[ Upstream commit 05df9732a0894846c46d0062d4af535c5002799d ]
The headset push button cannot work properly in case of the ALC257. This patch reverted the previous commit to correct the side effect.
--- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+)
sound/pci/hda/patch_realtek.c +1 -0
@@ -577,6 +577,7 @@ static void alc_shutup_pins(struct hda_codec *codec)switch (codec->core.vendor_id) {case 0x10ec0236 :case 0x10ec0256 : +case 0x10ec0257 :case 0x19e58326 :case 0x10ec0283 :case 0x10ec0285 :
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 403/691 ALSA: hda/generic: Unconditionally prefer preferred_dacs pairs
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
[ Upstream commit 1c801e7f77445bc56e5e1fec6191fd4503534787 ]
Some time ago, we introduced the obey_preferred_dacs flag for choosing the DAC/pin pairs specified by the driver instead of parsing the paths. This works as expected, per se, but there have been a few cases where we forgot to set this flag while preferred_dacs table is already set up. It ended up with incorrect wiring and made us wondering why it doesn't work.
Basically, when the preferred_dacs table is provided, it means that the driver really wants to wire up to follow that. That is, the presence of the preferred_dacs table itself is already a "do-it" flag.
In this patch, we simply replace the evaluation of obey_preferred_dacs flag with the presence of preferred_dacs table for fixing the misbehavior. Another patch to drop of the obsoleted flag will follow.
--- sound/pci/hda/hda_generic.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
sound/pci/hda/hda_generic.c +2 -2
@@ -1379,7 +1379,7 @@ static int try_assign_dacs(struct hda_codec *codec, int num_outs,struct nid_path *path;hda_nid_t pin = pins[i]; -if (!spec->obey_preferred_dacs) { +if (!spec->preferred_dacs) { path =snd_hda_get_path_from_idx (codec, path_idx[i]);if (path) { badness +=assign_out_path_ctls (codec, path);
@@ -1391,7 +1391,7 @@ static int try_assign_dacs(struct hda_codec *codec, int num_outs,if (dacs[i]) {if (is_dac_already_used (codec, dacs[i])) badness += bad->shared_primary; - }else if (spec->obey_preferred_dacs) { + }else if (spec->preferred_dacs) { badness +=BAD_NO_PRIMARY_DAC ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 404/691 ASoC: imx-card: Set card.owner to avoid a warning calltrace if SND=m
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hui Wang <[email protected]>
[ Upstream commit 47d7d3fd72afc7dcd548806291793ee6f3848215 ]
In most Linux distribution kernels, the SND is set to m, in such a case, when booting the kernel on i.MX8MP EVK board, there is a warning calltrace like below:
Call trace: snd_card_init+0x484/0x4cc [snd] snd_card_new+0x70/0xa8 [snd] snd_soc_bind_card+0x310/0xbd0 [snd_soc_core] snd_soc_register_card+0xf0/0x108 [snd_soc_core] devm_snd_soc_register_card+0x4c/0xa4 [snd_soc_core]
That is because the card.owner is not set, a warning calltrace is raised in the snd_card_init() due to it.
--- sound/soc/fsl/imx-card.c | 1 + 1 file changed, 1 insertion(+)
sound/soc/fsl/imx-card.c +1 -0
@@ -731,6 +731,7 @@ static int imx_card_probe(struct platform_device *pdev) data->plat_data = plat_data; data->card.dev = &pdev->dev; + data->card.owner =THIS_MODULE ;dev_set_drvdata (&pdev->dev, &data->card);snd_soc_card_set_drvdata (&data->card, data);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 405/691 ALSA: hda/conexant: Fix conflicting quirk for System76 Pangolin
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
[ Upstream commit b3ebb007060f89d5a45c9b99f06a55e36a1945b5 ]
We received a regression report for System76 Pangolin (pang14) due to the recent fix for Tuxedo Sirius devices to support the top speaker. The reason was the conflicting PCI SSID, as often seen.
As a workaround, now the codec SSID is checked and the quirk is applied conditionally only to Sirius devices.
--- sound/pci/hda/patch_conexant.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-)
sound/pci/hda/patch_conexant.c +19 -5
@@ -820,6 +820,23 @@ static const struct hda_pintbl cxt_pincfg_sws_js201d[] = { {} }; +/* pincfg quirk for Tuxedo Sirius; +* unfortunately the (PCI) SSID conflicts with System76 Pangolin pang14, +* which has incompatible pin setup, so we check the codec SSID (luckily +* different one!) and conditionally apply the quirk here +*/ +static void cxt_fixup_sirius_top_speaker (struct hda_codec *codec, +const struct hda_fixup *fix, +int action) +{ +/* ignore for incorrectly picked-up pang14 */ +if (codec->core.subsystem_id ==0x278212b3 ) +return ; +/* set up the top speaker pin */ +if (action ==HDA_FIXUP_ACT_PRE_PROBE ) +snd_hda_codec_set_pincfg (codec,0x1d ,0x82170111 ); +} +static const struct hda_fixup cxt_fixups[] = { [CXT_PINCFG_LENOVO_X200 ] = { .type =HDA_FIXUP_PINS ,
@@ -980,11 +997,8 @@ static const struct hda_fixup cxt_fixups[] = { .v.pins = cxt_pincfg_sws_js201d, }, [CXT_PINCFG_TOP_SPEAKER] = { - .type = HDA_FIXUP_PINS, - .v.pins = (const struct hda_pintbl []) { - {0x1d ,0x82170111 }, - { } - }, + .type = HDA_FIXUP_FUNC, + .v.func = cxt_fixup_sirius_top_speaker, }, };
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 406/691 f2fs: Require FMODE_WRITE for atomic write ioctls
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jann Horn <[email protected]>
commit 4f5a100f87f32cb65d4bb1ad282a08c92f6f591e upstream.
The F2FS ioctls for starting and committing atomic writes check for inode_owner_or_capable(), but this does not give LSMs like SELinux or Landlock an opportunity to deny the write access - if the caller's FSUID matches the inode's UID, inode_owner_or_capable() immediately returns true.
There are scenarios where LSMs want to deny a process the ability to write particular files, even files that the FSUID of the process owns; but this can currently partially be bypassed using atomic write ioctls in two ways:
- F2FS_IOC_START_ATOMIC_REPLACE + F2FS_IOC_COMMIT_ATOMIC_WRITE can truncate an inode to size 0
- F2FS_IOC_START_ATOMIC_WRITE + F2FS_IOC_ABORT_ATOMIC_WRITE can revert changes another process concurrently made to a file
Fix it by requiring FMODE_WRITE for these operations, just like for F2FS_IOC_MOVE_RANGE. Since any legitimate caller should only be using these ioctls when intending to write into the file, that seems unlikely to break anything.
--- fs/f2fs/file.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
fs/f2fs/file.c +15 -0
@@ -2010,6 +2010,9 @@ static int f2fs_ioc_start_atomic_write(struct file *filp)struct f2fs_sb_info *sbi =F2FS_I_SB (inode);int ret; +if (!(filp->f_mode &FMODE_WRITE )) +return -EBADF ; +if (!inode_owner_or_capable (&init_user_ns, inode))return -EACCES ;
@@ -2080,6 +2083,9 @@ static int f2fs_ioc_commit_atomic_write(struct file *filp)struct inode *inode =file_inode (filp);int ret; +if (!(filp->f_mode &FMODE_WRITE )) +return -EBADF ; +if (!inode_owner_or_capable (&init_user_ns, inode))return -EACCES ;
@@ -2122,6 +2128,9 @@ static int f2fs_ioc_start_volatile_write(struct file *filp)struct inode *inode =file_inode (filp);int ret; +if (!(filp->f_mode &FMODE_WRITE )) +return -EBADF ; +if (!inode_owner_or_capable (&init_user_ns, inode))return -EACCES ;
@@ -2157,6 +2166,9 @@ static int f2fs_ioc_release_volatile_write(struct file *filp)struct inode *inode =file_inode (filp);int ret; +if (!(filp->f_mode &FMODE_WRITE )) +return -EBADF ; +if (!inode_owner_or_capable (&init_user_ns, inode))return -EACCES ;
@@ -2186,6 +2198,9 @@ static int f2fs_ioc_abort_volatile_write(struct file *filp)struct inode *inode =file_inode (filp);int ret; +if (!(filp->f_mode &FMODE_WRITE )) +return -EBADF ; +if (!inode_owner_or_capable (&init_user_ns, inode))return -EACCES ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 407/691 wifi: ath9k: fix possible integer overflow in ath9k_get_et_stats()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Kandybka <[email protected]>
[ Upstream commit 3f66f26703093886db81f0610b97a6794511917c ]
In 'ath9k_get_et_stats()', promote TX stats counters to 'u64' to avoid possible integer overflow. Compile tested only.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
--- drivers/net/wireless/ath/ath9k/debug.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/wireless/ath/ath9k/debug.c +2 -2
@@ -1316,11 +1316,11 @@ void ath9k_get_et_stats(struct ieee80211_hw *hw,struct ath_softc *sc = hw->priv;int i =0 ; - data[i++] = (sc->debug.stats.txstats[PR_QNUM (IEEE80211_AC_BE )].tx_pkts_all + + data[i++] = ((u64 )sc->debug.stats.txstats[PR_QNUM (IEEE80211_AC_BE )].tx_pkts_all + sc->debug.stats.txstats[PR_QNUM (IEEE80211_AC_BK )].tx_pkts_all + sc->debug.stats.txstats[PR_QNUM (IEEE80211_AC_VI )].tx_pkts_all + sc->debug.stats.txstats[PR_QNUM (IEEE80211_AC_VO )].tx_pkts_all); - data[i++] = (sc->debug.stats.txstats[PR_QNUM (IEEE80211_AC_BE )].tx_bytes_all + + data[i++] = ((u64 )sc->debug.stats.txstats[PR_QNUM (IEEE80211_AC_BE )].tx_bytes_all + sc->debug.stats.txstats[PR_QNUM (IEEE80211_AC_BK )].tx_bytes_all + sc->debug.stats.txstats[PR_QNUM (IEEE80211_AC_VI )].tx_bytes_all + sc->debug.stats.txstats[PR_QNUM (IEEE80211_AC_VO )].tx_bytes_all);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 408/691 wifi: ath9k_htc: Use __skb_set_length() for resetting urb before resubmit
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Toke Høiland-Jørgensen <[email protected]>
[ Upstream commit 94745807f3ebd379f23865e6dab196f220664179 ]
Syzbot points out that skb_trim() has a sanity check on the existing length of the skb, which can be uninitialised in some error paths. The intent here is clearly just to reset the length to zero before resubmitting, so switch to calling __skb_set_length(skb, 0) directly. In addition, __skb_set_length() already contains a call to skb_reset_tail_pointer(), so remove the redundant call.
The syzbot report came from ath9k_hif_usb_reg_in_cb(), but there's a similar usage of skb_trim() in ath9k_hif_usb_rx_cb(), change both while we're at it.
--- drivers/net/wireless/ath/ath9k/hif_usb.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
drivers/net/wireless/ath/ath9k/hif_usb.c +2 -4
@@ -718,8 +718,7 @@ static void ath9k_hif_usb_rx_cb(struct urb *urb) } resubmit: -skb_reset_tail_pointer (skb); -skb_trim (skb,0 ); +__skb_set_length (skb,0 );usb_anchor_urb (urb, &hif_dev->rx_submitted); ret =usb_submit_urb (urb,GFP_ATOMIC );
@@ -756,8 +755,7 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb)case -ESHUTDOWN : goto free_skb;default : -skb_reset_tail_pointer (skb); -skb_trim (skb,0 ); +__skb_set_length (skb,0 ); goto resubmit; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 409/691 ice: Adjust over allocation of memory in ice_sched_add_root_node() and ice_sched_add_node()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aleksandr Mishin <[email protected]>
[ Upstream commit 62fdaf9e8056e9a9e6fe63aa9c816ec2122d60c6 ]
In ice_sched_add_root_node() and ice_sched_add_node() there are calls to devm_kcalloc() in order to allocate memory for array of pointers to 'ice_sched_node' structure. But incorrect types are used as sizeof() arguments in these calls (structures instead of pointers) which leads to over allocation of memory.
Adjust over allocation of memory by correcting types in devm_kcalloc() sizeof() arguments.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
--- drivers/net/ethernet/intel/ice/ice_sched.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
drivers/net/ethernet/intel/ice/ice_sched.c +2 -4
@@ -27,9 +27,8 @@ ice_sched_add_root_node(struct ice_port_info *pi,if (!root)return ICE_ERR_NO_MEMORY ; -/* coverity[suspicious_sizeof] */ root->children =devm_kcalloc (ice_hw_to_dev (hw), hw->max_children[0 ], -sizeof (*root),GFP_KERNEL ); +sizeof (*root->children),GFP_KERNEL );if (!root->children) {devm_kfree (ice_hw_to_dev (hw), root);return ICE_ERR_NO_MEMORY ;
@@ -180,10 +179,9 @@ ice_sched_add_node(struct ice_port_info *pi, u8 layer,if (!node)return ICE_ERR_NO_MEMORY ;if (hw->max_children[layer]) { -/* coverity[suspicious_sizeof] */ node->children =devm_kcalloc (ice_hw_to_dev (hw), hw->max_children[layer], -sizeof (*node),GFP_KERNEL ); +sizeof (*node->children),GFP_KERNEL );if (!node->children) {devm_kfree (ice_hw_to_dev (hw), node);return ICE_ERR_NO_MEMORY ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 410/691 net/xen-netback: prevent UAF in xenvif_flush_hash()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jeongjun Park <[email protected]>
[ Upstream commit 0fa5e94a1811d68fbffa0725efe6d4ca62c03d12 ]
During the list_for_each_entry_rcu iteration call of xenvif_flush_hash, kfree_rcu does not exist inside the rcu read critical section, so if kfree_rcu is called when the rcu grace period ends during the iteration, UAF occurs when accessing head->next after the entry becomes free.
Therefore, to solve this, you need to change it to list_for_each_entry_safe.
--- drivers/net/xen-netback/hash.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/net/xen-netback/hash.c +2 -3
@@ -95,7 +95,7 @@ static u32 xenvif_new_hash(struct xenvif *vif, const u8 *data,static void xenvif_flush_hash (struct xenvif *vif) { -struct xenvif_hash_cache_entry *entry; +struct xenvif_hash_cache_entry *entry, *n;unsigned long flags;if (xenvif_hash_cache_size ==0 )
@@ -103,8 +103,7 @@ static void xenvif_flush_hash(struct xenvif *vif)spin_lock_irqsave (&vif->hash.cache.lock, flags); -list_for_each_entry_rcu (entry, &vif->hash.cache.list, link, -lockdep_is_held (&vif->hash.cache.lock)) { +list_for_each_entry_safe (entry, n, &vif->hash.cache.list, link) {list_del_rcu (&entry->link); vif->hash.cache.count--;kfree_rcu (entry, rcu);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 411/691 net: hisilicon: hip04: fix OF node leak in probe()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Kozlowski <[email protected]>
[ Upstream commit 17555297dbd5bccc93a01516117547e26a61caf1 ]
Driver is leaking OF node reference fromof_parse_phandle_with_fixed_args() in probe().
--- drivers/net/ethernet/hisilicon/hip04_eth.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/ethernet/hisilicon/hip04_eth.c +1 -0
@@ -947,6 +947,7 @@ static int hip04_mac_probe(struct platform_device *pdev) priv->tx_coalesce_timer.function = tx_done; priv->map =syscon_node_to_regmap (arg.np); +of_node_put (arg.np);if (IS_ERR (priv->map)) {dev_warn (d,"no syscon hisilicon,hip04-ppe\n" ); ret =PTR_ERR (priv->map);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 412/691 net: hisilicon: hns_dsaf_mac: fix OF node leak in hns_mac_get_info()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Kozlowski <[email protected]>
[ Upstream commit 5680cf8d34e1552df987e2f4bb1bff0b2a8c8b11 ]
Driver is leaking OF node reference from of_parse_phandle_with_fixed_args() in hns_mac_get_info().
--- drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c +1 -0
@@ -933,6 +933,7 @@ static int hns_mac_get_info(struct hns_mac_cb *mac_cb) mac_cb->cpld_ctrl =NULL ; }else { syscon =syscon_node_to_regmap (cpld_args.np); +of_node_put (cpld_args.np);if (IS_ERR_OR_NULL (syscon)) {dev_dbg (mac_cb->dev,"no cpld-syscon found!\n" ); mac_cb->cpld_ctrl =NULL ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 413/691 net: hisilicon: hns_mdio: fix OF node leak in probe()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Kozlowski <[email protected]>
[ Upstream commit e62beddc45f487b9969821fad3a0913d9bc18a2f ]
Driver is leaking OF node reference fromof_parse_phandle_with_fixed_args() in probe().
--- drivers/net/ethernet/hisilicon/hns_mdio.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/ethernet/hisilicon/hns_mdio.c +1 -0
@@ -497,6 +497,7 @@ static int hns_mdio_probe(struct platform_device *pdev)MDIO_SC_RESET_ST ; } } +of_node_put (reg_args.np); }else {dev_warn (&pdev->dev,"find syscon ret = %#x\n" , ret); mdio_dev->subctrl_vbase =NULL ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 414/691 ACPI: PAD: fix crash in exit_round_robin()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Seiji Nishikawa <[email protected]>
[ Upstream commit 0a2ed70a549e61c5181bad5db418d223b68ae932 ]
The kernel occasionally crashes in cpumask_clear_cpu(), which is called within exit_round_robin(), because when executing clear_bit(nr, addr) with nr set to 0xffffffff, the address calculation may cause misalignment within the memory, leading to access to an invalid memory address.
----------
BUG: unable to handle kernel paging request at ffffffffe0740618
...
CPU: 3 PID: 2919323 Comm: acpi_pad/14 Kdump: loaded Tainted: G OE X --------- - - 4.18.0-425.19.2.el8_7.x86_64 #1
...
RIP: 0010:power_saving_thread+0x313/0x411 [acpi_pad]
Code: 89 cd 48 89 d3 eb d1 48 c7 c7 55 70 72 c0 e8 64 86 b0 e4 c6 05 0d a1 02 00 01 e9 bc fd ff ff 45 89 e4 42 8b 04 a5 20 82 72 c0 <f0> 48 0f b3 05 f4 9c 01 00 42 c7 04 a5 20 82 72 c0 ff ff ff ff 31
RSP: 0018:ff72a5d51fa77ec8 EFLAGS: 00010202
RAX: 00000000ffffffff RBX: ff462981e5d8cb80 RCX: 0000000000000000
RDX: 0000000000000000 RSI: 0000000000000246 RDI: 0000000000000246
RBP: ff46297556959d80 R08: 0000000000000382 R09: ff46297c8d0f38d8
R10: 0000000000000000 R11: 0000000000000001 R12: 000000000000000e
R13: 0000000000000000 R14: ffffffffffffffff R15: 000000000000000e
FS: 0000000000000000(0000) GS:ff46297a800c0000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: ffffffffe0740618 CR3: 0000007e20410004 CR4: 0000000000771ee0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
PKRU: 55555554
Call Trace:
? acpi_pad_add+0x120/0x120 [acpi_pad]
kthread+0x10b/0x130
? set_kthread_struct+0x50/0x50
ret_from_fork+0x1f/0x40
...CR2: ffffffffe0740618
crash> dis -lr ffffffffc0726923
...
/usr/src/debug/kernel-4.18.0-425.19.2.el8_7/linux-4.18.0-425.19.2.el8_7.x86_64/./include/linux/cpumask.h: 1140xffffffffc0726918 <power_saving_thread+776>: mov %r12d,%r12d/usr/src/debug/kernel-4.18.0-425.19.2.el8_7/linux-4.18.0-425.19.2.el8_7.x86_64/./include/linux/cpumask.h: 3250xffffffffc072691b <power_saving_thread+779>: mov -0x3f8d7de0(,%r12,4),%eax/usr/src/debug/kernel-4.18.0-425.19.2.el8_7/linux-4.18.0-425.19.2.el8_7.x86_64/./arch/x86/include/asm/bitops.h: 800xffffffffc0726923 <power_saving_thread+787>: lock btr %rax,0x19cf4(%rip) # 0xffffffffc0740620 <pad_busy_cpus_bits>
crash> px tsk_in_cpu[14]
$66 = 0xffffffff
crash> px 0xffffffffc072692c+0x19cf4
$99 = 0xffffffffc0740620
crash> sym 0xffffffffc0740620 ffffffffc0740620 (b) pad_busy_cpus_bits [acpi_pad]
crash> px pad_busy_cpus_bits[0]
$42 = 0xfffc0
----------
To fix this, ensure that tsk_in_cpu[tsk_index] != -1 before calling cpumask_clear_cpu() in exit_round_robin(), just as it is done in round_robin_cpu().
--- drivers/acpi/acpi_pad.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/acpi/acpi_pad.c +4 -2
@@ -129,8 +129,10 @@ static void exit_round_robin(unsigned int tsk_index) {struct cpumask *pad_busy_cpus =to_cpumask (pad_busy_cpus_bits); -cpumask_clear_cpu (tsk_in_cpu[tsk_index], pad_busy_cpus); - tsk_in_cpu[tsk_index] =-1 ; +if (tsk_in_cpu[tsk_index] !=-1 ) { +cpumask_clear_cpu (tsk_in_cpu[tsk_index], pad_busy_cpus); + tsk_in_cpu[tsk_index] =-1 ; + } }static unsigned int idle_pct =5 ;/* percentage */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 415/691 ACPICA: Fix memory leak if acpi_ps_get_next_namepath() fails
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Armin Wolf <[email protected]>
[ Upstream commit 5accb265f7a1b23e52b0ec42313d1e12895552f4 ]
ACPICA commit 2802af722bbde7bf1a7ac68df68e179e2555d361
If acpi_ps_get_next_namepath() fails, the previously allocated union acpi_parse_object needs to be freed before returning the status code.
The issue was first being reported on the Linux ACPI mailing list:
--- drivers/acpi/acpica/psargs.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/acpi/acpica/psargs.c +8 -0
@@ -820,6 +820,10 @@ acpi_ps_get_next_arg(struct acpi_walk_state *walk_state,acpi_ps_get_next_namepath (walk_state, parser_state, arg,ACPI_NOT_METHOD_CALL ); +if (ACPI_FAILURE (status)) { +acpi_ps_free_op (arg); +return_ACPI_STATUS (status); + } }else {/* Single complex argument, nothing returned */
@@ -854,6 +858,10 @@ acpi_ps_get_next_arg(struct acpi_walk_state *walk_state,acpi_ps_get_next_namepath (walk_state, parser_state, arg,ACPI_POSSIBLE_METHOD_CALL ); +if (ACPI_FAILURE (status)) { +acpi_ps_free_op (arg); +return_ACPI_STATUS (status); + }if (arg->common.aml_opcode ==AML_INT_METHODCALL_OP ) {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 416/691 ACPICA: Fix memory leak if acpi_ps_get_next_field() fails
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Armin Wolf <[email protected]>
[ Upstream commit e6169a8ffee8a012badd8c703716e761ce851b15 ]
ACPICA commit 1280045754264841b119a5ede96cd005bc09b5a7
If acpi_ps_get_next_field() fails, the previously created field list needs to be properly disposed before returning the status code.
--- drivers/acpi/acpica/psargs.c | 39 ++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+)
drivers/acpi/acpica/psargs.c +39 -0
@@ -25,6 +25,8 @@ acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state);static union acpi_parse_object *acpi_ps_get_next_field (struct acpi_parse_state *parser_state); +static void acpi_ps_free_field_list (union acpi_parse_object *start); +/******************************************************************************* * * FUNCTION: acpi_ps_get_next_package_length
@@ -683,6 +685,39 @@ static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_statereturn_PTR (field); } +/******************************************************************************* +* +* FUNCTION: acpi_ps_free_field_list +* +* PARAMETERS: start - First Op in field list +* +* RETURN: None. +* +* DESCRIPTION: Free all Op objects inside a field list. +* +******************************************************************************/ + +static void acpi_ps_free_field_list (union acpi_parse_object *start) +{ +union acpi_parse_object *cur = start; +union acpi_parse_object *next; +union acpi_parse_object *arg; + +while (cur) { + next = cur->common.next; + +/* AML_INT_CONNECTION_OP can have a single argument */ + + arg =acpi_ps_get_arg (cur,0 ); +if (arg) { +acpi_ps_free_op (arg); + } + +acpi_ps_free_op (cur); + cur = next; + } +} +/******************************************************************************* * * FUNCTION: acpi_ps_get_next_arg
@@ -751,6 +786,10 @@ acpi_ps_get_next_arg(struct acpi_walk_state *walk_state,while (parser_state->aml < parser_state->pkg_end) { field =acpi_ps_get_next_field (parser_state);if (!field) { +if (arg) { +acpi_ps_free_field_list (arg); + } +return_ACPI_STATUS (AE_NO_MEMORY ); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 417/691 net: sched: consistently use rcu_replace_pointer() in taprio_change()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Antipov <[email protected]>
[ Upstream commit d5c4546062fd6f5dbce575c7ea52ad66d1968678 ]
According to Vinicius (and carefully looking through the whole
https://syzkaller.appspot.com/bug?extid=b65e0af58423fc8a73aa
once again), txtime branch of 'taprio_change()' is not going to race against 'advance_sched()'. But using 'rcu_replace_pointer()' in the former may be a good idea as well.
--- net/sched/sch_taprio.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
net/sched/sch_taprio.c +3 -1
@@ -1599,7 +1599,9 @@ static int taprio_change(struct Qdisc *sch, struct nlattr *opt, goto unlock; } -rcu_assign_pointer (q->admin_sched, new_admin); +/* Not going to race against advance_sched(), but still */ + admin =rcu_replace_pointer (q->admin_sched, new_admin, +lockdep_rtnl_is_held ());if (admin)call_rcu (&admin->rcu, taprio_free_sched_cb); }else {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 418/691 blk_iocost: fix more out of bound shifts
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Konstantin Ovsepian <[email protected]>
[ Upstream commit 9bce8005ec0dcb23a58300e8522fe4a31da606fa ]
Recently running UBSAN caught few out of bound shifts in the ioc_forgive_debts() function:
UBSAN: shift-out-of-bounds in block/blk-iocost.c:2142:38 shift exponent 80 is too large for 64-bit type 'u64' (aka 'unsigned long long') ... UBSAN: shift-out-of-bounds in block/blk-iocost.c:2144:30 shift exponent 80 is too large for 64-bit type 'u64' (aka 'unsigned long long') ... Call Trace: <IRQ> dump_stack_lvl+0xca/0x130 __ubsan_handle_shift_out_of_bounds+0x22c/0x280 ? __lock_acquire+0x6441/0x7c10 ioc_timer_fn+0x6cec/0x7750 ? blk_iocost_init+0x720/0x720 ? call_timer_fn+0x5d/0x470 call_timer_fn+0xfa/0x470 ? blk_iocost_init+0x720/0x720 __run_timer_base+0x519/0x700
...
Actual impact of this issue was not identified but I propose to fix the undefined behaviour.
The proposed fix to prevent those out of bound shifts consist of precalculating exponent before using it the shift operations by taking min value from the actual exponent and maximum possible number of bits.
--- block/blk-iocost.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
block/blk-iocost.c +5 -3
@@ -2068,7 +2068,7 @@ static void ioc_forgive_debts(struct ioc *ioc, u64 usage_us_sum, int nr_debtors, struct ioc_now *now) {struct ioc_gq *iocg; -u64 dur, usage_pct, nr_cycles; +u64 dur, usage_pct, nr_cycles, nr_cycles_shift;/* if no debtor, reset the cycle */ if (!nr_debtors) {
@@ -2130,10 +2130,12 @@ static void ioc_forgive_debts(struct ioc *ioc, u64 usage_us_sum, int nr_debtors, old_debt = iocg->abs_vdebt; old_delay = iocg->delay; + nr_cycles_shift =min_t (u64, nr_cycles,BITS_PER_LONG -1 );if (iocg->abs_vdebt) - iocg->abs_vdebt = iocg->abs_vdebt >> nr_cycles ?:1 ; + iocg->abs_vdebt = iocg->abs_vdebt >> nr_cycles_shift ?:1 ; +if (iocg->delay) - iocg->delay = iocg->delay >> nr_cycles ?:1 ; + iocg->delay = iocg->delay >> nr_cycles_shift ?:1 ;iocg_kick_waitq (iocg, true, now);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 419/691 nvme-pci: qdepth 1 quirk
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Keith Busch <[email protected]>
[ Upstream commit 83bdfcbdbe5d901c5fa432decf12e1725a840a56 ]
Another device has been reported to be unreliable if we have more than one outstanding command. In this new case, data corruption may occur. Since we have two devices now needing this quirky behavior, make a generic quirk flag.
The same Apple quirk is clearly not "temporary", so update the comment while moving it.
--- drivers/nvme/host/nvme.h | 5 +++++ drivers/nvme/host/pci.c | 18 +++++++++--------- 2 files changed, 14 insertions(+), 9 deletions(-)
drivers/nvme/host/nvme.h +5 -0
@@ -86,6 +86,11 @@ enum nvme_quirks {*/ NVME_QUIRK_NO_DEEPEST_PS = (1 <<5 ), +/* +* Problems seen with concurrent commands +*/ + NVME_QUIRK_QDEPTH_ONE = (1 << 6), +/* * Set MEDIUM priority on SQ creation */
drivers/nvme/host/pci.c +9 -9
@@ -2518,15 +2518,8 @@ static int nvme_pci_enable(struct nvme_dev *dev)else dev->io_sqes =NVME_NVM_IOSQES ; -/* -* Temporary fix for the Apple controller found in the MacBook8,1 and -* some MacBook7,1 to avoid controller resets and data loss. -*/ -if (pdev->vendor ==PCI_VENDOR_ID_APPLE && pdev->device ==0x2001 ) { +if (dev->ctrl.quirks &NVME_QUIRK_QDEPTH_ONE ) { dev->q_depth =2 ; -dev_warn (dev->ctrl.device,"detected Apple NVMe controller, " -"set queue depth=%u to work around controller resets\n" , - dev->q_depth); }else if (pdev->vendor ==PCI_VENDOR_ID_SAMSUNG && (pdev->device ==0xa821 || pdev->device ==0xa822 ) &&NVME_CAP_MQES (dev->ctrl.cap) ==0 ) {
@@ -3366,6 +3359,8 @@ static const struct pci_device_id nvme_id_table[] = { NVME_QUIRK_BOGUS_NID, }, { PCI_VDEVICE(REDHAT, 0x0010), /* Qemu emulated controller */ .driver_data = NVME_QUIRK_BOGUS_NID, }, + { PCI_DEVICE(0x1217, 0x8760), /* O2 Micro 64GB Steam Deck */ + .driver_data = NVME_QUIRK_QDEPTH_ONE }, { PCI_DEVICE(0x126f, 0x2262), /* Silicon Motion generic */ .driver_data = NVME_QUIRK_NO_DEEPEST_PS | NVME_QUIRK_BOGUS_NID, },
@@ -3470,7 +3465,12 @@ static const struct pci_device_id nvme_id_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_AMAZON, 0xcd02), .driver_data = NVME_QUIRK_DMA_ADDRESS_BITS_48, }, { PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x2001), - .driver_data = NVME_QUIRK_SINGLE_VECTOR }, +/* +* Fix for the Apple controller found in the MacBook8,1 and +* some MacBook7,1 to avoid controller resets and data loss. +*/ + .driver_data = NVME_QUIRK_SINGLE_VECTOR | + NVME_QUIRK_QDEPTH_ONE }, { PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x2003) }, { PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x2005), .driver_data = NVME_QUIRK_SINGLE_VECTOR |
Signature · 1 line
2.43.0