6.7.6-rc1 review
Subsystems (4)
Greg Kroah-Hartman
maintainerPATCH 125/309 mptcp: check addrs list in userspace_pm_get_local_id
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Geliang Tang <[email protected]>
commit f012d796a6de662692159c539689e47e662853a8 upstream.
Before adding a new entry in mptcp_userspace_pm_get_local_id(), it's better to check whether this address is already in userspace pm local address list. If it's in the list, no need to add a new entry, just return it's address ID and use this address.
--- net/mptcp/pm_userspace.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
net/mptcp/pm_userspace.c +12 -1
@@ -130,10 +130,21 @@ int mptcp_userspace_pm_get_flags_and_ifiint mptcp_userspace_pm_get_local_id (struct mptcp_sock *msk,struct mptcp_addr_info *skc) { -struct mptcp_pm_addr_entry new_entry; +struct mptcp_pm_addr_entry *entry =NULL , *e, new_entry;__be16 msk_sport = ((struct inet_sock *)inet_sk ((struct sock *)msk))->inet_sport; +spin_lock_bh (&msk->pm.lock); +list_for_each_entry (e, &msk->pm.userspace_pm_local_addr_list, list) { +if (mptcp_addresses_equal (&e->addr, skc, false)) { + entry = e; +break ; + } + } +spin_unlock_bh (&msk->pm.lock); +if (entry) +return entry->addr.id; +memset (&new_entry,0 ,sizeof (struct mptcp_pm_addr_entry )); new_entry.addr = *skc; new_entry.addr.id =0 ;
Greg Kroah-Hartman
maintainerPATCH 126/309 mptcp: really cope with fastopen race
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paolo Abeni <[email protected]>
commit 337cebbd850f94147cee05252778f8f78b8c337f upstream.
Fastopen and PM-trigger subflow shutdown can race, as reported by syzkaller.
In my first attempt to close such race, I missed the fact that the subflow status can change again before the subflow_state_change callback is invoked.
Address the issue additionally copying with all the states directly reachable from TCP_FIN_WAIT1.
--- net/mptcp/protocol.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
net/mptcp/protocol.h +2 -1
@@ -1118,7 +1118,8 @@ static inline bool subflow_simultaneous_ {struct mptcp_subflow_context *subflow =mptcp_subflow_ctx (sk); -return (1 << sk->sk_state) & (TCPF_ESTABLISHED |TCPF_FIN_WAIT1 ) && +return (1 << sk->sk_state) & + (TCPF_ESTABLISHED |TCPF_FIN_WAIT1 |TCPF_FIN_WAIT2 |TCPF_CLOSING ) &&is_active_ssk (subflow) && !subflow->conn_finished; }
Greg Kroah-Hartman
maintainerPATCH 127/309 Revert "powerpc/pseries/iommu: Fix iommu initialisation during DLPAR add"
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Ellerman <[email protected]>
commit 1fba2bf8e9d5a27b7394856181b6200de7260b79 upstream.
This reverts commit ed8b94f6e0acd652ce69bd69d678a0c769172df8.
Gaurav reported that there are still problems with the patch and it should be reverted pending a fuller fix.
--- arch/powerpc/include/asm/ppc-pci.h | 3 --- arch/powerpc/kernel/iommu.c | 21 +++++---------------- arch/powerpc/platforms/pseries/pci_dlpar.c | 4 ---- 3 files changed, 5 insertions(+), 23 deletions(-)
arch/powerpc/include/asm/ppc-pci.h +0 -3
@@ -29,9 +29,6 @@ void *pci_traverse_device_nodes(struct dvoid *(*fn)(struct device_node *,void *), void *data);extern void pci_devs_phb_init_dynamic (struct pci_controller *phb); -extern void ppc_iommu_register_device (struct pci_controller *phb); -extern void ppc_iommu_unregister_device (struct pci_controller *phb); -/* From rtas_pci.h */ extern void init_pci_config_tokens (void );
arch/powerpc/kernel/iommu.c +5 -16
@@ -1390,21 +1390,6 @@ static const struct attribute_group *spa NULL, }; -void ppc_iommu_register_device (struct pci_controller *phb) -{ -iommu_device_sysfs_add (&phb->iommu, phb->parent, - spapr_tce_iommu_groups,"iommu-phb%04x" , - phb->global_number); -iommu_device_register (&phb->iommu, &spapr_tce_iommu_ops, - phb->parent); -} - -void ppc_iommu_unregister_device (struct pci_controller *phb) -{ -iommu_device_unregister (&phb->iommu); -iommu_device_sysfs_remove (&phb->iommu); -} -/* * This registers IOMMU devices of PHBs. This needs to happen * after core_initcall(iommu_init) + postcore_initcall(pci_driver_init) and
@@ -1415,7 +1400,11 @@ static int __init spapr_tce_setup_phb_iostruct pci_controller *hose;list_for_each_entry (hose, &hose_list, list_node) { -ppc_iommu_register_device (hose); +iommu_device_sysfs_add (&hose->iommu, hose->parent, + spapr_tce_iommu_groups,"iommu-phb%04x" , + hose->global_number); +iommu_device_register (&hose->iommu, &spapr_tce_iommu_ops, + hose->parent); }return 0 ; }
arch/powerpc/platforms/pseries/pci_dlpar.c +0 -4
@@ -35,8 +35,6 @@ struct pci_controller *init_phb_dynamic(pseries_msi_allocate_domains (phb); -ppc_iommu_register_device (phb); -/* Create EEH devices for the PHB */ eeh_phb_pe_create (phb);
@@ -78,8 +76,6 @@ int remove_phb_dynamic(struct pci_contro } } -ppc_iommu_unregister_device (phb); -pseries_msi_free_domains (phb);/* Keep a reference so phb isn't freed yet */
Greg Kroah-Hartman
maintainerPATCH 128/309 media: Revert "media: rkisp1: Drop IRQF_SHARED"
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tomi Valkeinen <[email protected]>
commit a107d643b2a3382e0a2d2c4ef08bf8c6bff4561d upstream.
This reverts commit 85d2a31fe4d9be1555f621ead7a520d8791e0f74.
The rkisp1 does share interrupt lines on some platforms, after all. Thus we need to revert this, and implement a fix for the rkisp1 shared irq handling in a follow-up patch.
--- drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c +1 -1
@@ -559,7 +559,7 @@ static int rkisp1_probe(struct platform_ rkisp1->irqs[il] = irq; } - ret =devm_request_irq (dev, irq, info->isrs[i].isr,0 , + ret =devm_request_irq (dev, irq, info->isrs[i].isr,IRQF_SHARED ,dev_driver_string (dev), dev);if (ret) {dev_err (dev,"request irq failed: %d\n" , ret);
Greg Kroah-Hartman
maintainerPATCH 129/309 scsi: Revert "scsi: fcoe: Fix potential deadlock on &fip->ctlr_lock"
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lee Duncan <[email protected]>
commit 977fe773dcc7098d8eaf4ee6382cb51e13e784cb upstream.
This reverts commit 1a1975551943f681772720f639ff42fbaa746212.
This commit causes interrupts to be lost for FCoE devices, since it changed sping locks from "bh" to "irqsave".
Instead, a work queue should be used, and will be addressed in a separate commit.
--- drivers/scsi/fcoe/fcoe_ctlr.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-)
drivers/scsi/fcoe/fcoe_ctlr.c +8 -12
@@ -319,17 +319,16 @@ static void fcoe_ctlr_announce(struct fc {struct fcoe_fcf *sel;struct fcoe_fcf *fcf; -unsigned long flags;mutex_lock (&fip->ctlr_mutex); -spin_lock_irqsave (&fip->ctlr_lock, flags); +spin_lock_bh (&fip->ctlr_lock);kfree_skb (fip->flogi_req); fip->flogi_req =NULL ;list_for_each_entry (fcf, &fip->fcfs, list) fcf->flogi_sent =0 ; -spin_unlock_irqrestore (&fip->ctlr_lock, flags); +spin_unlock_bh (&fip->ctlr_lock); sel = fip->sel_fcf;if (sel &ðer_addr_equal (sel->fcf_mac, fip->dest_addr))
@@ -700,7 +699,6 @@ int fcoe_ctlr_els_send(struct fcoe_ctlr {struct fc_frame *fp;struct fc_frame_header *fh; -unsigned long flags;u16 old_xid;u8 op;u8 mac[ETH_ALEN ];
@@ -734,11 +732,11 @@ int fcoe_ctlr_els_send(struct fcoe_ctlr op =FIP_DT_FLOGI ;if (fip->mode ==FIP_MODE_VN2VN )break ; -spin_lock_irqsave (&fip->ctlr_lock, flags); +spin_lock_bh (&fip->ctlr_lock);kfree_skb (fip->flogi_req); fip->flogi_req = skb; fip->flogi_req_send =1 ; -spin_unlock_irqrestore (&fip->ctlr_lock, flags); +spin_unlock_bh (&fip->ctlr_lock);schedule_work (&fip->timer_work);return -EINPROGRESS ;case ELS_FDISC :
@@ -1707,11 +1705,10 @@ static int fcoe_ctlr_flogi_send_locked(sstatic int fcoe_ctlr_flogi_retry (struct fcoe_ctlr *fip) {struct fcoe_fcf *fcf; -unsigned long flags;int error;mutex_lock (&fip->ctlr_mutex); -spin_lock_irqsave (&fip->ctlr_lock, flags); +spin_lock_bh (&fip->ctlr_lock);LIBFCOE_FIP_DBG (fip,"re-sending FLOGI - reselect\n" ); fcf =fcoe_ctlr_select (fip);if (!fcf || fcf->flogi_sent) {
@@ -1722,7 +1719,7 @@ static int fcoe_ctlr_flogi_retry(structfcoe_ctlr_solicit (fip,NULL ); error =fcoe_ctlr_flogi_send_locked (fip); } -spin_unlock_irqrestore (&fip->ctlr_lock, flags); +spin_unlock_bh (&fip->ctlr_lock);mutex_unlock (&fip->ctlr_mutex);return error; }
@@ -1739,9 +1736,8 @@ static int fcoe_ctlr_flogi_retry(structstatic void fcoe_ctlr_flogi_send (struct fcoe_ctlr *fip) {struct fcoe_fcf *fcf; -unsigned long flags; -spin_lock_irqsave (&fip->ctlr_lock, flags); +spin_lock_bh (&fip->ctlr_lock); fcf = fip->sel_fcf;if (!fcf || !fip->flogi_req_send) goto unlock;
@@ -1768,7 +1764,7 @@ static void fcoe_ctlr_flogi_send(struct }else /* XXX */ LIBFCOE_FIP_DBG (fip,"No FCF selected - defer send\n" ); unlock: -spin_unlock_irqrestore (&fip->ctlr_lock, flags); +spin_unlock_bh (&fip->ctlr_lock); }/**
Greg Kroah-Hartman
maintainerPATCH 130/309 Revert "drm/amd: flush any delayed gfxoff on suspend entry"
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mario Limonciello <[email protected]>
commit 916361685319098f696b798ef1560f69ed96e934 upstream.
commit ab4750332dbe ("drm/amdgpu/sdma5.2: add begin/end_use ring callbacks") caused GFXOFF control to be used more heavily and the codepath that was removed from commit 0dee72639533 ("drm/amd: flush any delayed gfxoff on suspend entry") now can be exercised at suspend again.
Users report that by using GNOME to suspend the lockscreen trigger will cause SDMA traffic and the system can deadlock.
This reverts commit 0dee726395333fea833eaaf838bc80962df886c8.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 1 - drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c | 9 ++++++++- 2 files changed, 8 insertions(+), 2 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +0 -1
@@ -4496,7 +4496,6 @@ int amdgpu_device_suspend(struct drm_devdrm_fb_helper_set_suspend_unlocked (adev_to_drm (adev)->fb_helper, true);cancel_delayed_work_sync (&adev->delayed_init_work); -flush_delayed_work (&adev->gfx.gfx_off_delay_work);amdgpu_ras_suspend (adev);
drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c +8 -1
@@ -723,8 +723,15 @@ void amdgpu_gfx_off_ctrl(struct amdgpu_dif (adev->gfx.gfx_off_req_count ==0 && !adev->gfx.gfx_off_state) { -schedule_delayed_work (&adev->gfx.gfx_off_delay_work, +/* If going to s2idle, no need to wait */ +if (adev->in_s0ix) { +if (!amdgpu_dpm_set_powergating_by_smu (adev, +AMD_IP_BLOCK_TYPE_GFX , true)) + adev->gfx.gfx_off_state = true; + }else { +schedule_delayed_work (&adev->gfx.gfx_off_delay_work, delay); + } } }else {if (adev->gfx.gfx_off_req_count ==0 ) {
Greg Kroah-Hartman
maintainerPATCH 131/309 Revert "drm/msm/gpu: Push gpu lock down past runpm"
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rob Clark <[email protected]>
commit 917e9b7c2350e3e53162fcf5035e5f2d68e2cbed upstream.
This reverts commit abe2023b4cea192ab266b351fd38dc9dbd846df0.
Changing the locking order means that scheduler/msm_job_run() can race with the recovery kthread worker, with the result that the GPU gets an extra runpm get when we are trying to power it off. Leaving the GPU in an unrecovered state.
I'll need to come up with a different scheme for appeasing lockdep.
Patchwork: https://patchwork.freedesktop.org/patch/573835/
--- drivers/gpu/drm/msm/msm_gpu.c | 11 +++++------ drivers/gpu/drm/msm/msm_ringbuffer.c | 7 +++++-- 2 files changed, 10 insertions(+), 8 deletions(-)
drivers/gpu/drm/msm/msm_gpu.c +5 -6
@@ -749,12 +749,14 @@ void msm_gpu_submit(struct msm_gpu *gpu,struct msm_ringbuffer *ring = submit->ring;unsigned long flags; -pm_runtime_get_sync (&gpu->pdev->dev); +WARN_ON (!mutex_is_locked (&gpu->lock)); -mutex_lock (&gpu->lock); +pm_runtime_get_sync (&gpu->pdev->dev);msm_gpu_hw_init (gpu); + submit->seqno = submit->hw_fence->seqno; +update_sw_cntrs (gpu);/*
@@ -779,11 +781,8 @@ void msm_gpu_submit(struct msm_gpu *gpu, gpu->funcs->submit (gpu, submit); gpu->cur_ctx_seqno = submit->queue->ctx->seqno; -hangcheck_timer_reset (gpu); - -mutex_unlock (&gpu->lock); -pm_runtime_put (&gpu->pdev->dev); +hangcheck_timer_reset (gpu); }/*
drivers/gpu/drm/msm/msm_ringbuffer.c +5 -2
@@ -21,8 +21,6 @@ static struct dma_fence *msm_job_run(strmsm_fence_init (submit->hw_fence, fctx); - submit->seqno = submit->hw_fence->seqno; -mutex_lock (&priv->lru.lock);for (i =0 ; i < submit->nr_bos; i++) {
@@ -34,8 +32,13 @@ static struct dma_fence *msm_job_run(strmutex_unlock (&priv->lru.lock); +/* TODO move submit path over to using a per-ring lock.. */ +mutex_lock (&gpu->lock); +msm_gpu_submit (gpu, submit); +mutex_unlock (&gpu->lock); +return dma_fence_get (submit->hw_fence); }
Greg Kroah-Hartman
maintainerPATCH 132/309 connector/cn_proc: revert "connector: Fix proc_event_num_listeners count not cleared"
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Keqi Wang <[email protected]>
commit 8929f95b2b587791a7dcd04cc91520194a76d3a6 upstream.
This reverts commit c46bfba1337d ("connector: Fix proc_event_num_listeners count not cleared").
It is not accurate to reset proc_event_num_listeners according to cn_netlink_send_mult() return value -ESRCH.
In the case of stress-ng netlink-proc, -ESRCH will always be returned, because netlink_broadcast_filtered will return -ESRCH, which may cause stress-ng netlink-proc performance degradation.
--- drivers/connector/cn_proc.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/connector/cn_proc.c +2 -3
@@ -108,9 +108,8 @@ static inline void send_msg(struct cn_ms filter_data[1 ] =0 ; } -if (cn_netlink_send_mult (msg, msg->len,0 ,CN_IDX_PROC ,GFP_NOWAIT , - cn_filter, (void *)filter_data) == -ESRCH ) -atomic_set (&proc_event_num_listeners,0 ); +cn_netlink_send_mult (msg, msg->len,0 ,CN_IDX_PROC ,GFP_NOWAIT , + cn_filter, (void *)filter_data);local_unlock (&local_event.lock); }
Greg Kroah-Hartman
maintainerPATCH 133/309 spi: omap2-mcspi: Revert FIFO support without DMA
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vaishnav Achath <[email protected]>
commit e56c671c2272d939d48a66be7e73b92b74c560c2 upstream.
MCSPI controller have few limitations regarding the transaction size when the FIFO buffer is enabled and the WCNT feature is used to find the end of word, in this case if WCNT is not a multiple of the FIFO Almost Empty Level (AEL), then the FIFO empty event is not generated correctly. In addition to this limitation, few other unknown sequence of events that causes the FIFO empty status to not reflect the exact status were found when FIFO is being used without DMA enabled during extended testing in AM65x platform. Till the exact root cause is found and fixed, revert the FIFO support without DMA.
See J721E Technical Reference Manual (SPRUI1C), section 12.1.5 for further details: http://www.ti.com/lit/pdf/spruil1
This reverts commit 75223bbea840e ("spi: omap2-mcspi: Add FIFO support without DMA")
--- drivers/spi/spi-omap2-mcspi.c | 137 ++---------------------------------------- 1 file changed, 8 insertions(+), 129 deletions(-)
drivers/spi/spi-omap2-mcspi.c +8 -129
@@ -53,8 +53,6 @@/* per-register bitmasks: */ #define OMAP2_MCSPI_IRQSTATUS_EOW BIT(17) -#define OMAP2_MCSPI_IRQSTATUS_TX0_EMPTY BIT(0) -#define OMAP2_MCSPI_IRQSTATUS_RX0_FULL BIT(2)#define OMAP2_MCSPI_MODULCTRL_SINGLE BIT(0)#define OMAP2_MCSPI_MODULCTRL_MS BIT(2)
@@ -293,7 +291,7 @@ static void omap2_mcspi_set_mode(struct }static void omap2_mcspi_set_fifo (const struct spi_device *spi, -struct spi_transfer *t,int enable,int dma_enabled) +struct spi_transfer *t,int enable) {struct spi_controller *ctlr = spi->controller;struct omap2_mcspi_cs *cs = spi->controller_state;
@@ -314,28 +312,20 @@ static void omap2_mcspi_set_fifo(const s max_fifo_depth =OMAP2_MCSPI_MAX_FIFODEPTH /2 ; else max_fifo_depth =OMAP2_MCSPI_MAX_FIFODEPTH ; -if (dma_enabled) - wcnt = t->len / bytes_per_word; -else - wcnt =0 ; + + wcnt = t->len / bytes_per_word;if (wcnt >OMAP2_MCSPI_MAX_FIFOWCNT ) goto disable_fifo; xferlevel = wcnt <<16 ;if (t->rx_buf !=NULL ) { chconf |=OMAP2_MCSPI_CHCONF_FFER ; -if (dma_enabled) - xferlevel |= (bytes_per_word -1 ) <<8 ; -else - xferlevel |= (max_fifo_depth -1 ) <<8 ; + xferlevel |= (bytes_per_word -1 ) <<8 ; }if (t->tx_buf !=NULL ) { chconf |=OMAP2_MCSPI_CHCONF_FFET ; -if (dma_enabled) - xferlevel |= bytes_per_word -1 ; -else - xferlevel |= (max_fifo_depth -1 ); + xferlevel |= bytes_per_word -1 ; }mcspi_write_reg (ctlr,OMAP2_MCSPI_XFERLEVEL , xferlevel);
@@ -892,113 +882,6 @@ out:return count - c; } -static unsigned -omap2_mcspi_txrx_piofifo (struct spi_device *spi,struct spi_transfer *xfer) -{ -struct omap2_mcspi_cs *cs = spi->controller_state; -struct omap2_mcspi *mcspi; -unsigned int count, c; -unsigned int iter, cwc; -int last_request; -void __iomem *base = cs->base; -void __iomem *tx_reg; -void __iomem *rx_reg; -void __iomem *chstat_reg; -void __iomem *irqstat_reg; -int word_len, bytes_per_word; -u8 *rx; -const u8 *tx; - - mcspi =spi_controller_get_devdata (spi->controller); - count = xfer->len; - c = count; - word_len = cs->word_len; - bytes_per_word =mcspi_bytes_per_word (word_len); - -/* -* We store the pre-calculated register addresses on stack to speed -* up the transfer loop. -*/ - tx_reg = base +OMAP2_MCSPI_TX0 ; - rx_reg = base +OMAP2_MCSPI_RX0 ; - chstat_reg = base +OMAP2_MCSPI_CHSTAT0 ; - irqstat_reg = base +OMAP2_MCSPI_IRQSTATUS ; - -if (c < (word_len >>3 )) -return 0 ; - - rx = xfer->rx_buf; - tx = xfer->tx_buf; - -do { -/* calculate number of words in current iteration */ - cwc =min ((unsigned int )mcspi->fifo_depth / bytes_per_word, - c / bytes_per_word); - last_request = cwc != (mcspi->fifo_depth / bytes_per_word); -if (tx) { -if (mcspi_wait_for_reg_bit (irqstat_reg, -OMAP2_MCSPI_IRQSTATUS_TX0_EMPTY ) <0 ) { -dev_err (&spi->dev,"TX Empty timed out\n" ); - goto out; - } -writel_relaxed (OMAP2_MCSPI_IRQSTATUS_TX0_EMPTY , irqstat_reg); - -for (iter =0 ; iter < cwc; iter++, tx += bytes_per_word) { -if (bytes_per_word ==1 ) -writel_relaxed (*tx, tx_reg); -else if (bytes_per_word ==2 ) -writel_relaxed (*((u16 *)tx), tx_reg); -else if (bytes_per_word ==4 ) -writel_relaxed (*((u32 *)tx), tx_reg); - } - } - -if (rx) { -if (!last_request && -mcspi_wait_for_reg_bit (irqstat_reg, -OMAP2_MCSPI_IRQSTATUS_RX0_FULL ) <0 ) { -dev_err (&spi->dev,"RX_FULL timed out\n" ); - goto out; - } -writel_relaxed (OMAP2_MCSPI_IRQSTATUS_RX0_FULL , irqstat_reg); - -for (iter =0 ; iter < cwc; iter++, rx += bytes_per_word) { -if (last_request && -mcspi_wait_for_reg_bit (chstat_reg, -OMAP2_MCSPI_CHSTAT_RXS ) <0 ) { -dev_err (&spi->dev,"RXS timed out\n" ); - goto out; - } -if (bytes_per_word ==1 ) - *rx =readl_relaxed (rx_reg); -else if (bytes_per_word ==2 ) - *((u16 *)rx) =readl_relaxed (rx_reg); -else if (bytes_per_word ==4 ) - *((u32 *)rx) =readl_relaxed (rx_reg); - } - } - -if (last_request) { -if (mcspi_wait_for_reg_bit (chstat_reg, -OMAP2_MCSPI_CHSTAT_EOT ) <0 ) { -dev_err (&spi->dev,"EOT timed out\n" ); - goto out; - } -if (mcspi_wait_for_reg_bit (chstat_reg, -OMAP2_MCSPI_CHSTAT_TXFFE ) <0 ) { -dev_err (&spi->dev,"TXFFE timed out\n" ); - goto out; - } -omap2_mcspi_set_enable (spi,0 ); - } - c -= cwc * bytes_per_word; - }while (c >= bytes_per_word); - -out: -omap2_mcspi_set_enable (spi,1 ); -return count - c; -} -static u32 omap2_mcspi_calc_divisor (u32 speed_hz,u32 ref_clk_hz) {u32 div;
@@ -1323,9 +1206,7 @@ static int omap2_mcspi_transfer_one(struif ((mcspi_dma->dma_rx && mcspi_dma->dma_tx) && ctlr->cur_msg_mapped && ctlr->can_dma (ctlr, spi, t)) -omap2_mcspi_set_fifo (spi, t,1 ,1 ); -else if (t->len >OMAP2_MCSPI_MAX_FIFODEPTH ) -omap2_mcspi_set_fifo (spi, t,1 ,0 ); +omap2_mcspi_set_fifo (spi, t,1 );omap2_mcspi_set_enable (spi,1 );
@@ -1338,8 +1219,6 @@ static int omap2_mcspi_transfer_one(stru ctlr->cur_msg_mapped && ctlr->can_dma(ctlr, spi, t)) count =omap2_mcspi_txrx_dma (spi, t); - else if (mcspi->fifo_depth > 0) - count =omap2_mcspi_txrx_piofifo (spi, t); else count =omap2_mcspi_txrx_pio (spi, t);
@@ -1352,7 +1231,7 @@ static int omap2_mcspi_transfer_one(struomap2_mcspi_set_enable (spi,0 );if (mcspi->fifo_depth >0 ) -omap2_mcspi_set_fifo (spi, t,0 ,0 ); +omap2_mcspi_set_fifo (spi, t,0 ); out:/* Restore defaults if they were overriden */
@@ -1375,7 +1254,7 @@ out:omap2_mcspi_set_cs (spi, !(spi->mode &SPI_CS_HIGH ));if (mcspi->fifo_depth >0 && t) -omap2_mcspi_set_fifo (spi, t,0 ,0 ); +omap2_mcspi_set_fifo (spi, t,0 );return status; }
Greg Kroah-Hartman
maintainerPATCH 134/309 drm/virtio: Set segment size for virtio_gpu device
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sebastian Ott <[email protected]>
commit 9c64e749cebd9c2d3d55261530a98bcccb83b950 upstream.
Set the segment size of the virtio_gpu device to the value used by the drm helpers when allocating sg lists to fix the following complaint from DMA_API debug code:
DMA-API: virtio-pci 0000:07:00.0: mapping sg segment longer than device claims to support [len=262144] [max=65536]
--- drivers/gpu/drm/virtio/virtgpu_drv.c | 1 + 1 file changed, 1 insertion(+)
drivers/gpu/drm/virtio/virtgpu_drv.c +1 -0
@@ -94,6 +94,7 @@ static int virtio_gpu_probe(struct virti goto err_free; } +dma_set_max_seg_size (dev->dev,dma_max_mapping_size (dev->dev) ?:UINT_MAX ); ret =virtio_gpu_init (vdev, dev);if (ret) goto err_free;
Greg Kroah-Hartman
maintainerPATCH 135/309 drm/amdgpu: Reset IH OVERFLOW_CLEAR bit
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Friedrich Vock <[email protected]>
commit 7330256268664ea0a7dd5b07a3fed363093477dd upstream.
Allows us to detect subsequent IH ring buffer overflows as well.
--- drivers/gpu/drm/amd/amdgpu/cik_ih.c | 6 ++++++ drivers/gpu/drm/amd/amdgpu/cz_ih.c | 5 +++++ drivers/gpu/drm/amd/amdgpu/iceland_ih.c | 5 +++++ drivers/gpu/drm/amd/amdgpu/ih_v6_0.c | 6 ++++++ drivers/gpu/drm/amd/amdgpu/ih_v6_1.c | 7 +++++++ drivers/gpu/drm/amd/amdgpu/navi10_ih.c | 6 ++++++ drivers/gpu/drm/amd/amdgpu/si_ih.c | 6 ++++++ drivers/gpu/drm/amd/amdgpu/tonga_ih.c | 6 ++++++ drivers/gpu/drm/amd/amdgpu/vega10_ih.c | 6 ++++++ drivers/gpu/drm/amd/amdgpu/vega20_ih.c | 6 ++++++ 10 files changed, 59 insertions(+)
drivers/gpu/drm/amd/amdgpu/cik_ih.c +6 -0
@@ -204,6 +204,12 @@ static u32 cik_ih_get_wptr(struct amdgpu tmp =RREG32 (mmIH_RB_CNTL); tmp |=IH_RB_CNTL__WPTR_OVERFLOW_CLEAR_MASK ;WREG32 (mmIH_RB_CNTL, tmp); + +/* Unset the CLEAR_OVERFLOW bit immediately so new overflows +* can be detected. +*/ + tmp &= ~IH_RB_CNTL__WPTR_OVERFLOW_CLEAR_MASK ; +WREG32 (mmIH_RB_CNTL, tmp); }return (wptr & ih->ptr_mask); }
drivers/gpu/drm/amd/amdgpu/cz_ih.c +5 -0
@@ -216,6 +216,11 @@ static u32 cz_ih_get_wptr(struct amdgpu_ tmp =REG_SET_FIELD (tmp,IH_RB_CNTL ,WPTR_OVERFLOW_CLEAR ,1 );WREG32 (mmIH_RB_CNTL, tmp); +/* Unset the CLEAR_OVERFLOW bit immediately so new overflows +* can be detected. +*/ + tmp =REG_SET_FIELD (tmp,IH_RB_CNTL ,WPTR_OVERFLOW_CLEAR ,0 ); +WREG32 (mmIH_RB_CNTL, tmp); out:return (wptr & ih->ptr_mask);
drivers/gpu/drm/amd/amdgpu/iceland_ih.c +5 -0
@@ -215,6 +215,11 @@ static u32 iceland_ih_get_wptr(struct am tmp =REG_SET_FIELD (tmp,IH_RB_CNTL ,WPTR_OVERFLOW_CLEAR ,1 );WREG32 (mmIH_RB_CNTL, tmp); +/* Unset the CLEAR_OVERFLOW bit immediately so new overflows +* can be detected. +*/ + tmp =REG_SET_FIELD (tmp,IH_RB_CNTL ,WPTR_OVERFLOW_CLEAR ,0 ); +WREG32 (mmIH_RB_CNTL, tmp); out:return (wptr & ih->ptr_mask);
drivers/gpu/drm/amd/amdgpu/ih_v6_0.c +6 -0
@@ -418,6 +418,12 @@ static u32 ih_v6_0_get_wptr(struct amdgp tmp =RREG32_NO_KIQ (ih_regs->ih_rb_cntl); tmp =REG_SET_FIELD (tmp,IH_RB_CNTL ,WPTR_OVERFLOW_CLEAR ,1 );WREG32_NO_KIQ (ih_regs->ih_rb_cntl, tmp); + +/* Unset the CLEAR_OVERFLOW bit immediately so new overflows +* can be detected. +*/ + tmp =REG_SET_FIELD (tmp,IH_RB_CNTL ,WPTR_OVERFLOW_CLEAR ,0 ); +WREG32_NO_KIQ (ih_regs->ih_rb_cntl, tmp); out:return (wptr & ih->ptr_mask); }
drivers/gpu/drm/amd/amdgpu/ih_v6_1.c +7 -0
@@ -418,6 +418,13 @@ static u32 ih_v6_1_get_wptr(struct amdgp tmp =RREG32_NO_KIQ (ih_regs->ih_rb_cntl); tmp =REG_SET_FIELD (tmp,IH_RB_CNTL ,WPTR_OVERFLOW_CLEAR ,1 );WREG32_NO_KIQ (ih_regs->ih_rb_cntl, tmp); + +/* Unset the CLEAR_OVERFLOW bit immediately so new overflows +* can be detected. +*/ + tmp =REG_SET_FIELD (tmp,IH_RB_CNTL ,WPTR_OVERFLOW_CLEAR ,0 ); +WREG32_NO_KIQ (ih_regs->ih_rb_cntl, tmp); + out:return (wptr & ih->ptr_mask); }
drivers/gpu/drm/amd/amdgpu/navi10_ih.c +6 -0
@@ -442,6 +442,12 @@ static u32 navi10_ih_get_wptr(struct amd tmp =RREG32_NO_KIQ (ih_regs->ih_rb_cntl); tmp =REG_SET_FIELD (tmp,IH_RB_CNTL ,WPTR_OVERFLOW_CLEAR ,1 );WREG32_NO_KIQ (ih_regs->ih_rb_cntl, tmp); + +/* Unset the CLEAR_OVERFLOW bit immediately so new overflows +* can be detected. +*/ + tmp =REG_SET_FIELD (tmp,IH_RB_CNTL ,WPTR_OVERFLOW_CLEAR ,0 ); +WREG32_NO_KIQ (ih_regs->ih_rb_cntl, tmp); out:return (wptr & ih->ptr_mask); }
drivers/gpu/drm/amd/amdgpu/si_ih.c +6 -0
@@ -119,6 +119,12 @@ static u32 si_ih_get_wptr(struct amdgpu_ tmp =RREG32 (IH_RB_CNTL ); tmp |=IH_RB_CNTL__WPTR_OVERFLOW_CLEAR_MASK ;WREG32 (IH_RB_CNTL , tmp); + +/* Unset the CLEAR_OVERFLOW bit immediately so new overflows +* can be detected. +*/ + tmp &= ~IH_RB_CNTL__WPTR_OVERFLOW_CLEAR_MASK ; +WREG32 (IH_RB_CNTL , tmp); }return (wptr & ih->ptr_mask); }
drivers/gpu/drm/amd/amdgpu/tonga_ih.c +6 -0
@@ -219,6 +219,12 @@ static u32 tonga_ih_get_wptr(struct amdg tmp =REG_SET_FIELD (tmp,IH_RB_CNTL ,WPTR_OVERFLOW_CLEAR ,1 );WREG32 (mmIH_RB_CNTL, tmp); +/* Unset the CLEAR_OVERFLOW bit immediately so new overflows +* can be detected. +*/ + tmp =REG_SET_FIELD (tmp,IH_RB_CNTL ,WPTR_OVERFLOW_CLEAR ,0 ); +WREG32 (mmIH_RB_CNTL, tmp); + out:return (wptr & ih->ptr_mask); }
drivers/gpu/drm/amd/amdgpu/vega10_ih.c +6 -0
@@ -373,6 +373,12 @@ static u32 vega10_ih_get_wptr(struct amd tmp =REG_SET_FIELD (tmp,IH_RB_CNTL ,WPTR_OVERFLOW_CLEAR ,1 );WREG32_NO_KIQ (ih_regs->ih_rb_cntl, tmp); +/* Unset the CLEAR_OVERFLOW bit immediately so new overflows +* can be detected. +*/ + tmp =REG_SET_FIELD (tmp,IH_RB_CNTL ,WPTR_OVERFLOW_CLEAR ,0 ); +WREG32_NO_KIQ (ih_regs->ih_rb_cntl, tmp); + out:return (wptr & ih->ptr_mask); }
drivers/gpu/drm/amd/amdgpu/vega20_ih.c +6 -0
@@ -421,6 +421,12 @@ static u32 vega20_ih_get_wptr(struct amd tmp =REG_SET_FIELD (tmp,IH_RB_CNTL ,WPTR_OVERFLOW_CLEAR ,1 );WREG32_NO_KIQ (ih_regs->ih_rb_cntl, tmp); +/* Unset the CLEAR_OVERFLOW bit immediately so new overflows +* can be detected. +*/ + tmp =REG_SET_FIELD (tmp,IH_RB_CNTL ,WPTR_OVERFLOW_CLEAR ,0 ); +WREG32_NO_KIQ (ih_regs->ih_rb_cntl, tmp); + out:return (wptr & ih->ptr_mask); }
Greg Kroah-Hartman
maintainerPATCH 136/309 drm/amd: Dont init MEC2 firmware when it fails to load
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: David McFarland <[email protected]>
commit 8ef85a0ce24a6d9322dfa2a67477e473c3619b4f upstream.
The same calls are made directly above, but conditional on the firmware loading and validating successfully.
--- drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 2 -- 1 file changed, 2 deletions(-)
drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c +0 -2
@@ -4027,8 +4027,6 @@ static int gfx_v10_0_init_microcode(stru err =0 ; adev->gfx.mec2_fw =NULL ; } -amdgpu_gfx_cp_init_microcode (adev,AMDGPU_UCODE_ID_CP_MEC2 ); -amdgpu_gfx_cp_init_microcode (adev,AMDGPU_UCODE_ID_CP_MEC2_JT );gfx_v10_0_check_fw_write_wait (adev); out:
Greg Kroah-Hartman
maintainerPATCH 137/309 drm/amd/display: fix incorrect mpc_combine array size
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wenjing Liu <[email protected]>
commit 39079fe8e660851abbafa90cd55cbf029210661f upstream.
[why]MAX_SURFACES is per stream, while MAX_PLANES is per asic. The mpc_combine is an array that records all the planes per asic. Therefore MAX_PLANES should be used as the array size. Using MAX_SURFACES causes array overflow when there are more than 3 planes.
[how]
Use the MAX_PLANES for the mpc_combine array size.
--- drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c +1 -1
@@ -1089,7 +1089,7 @@ struct pipe_slice_table {struct pipe_ctx *pri_pipe;struct dc_plane_state *plane;int slice_count; - } mpc_combines[MAX_SURFACES ]; + } mpc_combines[MAX_PLANES ];int mpc_combine_count; };
Greg Kroah-Hartman
maintainerPATCH 138/309 drm/amd/display: Fix dcn35 8k30 Underflow/Corruption Issue
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fangzhi Zuo <[email protected]>
commit faf51b201bc42adf500945732abb6220c707d6f3 upstream.
[why]
odm calculation is missing for pipe split policy determination and cause Underflow/Corruption issue.
[how]
Add the odm calculation.
--- drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c | 27 +++------- drivers/gpu/drm/amd/display/dc/inc/core_types.h | 2 2 files changed, 12 insertions(+), 17 deletions(-)
drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c +10 -17
@@ -791,35 +791,28 @@ static void populate_dml_surface_cfg_fro } } -/*TODO no support for mpc combine, need rework - should calculate scaling params based on plane+stream*/ -static struct scaler_data get_scaler_data_for_plane (const struct dc_plane_state *in,const struct dc_state *context) +static struct scaler_data get_scaler_data_for_plane (const struct dc_plane_state *in,struct dc_state *context) {int i; -struct scaler_data data = {0 }; +struct pipe_ctx *temp_pipe = &context->res_ctx.temp_pipe; + +memset (temp_pipe,0 ,sizeof (struct pipe_ctx ));for (i =0 ; i <MAX_PIPES ; i++) {const struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];if (pipe->plane_state == in && !pipe->prev_odm_pipe) { -const struct pipe_ctx *next_pipe = pipe->next_odm_pipe; + temp_pipe->stream = pipe->stream; + temp_pipe->plane_state = pipe->plane_state; + temp_pipe->plane_res.scl_data.taps = pipe->plane_res.scl_data.taps; - data = context->res_ctx.pipe_ctx[i].plane_res.scl_data; -while (next_pipe) { - data.h_active += next_pipe->plane_res.scl_data.h_active; - data.recout.width += next_pipe->plane_res.scl_data.recout.width; -if (in->rotation ==ROTATION_ANGLE_0 || in->rotation ==ROTATION_ANGLE_180 ) { - data.viewport.width += next_pipe->plane_res.scl_data.viewport.width; - }else { - data.viewport.height += next_pipe->plane_res.scl_data.viewport.height; - } - next_pipe = next_pipe->next_odm_pipe; - } +resource_build_scaling_params (temp_pipe);break ; } }ASSERT (i <MAX_PIPES ); -return data; +return temp_pipe->plane_res.scl_data; }static void populate_dummy_dml_plane_cfg (struct dml_plane_cfg_st *out,unsigned int location,const struct dc_stream_state *in)
@@ -864,7 +857,7 @@ static void populate_dummy_dml_plane_cfg out->ScalerEnabled[location] = false; } -static void populate_dml_plane_cfg_from_plane_state (struct dml_plane_cfg_st *out,unsigned int location,const struct dc_plane_state *in,const struct dc_state *context) +static void populate_dml_plane_cfg_from_plane_state (struct dml_plane_cfg_st *out,unsigned int location,const struct dc_plane_state *in,struct dc_state *context) {const struct scaler_data scaler_data =get_scaler_data_for_plane (in, context);
drivers/gpu/drm/amd/display/dc/inc/core_types.h +2 -0
@@ -462,6 +462,8 @@ struct resource_context {unsigned int hpo_dp_link_enc_to_link_idx[MAX_HPO_DP2_LINK_ENCODERS ];int hpo_dp_link_enc_ref_cnts[MAX_HPO_DP2_LINK_ENCODERS ];bool is_mpc_3dlut_acquired[MAX_PIPES ]; +/* solely used for build scalar data in dml2 */ +struct pipe_ctx temp_pipe; };struct dce_bw_output {
Greg Kroah-Hartman
maintainerPATCH 139/309 lsm: fix default return value of the socket_getpeersec_*() hooks
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ondrej Mosnacek <[email protected]>
commit 5a287d3d2b9de2b3e747132c615599907ba5c3c1 upstream.
For these hooks the true "neutral" value is -EOPNOTSUPP, which is currently what is returned when no LSM provides this hook and what LSMs return when there is no security context set on the socket. Correct the value in <linux/lsm_hooks.h> and adjust the dispatch functions in security/security.c to avoid issues when the BPF LSM is enabled.
--- include/linux/lsm_hook_defs.h | 4 ++-- security/security.c | 31 +++++++++++++++++++++++++++---- 2 files changed, 29 insertions(+), 6 deletions(-)
include/linux/lsm_hook_defs.h +2 -2
@@ -311,9 +311,9 @@ LSM_HOOK(int, 0, socket_getsockopt, stru LSM_HOOK(int, 0, socket_setsockopt, struct socket *sock, int level, int optname) LSM_HOOK(int, 0, socket_shutdown, struct socket *sock, int how) LSM_HOOK(int, 0, socket_sock_rcv_skb, struct sock *sk, struct sk_buff *skb) -LSM_HOOK(int, 0, socket_getpeersec_stream, struct socket *sock, +LSM_HOOK(int, -ENOPROTOOPT, socket_getpeersec_stream, struct socket *sock, sockptr_t optval, sockptr_t optlen, unsigned int len) -LSM_HOOK(int, 0, socket_getpeersec_dgram, struct socket *sock, +LSM_HOOK(int, -ENOPROTOOPT, socket_getpeersec_dgram, struct socket *sock, struct sk_buff *skb, u32 *secid) LSM_HOOK(int, 0, sk_alloc_security, struct sock *sk, int family, gfp_t priority) LSM_HOOK(void, LSM_RET_VOID, sk_free_security, struct sock *sk)
security/security.c +27 -4
@@ -4387,8 +4387,20 @@ EXPORT_SYMBOL(security_sock_rcv_skb);int security_socket_getpeersec_stream (struct socket *sock,sockptr_t optval,sockptr_t optlen,unsigned int len) { -return call_int_hook (socket_getpeersec_stream, -ENOPROTOOPT , sock, - optval, optlen, len); +struct security_hook_list *hp; +int rc; + +/* +* Only one module will provide a security context. +*/ +hlist_for_each_entry (hp, &security_hook_heads.socket_getpeersec_stream, + list) { + rc = hp->hook.socket_getpeersec_stream (sock, optval, optlen, + len); +if (rc !=LSM_RET_DEFAULT (socket_getpeersec_stream)) +return rc; + } +return LSM_RET_DEFAULT (socket_getpeersec_stream); }/**
@@ -4408,8 +4420,19 @@ int security_socket_getpeersec_stream(stint security_socket_getpeersec_dgram (struct socket *sock,struct sk_buff *skb,u32 *secid) { -return call_int_hook (socket_getpeersec_dgram, -ENOPROTOOPT , sock, - skb, secid); +struct security_hook_list *hp; +int rc; + +/* +* Only one module will provide a security context. +*/ +hlist_for_each_entry (hp, &security_hook_heads.socket_getpeersec_dgram, + list) { + rc = hp->hook.socket_getpeersec_dgram (sock, skb, secid); +if (rc !=LSM_RET_DEFAULT (socket_getpeersec_dgram)) +return rc; + } +return LSM_RET_DEFAULT (socket_getpeersec_dgram); }EXPORT_SYMBOL (security_socket_getpeersec_dgram);
Greg Kroah-Hartman
maintainerPATCH 140/309 lsm: fix the logic in security_inode_getsecctx()
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ondrej Mosnacek <[email protected]>
commit 99b817c173cd213671daecd25ca27f56b0c7c4ec upstream.
The inode_getsecctx LSM hook has previously been corrected to have -EOPNOTSUPP instead of 0 as the default return value to fix BPF LSM behavior. However, the call_int_hook()-generated loop in security_inode_getsecctx() was left treating 0 as the neutral value, so after an LSM returns 0, the loop continues to try other LSMs, and if one of them returns a non-zero value, the function immediately returns with said value. So in a situation where SELinux and the BPF LSMs registered this hook, -EOPNOTSUPP would be incorrectly returned whenever SELinux returned 0.
Fix this by open-coding the call_int_hook() loop and making it use the correct LSM_RET_DEFAULT() value as the neutral one, similar to what other hooks do.
--- security/security.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-)
security/security.c +13 -1
@@ -4030,7 +4030,19 @@ EXPORT_SYMBOL(security_inode_setsecctx);*/ int security_inode_getsecctx (struct inode *inode,void **ctx,u32 *ctxlen) { -return call_int_hook (inode_getsecctx, -EOPNOTSUPP , inode, ctx, ctxlen); +struct security_hook_list *hp; +int rc; + +/* +* Only one module will provide a security context. +*/ +hlist_for_each_entry (hp, &security_hook_heads.inode_getsecctx, list) { + rc = hp->hook.inode_getsecctx (inode, ctx, ctxlen); +if (rc !=LSM_RET_DEFAULT (inode_getsecctx)) +return rc; + } + +return LSM_RET_DEFAULT (inode_getsecctx); }EXPORT_SYMBOL (security_inode_getsecctx);
Greg Kroah-Hartman
maintainerPATCH 141/309 firewire: core: correct documentation of fw_csr_string() kernel API
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Sakamoto <[email protected]>
commit 5f9ab17394f831cb7986ec50900fa37507a127f1 upstream.
Against its current description, the kernel API can accepts all types of directory entries.
This commit corrects the documentation.
--- drivers/firewire/core-device.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
drivers/firewire/core-device.c +3 -4
@@ -100,10 +100,9 @@ static int textual_leaf_to_string(const* @buf: where to put the string * @size: size of @buf, in bytes * -* The string is taken from a minimal ASCII text descriptor leaf after -* the immediate entry with @key. The string is zero-terminated. -* An overlong string is silently truncated such that it and the -* zero byte fit into @size. +* The string is taken from a minimal ASCII text descriptor leaf just after the entry with the +* @key. The string is zero-terminated. An overlong string is silently truncated such that it +* and the zero byte fit into @size. * * Returns strlen(buf) or a negative error code. */
Greg Kroah-Hartman
maintainerPATCH 142/309 ALSA: hda/realtek: Apply headset jack quirk for non-bass alc287 thinkpads
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: José Relvas <[email protected]>
commit 2468e8922d2f6da81a6192b73023eff67e3fefdd upstream.
There currently exists two thinkpad headset jack fixups:ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK ALC285_FIXUP_THINKPAD_HEADSET_JACK
The latter is applied to alc285 and alc287 thinkpads which contain bass speakers.
However, the former was only being applied to alc285 thinkpads, leaving non-bass alc287 thinkpads with no headset button controls. This patch fixes that by adding ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK to the alc287 chains, allowing the detection of headset buttons.
--- sound/pci/hda/patch_realtek.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
sound/pci/hda/patch_realtek.c +3 -1
@@ -9570,7 +9570,7 @@ static const struct hda_fixup alc269_fix .type = HDA_FIXUP_FUNC, .v.func = cs35l41_fixup_i2c_two, .chained = true, - .chain_id = ALC269_FIXUP_THINKPAD_ACPI, + .chain_id = ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK, }, [ALC287_FIXUP_TAS2781_I2C] = { .type = HDA_FIXUP_FUNC,
@@ -9591,6 +9591,8 @@ static const struct hda_fixup alc269_fix [ALC287_FIXUP_THINKPAD_I2S_SPK] = { .type = HDA_FIXUP_FUNC, .v.func = alc287_fixup_bind_dacs, + .chained = true, + .chain_id = ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK, }, [ALC287_FIXUP_MG_RTKC_CSAMP_CS35L41_I2C_THINKPAD] = { .type = HDA_FIXUP_FUNC,
Greg Kroah-Hartman
maintainerPATCH 143/309 kbuild: Fix changing ELF file type for output of gen_btf for big endian
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nathan Chancellor <[email protected]>
commit e3a9ee963ad8ba677ca925149812c5932b49af69 upstream.
Commit 90ceddcb4950 ("bpf: Support llvm-objcopy for vmlinux BTF") changed the ELF type of .btf.vmlinux.bin.o to ET_REL via dd, which works fine for little endian platforms:
00000000 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 |.ELF............| -00000010 03 00 b7 00 01 00 00 00 00 00 00 80 00 80 ff ff |................| +00000010 01 00 b7 00 01 00 00 00 00 00 00 80 00 80 ff ff |................|
However, for big endian platforms, it changes the wrong byte, resulting in an invalid ELF file type, which ld.lld rejects:
00000000 7f 45 4c 46 02 02 01 00 00 00 00 00 00 00 00 00 |.ELF............| -00000010 00 03 00 16 00 00 00 01 00 00 00 00 00 10 00 00 |................| +00000010 01 03 00 16 00 00 00 01 00 00 00 00 00 10 00 00 |................|
Type: <unknown>: 103
ld.lld: error: .btf.vmlinux.bin.o: unknown file type
Fix this by updating the entire 16-bit e_type field rather than just a single byte, so that everything works correctly for all platforms and linkers.
00000000 7f 45 4c 46 02 02 01 00 00 00 00 00 00 00 00 00 |.ELF............| -00000010 00 03 00 16 00 00 00 01 00 00 00 00 00 10 00 00 |................| +00000010 00 01 00 16 00 00 00 01 00 00 00 00 00 10 00 00 |................|
Type: REL (Relocatable file)
While in the area, update the comment to mention that binutils 2.35+ matches LLD's behavior of rejecting an ET_EXEC input, which occurred after the comment was added.
--- scripts/link-vmlinux.sh | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
scripts/link-vmlinux.sh +7 -2
@@ -135,8 +135,13 @@ gen_btf() ${OBJCOPY} --only-section=.BTF --set-section-flags .BTF=alloc,readonly \ --strip-all ${1} ${2} 2>/dev/null # Change e_type to ET_REL so that it can be used to link final vmlinux. - # Unlike GNU ld, lld does not allow an ET_EXEC input. - printf '\1' | dd of=${2} conv=notrunc bs=1 seek=16 status=none + # GNU ld 2.35+ and lld do not allow an ET_EXEC input. + if is_enabled CONFIG_CPU_BIG_ENDIAN; then + et_rel='\0\1' + else + et_rel='\1\0' + fi + printf "${et_rel}" | dd of=${2} conv=notrunc bs=1 seek=16 status=none } # Create ${2} .S file with all symbols from the ${1} object file
Greg Kroah-Hartman
maintainerPATCH 144/309 nfc: nci: free rx_data_reassembly skb on NCI device cleanup
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fedor Pchelkin <[email protected]>
commit bfb007aebe6bff451f7f3a4be19f4f286d0d5d9c upstream.
rx_data_reassembly skb is stored during NCI data exchange for processing fragmented packets. It is dropped only when the last fragment is processed or when an NTF packet with NCI_OP_RF_DEACTIVATE_NTF opcode is received. However, the NCI device may be deallocated before that which leads to skb leak.
As by design the rx_data_reassembly skb is bound to the NCI device and nothing prevents the device to be freed before the skb is processed in some way and cleaned, free it on the NCI device cleanup.
Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
--- net/nfc/nci/core.c | 4 ++++ 1 file changed, 4 insertions(+)
net/nfc/nci/core.c +4 -0
@@ -1208,6 +1208,10 @@ void nci_free_device(struct nci_dev *nde {nfc_free_device (ndev->nfc_dev);nci_hci_deallocate (ndev); + +/* drop partial rx data packet if present */ +if (ndev->rx_data_reassembly) +kfree_skb (ndev->rx_data_reassembly);kfree (ndev); }EXPORT_SYMBOL (nci_free_device);
Greg Kroah-Hartman
maintainerPATCH 145/309 net: hsr: remove WARN_ONCE() in send_hsr_supervision_frame()
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nikita Zhandarovich <[email protected]>
commit 37e8c97e539015637cb920d3e6f1e404f707a06e upstream.
Syzkaller reported [1] hitting a warning after failing to allocate resources for skb in hsr_init_skb(). Since a WARN_ONCE() call will not help much in this case, it might be prudent to switch to netdev_warn_once(). At the very least it will suppress syzkaller reports such as [1].
Just in case, use netdev_warn_once() in send_prp_supervision_frame() for similar reasons.
[1]
HSR: Could not send supervision frame
WARNING: CPU: 1 PID: 85 at net/hsr/hsr_device.c:294 send_hsr_supervision_frame+0x60a/0x810 net/hsr/hsr_device.c:294 RIP: 0010:send_hsr_supervision_frame+0x60a/0x810 net/hsr/hsr_device.c:294 ... Call Trace: <IRQ> hsr_announce+0x114/0x370 net/hsr/hsr_device.c:382 call_timer_fn+0x193/0x590 kernel/time/timer.c:1700 expire_timers kernel/time/timer.c:1751 [inline] __run_timers+0x764/0xb20 kernel/time/timer.c:2022 run_timer_softirq+0x58/0xd0 kernel/time/timer.c:2035 __do_softirq+0x21a/0x8de kernel/softirq.c:553 invoke_softirq kernel/softirq.c:427 [inline] __irq_exit_rcu kernel/softirq.c:632 [inline] irq_exit_rcu+0xb7/0x120 kernel/softirq.c:644 sysvec_apic_timer_interrupt+0x95/0xb0 arch/x86/kernel/apic/apic.c:1076 </IRQ> <TASK> asm_sysvec_apic_timer_interrupt+0x1a/0x20 arch/x86/include/asm/idtentry.h:649
...
This issue is also found in older kernels (at least up to 5.10).
--- net/hsr/hsr_device.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
net/hsr/hsr_device.c +2 -2
@@ -291,7 +291,7 @@ static void send_hsr_supervision_frame(s skb =hsr_init_skb (master);if (!skb) { -WARN_ONCE (1 ,"HSR: Could not send supervision frame\n" ); +netdev_warn_once (master->dev,"HSR: Could not send supervision frame\n" );return ; }
@@ -338,7 +338,7 @@ static void send_prp_supervision_frame(s skb =hsr_init_skb (master);if (!skb) { -WARN_ONCE (1 ,"PRP: Could not send supervision frame\n" ); +netdev_warn_once (master->dev,"PRP: Could not send supervision frame\n" );return ; }
Greg Kroah-Hartman
maintainerPATCH 146/309 net: stmmac: do not clear TBS enable bit on link up/down
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Esben Haabendal <[email protected]>
commit 4896bb7c0b31a0a3379b290ea7729900c59e0c69 upstream.
With the dma conf being reallocated on each call to stmmac_open(), any information in there is lost, unless we specifically handle it.
The STMMAC_TBS_EN bit is set when adding an etf qdisc, and the etf qdisc therefore would stop working when link was set down and then back up.
--- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +3 -0
@@ -3869,6 +3869,9 @@ static int __stmmac_open(struct net_devi priv->rx_copybreak =STMMAC_RX_COPYBREAK ; buf_sz = dma_conf->dma_buf_sz; +for (int i =0 ; i <MTL_MAX_TX_QUEUES ; i++) +if (priv->dma_conf.tx_queue[i].tbs &STMMAC_TBS_EN ) + dma_conf->tx_queue[i].tbs = priv->dma_conf.tx_queue[i].tbs;memcpy (&priv->dma_conf, dma_conf,sizeof (*dma_conf));stmmac_reset_queues_param (priv);
Greg Kroah-Hartman
maintainerPATCH 147/309 parisc: Fix random data corruption from exception handler
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Helge Deller <[email protected]>
commit 8b1d72395635af45410b66cc4c4ab37a12c4a831 upstream.
The current exception handler implementation, which assists when accessing user space memory, may exhibit random data corruption if the compiler decides to use a different register than the specified register %r29 (defined in ASM_EXCEPTIONTABLE_REG) for the error code. If the compiler choose another register, the fault handler will nevertheless store -EFAULT into %r29 and thus trash whatever this register is used for.
Looking at the assembly I found that this happens sometimes in emulate_ldd().
To solve the issue, the easiest solution would be if it somehow is possible to tell the fault handler which register is used to hold the error code. Using %0 or %1 in the inline assembly is not posssible as it will show up as e.g. %r29 (with the "%r" prefix), which the GNU assembler can not convert to an integer.
This patch takes another, better and more flexible approach:
We extend the __ex_table (which is out of the execution path) by one 32-word. In this word we tell the compiler to insert the assembler instruction "or %r0,%r0,%reg", where %reg references the register which the compiler choosed for the error return code.
In case of an access failure, the fault handler finds the __ex_table entry and can examine the opcode. The used register is encoded in the lowest 5 bits, and the fault handler can then store -EFAULT into this register.
Since we extend the __ex_table to 3 words we can't use the BUILDTIME_TABLE_SORT config option any longer.
--- arch/parisc/Kconfig | 1 arch/parisc/include/asm/assembly.h | 1 arch/parisc/include/asm/extable.h | 64 ++++++++++++++++++++++++++++++++ arch/parisc/include/asm/special_insns.h | 6 ++- arch/parisc/include/asm/uaccess.h | 48 +++--------------------- arch/parisc/kernel/cache.c | 4 +- arch/parisc/kernel/unaligned.c | 44 +++++++++++----------- arch/parisc/mm/fault.c | 11 ++++- 8 files changed, 108 insertions(+), 71 deletions(-) create mode 100644 arch/parisc/include/asm/extable.h
arch/parisc/Kconfig +0 -1
@@ -25,7 +25,6 @@ config PARISC select RTC_DRV_GENERIC select INIT_ALL_POSSIBLE select BUG - select BUILDTIME_TABLE_SORT select HAVE_KERNEL_UNCOMPRESSED select HAVE_PCI select HAVE_PERF_EVENTS
arch/parisc/include/asm/assembly.h +1 -0
@@ -576,6 +576,7 @@ .section __ex_table,"aw" ! \ .align 4 ! \ .word (fault_addr - .), (except_addr - .) ! \ + or %r0,%r0,%r0 ! \ .previous
arch/parisc/include/asm/extable.h new file +64 -0
64 lines not on this page · raw message
arch/parisc/include/asm/special_insns.h +4 -2
@@ -8,7 +8,8 @@"copy %%r0,%0\n" \"8:\tlpa %%r0(%1),%0\n" \"9:\n" \ -ASM_EXCEPTIONTABLE_ENTRY (8b ,9b ) \ +ASM_EXCEPTIONTABLE_ENTRY (8b ,9b , \ +"or %%r0,%%r0,%%r0" ) \ : "=&r" (pa) \: " r" (va) \ : " memory" \
@@ -22,7 +23,8 @@"copy %%r0,%0\n" \"8:\tlpa %%r0(%%sr3,%1),%0\n" \"9:\n" \ -ASM_EXCEPTIONTABLE_ENTRY (8b ,9b ) \ +ASM_EXCEPTIONTABLE_ENTRY (8b ,9b , \ +"or %%r0,%%r0,%%r0" ) \ : "=&r" (pa) \: " r" (va) \ : " memory" \
arch/parisc/include/asm/uaccess.h +7 -41
94 lines not on this page · raw message
arch/parisc/kernel/cache.c +2 -2
@@ -850,7 +850,7 @@ SYSCALL_DEFINE3(cacheflush, unsigned lon#endif " fic,m %3(%4,%0)\n" "2: sync\n" -ASM_EXCEPTIONTABLE_ENTRY_EFAULT (1b ,2b ) +ASM_EXCEPTIONTABLE_ENTRY_EFAULT (1b ,2b ,"%1" ) : "+r" (start), "+r" (error) : "r" (end), "r" (dcache_stride), "i" (SR_USER)); }
@@ -865,7 +865,7 @@ SYSCALL_DEFINE3(cacheflush, unsigned lon#endif " fdc,m %3(%4,%0)\n" "2: sync\n" -ASM_EXCEPTIONTABLE_ENTRY_EFAULT (1b ,2b ) +ASM_EXCEPTIONTABLE_ENTRY_EFAULT (1b ,2b ,"%1" ) : "+r" (start), "+r" (error) : "r" (end), "r" (icache_stride), "i" (SR_USER)); }
arch/parisc/kernel/unaligned.c +22 -22
92 lines not on this page · raw message
arch/parisc/mm/fault.c +8 -3
@@ -150,11 +150,16 @@ int fixup_exception(struct pt_regs *regs* Fix up get_user() and put_user(). * ASM_EXCEPTIONTABLE_ENTRY_EFAULT() sets the least-significant * bit in the relative address of the fixup routine to indicate -* that gr[ASM_EXCEPTIONTABLE_REG] should be loaded with -* -EFAULT to report a userspace access error. +* that the register encoded in the "or %r0,%r0,register" +* opcode should be loaded with -EFAULT to report a userspace +* access error. */ if (fix->fixup &1 ) { - regs->gr[ASM_EXCEPTIONTABLE_REG ] = -EFAULT ; +int fault_error_reg = fix->err_opcode &0x1f ; +if (!WARN_ON (!fault_error_reg)) + regs->gr[fault_error_reg] = -EFAULT ; +pr_debug ("Unalignment fixup of register %d at %pS\n" , + fault_error_reg, (void *)regs->iaoq[0 ]);/* zero target register for get_user() */ if (parisc_acctyp (0 , regs->iir) ==VM_READ ) {
Greg Kroah-Hartman
maintainerPATCH 148/309 parisc: BTLB: Fix crash when setting up BTLB at CPU bringup
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Helge Deller <[email protected]>
commit 913b9d443a0180cf0de3548f1ab3149378998486 upstream.
When using hotplug and bringing up a 32-bit CPU, ask the firmware about the BTLB information to set up the static (block) TLB entries.
For that write access to the static btlb_info struct is needed, but since it is marked __ro_after_init the kernel segfaults with missing write permissions.
Fix the crash by dropping the __ro_after_init annotation.
--- arch/parisc/kernel/cache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/parisc/kernel/cache.c +1 -1
@@ -58,7 +58,7 @@ int pa_serialize_tlb_flushes __ro_after_struct pdc_cache_info cache_info__ro_after_init ;#ifndef CONFIG_PA20 -struct pdc_btlb_info btlb_info__ro_after_init ; +struct pdc_btlb_info btlb_info;#endif DEFINE_STATIC_KEY_TRUE (parisc_has_cache);
Greg Kroah-Hartman
maintainerPATCH 149/309 xen-netback: properly sync TX responses
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jan Beulich <[email protected]>
commit 7b55984c96ffe9e236eb9c82a2196e0b1f84990d upstream.
Invoking the make_tx_response() / push_tx_responses() pair with no lock held would be acceptable only if all such invocations happened from the same context (NAPI instance or dealloc thread). Since this isn't the case, and since the interface "spec" also doesn't demand that multicast operations may only be performed with no in-flight transmits, MCAST_{ADD,DEL} processing also needs to acquire the response lock around the invocations.
To prevent similar mistakes going forward, "downgrade" the present functions to private helpers of just the two remaining ones using them directly, with no forward declarations anymore. This involves renaming what so far was make_tx_response(), for the new function of that name to serve the new (wrapper) purpose.
While there,
- constify the txp parameters,
- correct xenvif_idx_release()'s status parameter's type,
- rename {,_}make_tx_response()'s status parameters for consistency with xenvif_idx_release()'s.
--- drivers/net/xen-netback/netback.c | 84 ++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 44 deletions(-)
drivers/net/xen-netback/netback.c +40 -44
@@ -104,13 +104,12 @@ bool provides_xdp_headroom = true;module_param (provides_xdp_headroom, bool,0644 );static void xenvif_idx_release (struct xenvif_queue *queue,u16 pending_idx, -u8 status); +s8 status);static void make_tx_response (struct xenvif_queue *queue, -struct xen_netif_tx_request *txp, +const struct xen_netif_tx_request *txp,unsigned int extra_count, -s8 st); -static void push_tx_responses (struct xenvif_queue *queue); +s8 status);static void xenvif_idx_unmap (struct xenvif_queue *queue,u16 pending_idx);
@@ -208,13 +207,9 @@ static void xenvif_tx_err(struct xenvif_ unsigned int extra_count, RING_IDX end) {RING_IDX cons = queue->tx.req_cons; -unsigned long flags; do { - spin_lock_irqsave(&queue->response_lock, flags); make_tx_response(queue, txp, extra_count, XEN_NETIF_RSP_ERROR); - push_tx_responses(queue); - spin_unlock_irqrestore(&queue->response_lock, flags); if (cons == end) break; RING_COPY_REQUEST(&queue->tx, cons++, txp);
@@ -465,12 +460,7 @@ static void xenvif_get_requests(struct xfor (shinfo->nr_frags =0 ; nr_slots >0 && shinfo->nr_frags <MAX_SKB_FRAGS ; nr_slots--) {if (unlikely (!txp->size)) { -unsigned long flags; - -spin_lock_irqsave (&queue->response_lock, flags);make_tx_response (queue, txp,0 ,XEN_NETIF_RSP_OKAY ); -push_tx_responses (queue); -spin_unlock_irqrestore (&queue->response_lock, flags); ++txp;continue ; }
@@ -496,14 +486,8 @@ static void xenvif_get_requests(struct xfor (shinfo->nr_frags =0 ; shinfo->nr_frags < nr_slots; ++txp) {if (unlikely (!txp->size)) { -unsigned long flags; - -spin_lock_irqsave (&queue->response_lock, flags);make_tx_response (queue, txp,0 ,XEN_NETIF_RSP_OKAY ); -push_tx_responses (queue); -spin_unlock_irqrestore (&queue->response_lock, - flags);continue ; }
@@ -995,7 +979,6 @@ static void xenvif_tx_build_gops(struct (ret ==0 ) ?XEN_NETIF_RSP_OKAY : XEN_NETIF_RSP_ERROR); -push_tx_responses (queue);continue ; }
@@ -1007,7 +990,6 @@ static void xenvif_tx_build_gops(structmake_tx_response (queue, &txreq, extra_count,XEN_NETIF_RSP_OKAY ); -push_tx_responses (queue);continue ; }
@@ -1433,8 +1415,35 @@ int xenvif_tx_action(struct xenvif_queuereturn work_done; } +static void _make_tx_response (struct xenvif_queue *queue, +const struct xen_netif_tx_request *txp, +unsigned int extra_count, +s8 status) +{ +RING_IDX i = queue->tx.rsp_prod_pvt; +struct xen_netif_tx_response *resp; + + resp =RING_GET_RESPONSE (&queue->tx, i); + resp->id = txp->id; + resp->status = status; + +while (extra_count-- !=0 ) +RING_GET_RESPONSE (&queue->tx, ++i)->status =XEN_NETIF_RSP_NULL ; + + queue->tx.rsp_prod_pvt = ++i; +} + +static void push_tx_responses (struct xenvif_queue *queue) +{ +int notify; + +RING_PUSH_RESPONSES_AND_CHECK_NOTIFY (&queue->tx, notify); +if (notify) +notify_remote_via_irq (queue->tx_irq); +} +static void xenvif_idx_release (struct xenvif_queue *queue,u16 pending_idx, -u8 status) +s8 status) {struct pending_tx_info *pending_tx_info;pending_ring_idx_t index;
@@ -1444,8 +1453,8 @@ static void xenvif_idx_release(struct xespin_lock_irqsave (&queue->response_lock, flags); -make_tx_response (queue, &pending_tx_info->req, - pending_tx_info->extra_count, status); +_make_tx_response (queue, &pending_tx_info->req, + pending_tx_info->extra_count, status);/* Release the pending index before pusing the Tx response so * its available before a new Tx request is pushed by the
@@ -1459,32 +1468,19 @@ static void xenvif_idx_release(struct xespin_unlock_irqrestore (&queue->response_lock, flags); } -static void make_tx_response (struct xenvif_queue *queue, -struct xen_netif_tx_request *txp, +const struct xen_netif_tx_request *txp,unsigned int extra_count, -s8 st) +s8 status) { -RING_IDX i = queue->tx.rsp_prod_pvt; -struct xen_netif_tx_response *resp; - - resp =RING_GET_RESPONSE (&queue->tx, i); - resp->id = txp->id; - resp->status = st; - -while (extra_count-- !=0 ) -RING_GET_RESPONSE (&queue->tx, ++i)->status =XEN_NETIF_RSP_NULL ; +unsigned long flags; - queue->tx.rsp_prod_pvt = ++i; -} +spin_lock_irqsave (&queue->response_lock, flags); -static void push_tx_responses (struct xenvif_queue *queue) -{ -int notify; +_make_tx_response (queue, txp, extra_count, status); +push_tx_responses (queue); -RING_PUSH_RESPONSES_AND_CHECK_NOTIFY (&queue->tx, notify); -if (notify) -notify_remote_via_irq (queue->tx_irq); +spin_unlock_irqrestore (&queue->response_lock, flags); }static void xenvif_idx_unmap (struct xenvif_queue *queue,u16 pending_idx)
Greg Kroah-Hartman
maintainerPATCH 150/309 um: Fix adding -no-pie for clang
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nathan Chancellor <[email protected]>
commit 846cfbeed09b45d985079a9173cf390cc053715b upstream.
The kernel builds with -fno-PIE, so commit 883354afbc10 ("um: link vmlinux with -no-pie") added the compiler linker flag '-no-pie' via cc-option because '-no-pie' was only supported in GCC 6.1.0 and newer.
While this works for GCC, this does not work for clang because cc-option uses '-c', which stops the pipeline right before linking, so '-no-pie' is unconsumed and clang warns, causing cc-option to fail just as it would if the option was entirely unsupported:
$ clang -Werror -no-pie -c -o /dev/null -x c /dev/null clang-16: error: argument unused during compilation: '-no-pie' [-Werror,-Wunused-command-line-argument]
A recent version of clang exposes this because it generates a relocation under '-mcmodel=large' that is not supported in PIE mode:
/usr/sbin/ld: init/main.o: relocation R_X86_64_32 against symbol `saved_command_line' can not be used when making a PIE object; recompile with -fPIE /usr/sbin/ld: failed to set dynamic section sizes: bad value
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Remove the cc-option check altogether. It is wasteful to invoke the compiler to check for '-no-pie' because only one supported compiler version does not support it, GCC 5.x (as it is supported with the minimum version of clang and GCC 6.1.0+). Use a combination of the gcc-min-version macro and CONFIG_CC_IS_CLANG to unconditionally add '-no-pie' with CONFIG_LD_SCRIPT_DYN=y, so that it is enabled with all compilers that support this. Furthermore, using gcc-min-version can help turn this back into
LINK-$(CONFIG_LD_SCRIPT_DYN) += -no-pie
when the minimum version of GCC is bumped past 6.1.0.
--- arch/um/Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
arch/um/Makefile +3 -1
@@ -115,7 +115,9 @@ archprepare: $(Q)$(MAKE) $(build)=$(HOST_DIR)/um include/generated/user_constants.h LINK-$(CONFIG_LD_SCRIPT_STATIC) += -static -LINK-$(CONFIG_LD_SCRIPT_DYN) += $(call cc-option, -no-pie) +ifdef CONFIG_LD_SCRIPT_DYN +LINK-$(call gcc-min-version, 60100)$(CONFIG_CC_IS_CLANG) += -no-pie +endif LINK-$(CONFIG_LD_SCRIPT_DYN_RPATH) += -Wl,-rpath,/lib CFLAGS_NO_HARDENING := $(call cc-option, -fno-PIC,) $(call cc-option, -fno-pic,) \
Greg Kroah-Hartman
maintainerPATCH 151/309 modpost: Add .ltext and .ltext.* to TEXT_SECTIONS
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nathan Chancellor <[email protected]>
commit 397586506c3da005b9333ce5947ad01e8018a3be upstream.
After the linked LLVM change, building ARCH=um defconfig results in a segmentation fault in modpost. Prior to commit a23e7584ecf3 ("modpost:
unify 'sym' and 'to' in default_mismatch_handler()"), there was a warning:
WARNING: modpost: vmlinux.o(__ex_table+0x88): Section mismatch in reference to the .ltext:(unknown)
WARNING: modpost: The relocation at __ex_table+0x88 references
section ".ltext" which is not in the list of
authorized sections. If you're adding a new section
and/or if this reference is valid, add ".ltext" to the
list of authorized sections to jump to on fault.
This can be achieved by adding ".ltext" to
OTHER_TEXT_SECTIONS in scripts/mod/modpost.c.
The linked LLVM change moves global objects to the '.ltext' (and '.ltext.*' with '-ffunction-sections') sections with '-mcmodel=large', which ARCH=um uses. These sections should be handled just as '.text' and '.text.*' are, so add them to TEXT_SECTIONS.
--- scripts/mod/modpost.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
scripts/mod/modpost.c +2 -1
@@ -807,7 +807,8 @@ static void check_section(const char *mo#define DATA_SECTIONS ".data", ".data.rel"#define TEXT_SECTIONS ".text", ".text.*", ".sched.text", \ - ".kprobes.text", ".cpuidle.text", ".noinstr.text" + ".kprobes.text", ".cpuidle.text", ".noinstr.text", \ + ".ltext", ".ltext.*"#define OTHER_TEXT_SECTIONS ".ref.text", ".head.text", ".spinlock.text", \ ".fixup", ".entry.text", ".exception.text", \ ".coldtext", ".softirqentry.text"
Greg Kroah-Hartman
maintainerPATCH 152/309 ALSA: hda/realtek: Enable headset mic on Vaio VJFE-ADL
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Edson Juliano Drosdeck <[email protected]>
commit c7de2d9bb68a5fc71c25ff96705a80a76c8436eb upstream.
Vaio VJFE-ADL is equipped with ALC269VC, and it needs ALC298_FIXUP_SPK_VOLUME quirk to make its headset mic work.
--- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+)
sound/pci/hda/patch_realtek.c +1 -0
@@ -10312,6 +10312,7 @@ static const struct snd_pci_quirk alc269SND_PCI_QUIRK (0x1d72 ,0x1945 ,"Redmi G" ,ALC256_FIXUP_ASUS_HEADSET_MIC ),SND_PCI_QUIRK (0x1d72 ,0x1947 ,"RedmiBook Air" ,ALC255_FIXUP_XIAOMI_HEADSET_MIC ),SND_PCI_QUIRK (0x2782 ,0x0232 ,"CHUWI CoreBook XPro" ,ALC269VB_FIXUP_CHUWI_COREBOOK_XPRO ), +SND_PCI_QUIRK (0x2782 ,0x1707 ,"Vaio VJFE-ADL" ,ALC298_FIXUP_SPK_VOLUME ),SND_PCI_QUIRK (0x8086 ,0x2074 ,"Intel NUC 8" ,ALC233_FIXUP_INTEL_NUC8_DMIC ),SND_PCI_QUIRK (0x8086 ,0x2080 ,"Intel NUC 8 Rugged" ,ALC256_FIXUP_INTEL_NUC8_RUGGED ), SND_PCI_QUIRK(0x8086, 0x2081, "Intel NUC 10", ALC256_FIXUP_INTEL_NUC10),
Greg Kroah-Hartman
maintainerPATCH 153/309 ALSA: hda/realtek - Add speaker pin verbtable for Dell dual speaker platform
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kailang Yang <[email protected]>
commit fcfc9f711d1e2fc7876ac12b1b16c509404b9625 upstream.
SSID 0x0c0d platform. It can't mute speaker when HP plugged. This patch add quirk to fill speaker pin verbtable. And disable speaker passthrough.
--- sound/pci/hda/patch_realtek.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
sound/pci/hda/patch_realtek.c +5 -2
@@ -439,6 +439,10 @@ static void alc_fill_eapd_coef(struct hdalc_update_coef_idx (codec,0x67 ,0xf000 ,0x3000 ); fallthrough;case 0x10ec0215 : +case 0x10ec0285 : +case 0x10ec0289 : +alc_update_coef_idx (codec,0x36 ,1 <<13 ,0 ); + fallthrough;case 0x10ec0230 :case 0x10ec0233 :case 0x10ec0235 :
@@ -452,9 +456,7 @@ static void alc_fill_eapd_coef(struct hdcase 0x10ec0283 :case 0x10ec0286 :case 0x10ec0288 : -case 0x10ec0285 :case 0x10ec0298 : -case 0x10ec0289 :case 0x10ec0300 :alc_update_coef_idx (codec,0x10 ,1 <<9 ,0 );break ;
@@ -9722,6 +9724,7 @@ static const struct snd_pci_quirk alc269SND_PCI_QUIRK (0x1028 ,0x0b71 ,"Dell Inspiron 16 Plus 7620" ,ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS ),SND_PCI_QUIRK (0x1028 ,0x0beb ,"Dell XPS 15 9530 (2023)" ,ALC289_FIXUP_DELL_CS35L41_SPI_2 ),SND_PCI_QUIRK (0x1028 ,0x0c03 ,"Dell Precision 5340" ,ALC269_FIXUP_DELL4_MIC_NO_PRESENCE ), +SND_PCI_QUIRK (0x1028 ,0x0c0d ,"Dell Oasis" ,ALC289_FIXUP_RTK_AMP_DUAL_SPK ),SND_PCI_QUIRK (0x1028 ,0x0c19 ,"Dell Precision 3340" ,ALC236_FIXUP_DELL_DUAL_CODECS ),SND_PCI_QUIRK (0x1028 ,0x0c1a ,"Dell Precision 3340" ,ALC236_FIXUP_DELL_DUAL_CODECS ), SND_PCI_QUIRK(0x1028, 0x0c1b, "Dell Precision 3440", ALC236_FIXUP_DELL_DUAL_CODECS),
Greg Kroah-Hartman
maintainerPATCH 154/309 ASoC: codecs: wcd938x: handle deferred probe
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Kozlowski <[email protected]>
commit 086df711d9b886194481b4fbe525eb43e9ae7403 upstream.
WCD938x sound codec driver ignores return status of getting regulators and returns EINVAL instead of EPROBE_DEFER. If regulator provider probes after the codec, system is left without probed audio:
wcd938x_codec audio-codec: wcd938x_probe: Fail to obtain platform data
wcd938x_codec: probe of audio-codec failed with error -22
--- sound/soc/codecs/wcd938x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/soc/codecs/wcd938x.c +1 -1
@@ -3589,7 +3589,7 @@ static int wcd938x_probe(struct platform ret =wcd938x_populate_dt_data (wcd938x, dev);if (ret) {dev_err (dev,"%s: Fail to obtain platform data\n" , __func__); -return -EINVAL ; +return ret; } ret =wcd938x_add_slave_components (wcd938x, dev, &match);
Greg Kroah-Hartman
maintainerPATCH 155/309 ALSA: hda/cs8409: Suppress vmaster control for Dolphin models
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vitaly Rodionov <[email protected]>
commit a2ed0a44d637ef9deca595054c206da7d6cbdcbc upstream.
Customer has reported an issue with specific desktop platform where two CS42L42 codecs are connected to CS8409 HDA bridge. If "Master Volume Control" is created then on Ubuntu OS UCM left/right balance slider in UI audio settings has no effect. This patch will fix this issue for a target paltform.
--- sound/pci/hda/patch_cs8409.c | 1 + 1 file changed, 1 insertion(+)
sound/pci/hda/patch_cs8409.c +1 -0
@@ -1371,6 +1371,7 @@ void dolphin_fixups(struct hda_codec *co spec->scodecs[CS8409_CODEC1 ] = &dolphin_cs42l42_1; spec->scodecs[CS8409_CODEC1 ]->codec = codec; spec->num_scodecs =2 ; + spec->gen.suppress_vmaster =1 ; codec->patch_ops = cs8409_dolphin_patch_ops;
Greg Kroah-Hartman
maintainerPATCH 156/309 ALSA: hda/realtek: fix mute/micmute LEDs for HP ZBook Power
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Chi <[email protected]>
commit 1513664f340289cf10402753110f3cff12a738aa upstream.
The HP ZBook Power using ALC236 codec which using 0x02 to control mute LED and 0x01 to control micmute LED. Therefore, add a quirk to make it works.
--- sound/pci/hda/patch_realtek.c | 2 ++ 1 file changed, 2 insertions(+)
sound/pci/hda/patch_realtek.c +2 -0
@@ -9951,6 +9951,8 @@ static const struct snd_pci_quirk alc269SND_PCI_QUIRK (0x103c ,0x8c72 ,"HP EliteBook 865 G11" ,ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED ),SND_PCI_QUIRK (0x103c ,0x8c96 ,"HP" ,ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF ),SND_PCI_QUIRK (0x103c ,0x8c97 ,"HP ZBook" ,ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF ), +SND_PCI_QUIRK (0x103c ,0x8ca1 ,"HP ZBook Power" ,ALC236_FIXUP_HP_GPIO_LED ), +SND_PCI_QUIRK (0x103c ,0x8ca2 ,"HP ZBook Power" ,ALC236_FIXUP_HP_GPIO_LED ),SND_PCI_QUIRK (0x103c ,0x8ca4 ,"HP ZBook Fury" ,ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED ),SND_PCI_QUIRK (0x103c ,0x8ca7 ,"HP ZBook Fury" ,ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED ), SND_PCI_QUIRK(0x103c, 0x8cf5, "HP ZBook Studio 16", ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED),
Greg Kroah-Hartman
maintainerPATCH 157/309 binder: signal epoll threads of self-work
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Carlos Llamas <[email protected]>
commit 97830f3c3088638ff90b20dfba2eb4d487bf14d7 upstream.
In (e)poll mode, threads often depend on I/O events to determine when data is ready for consumption. Within binder, a thread may initiate a command via BINDER_WRITE_READ without a read buffer and then make use of epoll_wait() or similar to consume any responses afterwards.
It is then crucial that epoll threads are signaled via wakeup when they queue their own work. Otherwise, they risk waiting indefinitely for an event leaving their work unhandled. What is worse, subsequent commands won't trigger a wakeup either as the thread has pending work.
--- drivers/android/binder.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
drivers/android/binder.c +10 -0
@@ -478,6 +478,16 @@ binder_enqueue_thread_work_ilocked(struc {WARN_ON (!list_empty (&thread->waiting_thread_node));binder_enqueue_work_ilocked (work, &thread->todo); + +/* (e)poll-based threads require an explicit wakeup signal when +* queuing their own work; they rely on these events to consume +* messages without I/O block. Without it, threads risk waiting +* indefinitely without handling the work. +*/ +if (thread->looper &BINDER_LOOPER_STATE_POLL && + thread->pid == current->pid && !thread->process_todo) +wake_up_interruptible_sync (&thread->wait); + thread->process_todo = true; }
Greg Kroah-Hartman
maintainerPATCH 158/309 misc: fastrpc: Mark all sessions as invalid in cb_remove
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ekansh Gupta <[email protected]>
commit a4e61de63e34860c36a71d1a364edba16fb6203b upstream.
In remoteproc shutdown sequence, rpmsg_remove will get called which would depopulate all the child nodes that have been created during rpmsg_probe. This would result in cb_remove call for all the context banks for the remoteproc. In cb_remove function, session 0 is getting skipped which is not correct as session 0 will never become available again. Add changes to mark session 0 also as invalid.
--- drivers/misc/fastrpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/misc/fastrpc.c +1 -1
@@ -2191,7 +2191,7 @@ static int fastrpc_cb_remove(struct platint i;spin_lock_irqsave (&cctx->lock, flags); -for (i =1 ; i <FASTRPC_MAX_SESSIONS ; i++) { +for (i =0 ; i <FASTRPC_MAX_SESSIONS ; i++) {if (cctx->session[i].sid == sess->sid) { cctx->session[i].valid = false; cctx->sesscount--;
Greg Kroah-Hartman
maintainerPATCH 159/309 ext4: fix double-free of blocks due to wrong extents moved_len
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baokun Li <[email protected]>
commit 55583e899a5357308274601364741a83e78d6ac4 upstream.
In ext4_move_extents(), moved_len is only updated when all moves are successfully executed, and only discards orig_inode and donor_inode preallocations when moved_len is not zero. When the loop fails to exit after successfully moving some extents, moved_len is not updated and remains at 0, so it does not discard the preallocations.
If the moved extents overlap with the preallocated extents, the overlapped extents are freed twice in ext4_mb_release_inode_pa() and ext4_process_freed_data() (as described in commit 94d7c16cbbbd ("ext4:
Fix double-free of blocks with EXT4_IOC_MOVE_EXT")), and bb_free is incremented twice. Hence when trim is executed, a zero-division bug is triggered in mb_update_avg_fragment_size() because bb_free is not zero and bb_fragments is zero.
Therefore, update move_len after each extent move to avoid the issue.
--- fs/ext4/move_extent.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
fs/ext4/move_extent.c +2 -4
@@ -618,6 +618,7 @@ ext4_move_extents(struct file *o_filp, s goto out; o_end = o_start + len; + *moved_len =0 ;while (o_start < o_end) {struct ext4_extent *ex;ext4_lblk_t cur_blk, next_blk;
@@ -672,7 +673,7 @@ ext4_move_extents(struct file *o_filp, s*/ ext4_double_up_write_data_sem (orig_inode, donor_inode);/* Swap original branches with new branches */ -move_extent_per_page (o_filp, donor_inode, + *moved_len +=move_extent_per_page (o_filp, donor_inode, orig_page_index, donor_page_index, offset_in_page, cur_len, unwritten, &ret);
@@ -682,9 +683,6 @@ ext4_move_extents(struct file *o_filp, s o_start += cur_len; d_start += cur_len; } - *moved_len = o_start - orig_blk; -if (*moved_len > len) - *moved_len = len; out:if (*moved_len) {
Greg Kroah-Hartman
maintainerPATCH 160/309 ext4: avoid bb_free and bb_fragments inconsistency in mb_free_blocks()
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baokun Li <[email protected]>
commit 2331fd4a49864e1571b4f50aa3aa1536ed6220d0 upstream.
After updating bb_free in mb_free_blocks, it is possible to return without updating bb_fragments because the block being freed is found to have already been freed, which leads to inconsistency between bb_free and bb_fragments.
Since the group may be unlocked in ext4_grp_locked_error(), this can lead to problems such as dividing by zero when calculating the average fragment length. Hence move the update of bb_free to after the block double-free check guarantees that the corresponding statistics are updated only after the core block bitmap is modified.
--- fs/ext4/mballoc.c | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-)
fs/ext4/mballoc.c +21 -18
@@ -1910,11 +1910,6 @@ static void mb_free_blocks(struct inodemb_check_buddy (e4b);mb_free_blocks_double (inode, e4b, first, count); -this_cpu_inc (discard_pa_seq); - e4b->bd_info->bb_free += count; -if (first < e4b->bd_info->bb_first_free) - e4b->bd_info->bb_first_free = first; -/* access memory sequentially: check left neighbour, * clear range and then check right neighbour */
@@ -1928,23 +1923,31 @@ static void mb_free_blocks(struct inodestruct ext4_sb_info *sbi =EXT4_SB (sb);ext4_fsblk_t blocknr; +/* +* Fastcommit replay can free already freed blocks which +* corrupts allocation info. Regenerate it. +*/ +if (sbi->s_mount_state &EXT4_FC_REPLAY ) { +mb_regenerate_buddy (e4b); + goto check; + } + blocknr =ext4_group_first_block_no (sb, e4b->bd_group); blocknr +=EXT4_C2B (sbi, block); -if (!(sbi->s_mount_state &EXT4_FC_REPLAY )) { -ext4_grp_locked_error (sb, e4b->bd_group, - inode ? inode->i_ino :0 , - blocknr, -"freeing already freed block (bit %u); block bitmap corrupt." , - block); -ext4_mark_group_bitmap_corrupted ( - sb, e4b->bd_group, +ext4_grp_locked_error (sb, e4b->bd_group, + inode ? inode->i_ino :0 , blocknr, +"freeing already freed block (bit %u); block bitmap corrupt." , + block); +ext4_mark_group_bitmap_corrupted (sb, e4b->bd_group,EXT4_GROUP_INFO_BBITMAP_CORRUPT ); - }else { -mb_regenerate_buddy (e4b); - } - goto done; +return ; } +this_cpu_inc (discard_pa_seq); + e4b->bd_info->bb_free += count; +if (first < e4b->bd_info->bb_first_free) + e4b->bd_info->bb_first_free = first; +/* let's maintain fragments counter */ if (left_is_free && right_is_free) e4b->bd_info->bb_fragments--;
@@ -1969,9 +1972,9 @@ static void mb_free_blocks(struct inodeif (first <= last)mb_buddy_mark_free (e4b, first >>1 , last >>1 ); -done:mb_set_largest_free_order (sb, e4b->bd_info);mb_update_avg_fragment_size (sb, e4b->bd_info); +check:mb_check_buddy (e4b); }
Greg Kroah-Hartman
maintainerPATCH 161/309 tracing/timerlat: Move hrtimer_init to timerlat_fd open()
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Bristot de Oliveira <[email protected]>
commit 1389358bb008e7625942846e9f03554319b7fecc upstream.
Currently, the timerlat's hrtimer is initialized at the first read of timerlat_fd, and destroyed at close(). It works, but it causes an error if the user program open() and close() the file without reading.
Here's an example:
# echo NO_OSNOISE_WORKLOAD > /sys/kernel/debug/tracing/osnoise/options # echo timerlat > /sys/kernel/debug/tracing/current_tracer
# cat <<EOF > ./timerlat_load.py # !/usr/bin/env python3
timerlat_fd = open("/sys/kernel/tracing/osnoise/per_cpu/cpu0/timerlat_fd", 'r') timerlat_fd.close();
EOF
# ./taskset -c 0 ./timerlat_load.py <BOOM>
BUG: kernel NULL pointer dereference, address: 0000000000000010 #PF: supervisor read access in kernel mode #PF: error_code(0x0000) - not-present page PGD 0 P4D 0 Oops: 0000 [#1] PREEMPT SMP NOPTI CPU: 1 PID: 2673 Comm: python3 Not tainted 6.6.13-200.fc39.x86_64 #1 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-1.fc39 04/01/2014 RIP: 0010:hrtimer_active+0xd/0x50 Code: 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 f3 0f 1e fa 0f 1f 44 00 00 48 8b 57 30 <8b> 42 10 a8 01 74 09 f3 90 8b 42 10 a8 01 75 f7 80 7f 38 00 75 1d RSP: 0018:ffffb031009b7e10 EFLAGS: 00010286 RAX: 000000000002db00 RBX: ffff9118f786db08 RCX: 0000000000000000 RDX: 0000000000000000 RSI: ffff9117a0e64400 RDI: ffff9118f786db08 RBP: ffff9118f786db80 R08: ffff9117a0ddd420 R09: ffff9117804d4f70 R10: 0000000000000000 R11: 0000000000000000 R12: ffff9118f786db08 R13: ffff91178fdd5e20 R14: ffff9117840978c0 R15: 0000000000000000 FS: 00007f2ffbab1740(0000) GS:ffff9118f7840000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000010 CR3: 00000001b402e000 CR4: 0000000000750ee0 PKRU: 55555554 Call Trace: <TASK> ? __die+0x23/0x70 ? page_fault_oops+0x171/0x4e0 ? srso_alias_return_thunk+0x5/0x7f ? avc_has_extended_perms+0x237/0x520 ? exc_page_fault+0x7f/0x180 ? asm_exc_page_fault+0x26/0x30 ? hrtimer_active+0xd/0x50 hrtimer_cancel+0x15/0x40 timerlat_fd_release+0x48/0xe0 __fput+0xf5/0x290 __x64_sys_close+0x3d/0x80 do_syscall_64+0x60/0x90 ? srso_alias_return_thunk+0x5/0x7f ? __x64_sys_ioctl+0x72/0xd0 ? srso_alias_return_thunk+0x5/0x7f ? syscall_exit_to_user_mode+0x2b/0x40 ? srso_alias_return_thunk+0x5/0x7f ? do_syscall_64+0x6c/0x90 ? srso_alias_return_thunk+0x5/0x7f ? exit_to_user_mode_prepare+0x142/0x1f0 ? srso_alias_return_thunk+0x5/0x7f ? syscall_exit_to_user_mode+0x2b/0x40 ? srso_alias_return_thunk+0x5/0x7f ? do_syscall_64+0x6c/0x90 entry_SYSCALL_64_after_hwframe+0x6e/0xd8 RIP: 0033:0x7f2ffb321594 Code: 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 80 3d d5 cd 0d 00 00 74 13 b8 03 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 3c c3 0f 1f 00 55 48 89 e5 48 83 ec 10 89 7d RSP: 002b:00007ffe8d8eef18 EFLAGS: 00000202 ORIG_RAX: 0000000000000003 RAX: ffffffffffffffda RBX: 00007f2ffba4e668 RCX: 00007f2ffb321594 RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000003 RBP: 00007ffe8d8eef40 R08: 0000000000000000 R09: 0000000000000000 R10: 55c926e3167eae79 R11: 0000000000000202 R12: 0000000000000003 R13: 00007ffe8d8ef030 R14: 0000000000000000 R15: 00007f2ffba4e668 </TASK> CR2: 0000000000000010 ---[ end trace 0000000000000000 ]---
Move hrtimer_init to timerlat_fd open() to avoid this problem.
--- kernel/trace/trace_osnoise.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
kernel/trace/trace_osnoise.c +3 -3
@@ -2444,6 +2444,9 @@ static int timerlat_fd_open(struct inode tlat =this_cpu_tmr_var (); tlat->count =0 ; +hrtimer_init (&tlat->timer,CLOCK_MONOTONIC ,HRTIMER_MODE_ABS_PINNED_HARD ); + tlat->timer.function = timerlat_irq; +migrate_enable ();return 0 ; };
@@ -2526,9 +2529,6 @@ timerlat_fd_read(struct file *file, char tlat->tracing_thread = false; tlat->kthread = current; -hrtimer_init (&tlat->timer,CLOCK_MONOTONIC ,HRTIMER_MODE_ABS_PINNED_HARD ); - tlat->timer.function = timerlat_irq; -/* Annotate now to drift new period */ tlat->abs_period =hrtimer_cb_get_time (&tlat->timer);
Greg Kroah-Hartman
maintainerPATCH 162/309 tracing: Fix wasted memory in saved_cmdlines logic
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt (Google) <[email protected]>
commit 44dc5c41b5b1267d4dd037d26afc0c4d3a568acb upstream.
While looking at improving the saved_cmdlines cache I found a huge amount of wasted memory that should be used for the cmdlines.
The tracing data saves pids during the trace. At sched switch, if a trace occurred, it will save the comm of the task that did the trace. This is saved in a "cache" that maps pids to comms and exposed to user space via the /sys/kernel/tracing/saved_cmdlines file. Currently it only caches by default 128 comms.
The structure that uses this creates an array to store the pids using PID_MAX_DEFAULT (which is usually set to 32768). This causes the structure to be of the size of 131104 bytes on 64 bit machines.
In hex: 131104 = 0x20020, and since the kernel allocates generic memory in powers of two, the kernel would allocate 0x40000 or 262144 bytes to store this structure. That leaves 131040 bytes of wasted space.
Worse, the structure points to an allocated array to store the comm names, which is 16 bytes times the amount of names to save (currently 128), which is 2048 bytes. Instead of allocating a separate array, make the structure end with a variable length string and use the extra space for that.
This is similar to a recommendation that Linus had made about eventfs_inode names:
https://lore.kernel.org/all/[email protected]/
Instead of allocating a separate string array to hold the saved comms,
have the structure end with: char saved_cmdlines[]; and round up to the next power of two over sizeof(struct saved_cmdline_buffers) + num_cmdlines * TASK_COMM_LEN It will use this extra space for the saved_cmdline portion.
Now, instead of saving only 128 comms by default, by using this wasted space at the end of the structure it can save over 8000 comms and even saves space by removing the need for allocating the other array.
--- kernel/trace/trace.c | 75 +++++++++++++++++++++++++-------------------------- 1 file changed, 37 insertions(+), 38 deletions(-)
kernel/trace/trace.c +37 -38
@@ -2312,7 +2312,7 @@ struct saved_cmdlines_buffer {unsigned *map_cmdline_to_pid;unsigned cmdline_num;int cmdline_idx; -char *saved_cmdlines; +char saved_cmdlines[]; };static struct saved_cmdlines_buffer *savedcmd;
@@ -2326,47 +2326,58 @@ static inline void set_cmdline(int idx,strncpy (get_saved_cmdlines (idx), cmdline,TASK_COMM_LEN ); } -static int allocate_cmdlines_buffer (unsigned int val, -struct saved_cmdlines_buffer *s) +static void free_saved_cmdlines_buffer (struct saved_cmdlines_buffer *s) { +int order =get_order (sizeof (*s) + s->cmdline_num *TASK_COMM_LEN ); + +kfree (s->map_cmdline_to_pid); +free_pages ((unsigned long )s, order); +} + +static struct saved_cmdlines_buffer *allocate_cmdlines_buffer (unsigned int val) +{ +struct saved_cmdlines_buffer *s; +struct page *page; +int orig_size, size; +int order; + +/* Figure out how much is needed to hold the given number of cmdlines */ + orig_size =sizeof (*s) + val *TASK_COMM_LEN ; + order =get_order (orig_size); + size =1 << (order +PAGE_SHIFT ); + page =alloc_pages (GFP_KERNEL , order); +if (!page) +return NULL ; + + s =page_address (page); +memset (s,0 ,sizeof (*s)); + +/* Round up to actual allocation */ + val = (size -sizeof (*s)) /TASK_COMM_LEN ; + s->cmdline_num = val; + s->map_cmdline_to_pid =kmalloc_array (val,sizeof (*s->map_cmdline_to_pid),GFP_KERNEL ); -if (!s->map_cmdline_to_pid) -return -ENOMEM ; - - s->saved_cmdlines =kmalloc_array (TASK_COMM_LEN , val,GFP_KERNEL ); -if (!s->saved_cmdlines) { -kfree (s->map_cmdline_to_pid); -return -ENOMEM ; +if (!s->map_cmdline_to_pid) { +free_saved_cmdlines_buffer (s); +return NULL ; } s->cmdline_idx =0 ; - s->cmdline_num = val;memset (&s->map_pid_to_cmdline,NO_CMDLINE_MAP ,sizeof (s->map_pid_to_cmdline));memset (s->map_cmdline_to_pid,NO_CMDLINE_MAP , val *sizeof (*s->map_cmdline_to_pid)); -return 0 ; +return s; }static int trace_create_savedcmd (void ) { -int ret; - - savedcmd =kmalloc (sizeof (*savedcmd),GFP_KERNEL ); -if (!savedcmd) -return -ENOMEM ; + savedcmd =allocate_cmdlines_buffer (SAVED_CMDLINES_DEFAULT ); - ret =allocate_cmdlines_buffer (SAVED_CMDLINES_DEFAULT , savedcmd); -if (ret <0 ) { -kfree (savedcmd); - savedcmd =NULL ; -return -ENOMEM ; - } - -return 0 ; +return savedcmd ?0 : -ENOMEM ; }int is_tracing_stopped (void )
@@ -6048,26 +6059,14 @@ tracing_saved_cmdlines_size_read(structreturn simple_read_from_buffer (ubuf, cnt, ppos, buf, r); } -static void free_saved_cmdlines_buffer (struct saved_cmdlines_buffer *s) -{ -kfree (s->saved_cmdlines); -kfree (s->map_cmdline_to_pid); -kfree (s); -} -static int tracing_resize_saved_cmdlines (unsigned int val) {struct saved_cmdlines_buffer *s, *savedcmd_temp; - s =kmalloc (sizeof (*s),GFP_KERNEL ); + s =allocate_cmdlines_buffer (val);if (!s)return -ENOMEM ; -if (allocate_cmdlines_buffer (val, s) <0 ) { -kfree (s); -return -ENOMEM ; - } -preempt_disable ();arch_spin_lock (&trace_cmdline_lock); savedcmd_temp = savedcmd;
Greg Kroah-Hartman
maintainerPATCH 163/309 tracing/synthetic: Fix trace_string() return value
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thorsten Blum <[email protected]>
commit 9b6326354cf9a41521b79287da3bfab022ae0b6d upstream.
Fix trace_string() by assigning the string length to the return variable which got lost in commit ddeea494a16f ("tracing/synthetic: Use union instead of casts") and caused trace_string() to always return 0.
--- kernel/trace/trace_events_synth.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
kernel/trace/trace_events_synth.c +2 -1
@@ -441,8 +441,9 @@ static unsigned int trace_string(structif (is_dynamic) {union trace_synth_field *data = &entry->fields[*n_u64]; + len =fetch_store_strlen ((unsigned long )str_val); data->as_dynamic.offset =struct_size (entry, fields, event->n_u64) + data_size; - data->as_dynamic.len =fetch_store_strlen ((unsigned long )str_val); + data->as_dynamic.len = len; ret =fetch_store_string ((unsigned long )str_val, &entry->fields[*n_u64], entry);
Greg Kroah-Hartman
maintainerPATCH 164/309 tracing/probes: Fix to show a parse error for bad type for $comm
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Masami Hiramatsu (Google) <[email protected]>
commit 8c427cc2fa73684ea140999e121b7b6c1c717632 upstream.
Fix to show a parse error for bad type (non-string) for $comm/$COMM and immediate-string. With this fix, error_log file shows appropriate error message as below.
/sys/kernel/tracing # echo 'p vfs_read $comm:u32' >> kprobe_events
sh: write error: Invalid argument
/sys/kernel/tracing # echo 'p vfs_read \"hoge":u32' >> kprobe_events
sh: write error: Invalid argument
/sys/kernel/tracing # cat error_log
[ 30.144183] trace_kprobe: error: $comm and immediate-string only accepts string type
Command: p vfs_read $comm:u32
^
[ 62.618500] trace_kprobe: error: $comm and immediate-string only accepts string type
Command: p vfs_read \"hoge":u32
^--- kernel/trace/trace_probe.c | 7 +++++-- kernel/trace/trace_probe.h | 3 ++- 2 files changed, 7 insertions(+), 3 deletions(-)
kernel/trace/trace_probe.c +5 -2
@@ -1159,9 +1159,12 @@ static int traceprobe_parse_probe_arg_boif (!(ctx->flags &TPARG_FL_TEVENT ) && (strcmp (arg,"$comm" ) ==0 ||strcmp (arg,"$COMM" ) ==0 ||strncmp (arg,"\\\"" ,2 ) ==0 )) { -/* The type of $comm must be "string", and not an array. */ -if (parg->count || (t &&strcmp (t,"string" ))) +/* The type of $comm must be "string", and not an array type. */ +if (parg->count || (t &&strcmp (t,"string" ))) { +trace_probe_log_err (ctx->offset + (t ? (t - arg) :0 ), +NEED_STRING_TYPE ); goto out; + } parg->type =find_fetch_type ("string" , ctx->flags); }else parg->type =find_fetch_type (t, ctx->flags);
kernel/trace/trace_probe.h +2 -1
@@ -515,7 +515,8 @@ extern int traceprobe_define_arg_fields(C (BAD_HYPHEN ,"Failed to parse single hyphen. Forgot '>'?" ), \C (NO_BTF_FIELD ,"This field is not found." ), \C (BAD_BTF_TID ,"Failed to get BTF type info." ),\ -C (BAD_TYPE4STR ,"This type does not fit for string." ), +C (BAD_TYPE4STR ,"This type does not fit for string." ),\ +C (NEED_STRING_TYPE ,"$comm and immediate-string only accepts string type" ), #undef C #define C(a, b) TP_ERR_##a
Greg Kroah-Hartman
maintainerPATCH 165/309 tracing/probes: Fix to set arg size and fmt after setting type from BTF
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Masami Hiramatsu (Google) <[email protected]>
commit 9a571c1e275cedacd48c66a6bddd0c23f1dffdbf upstream.
Since the BTF type setting updates probe_arg::type, the type size calculation and setting print-fmt should be done after that. Without this fix, the argument size and print-fmt can be wrong.
--- kernel/trace/trace_probe.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-)
kernel/trace/trace_probe.c +13 -12
@@ -1172,18 +1172,6 @@ static int traceprobe_parse_probe_arg_botrace_probe_log_err (ctx->offset + (t ? (t - arg) :0 ),BAD_TYPE ); goto out; } - parg->offset = *size; - *size += parg->type->size * (parg->count ?:1 ); - - ret = -ENOMEM ; -if (parg->count) { - len =strlen (parg->type->fmttype) +6 ; - parg->fmt =kmalloc (len,GFP_KERNEL ); -if (!parg->fmt) - goto out; -snprintf (parg->fmt, len,"%s[%d]" , parg->type->fmttype, - parg->count); - } code = tmp =kcalloc (FETCH_INSN_MAX ,sizeof (*code),GFP_KERNEL );if (!code)
@@ -1207,6 +1195,19 @@ static int traceprobe_parse_probe_arg_bo goto fail; } } + parg->offset = *size; + *size += parg->type->size * (parg->count ?:1 ); + +if (parg->count) { + len =strlen (parg->type->fmttype) +6 ; + parg->fmt =kmalloc (len,GFP_KERNEL ); +if (!parg->fmt) { + ret = -ENOMEM ; + goto out; + } +snprintf (parg->fmt, len,"%s[%d]" , parg->type->fmttype, + parg->count); + } ret = -EINVAL ;/* Store operation */
Greg Kroah-Hartman
maintainerPATCH 166/309 tracing/probes: Fix to search structure fields correctly
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Masami Hiramatsu (Google) <[email protected]>
commit 9704669c386f9bbfef2e002e7e690c56b7dcf5de upstream.
Fix to search a field from the structure which has anonymous union correctly.
Since the reference type pointer was updated in the loop, the search loop suddenly aborted where it hits an anonymous union. Thus it can not find the field after the anonymous union. This avoids updating the cursor type pointer in the loop.
--- kernel/trace/trace_btf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/trace/trace_btf.c +2 -2
@@ -91,8 +91,8 @@ const struct btf_member *btf_find_struct_member(struct btf *btf,for_each_member (i, type, member) {if (!member->name_off) {/* Anonymous union/struct: push it for later use */ - type =btf_type_skip_modifiers (btf, member->type, &tid); -if (type && top <BTF_ANON_STACK_MAX ) { +if (btf_type_skip_modifiers (btf, member->type, &tid) && + top <BTF_ANON_STACK_MAX ) { anon_stack[top].tid = tid; anon_stack[top++].offset = cur_offset + member->offset;
Signature · 1 line
2.43.2
Greg Kroah-Hartman
maintainerPATCH 167/309 Revert "workqueue: Override implicit ordered attribute in workqueue_apply_unbound_cpumask()"
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tejun Heo <[email protected]>
commit aac8a59537dfc704ff344f1aacfd143c089ee20f upstream.
This reverts commit ca10d851b9ad0338c19e8e3089e24d565ebfffd7.
The commit allowed workqueue_apply_unbound_cpumask() to clear __WQ_ORDERED on now removed implicitly ordered workqueues. This was incorrect in that system-wide config change shouldn't break ordering properties of all workqueues. The reason why apply_workqueue_attrs() path was allowed to do so was because it was targeting the specific workqueue - either the workqueue had WQ_SYSFS set or the workqueue user specifically tried to change max_active, both of which indicate that the workqueue doesn't need to be ordered.
The implicitly ordered workqueue promotion was removed by the previous commit 3bc1e711c26b ("workqueue: Don't implicitly make UNBOUND workqueues w/ @max_active==1 ordered"). However, it didn't update this path and broke build. Let's revert the commit which was incorrect in the first place which also fixes build.
--- kernel/workqueue.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-)
kernel/workqueue.c +2 -6
@@ -5793,13 +5793,9 @@ static int workqueue_apply_unbound_cpumalist_for_each_entry (wq, &workqueues, list) {if (!(wq->flags &WQ_UNBOUND ))continue ; -/* creating multiple pwqs breaks ordering guarantee */ -if (!list_empty (&wq->pwqs)) { -if (wq->flags & __WQ_ORDERED_EXPLICIT) -continue ; - wq->flags &= ~__WQ_ORDERED; - } +if (wq->flags & __WQ_ORDERED) +continue ; ctx =apply_wqattrs_prepare (wq, wq->unbound_attrs, unbound_cpumask);if (IS_ERR (ctx)) {
Greg Kroah-Hartman
maintainerPATCH 168/309 staging: iio: ad5933: fix type mismatch regression
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Schiller <[email protected]>
commit 6db053cd949fcd6254cea9f2cd5d39f7bd64379c upstream.
Commit 4c3577db3e4f ("Staging: iio: impedance-analyzer: Fix sparse warning") fixed a compiler warning, but introduced a bug that resulted in one of the two 16 bit IIO channels always being zero (when both are enabled).
This is because int is 32 bits wide on most architectures and in the case of a little-endian machine the two most significant bytes would occupy the buffer for the second channel as 'val' is being passed as a void pointer to 'iio_push_to_buffers()'.
Fix by defining 'val' as u16. Tested working on ARM64.
--- drivers/staging/iio/impedance-analyzer/ad5933.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/staging/iio/impedance-analyzer/ad5933.c +1 -1
@@ -608,7 +608,7 @@ static void ad5933_work(struct work_stru struct ad5933_state, work.work);struct iio_dev *indio_dev =i2c_get_clientdata (st->client);__be16 buf[2 ]; -int val[2 ]; +u16 val[2 ];unsigned char status;int ret;
Greg Kroah-Hartman
maintainerPATCH 169/309 iio: magnetometer: rm3100: add boundary check for the value read from RM3100_REG_TMRC
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: zhili.liu <[email protected]>
commit 792595bab4925aa06532a14dd256db523eb4fa5e upstream.
Recently, we encounter kernel crash in function rm3100_common_probe caused by out of bound access of array rm3100_samp_rates (because of underlying hardware failures). Add boundary check to prevent out of bound access.
--- drivers/iio/magnetometer/rm3100-core.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
drivers/iio/magnetometer/rm3100-core.c +8 -2
@@ -530,6 +530,7 @@ int rm3100_common_probe(struct device *dstruct rm3100_data *data;unsigned int tmp;int ret; +int samp_rate_index; indio_dev =devm_iio_device_alloc (dev,sizeof (*data));if (!indio_dev)
@@ -586,9 +587,14 @@ int rm3100_common_probe(struct device *d ret =regmap_read (regmap,RM3100_REG_TMRC , &tmp);if (ret <0 )return ret; + + samp_rate_index = tmp -RM3100_TMRC_OFFSET ; +if (samp_rate_index <0 || samp_rate_index >=RM3100_SAMP_NUM ) { +dev_err (dev,"The value read from RM3100_REG_TMRC is invalid!\n" ); +return -EINVAL ; + }/* Initializing max wait time, which is double conversion time. */ - data->conversion_time = rm3100_samp_rates[tmp -RM3100_TMRC_OFFSET ][2 ] - *2 ; + data->conversion_time = rm3100_samp_rates[samp_rate_index][2 ] *2 ;/* Cycle count values may not be what we want. */ if ((tmp -RM3100_TMRC_OFFSET ) ==0 )
Greg Kroah-Hartman
maintainerPATCH 170/309 iio: core: fix memleak in iio_device_register_sysfs
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dinghao Liu <[email protected]>
commit 95a0d596bbd0552a78e13ced43f2be1038883c81 upstream.
When iio_device_register_sysfs_group() fails, we should free iio_dev_opaque->chan_attr_group.attrs to prevent potential memleak.
--- drivers/iio/industrialio-core.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/iio/industrialio-core.c +4 -1
@@ -1581,10 +1581,13 @@ static int iio_device_register_sysfs(str ret =iio_device_register_sysfs_group (indio_dev, &iio_dev_opaque->chan_attr_group);if (ret) - goto error_clear_attrs; + goto error_free_chan_attrs;return 0 ; +error_free_chan_attrs: +kfree (iio_dev_opaque->chan_attr_group.attrs); + iio_dev_opaque->chan_attr_group.attrs =NULL ; error_clear_attrs:iio_free_chan_devattr_list (&iio_dev_opaque->channel_attr_list);
Greg Kroah-Hartman
maintainerPATCH 171/309 iio: commom: st_sensors: ensure proper DMA alignment
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nuno Sa <[email protected]>
commit 862cf85fef85becc55a173387527adb4f076fab0 upstream.
Aligning the buffer to the L1 cache is not sufficient in some platforms as they might have larger cacheline sizes for caches after L1 and thus, we can't guarantee DMA safety.
That was the whole reason to introduce IIO_DMA_MINALIGN in [1]. Do the same for st_sensors common buffer.
While at it, moved the odr_lock before buffer_data as we definitely don't want any other data to share a cacheline with the buffer.
[1]: https://lore.kernel.org/linux-iio/[email protected]/
--- include/linux/iio/common/st_sensors.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
include/linux/iio/common/st_sensors.h +2 -2
@@ -258,9 +258,9 @@ struct st_sensor_data {bool hw_irq_trigger;s64 hw_timestamp; -char buffer_data[ST_SENSORS_MAX_BUFFER_SIZE ]____cacheline_aligned ; -struct mutex odr_lock; + +char buffer_data[ST_SENSORS_MAX_BUFFER_SIZE ]__aligned(IIO_DMA_MINALIGN) ; };#ifdef CONFIG_IIO_BUFFER
Greg Kroah-Hartman
maintainerPATCH 172/309 iio: accel: bma400: Fix a compilation problem
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mario Limonciello <[email protected]>
commit 4cb81840d8f29b66d9d05c6d7f360c9560f7e2f4 upstream.
The kernel fails when compiling without CONFIG_REGMAP_I2C but with CONFIG_BMA400.
``` ld: drivers/iio/accel/bma400_i2c.o: in function `bma400_i2c_probe': bma400_i2c.c:(.text+0x23): undefined reference to `__devm_regmap_init_i2c' ```
--- drivers/iio/accel/Kconfig | 2 ++ 1 file changed, 2 insertions(+)
drivers/iio/accel/Kconfig +2 -0
@@ -219,10 +219,12 @@ config BMA400 config BMA400_I2C tristate + select REGMAP_I2C depends on BMA400 config BMA400_SPI tristate + select REGMAP_SPI depends on BMA400 config BMC150_ACCEL
Greg Kroah-Hartman
maintainerPATCH 173/309 iio: adc: ad_sigma_delta: ensure proper DMA alignment
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nuno Sa <[email protected]>
commit 59598510be1d49e1cff7fd7593293bb8e1b2398b upstream.
Aligning the buffer to the L1 cache is not sufficient in some platforms as they might have larger cacheline sizes for caches after L1 and thus, we can't guarantee DMA safety.
That was the whole reason to introduce IIO_DMA_MINALIGN in [1]. Do the same for the sigma_delta ADCs.
[1]: https://lore.kernel.org/linux-iio/[email protected]/
--- include/linux/iio/adc/ad_sigma_delta.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
include/linux/iio/adc/ad_sigma_delta.h +3 -1
@@ -8,6 +8,8 @@#ifndef __AD_SIGMA_DELTA_H__#define __AD_SIGMA_DELTA_H__ +#include <linux/iio/iio.h> +enum ad_sigma_delta_mode {AD_SD_MODE_CONTINUOUS =0 , AD_SD_MODE_SINGLE = 1,
@@ -99,7 +101,7 @@ struct ad_sigma_delta {* 'rx_buf' is up to 32 bits per sample + 64 bit timestamp, * rounded to 16 bytes to take into account padding. */ -uint8_t tx_buf[4 ]____cacheline_aligned ; +uint8_t tx_buf[4 ]__aligned(IIO_DMA_MINALIGN) ;uint8_t rx_buf[16 ]__aligned(8) ; };
Greg Kroah-Hartman
maintainerPATCH 174/309 iio: imu: adis: ensure proper DMA alignment
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nuno Sa <[email protected]>
commit 8e98b87f515d8c4bae521048a037b2cc431c3fd5 upstream.
Aligning the buffer to the L1 cache is not sufficient in some platforms as they might have larger cacheline sizes for caches after L1 and thus, we can't guarantee DMA safety.
That was the whole reason to introduce IIO_DMA_MINALIGN in [1]. Do the same for the sigma_delta ADCs.
[1]: https://lore.kernel.org/linux-iio/[email protected]/
--- include/linux/iio/imu/adis.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
include/linux/iio/imu/adis.h +2 -1
@@ -11,6 +11,7 @@#include <linux/spi/spi.h> #include <linux/interrupt.h> +#include <linux/iio/iio.h> #include <linux/iio/types.h> #define ADIS_WRITE_REG (reg) ((0x80 | (reg)))
@@ -131,7 +132,7 @@ struct adis {unsigned long irq_flag;void *buffer; -u8 tx[10 ]____cacheline_aligned ; +u8 tx[10 ]__aligned(IIO_DMA_MINALIGN) ;u8 rx[4 ]; };
Greg Kroah-Hartman
maintainerPATCH 175/309 iio: imu: bno055: serdev requires REGMAP
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Randy Dunlap <[email protected]>
commit 35ec2d03b282a939949090bd8c39eb37a5856721 upstream.
There are a ton of build errors when REGMAP is not set, so select REGMAP to fix all of them.
Examples (not all of them):
../drivers/iio/imu/bno055/bno055_ser_core.c:495:15: error: variable 'bno055_ser_regmap_bus' has initializer but incomplete type
495 | static struct regmap_bus bno055_ser_regmap_bus = {../drivers/iio/imu/bno055/bno055_ser_core.c:496:10: error: 'struct regmap_bus' has no member named 'write'
496 | .write = bno055_ser_write_reg,../drivers/iio/imu/bno055/bno055_ser_core.c:497:10: error: 'struct regmap_bus' has no member named 'read'
497 | .read = bno055_ser_read_reg,../drivers/iio/imu/bno055/bno055_ser_core.c: In function 'bno055_ser_probe':../drivers/iio/imu/bno055/bno055_ser_core.c:532:18: error: implicit declaration of function 'devm_regmap_init'; did you mean 'vmem_map_init'? [-Werror=implicit-function-declaration]
532 | regmap = devm_regmap_init(&serdev->dev, &bno055_ser_regmap_bus,../drivers/iio/imu/bno055/bno055_ser_core.c:532:16: warning: assignment to 'struct regmap *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
532 | regmap = devm_regmap_init(&serdev->dev, &bno055_ser_regmap_bus,../drivers/iio/imu/bno055/bno055_ser_core.c: At top level:../drivers/iio/imu/bno055/bno055_ser_core.c:495:26: error: storage size of 'bno055_ser_regmap_bus' isn't known
495 | static struct regmap_bus bno055_ser_regmap_bus = {
--- drivers/iio/imu/bno055/Kconfig | 1 + 1 file changed, 1 insertion(+)
drivers/iio/imu/bno055/Kconfig +1 -0
@@ -8,6 +8,7 @@ config BOSCH_BNO055 config BOSCH_BNO055_SERIAL tristate "Bosch BNO055 attached via UART" depends on SERIAL_DEV_BUS + select REGMAP select BOSCH_BNO055 help Enable this to support Bosch BNO055 IMUs attached via UART.
Greg Kroah-Hartman
maintainerPATCH 176/309 iio: pressure: bmp280: Add missing bmp085 to SPI id table
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sam Protsenko <[email protected]>
commit b67f3e653e305abf1471934d7b9fdb9ad2df3eef upstream.
"bmp085" is missing in bmp280_spi_id[] table, which leads to the next warning in dmesg:
SPI driver bmp280 has no spi_device_id for bosch,bmp085
Add "bmp085" to bmp280_spi_id[] by mimicking its existing description in bmp280_of_spi_match[] table to fix the above warning.
--- drivers/iio/pressure/bmp280-spi.c | 1 + 1 file changed, 1 insertion(+)
drivers/iio/pressure/bmp280-spi.c +1 -0
@@ -91,6 +91,7 @@ static const struct of_device_id bmp280_MODULE_DEVICE_TABLE (of, bmp280_of_spi_match);static const struct spi_device_id bmp280_spi_id[] = { + {"bmp085" , (kernel_ulong_t)&bmp180_chip_info }, {"bmp180" , (kernel_ulong_t)&bmp180_chip_info }, {"bmp181" , (kernel_ulong_t)&bmp180_chip_info }, {"bmp280" , (kernel_ulong_t)&bmp280_chip_info },
Greg Kroah-Hartman
maintainerPATCH 177/309 pmdomain: mediatek: fix race conditions with genpd
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eugen Hristev <[email protected]>
commit c41336f4d69057cbf88fed47951379b384540df5 upstream.
If the power domains are registered first with genpd and *after that* the driver attempts to power them on in the probe sequence, then it is possible that a race condition occurs if genpd tries to power them on in the same time.
The same is valid for powering them off before unregistering them from genpd.
Attempt to fix race conditions by first removing the domains from genpd and *after that* powering down domains.
Also first power up the domains and *after that* register them to genpd.
--- drivers/pmdomain/mediatek/mtk-pm-domains.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-)
drivers/pmdomain/mediatek/mtk-pm-domains.c +7 -8
@@ -561,6 +561,11 @@ static int scpsys_add_subdomain(struct s goto err_put_node; } +/* recursive call to add all subdomains */ + ret =scpsys_add_subdomain (scpsys, child); +if (ret) + goto err_put_node; + ret =pm_genpd_add_subdomain (parent_pd, child_pd);if (ret) { dev_err(scpsys->dev, "failed to add %s subdomain to parent %s\n",
@@ -570,11 +575,6 @@ static int scpsys_add_subdomain(struct sdev_dbg (scpsys->dev,"%s add subdomain: %s\n" , parent_pd->name, child_pd->name); } - -/* recursive call to add all subdomains */ - ret =scpsys_add_subdomain (scpsys, child); -if (ret) - goto err_put_node; }return 0 ;
@@ -588,9 +588,6 @@ static void scpsys_remove_one_domain(str {int ret; -if (scpsys_domain_is_on (pd)) -scpsys_power_off (&pd->genpd); -/* * We're in the error cleanup already, so we only complain, * but won't emit another error on top of the original one.
@@ -600,6 +597,8 @@ static void scpsys_remove_one_domain(strdev_err (pd->scpsys->dev,"failed to remove domain '%s' : %d - state may be inconsistent\n" , pd->genpd.name, ret); +if (scpsys_domain_is_on (pd)) +scpsys_power_off (&pd->genpd);clk_bulk_put (pd->num_clks, pd->clks);clk_bulk_put (pd->num_subsys_clks, pd->subsys_clks);
Greg Kroah-Hartman
maintainerPATCH 178/309 media: rc: bpf attach/detach requires write permission
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Young <[email protected]>
commit 6a9d552483d50953320b9d3b57abdee8d436f23f upstream.
Note that bpf attach/detach also requires CAP_NET_ADMIN.
--- drivers/media/rc/bpf-lirc.c | 6 +++--- drivers/media/rc/lirc_dev.c | 5 ++++- drivers/media/rc/rc-core-priv.h | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-)
drivers/media/rc/bpf-lirc.c +3 -3
@@ -253,7 +253,7 @@ int lirc_prog_attach(const union bpf_attif (attr->attach_flags)return -EINVAL ; - rcdev =rc_dev_get_from_fd (attr->target_fd); + rcdev =rc_dev_get_from_fd (attr->target_fd, true);if (IS_ERR (rcdev))return PTR_ERR (rcdev);
@@ -278,7 +278,7 @@ int lirc_prog_detach(const union bpf_attif (IS_ERR (prog))return PTR_ERR (prog); - rcdev =rc_dev_get_from_fd (attr->target_fd); + rcdev =rc_dev_get_from_fd (attr->target_fd, true);if (IS_ERR (rcdev)) {bpf_prog_put (prog);return PTR_ERR (rcdev);
@@ -303,7 +303,7 @@ int lirc_prog_query(const union bpf_attrif (attr->query.query_flags)return -EINVAL ; - rcdev =rc_dev_get_from_fd (attr->query.target_fd); + rcdev =rc_dev_get_from_fd (attr->query.target_fd, false);if (IS_ERR (rcdev))return PTR_ERR (rcdev);
drivers/media/rc/lirc_dev.c +4 -1
@@ -814,7 +814,7 @@ void __exit lirc_dev_exit(void)unregister_chrdev_region (lirc_base_dev,RC_DEV_MAX ); } -struct rc_dev *rc_dev_get_from_fd (int fd) +struct rc_dev *rc_dev_get_from_fd (int fd,bool write) {struct fd f =fdget (fd);struct lirc_fh *fh;
@@ -828,6 +828,9 @@ struct rc_dev *rc_dev_get_from_fd(int fdreturn ERR_PTR (-EINVAL ); } +if (write && !(f.file->f_mode &FMODE_WRITE )) +return ERR_PTR (-EPERM ); + fh = f.file->private_data; dev = fh->rc;
drivers/media/rc/rc-core-priv.h +1 -1
@@ -325,7 +325,7 @@ void lirc_raw_event(struct rc_dev *dev,void lirc_scancode_event (struct rc_dev *dev,struct lirc_scancode *lsc);int lirc_register (struct rc_dev *dev);void lirc_unregister (struct rc_dev *dev); -struct rc_dev *rc_dev_get_from_fd (int fd); +struct rc_dev *rc_dev_get_from_fd (int fd,bool write);#else static inline int lirc_dev_init (void ) {return 0 ; }static inline void lirc_dev_exit (void ) {}
Greg Kroah-Hartman
maintainerPATCH 179/309 eventfs: Remove "lookup" parameter from create_dir/file_dentry()
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Steven Rostedt (Google)" <[email protected]>
commit b0f7e2d739b4aac131ea1662d086a07775097b05 upstream.
The "lookup" parameter is a way to differentiate the call to create_file/dir_dentry() from when it's just a lookup (no need to up the dentry refcount) and accessed via a readdir (need to up the refcount).
But reality, it just makes the code more complex. Just up the refcount and let the caller decide to dput() the result or not.
--- fs/tracefs/event_inode.c | 55 +++++++++++++++++------------------------------ 1 file changed, 20 insertions(+), 35 deletions(-)
fs/tracefs/event_inode.c +20 -35
@@ -419,16 +419,14 @@ void eventfs_set_ei_status_free(struct t* @mode: The mode of the file. * @data: The data to use to set the inode of the file with on open() * @fops: The fops of the file to be created. -* @lookup: If called by the lookup routine, in which case, dput() the created dentry. * * Create a dentry for a file of an eventfs_inode @ei and place it into the -* address located at @e_dentry. If the @e_dentry already has a dentry, then -* just do a dget() on it and return. Otherwise create the dentry and attach it. +* address located at @e_dentry. */ static struct dentry *create_file_dentry (struct eventfs_inode *ei,int idx,struct dentry *parent,const char *name,umode_t mode,void *data, -const struct file_operations *fops,bool lookup) +const struct file_operations *fops) {struct eventfs_attr *attr =NULL ;struct dentry **e_dentry = &ei->d_children[idx];
@@ -443,9 +441,7 @@ create_file_dentry(struct eventfs_inode }/* If the e_dentry already has a dentry, use it */ if (*e_dentry) { -/* lookup does not need to up the ref count */ -if (!lookup) -dget (*e_dentry); +dget (*e_dentry);mutex_unlock (&eventfs_mutex);return *e_dentry; }
@@ -470,13 +466,12 @@ create_file_dentry(struct eventfs_inode* way to being freed, don't return it. If e_dentry is NULL * it means it was already freed. */ -if (ei->is_freed) +if (ei->is_freed) { dentry =NULL ; -else + }else { dentry = *e_dentry; -/* The lookup does not need to up the dentry refcount */ -if (dentry && !lookup)dget (dentry); + }mutex_unlock (&eventfs_mutex);return dentry; }
@@ -494,9 +489,6 @@ create_file_dentry(struct eventfs_inode }mutex_unlock (&eventfs_mutex); -if (lookup) -dput (dentry); -return dentry; }
@@ -529,13 +521,12 @@ static void eventfs_post_create_dir(stru* @pei: The eventfs_inode parent of ei. * @ei: The eventfs_inode to create the directory for * @parent: The dentry of the parent of this directory -* @lookup: True if this is called by the lookup code * * This creates and attaches a directory dentry to the eventfs_inode @ei. */ static struct dentry *create_dir_dentry (struct eventfs_inode *pei,struct eventfs_inode *ei, -struct dentry *parent,bool lookup) +struct dentry *parent) {struct dentry *dentry =NULL ;
@@ -547,11 +538,9 @@ create_dir_dentry(struct eventfs_inode *return NULL ; }if (ei->dentry) { -/* If the dentry already has a dentry, use it */ +/* If the eventfs_inode already has a dentry, use it */ dentry = ei->dentry; -/* lookup does not need to up the ref count */ -if (!lookup) -dget (dentry); +dget (dentry);mutex_unlock (&eventfs_mutex);return dentry; }
@@ -571,7 +560,7 @@ create_dir_dentry(struct eventfs_inode ** way to being freed. */ dentry = ei->dentry; -if (dentry && !lookup) +if (dentry)dget (dentry);mutex_unlock (&eventfs_mutex);return dentry;
@@ -591,9 +580,6 @@ create_dir_dentry(struct eventfs_inode * }mutex_unlock (&eventfs_mutex); -if (lookup) -dput (dentry); -return dentry; }
@@ -618,8 +604,8 @@ static struct dentry *eventfs_root_lookustruct eventfs_inode *ei;struct dentry *ei_dentry =NULL ;struct dentry *ret =NULL ; +struct dentry *d;const char *name = dentry->d_name.name; -bool created = false;umode_t mode;void *data;int idx;
@@ -655,13 +641,10 @@ static struct dentry *eventfs_root_looku ret =simple_lookup (dir, dentry, flags);if (IS_ERR (ret)) goto out; -create_dir_dentry (ei, ei_child, ei_dentry, true); - created = true; -break ; - } - -if (created) + d =create_dir_dentry (ei, ei_child, ei_dentry); +dput (d); goto out; + }for (i =0 ; i < ei->nr_entries; i++) { entry = &ei->entries[i];
@@ -679,8 +662,8 @@ static struct dentry *eventfs_root_looku ret =simple_lookup (dir, dentry, flags);if (IS_ERR (ret)) goto out; -create_file_dentry (ei, i, ei_dentry, name, mode, cdata, - fops, true); + d =create_file_dentry (ei, i, ei_dentry, name, mode, cdata, fops); +dput (d);break ; } }
@@ -797,9 +780,10 @@ static int dcache_dir_open_wrapper(strucinode_lock (parent->d_inode);list_for_each_entry_srcu (ei_child, &ei->children, list,srcu_read_lock_held (&eventfs_srcu)) { - d =create_dir_dentry (ei, ei_child, parent, false); + d =create_dir_dentry (ei, ei_child, parent);if (d) { ret =add_dentries (&dentries, d, cnt); +dput (d);if (ret <0 )break ; cnt++;
@@ -819,9 +803,10 @@ static int dcache_dir_open_wrapper(strucmutex_unlock (&eventfs_mutex);if (r <=0 )continue ; - d =create_file_dentry (ei, i, parent, name, mode, cdata, fops, false); + d =create_file_dentry (ei, i, parent, name, mode, cdata, fops);if (d) { ret =add_dentries (&dentries, d, cnt); +dput (d);if (ret <0 )break ; cnt++;
Greg Kroah-Hartman
maintainerPATCH 180/309 eventfs: Stop using dcache_readdir() for getdents()
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Steven Rostedt (Google)" <[email protected]>
commit 493ec81a8fb8e4ada6f223b8b73791a1280d4774 upstream.
The eventfs creates dynamically allocated dentries and inodes. Using the dcache_readdir() logic for its own directory lookups requires hiding the cursor of the dcache logic and playing games to allow the dcache_readdir() to still have access to the cursor while the eventfs saved what it created and what it needs to release.
Instead, just have eventfs have its own iterate_shared callback function that will fill in the dent entries. This simplifies the code quite a bit.
--- fs/tracefs/event_inode.c | 194 +++++++++++++++-------------------------------- 1 file changed, 64 insertions(+), 130 deletions(-)
fs/tracefs/event_inode.c +64 -130
@@ -53,9 +53,7 @@ enum {static struct dentry *eventfs_root_lookup (struct inode *dir,struct dentry *dentry,unsigned int flags); -static int dcache_dir_open_wrapper (struct inode *inode,struct file *file); -static int dcache_readdir_wrapper (struct file *file,struct dir_context *ctx); -static int eventfs_release (struct inode *inode,struct file *file); +static int eventfs_iterate (struct file *file,struct dir_context *ctx);static void update_attr (struct eventfs_attr *attr,struct iattr *iattr) {
@@ -213,11 +211,9 @@ static const struct inode_operations eve };static const struct file_operations eventfs_file_operations = { - .open = dcache_dir_open_wrapper, .read = generic_read_dir, - .iterate_shared = dcache_readdir_wrapper, + .iterate_shared = eventfs_iterate, .llseek = generic_file_llseek, - .release = eventfs_release, };/* Return the evenfs_inode of the "events" directory */
@@ -672,128 +668,87 @@ static struct dentry *eventfs_root_lookureturn ret; } -struct dentry_list { -void *cursor; -struct dentry **dentries; -}; - -/** -* eventfs_release - called to release eventfs file/dir -* @inode: inode to be released -* @file: file to be released (not used) -*/ -static int eventfs_release (struct inode *inode,struct file *file) -{ -struct tracefs_inode *ti; -struct dentry_list *dlist = file->private_data; -void *cursor; -int i; - - ti =get_tracefs (inode); -if (!(ti->flags &TRACEFS_EVENT_INODE )) -return -EINVAL ; - -if (WARN_ON_ONCE (!dlist)) -return -EINVAL ; - -for (i =0 ; dlist->dentries && dlist->dentries[i]; i++) { -dput (dlist->dentries[i]); - } - - cursor = dlist->cursor; -kfree (dlist->dentries); -kfree (dlist); - file->private_data = cursor; -return dcache_dir_close (inode, file); -} - -static int add_dentries (struct dentry ***dentries,struct dentry *d,int cnt) -{ -struct dentry **tmp; - - tmp =krealloc (*dentries,sizeof (d) * (cnt +2 ),GFP_NOFS ); -if (!tmp) -return -1 ; - tmp[cnt] = d; - tmp[cnt +1 ] =NULL ; - *dentries = tmp; -return 0 ; -} - -/** -* dcache_dir_open_wrapper - eventfs open wrapper -* @inode: not used -* @file: dir to be opened (to create it's children) -* -* Used to dynamic create file/dir with-in @file, all the -* file/dir will be created. If already created then references -* will be increased +/* +* Walk the children of a eventfs_inode to fill in getdents(). */ -static int dcache_dir_open_wrapper (struct inode *inode,struct file *file) +static int eventfs_iterate (struct file *file,struct dir_context *ctx) {const struct file_operations *fops; +struct inode *f_inode =file_inode (file);const struct eventfs_entry *entry;struct eventfs_inode *ei_child;struct tracefs_inode *ti;struct eventfs_inode *ei; -struct dentry_list *dlist; -struct dentry **dentries =NULL ; -struct dentry *parent =file_dentry (file); -struct dentry *d; -struct inode *f_inode =file_inode (file); -const char *name = parent->d_name.name; +struct dentry *ei_dentry =NULL ; +struct dentry *dentry; +const char *name;umode_t mode; -void *data; -int cnt =0 ;int idx; -int ret; -int i; -int r; +int ret = -EINVAL ; +int ino; +int i, r, c; + +if (!dir_emit_dots (file, ctx)) +return 0 ; ti =get_tracefs (f_inode);if (!(ti->flags &TRACEFS_EVENT_INODE ))return -EINVAL ; -if (WARN_ON_ONCE (file->private_data)) -return -EINVAL ; + c = ctx->pos -2 ; idx =srcu_read_lock (&eventfs_srcu);mutex_lock (&eventfs_mutex); ei =READ_ONCE (ti->private); +if (ei && !ei->is_freed) + ei_dentry =READ_ONCE (ei->dentry);mutex_unlock (&eventfs_mutex); -if (!ei) { -srcu_read_unlock (&eventfs_srcu, idx); -return -EINVAL ; - } - - - data = ei->data; +if (!ei || !ei_dentry) + goto out; - dlist =kmalloc (sizeof (*dlist),GFP_KERNEL ); -if (!dlist) { -srcu_read_unlock (&eventfs_srcu, idx); -return -ENOMEM ; - } + ret =0 ; -inode_lock (parent->d_inode); +/* +* Need to create the dentries and inodes to have a consistent +* inode number. +*/ list_for_each_entry_srcu (ei_child, &ei->children, list,srcu_read_lock_held (&eventfs_srcu)) { - d =create_dir_dentry (ei, ei_child, parent); -if (d) { - ret =add_dentries (&dentries, d, cnt); -dput (d); -if (ret <0 ) -break ; - cnt++; + +if (c >0 ) { + c--; +continue ; } + +if (ei_child->is_freed) +continue ; + + name = ei_child->name; + + dentry =create_dir_dentry (ei, ei_child, ei_dentry); +if (!dentry) + goto out; + ino = dentry->d_inode->i_ino; +dput (dentry); + +if (!dir_emit (ctx, name,strlen (name), ino,DT_DIR )) + goto out; + ctx->pos++; }for (i =0 ; i < ei->nr_entries; i++) { -void *cdata = data; +void *cdata = ei->data; + +if (c >0 ) { + c--; +continue ; + } + entry = &ei->entries[i]; name = entry->name; +mutex_lock (&eventfs_mutex);/* If ei->is_freed, then the event itself may be too */ if (!ei->is_freed)
@@ -803,42 +758,21 @@ static int dcache_dir_open_wrapper(strucmutex_unlock (&eventfs_mutex);if (r <=0 )continue ; - d =create_file_dentry (ei, i, parent, name, mode, cdata, fops); -if (d) { - ret =add_dentries (&dentries, d, cnt); -dput (d); -if (ret <0 ) -break ; - cnt++; - } - } -inode_unlock (parent->d_inode); -srcu_read_unlock (&eventfs_srcu, idx); - ret =dcache_dir_open (inode, file); -/* -* dcache_dir_open() sets file->private_data to a dentry cursor. -* Need to save that but also save all the dentries that were -* opened by this function. -*/ - dlist->cursor = file->private_data; - dlist->dentries = dentries; - file->private_data = dlist; -return ret; -} + dentry =create_file_dentry (ei, i, ei_dentry, name, mode, cdata, fops); +if (!dentry) + goto out; + ino = dentry->d_inode->i_ino; +dput (dentry); -/* -* This just sets the file->private_data back to the cursor and back. -*/ -static int dcache_readdir_wrapper (struct file *file,struct dir_context *ctx) -{ -struct dentry_list *dlist = file->private_data; -int ret; +if (!dir_emit (ctx, name,strlen (name), ino,DT_REG )) + goto out; + ctx->pos++; + } + ret =1 ; + out: +srcu_read_unlock (&eventfs_srcu, idx); - file->private_data = dlist->cursor; - ret =dcache_readdir (file, ctx); - dlist->cursor = file->private_data; - file->private_data = dlist;return ret; }
Greg Kroah-Hartman
maintainerPATCH 181/309 eventfs: Have eventfs_iterate() stop immediately if ei->is_freed is set
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Steven Rostedt (Google)" <[email protected]>
commit e109deadb73318cf4a3bd61287d969f705df278f upstream.
If ei->is_freed is set in eventfs_iterate(), it means that the directory that is being iterated on is in the process of being freed. Just exit the loop immediately when that is ever detected, and separate out the return of the entry->callback() from ei->is_freed.
--- fs/tracefs/event_inode.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
fs/tracefs/event_inode.c +6 -5
@@ -750,11 +750,12 @@ static int eventfs_iterate(struct file * name = entry->name;mutex_lock (&eventfs_mutex); -/* If ei->is_freed, then the event itself may be too */ -if (!ei->is_freed) - r = entry->callback (name, &mode, &cdata, &fops); -else - r =-1 ; +/* If ei->is_freed then just bail here, nothing more to do */ +if (ei->is_freed) { +mutex_unlock (&eventfs_mutex); + goto out; + } + r = entry->callback (name, &mode, &cdata, &fops);mutex_unlock (&eventfs_mutex);if (r <=0 )continue ;
Greg Kroah-Hartman
maintainerPATCH 182/309 eventfs: Do ctx->pos update for all iterations in eventfs_iterate()
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Steven Rostedt (Google)" <[email protected]>
commit 1e4624eb5a0ecaae0d2c4e3019bece119725bb98 upstream.
The ctx->pos was only updated when it added an entry, but the "skip to current pos" check (c--) happened for every loop regardless of if the entry was added or not. This inconsistency caused readdir to be incorrect.
It was due to:
for (i = 0; i < ei->nr_entries; i++) {
if (c > 0) {
c--;
continue;
}
mutex_lock(&eventfs_mutex);
/* If ei->is_freed then just bail here, nothing more to do */
if (ei->is_freed) {
mutex_unlock(&eventfs_mutex);
goto out;
}
r = entry->callback(name, &mode, &cdata, &fops);
mutex_unlock(&eventfs_mutex);
[..]
ctx->pos++;
}But this can cause the iterator to return a file that was already read. That's because of the way the callback() works. Some events may not have all files, and the callback can return 0 to tell eventfs to skip the file for this directory.
for instance, we have:
# ls /sys/kernel/tracing/events/ftrace/function format hist hist_debug id inject
and
# ls /sys/kernel/tracing/events/sched/sched_switch/ enable filter format hist hist_debug id inject trigger
Where the function directory is missing "enable", "filter" and "trigger". That's because the callback() for events has:
static int event_callback(const char *name, umode_t *mode, void **data,
const struct file_operations **fops)
{
struct trace_event_file *file = *data;
struct trace_event_call *call = file->event_call;[..]
/*
* Only event directories that can be enabled should have
* triggers or filters, with the exception of the "print"
* event that can have a "trigger" file.
*/
if (!(call->flags & TRACE_EVENT_FL_IGNORE_ENABLE)) {
if (call->class->reg && strcmp(name, "enable") == 0) {
*mode = TRACE_MODE_WRITE;
*fops = &ftrace_enable_fops;
return 1;
}
if (strcmp(name, "filter") == 0) {
*mode = TRACE_MODE_WRITE;
*fops = &ftrace_event_filter_fops;
return 1;
}
}
if (!(call->flags & TRACE_EVENT_FL_IGNORE_ENABLE) ||
strcmp(trace_event_name(call), "print") == 0) {
if (strcmp(name, "trigger") == 0) {
*mode = TRACE_MODE_WRITE;
*fops = &event_trigger_fops;
return 1;
}
}
[..]
return 0;
}Where the function event has the TRACE_EVENT_FL_IGNORE_ENABLE set.
This means that the entries array elements for "enable", "filter" and "trigger" when called on the function event will have the callback return 0 and not 1, to tell eventfs to skip these files for it.
Because the "skip to current ctx->pos" check happened for all entries, but the ctx->pos++ only happened to entries that exist, it would confuse the reading of a directory. Which would cause:
# ls /sys/kernel/tracing/events/ftrace/function/ format hist hist hist_debug hist_debug id inject inject
The missing "enable", "filter" and "trigger" caused ls to show "hist", "hist_debug" and "inject" twice.
Update the ctx->pos for every iteration to keep its update and the "skip" update consistent. This also means that on error, the ctx->pos needs to be decremented if it was incremented without adding something.
--- fs/tracefs/event_inode.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-)
fs/tracefs/event_inode.c +14 -7
@@ -722,6 +722,8 @@ static int eventfs_iterate(struct file *continue ; } + ctx->pos++; +if (ei_child->is_freed)continue ;
@@ -729,13 +731,12 @@ static int eventfs_iterate(struct file * dentry =create_dir_dentry (ei, ei_child, ei_dentry);if (!dentry) - goto out; + goto out_dec; ino = dentry->d_inode->i_ino;dput (dentry);if (!dir_emit (ctx, name,strlen (name), ino,DT_DIR )) - goto out; - ctx->pos++; + goto out_dec; }for (i =0 ; i < ei->nr_entries; i++) {
@@ -746,6 +747,8 @@ static int eventfs_iterate(struct file *continue ; } + ctx->pos++; + entry = &ei->entries[i]; name = entry->name;
@@ -753,7 +756,7 @@ static int eventfs_iterate(struct file */* If ei->is_freed then just bail here, nothing more to do */ if (ei->is_freed) {mutex_unlock (&eventfs_mutex); - goto out; + goto out_dec; } r = entry->callback (name, &mode, &cdata, &fops);mutex_unlock (&eventfs_mutex);
@@ -762,19 +765,23 @@ static int eventfs_iterate(struct file * dentry =create_file_dentry (ei, i, ei_dentry, name, mode, cdata, fops);if (!dentry) - goto out; + goto out_dec; ino = dentry->d_inode->i_ino;dput (dentry);if (!dir_emit (ctx, name,strlen (name), ino,DT_REG )) - goto out; - ctx->pos++; + goto out_dec; } ret =1 ; out:srcu_read_unlock (&eventfs_srcu, idx);return ret; + + out_dec: +/* Incremented ctx->pos without adding something, reset it */ + ctx->pos--; + goto out; }/**
Greg Kroah-Hartman
maintainerPATCH 183/309 eventfs: Read ei->entries before ei->children in eventfs_iterate()
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Steven Rostedt (Google)" <[email protected]>
commit 704f960dbee2f1634f4b4e16f208cb16eaf41c1e upstream.
In order to apply a shortcut to skip over the current ctx->pos immediately, by using the ei->entries array, the reading of that array should be first. Moving the array reading before the linked list reading will make the shortcut change diff nicer to read.
--- fs/tracefs/event_inode.c | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-)
fs/tracefs/event_inode.c +23 -23
@@ -714,8 +714,8 @@ static int eventfs_iterate(struct file ** Need to create the dentries and inodes to have a consistent * inode number. */ -list_for_each_entry_srcu (ei_child, &ei->children, list, -srcu_read_lock_held (&eventfs_srcu)) { +for (i =0 ; i < ei->nr_entries; i++) { +void *cdata = ei->data;if (c >0 ) { c--;
@@ -724,23 +724,32 @@ static int eventfs_iterate(struct file * ctx->pos++; -if (ei_child->is_freed) -continue ; + entry = &ei->entries[i]; + name = entry->name; - name = ei_child->name; +mutex_lock (&eventfs_mutex); +/* If ei->is_freed then just bail here, nothing more to do */ +if (ei->is_freed) { +mutex_unlock (&eventfs_mutex); + goto out_dec; + } + r = entry->callback (name, &mode, &cdata, &fops); +mutex_unlock (&eventfs_mutex); +if (r <=0 ) +continue ; - dentry =create_dir_dentry (ei, ei_child, ei_dentry); + dentry =create_file_dentry (ei, i, ei_dentry, name, mode, cdata, fops);if (!dentry) goto out_dec; ino = dentry->d_inode->i_ino;dput (dentry); -if (!dir_emit (ctx, name,strlen (name), ino,DT_DIR )) +if (!dir_emit (ctx, name,strlen (name), ino,DT_REG )) goto out_dec; } -for (i =0 ; i < ei->nr_entries; i++) { -void *cdata = ei->data; +list_for_each_entry_srcu (ei_child, &ei->children, list, +srcu_read_lock_held (&eventfs_srcu)) {if (c >0 ) { c--;
@@ -749,27 +758,18 @@ static int eventfs_iterate(struct file * ctx->pos++; - entry = &ei->entries[i]; - name = entry->name; - -mutex_lock (&eventfs_mutex); -/* If ei->is_freed then just bail here, nothing more to do */ -if (ei->is_freed) { -mutex_unlock (&eventfs_mutex); - goto out_dec; - } - r = entry->callback (name, &mode, &cdata, &fops); -mutex_unlock (&eventfs_mutex); -if (r <=0 ) +if (ei_child->is_freed)continue ; - dentry =create_file_dentry (ei, i, ei_dentry, name, mode, cdata, fops); + name = ei_child->name; + + dentry =create_dir_dentry (ei, ei_child, ei_dentry);if (!dentry) goto out_dec; ino = dentry->d_inode->i_ino;dput (dentry); -if (!dir_emit (ctx, name,strlen (name), ino,DT_REG )) +if (!dir_emit (ctx, name,strlen (name), ino,DT_DIR )) goto out_dec; } ret =1 ;
Greg Kroah-Hartman
maintainerPATCH 184/309 eventfs: Shortcut eventfs_iterate() by skipping entries already read
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Steven Rostedt (Google)" <[email protected]>
commit 1de94b52d5e8d8b32f0252f14fad1f1edc2e71f1 upstream.
As the ei->entries array is fixed for the duration of the eventfs_inode, it can be used to skip over already read entries in eventfs_iterate().
That is, if ctx->pos is greater than zero, there's no reason in doing the loop across the ei->entries array for the entries less than ctx->pos. Instead, start the lookup of the entries at the current ctx->pos.
--- fs/tracefs/event_inode.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-)
fs/tracefs/event_inode.c +10 -13
@@ -708,21 +708,15 @@ static int eventfs_iterate(struct file *if (!ei || !ei_dentry) goto out; - ret =0 ; -/* * Need to create the dentries and inodes to have a consistent * inode number. */ -for (i =0 ; i < ei->nr_entries; i++) { -void *cdata = ei->data; - -if (c >0 ) { - c--; -continue ; - } + ret =0 ; - ctx->pos++; +/* Start at 'c' to jump over already read entries */ +for (i = c; i < ei->nr_entries; i++, ctx->pos++) { +void *cdata = ei->data; entry = &ei->entries[i]; name = entry->name;
@@ -731,7 +725,7 @@ static int eventfs_iterate(struct file */* If ei->is_freed then just bail here, nothing more to do */ if (ei->is_freed) {mutex_unlock (&eventfs_mutex); - goto out_dec; + goto out; } r = entry->callback (name, &mode, &cdata, &fops);mutex_unlock (&eventfs_mutex);
@@ -740,14 +734,17 @@ static int eventfs_iterate(struct file * dentry =create_file_dentry (ei, i, ei_dentry, name, mode, cdata, fops);if (!dentry) - goto out_dec; + goto out; ino = dentry->d_inode->i_ino;dput (dentry);if (!dir_emit (ctx, name,strlen (name), ino,DT_REG )) - goto out_dec; + goto out; } +/* Subtract the skipped entries above */ + c -=min ((unsigned int )c, (unsigned int )ei->nr_entries); +list_for_each_entry_srcu (ei_child, &ei->children, list,srcu_read_lock_held (&eventfs_srcu)) {
Greg Kroah-Hartman
maintainerPATCH 185/309 eventfs: Have the inodes all for files and directories all be the same
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Steven Rostedt (Google)" <[email protected]>
commit 53c41052ba3121761e6f62a813961164532a214f upstream.
The dentries and inodes are created in the readdir for the sole purpose of getting a consistent inode number. Linus stated that is unnecessary, and that all inodes can have the same inode number. For a virtual file system they are pretty meaningless.
Instead use a single unique inode number for all files and one for all directories.
--- fs/tracefs/event_inode.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
fs/tracefs/event_inode.c +10 -0
@@ -32,6 +32,10 @@*/ static DEFINE_MUTEX (eventfs_mutex); +/* Choose something "unique" ;-) */ +#define EVENTFS_FILE_INODE_INO 0x12c4e37 +#define EVENTFS_DIR_INODE_INO 0x134b2f5 +/* * The eventfs_inode (ei) itself is protected by SRCU. It is released from * its parent's list and will have is_freed set (under eventfs_mutex).
@@ -314,6 +318,9 @@ static struct dentry *create_file(const inode->i_fop = fop; inode->i_private = data; +/* All files will have the same inode number */ + inode->i_ino =EVENTFS_FILE_INODE_INO ; + ti =get_tracefs (inode); ti->flags |=TRACEFS_EVENT_INODE ;d_instantiate (dentry, inode);
@@ -350,6 +357,9 @@ static struct dentry *create_dir(struct inode->i_op = &eventfs_root_dir_inode_operations; inode->i_fop = &eventfs_file_operations; +/* All directories will have the same inode number */ + inode->i_ino =EVENTFS_DIR_INODE_INO ; + ti =get_tracefs (inode); ti->flags |=TRACEFS_EVENT_INODE ;
Greg Kroah-Hartman
maintainerPATCH 186/309 eventfs: Do not create dentries nor inodes in iterate_shared
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Steven Rostedt (Google)" <[email protected]>
commit 852e46e239ee6db3cd220614cf8bce96e79227c2 upstream.
The original eventfs code added a wrapper around the dcache_readdir open callback and created all the dentries and inodes at open, and increment their ref count. A wrapper was added around the dcache_readdir release function to decrement all the ref counts of those created inodes and dentries. But this proved to be buggy[1] for when a kprobe was created during a dir read, it would create a dentry between the open and the release, and because the release would decrement all ref counts of all files and directories, that would include the kprobe directory that was not there to have its ref count incremented in open. This would cause the ref count to go to negative and later crash the kernel.
To solve this, the dentries and inodes that were created and had their ref count upped in open needed to be saved. That list needed to be passed from the open to the release, so that the release would only decrement the ref counts of the entries that were incremented in the open.
Unfortunately, the dcache_readdir logic was already using the file->private_data, which is the only field that can be used to pass information from the open to the release. What was done was the eventfs created another descriptor that had a void pointer to save the dcache_readdir pointer, and it wrapped all the callbacks, so that it could save the list of entries that had their ref counts incremented in the open, and pass it to the release. The wrapped callbacks would just put back the dcache_readdir pointer and call the functions it used so it could still use its data[2].
But Linus had an issue with the "hijacking" of the file->private_data (unfortunately this discussion was on a security list, so no public link). Which we finally agreed on doing everything within the iterate_shared callback and leave the dcache_readdir out of it[3]. All the information needed for the getents() could be created then.
But this ended up being buggy too[4]. The iterate_shared callback was not the right place to create the dentries and inodes. Even Christian Brauner had issues with that[5].
An attempt was to go back to creating the inodes and dentries at the open, create an array to store the information in the file->private_data, and pass that information to the other callbacks.[6]
The difference between that and the original method, is that it does not use dcache_readdir. It also does not up the ref counts of the dentries and pass them. Instead, it creates an array of a structure that saves the dentry's name and inode number. That information is used in the iterate_shared callback, and the array is freed in the dir release. The dentries and inodes created in the open are not used for the iterate_share or release callbacks. Just their names and inode numbers.
Linus did not like that either[7] and just wanted to remove the dentries being created in iterate_shared and use the hard coded inode numbers.
[ All this while Linus enjoyed an unexpected vacation during the merge
window due to lack of power. ]
[1] https://lore.kernel.org/linux-trace-kernel/[email protected]/
[2] https://lore.kernel.org/linux-trace-kernel/[email protected]/
[3] https://lore.kernel.org/linux-trace-kernel/[email protected]/
[4] https://lore.kernel.org/all/[email protected]/
[5] https://lore.kernel.org/all/20240111-unzahl-gefegt-433acb8a841d@brauner/
[6] https://lore.kernel.org/all/[email protected]/
[7] https://lore.kernel.org/all/[email protected]/
--- fs/tracefs/event_inode.c | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-)
fs/tracefs/event_inode.c +5 -15
@@ -689,8 +689,6 @@ static int eventfs_iterate(struct file *struct eventfs_inode *ei_child;struct tracefs_inode *ti;struct eventfs_inode *ei; -struct dentry *ei_dentry =NULL ; -struct dentry *dentry;const char *name;umode_t mode;int idx;
@@ -711,11 +709,11 @@ static int eventfs_iterate(struct file *mutex_lock (&eventfs_mutex); ei =READ_ONCE (ti->private); -if (ei && !ei->is_freed) - ei_dentry =READ_ONCE (ei->dentry); +if (ei && ei->is_freed) + ei =NULL ;mutex_unlock (&eventfs_mutex); -if (!ei || !ei_dentry) +if (!ei) goto out;/*
@@ -742,11 +740,7 @@ static int eventfs_iterate(struct file *if (r <=0 )continue ; - dentry =create_file_dentry (ei, i, ei_dentry, name, mode, cdata, fops); -if (!dentry) - goto out; - ino = dentry->d_inode->i_ino; -dput (dentry); + ino =EVENTFS_FILE_INODE_INO ;if (!dir_emit (ctx, name,strlen (name), ino,DT_REG )) goto out;
@@ -770,11 +764,7 @@ static int eventfs_iterate(struct file * name = ei_child->name; - dentry =create_dir_dentry (ei, ei_child, ei_dentry); -if (!dentry) - goto out_dec; - ino = dentry->d_inode->i_ino; -dput (dentry); + ino =EVENTFS_DIR_INODE_INO ;if (!dir_emit (ctx, name,strlen (name), ino,DT_DIR )) goto out_dec;
Greg Kroah-Hartman
maintainerPATCH 187/309 eventfs: Use kcalloc() instead of kzalloc()
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Erick Archer <[email protected]>
commit 1057066009c4325bb1d8430c9274894d0860e7c3 upstream.
As noted in the "Deprecated Interfaces, Language Features, Attributes, and Conventions" documentation [1], size calculations (especially multiplication) should not be performed in memory allocator (or similar) function arguments due to the risk of them overflowing. This could lead to values wrapping around and a smaller allocation being made than the caller was expecting. Using those allocations could lead to linear overflows of heap memory and other misbehaviors.
So, use the purpose specific kcalloc() function instead of the argument size * count in the kzalloc() function.
--- fs/tracefs/event_inode.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
fs/tracefs/event_inode.c +3 -3
@@ -97,7 +97,7 @@ static int eventfs_set_attr(struct mnt_i/* Preallocate the children mode array if necessary */ if (!(dentry->d_inode->i_mode &S_IFDIR )) {if (!ei->entry_attrs) { - ei->entry_attrs =kzalloc (sizeof (*ei->entry_attrs) * ei->nr_entries, + ei->entry_attrs =kcalloc (ei->nr_entries,sizeof (*ei->entry_attrs),GFP_NOFS );if (!ei->entry_attrs) { ret = -ENOMEM ;
@@ -836,7 +836,7 @@ struct eventfs_inode *eventfs_create_dir }if (size) { - ei->d_children =kzalloc (sizeof (*ei->d_children) * size,GFP_KERNEL ); + ei->d_children =kcalloc (size,sizeof (*ei->d_children),GFP_KERNEL );if (!ei->d_children) {kfree_const (ei->name);kfree (ei);
@@ -903,7 +903,7 @@ struct eventfs_inode *eventfs_create_eve goto fail;if (size) { - ei->d_children =kzalloc (sizeof (*ei->d_children) * size,GFP_KERNEL ); + ei->d_children =kcalloc (size,sizeof (*ei->d_children),GFP_KERNEL );if (!ei->d_children) goto fail; }
Greg Kroah-Hartman
maintainerPATCH 188/309 eventfs: Save directory inodes in the eventfs_inode structure
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Steven Rostedt (Google)" <[email protected]>
commit 834bf76add3e6168038150f162cbccf1fd492a67 upstream.
The eventfs inodes and directories are allocated when referenced. But this leaves the issue of keeping consistent inode numbers and the number is only saved in the inode structure itself. When the inode is no longer referenced, it can be freed. When the file that the inode was representing is referenced again, the inode is once again created, but the inode number needs to be the same as it was before.
Just making the inode numbers the same for all files is fine, but that does not work with directories. The find command will check for loops via the inode number and having the same inode number for directories triggers:
# find /sys/kernel/tracing find: File system loop detected; '/sys/kernel/debug/tracing/events/initcall/initcall_finish' is part of the same file system loop as '/sys/kernel/debug/tracing/events/initcall'. [..]
Linus pointed out that the eventfs_inode structure ends with a single 32bit int, and on 64 bit machines, there's likely a 4 byte hole due to alignment. We can use this hole to store the inode number for the eventfs_inode. All directories in eventfs are represented by an eventfs_inode and that data structure can hold its inode number.
That last int was also purposely placed at the end of the structure to prevent holes from within. Now that there's a 4 byte number to hold the inode, both the inode number and the last integer can be moved up in the structure for better cache locality, where the llist and rcu fields can be moved to the end as they are only used when the eventfs_inode is being deleted.
--- fs/tracefs/event_inode.c | 14 +++++++++++--- fs/tracefs/internal.h | 7 ++++--- 2 files changed, 15 insertions(+), 6 deletions(-)
fs/tracefs/event_inode.c +11 -3
@@ -34,7 +34,15 @@ static DEFINE_MUTEX(eventfs_mutex);/* Choose something "unique" ;-) */ #define EVENTFS_FILE_INODE_INO 0x12c4e37 -#define EVENTFS_DIR_INODE_INO 0x134b2f5 + +/* Just try to make something consistent and unique */ +static int eventfs_dir_ino (struct eventfs_inode *ei) +{ +if (!ei->ino) + ei->ino =get_next_ino (); + +return ei->ino; +}/* * The eventfs_inode (ei) itself is protected by SRCU. It is released from
@@ -358,7 +366,7 @@ static struct dentry *create_dir(struct inode->i_fop = &eventfs_file_operations;/* All directories will have the same inode number */ - inode->i_ino =EVENTFS_DIR_INODE_INO ; + inode->i_ino =eventfs_dir_ino (ei); ti =get_tracefs (inode); ti->flags |=TRACEFS_EVENT_INODE ;
@@ -764,7 +772,7 @@ static int eventfs_iterate(struct file * name = ei_child->name; - ino =EVENTFS_DIR_INODE_INO ; + ino =eventfs_dir_ino (ei_child);if (!dir_emit (ctx, name,strlen (name), ino,DT_DIR )) goto out_dec;
fs/tracefs/internal.h +4 -3
@@ -55,6 +55,10 @@ struct eventfs_inode {struct eventfs_attr *entry_attrs;struct eventfs_attr attr;void *data; + unsigned int is_freed:1; + unsigned int is_events:1; + unsigned int nr_entries:30; +unsigned int ino;/* * Union - used for deletion * @llist: for calling dput() if needed after RCU
@@ -64,9 +68,6 @@ struct eventfs_inode {struct llist_node llist;struct rcu_head rcu; }; - unsigned int is_freed:1; - unsigned int is_events:1; - unsigned int nr_entries:30; };static inline struct tracefs_inode *get_tracefs (const struct inode *inode)
Greg Kroah-Hartman
maintainerPATCH 189/309 tracefs: Zero out the tracefs_inode when allocating it
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Steven Rostedt (Google)" <[email protected]>
commit d81786f53aec14fd4d56263145a0635afbc64617 upstream.
eventfs uses the tracefs_inode and assumes that it's already initialized to zero. That is, it doesn't set fields to zero (like ti->private) after getting its tracefs_inode. This causes bugs due to stale values.
Just initialize the entire structure to zero on allocation so there isn't any more surprises.
This is a partial fix to access to ti->private. The assignment still needs to be made before the dentry is instantiated.
--- fs/tracefs/inode.c | 6 ++++-- fs/tracefs/internal.h | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-)
fs/tracefs/inode.c +4 -2
@@ -38,8 +38,6 @@ static struct inode *tracefs_alloc_inodeif (!ti)return NULL ; - ti->flags =0 ; -return &ti->vfs_inode; }
@@ -779,7 +777,11 @@ static void init_once(void *foo) {struct tracefs_inode *ti = (struct tracefs_inode *) foo; +/* inode_init_once() calls memset() on the vfs_inode portion */ inode_init_once (&ti->vfs_inode); + +/* Zero out the rest */ +memset_after (ti,0 , vfs_inode); }static int __init tracefs_init (void )
fs/tracefs/internal.h +2 -1
@@ -11,9 +11,10 @@ enum { };struct tracefs_inode { +struct inode vfs_inode; +/* The below gets initialized with memset_after(ti, 0, vfs_inode) */ unsigned long flags;void *private; -struct inode vfs_inode; };/*
Greg Kroah-Hartman
maintainerPATCH 190/309 eventfs: Initialize the tracefs inode properly
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linus Torvalds <[email protected]>
commit 4fa4b010b83fb2f837b5ef79e38072a79e96e4f1 upstream.
The tracefs-specific fields in the inode were not initialized before the inode was exposed to others through the dentry with 'd_instantiate()'.
Move the field initializations up to before the d_instantiate.
--- fs/tracefs/event_inode.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
fs/tracefs/event_inode.c +2 -4
@@ -370,6 +370,8 @@ static struct dentry *create_dir(struct ti =get_tracefs (inode); ti->flags |=TRACEFS_EVENT_INODE ; +/* Only directories have ti->private set to an ei, not files */ + ti->private = ei;inc_nlink (inode);d_instantiate (dentry, inode);
@@ -515,7 +517,6 @@ create_file_dentry(struct eventfs_inodestatic void eventfs_post_create_dir (struct eventfs_inode *ei) {struct eventfs_inode *ei_child; -struct tracefs_inode *ti;lockdep_assert_held (&eventfs_mutex);
@@ -525,9 +526,6 @@ static void eventfs_post_create_dir(stru srcu_read_lock_held(&eventfs_srcu)) { ei_child->d_parent = ei->dentry; } - - ti =get_tracefs (ei->dentry->d_inode); - ti->private = ei; }/**
Greg Kroah-Hartman
maintainerPATCH 191/309 tracefs: Avoid using the ei->dentry pointer unnecessarily
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linus Torvalds <[email protected]>
commit 99c001cb617df409dac275a059d6c3f187a2da7a upstream.
The eventfs_find_events() code tries to walk up the tree to find the event directory that a dentry belongs to, in order to then find the eventfs inode that is associated with that event directory.
However, it uses an odd combination of walking the dentry parent, looking up the eventfs inode associated with that, and then looking up the dentry from there. Repeat.
But the code shouldn't have back-pointers to dentries in the first place, and it should just walk the dentry parenthood chain directly.
Similarly, 'set_top_events_ownership()' looks up the dentry from the eventfs inode, but the only reason it wants a dentry is to look up the superblock in order to look up the root dentry.
But it already has the real filesystem inode, which has that same superblock pointer. So just pass in the superblock pointer using the information that's already there, instead of looking up extraneous data that is irrelevant.
--- fs/tracefs/event_inode.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-)
fs/tracefs/event_inode.c +12 -14
@@ -156,33 +156,30 @@ static int eventfs_set_attr(struct mnt_ireturn ret; } -static void update_top_events_attr (struct eventfs_inode *ei,struct dentry *dentry) +static void update_top_events_attr (struct eventfs_inode *ei,struct super_block *sb) { -struct inode *inode; +struct inode *root;/* Only update if the "events" was on the top level */ if (!ei || !(ei->attr.mode &EVENTFS_TOPLEVEL ))return ;/* Get the tracefs root inode. */ - inode =d_inode (dentry->d_sb->s_root); - ei->attr.uid = inode->i_uid; - ei->attr.gid = inode->i_gid; + root =d_inode (sb->s_root); + ei->attr.uid = root->i_uid; + ei->attr.gid = root->i_gid; }static void set_top_events_ownership (struct inode *inode) {struct tracefs_inode *ti =get_tracefs (inode);struct eventfs_inode *ei = ti->private; -struct dentry *dentry;/* The top events directory doesn't get automatically updated */ if (!ei || !ei->is_events || !(ei->attr.mode &EVENTFS_TOPLEVEL ))return ; - dentry = ei->dentry; - -update_top_events_attr (ei, dentry); +update_top_events_attr (ei, inode->i_sb);if (!(ei->attr.mode &EVENTFS_SAVE_UID )) inode->i_uid = ei->attr.uid;
@@ -235,8 +232,10 @@ static struct eventfs_inode *eventfs_finmutex_lock (&eventfs_mutex); do { - /* The parent always has an ei, except for events itself */ - ei = dentry->d_parent->d_fsdata; + // The parent is stable because we do not do renames + dentry = dentry->d_parent; + // ... and directories always have d_fsdata + ei = dentry->d_fsdata; /* * If the ei is being freed, the ownership of the children
@@ -246,12 +245,11 @@ static struct eventfs_inode *eventfs_fin ei =NULL ;break ; } - - dentry = ei->dentry; +// Walk upwards until you find the events inode }while (!ei->is_events);mutex_unlock (&eventfs_mutex); -update_top_events_attr (ei, dentry); +update_top_events_attr (ei, dentry->d_sb);return ei; }
Greg Kroah-Hartman
maintainerPATCH 192/309 tracefs: dentry lookup crapectomy
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linus Torvalds <[email protected]>
commit 49304c2b93e4f7468b51ef717cbe637981397115 upstream.
The dentry lookup for eventfs files was very broken, and had lots of signs of the old situation where the filesystem names were all created statically in the dentry tree, rather than being looked up dynamically based on the eventfs data structures.
You could see it in the naming - how it claimed to "create" dentries rather than just look up the dentries that were given it.
You could see it in various nonsensical and very incorrect operations, like using "simple_lookup()" on the dentries that were passed in, which only results in those dentries becoming negative dentries. Which meant that any other lookup would possibly return ENOENT if it saw that negative dentry before the data was then later filled in.
You could see it in the immense amount of nonsensical code that didn't actually just do lookups.
--- fs/tracefs/event_inode.c | 275 ++++++++--------------------------------------- fs/tracefs/inode.c | 69 ----------- fs/tracefs/internal.h | 3 3 files changed, 50 insertions(+), 297 deletions(-)
fs/tracefs/event_inode.c +50 -225
@@ -230,7 +230,6 @@ static struct eventfs_inode *eventfs_fin {struct eventfs_inode *ei; -mutex_lock (&eventfs_mutex); do { // The parent is stable because we do not do renames dentry = dentry->d_parent;
@@ -247,7 +246,6 @@ static struct eventfs_inode *eventfs_fin }// Walk upwards until you find the events inode }while (!ei->is_events); -mutex_unlock (&eventfs_mutex);update_top_events_attr (ei, dentry->d_sb);
@@ -280,11 +278,10 @@ static void update_inode_attr(struct den }/** -* create_file - create a file in the tracefs filesystem -* @name: the name of the file to create. +* lookup_file - look up a file in the tracefs filesystem +* @dentry: the dentry to look up * @mode: the permission that the file should have. * @attr: saved attributes changed by user -* @parent: parent dentry for this file. * @data: something that the caller will want to get to later on. * @fop: struct file_operations that should be used for this file. *
@@ -292,13 +289,13 @@ static void update_inode_attr(struct den* directory. The inode.i_private pointer will point to @data in the open() * call. */ -static struct dentry *create_file (const char *name,umode_t mode, +static struct dentry *lookup_file (struct dentry *dentry, +umode_t mode,struct eventfs_attr *attr, -struct dentry *parent,void *data, +void *data,const struct file_operations *fop) {struct tracefs_inode *ti; -struct dentry *dentry;struct inode *inode;if (!(mode &S_IFMT ))
@@ -307,15 +304,9 @@ static struct dentry *create_file(constif (WARN_ON_ONCE (!S_ISREG (mode)))return NULL ; -WARN_ON_ONCE (!parent); - dentry =eventfs_start_creating (name, parent); - -if (IS_ERR (dentry)) -return dentry; - inode =tracefs_get_inode (dentry->d_sb);if (unlikely (!inode)) -return eventfs_failed_creating (dentry); +return ERR_PTR (-ENOMEM );/* If the user updated the directory's attributes, use them */ update_inode_attr (dentry, inode, attr, mode);
@@ -329,32 +320,29 @@ static struct dentry *create_file(const ti =get_tracefs (inode); ti->flags |=TRACEFS_EVENT_INODE ; -d_instantiate (dentry, inode); + +d_add (dentry, inode);fsnotify_create (dentry->d_parent->d_inode, dentry); -return eventfs_end_creating (dentry); +return dentry; };/** -* create_dir - create a dir in the tracefs filesystem +* lookup_dir_entry - look up a dir in the tracefs filesystem +* @dentry: the directory to look up * @ei: the eventfs_inode that represents the directory to create -* @parent: parent dentry for this file. * -* This function will create a dentry for a directory represented by +* This function will look up a dentry for a directory represented by * a eventfs_inode. */ -static struct dentry *create_dir (struct eventfs_inode *ei,struct dentry *parent) +static struct dentry *lookup_dir_entry (struct dentry *dentry, +struct eventfs_inode *pei,struct eventfs_inode *ei) {struct tracefs_inode *ti; -struct dentry *dentry;struct inode *inode; - dentry =eventfs_start_creating (ei->name, parent); -if (IS_ERR (dentry)) -return dentry; - inode =tracefs_get_inode (dentry->d_sb);if (unlikely (!inode)) -return eventfs_failed_creating (dentry); +return ERR_PTR (-ENOMEM );/* If the user updated the directory's attributes, use them */ update_inode_attr(dentry, inode, &ei->attr,
@@ -371,11 +359,14 @@ static struct dentry *create_dir(struct/* Only directories have ti->private set to an ei, not files */ ti->private = ei; + dentry->d_fsdata = ei; + ei->dentry = dentry;// Remove me! +inc_nlink (inode); -d_instantiate (dentry, inode); +d_add (dentry, inode);inc_nlink (dentry->d_parent->d_inode);fsnotify_mkdir (dentry->d_parent->d_inode, dentry); -return eventfs_end_creating (dentry); +return dentry; }static void free_ei (struct eventfs_inode *ei)
@@ -425,7 +416,7 @@ void eventfs_set_ei_status_free(struct t }/** -* create_file_dentry - create a dentry for a file of an eventfs_inode +* lookup_file_dentry - create a dentry for a file of an eventfs_inode * @ei: the eventfs_inode that the file will be created under * @idx: the index into the d_children[] of the @ei * @parent: The parent dentry of the created file.
@@ -438,157 +429,21 @@ void eventfs_set_ei_status_free(struct t* address located at @e_dentry. */ static struct dentry * -create_file_dentry (struct eventfs_inode *ei,int idx, -struct dentry *parent,const char *name,umode_t mode,void *data, +lookup_file_dentry (struct dentry *dentry, +struct eventfs_inode *ei,int idx, +umode_t mode,void *data,const struct file_operations *fops) {struct eventfs_attr *attr =NULL ;struct dentry **e_dentry = &ei->d_children[idx]; -struct dentry *dentry; -WARN_ON_ONCE (!inode_is_locked (parent->d_inode)); - -mutex_lock (&eventfs_mutex); -if (ei->is_freed) { -mutex_unlock (&eventfs_mutex); -return NULL ; - } -/* If the e_dentry already has a dentry, use it */ -if (*e_dentry) { -dget (*e_dentry); -mutex_unlock (&eventfs_mutex); -return *e_dentry; - } - -/* ei->entry_attrs are protected by SRCU */ if (ei->entry_attrs) attr = &ei->entry_attrs[idx]; -mutex_unlock (&eventfs_mutex); - - dentry =create_file (name, mode, attr, parent, data, fops); - -mutex_lock (&eventfs_mutex); - -if (IS_ERR_OR_NULL (dentry)) { -/* -* When the mutex was released, something else could have -* created the dentry for this e_dentry. In which case -* use that one. -* -* If ei->is_freed is set, the e_dentry is currently on its -* way to being freed, don't return it. If e_dentry is NULL -* it means it was already freed. -*/ -if (ei->is_freed) { - dentry =NULL ; - }else { - dentry = *e_dentry; -dget (dentry); - } -mutex_unlock (&eventfs_mutex); -return dentry; - } + dentry->d_fsdata = ei;// NOTE: ei of _parent_ +lookup_file (dentry, mode, attr, data, fops); -if (!*e_dentry && !ei->is_freed) { - *e_dentry = dentry; - dentry->d_fsdata = ei; - }else { -/* -* Should never happen unless we get here due to being freed. -* Otherwise it means two dentries exist with the same name. -*/ -WARN_ON_ONCE (!ei->is_freed); - dentry =NULL ; - } -mutex_unlock (&eventfs_mutex); - -return dentry; -} - -/** -* eventfs_post_create_dir - post create dir routine -* @ei: eventfs_inode of recently created dir -* -* Map the meta-data of files within an eventfs dir to their parent dentry -*/ -static void eventfs_post_create_dir (struct eventfs_inode *ei) -{ -struct eventfs_inode *ei_child; - -lockdep_assert_held (&eventfs_mutex); - -/* srcu lock already held */ -/* fill parent-child relation */ -list_for_each_entry_srcu (ei_child, &ei->children, list, -srcu_read_lock_held (&eventfs_srcu)) { - ei_child->d_parent = ei->dentry; - } -} - -/** -* create_dir_dentry - Create a directory dentry for the eventfs_inode -* @pei: The eventfs_inode parent of ei. -* @ei: The eventfs_inode to create the directory for -* @parent: The dentry of the parent of this directory -* -* This creates and attaches a directory dentry to the eventfs_inode @ei. -*/ -static struct dentry * -create_dir_dentry (struct eventfs_inode *pei,struct eventfs_inode *ei, -struct dentry *parent) -{ -struct dentry *dentry =NULL ; - -WARN_ON_ONCE (!inode_is_locked (parent->d_inode)); - -mutex_lock (&eventfs_mutex); -if (pei->is_freed || ei->is_freed) { -mutex_unlock (&eventfs_mutex); -return NULL ; - } -if (ei->dentry) { -/* If the eventfs_inode already has a dentry, use it */ - dentry = ei->dentry; -dget (dentry); -mutex_unlock (&eventfs_mutex); -return dentry; - } -mutex_unlock (&eventfs_mutex); - - dentry =create_dir (ei, parent); - -mutex_lock (&eventfs_mutex); - -if (IS_ERR_OR_NULL (dentry) && !ei->is_freed) { -/* -* When the mutex was released, something else could have -* created the dentry for this e_dentry. In which case -* use that one. -* -* If ei->is_freed is set, the e_dentry is currently on its -* way to being freed. -*/ - dentry = ei->dentry; -if (dentry) -dget (dentry); -mutex_unlock (&eventfs_mutex); -return dentry; - } - -if (!ei->dentry && !ei->is_freed) { - ei->dentry = dentry; -eventfs_post_create_dir (ei); - dentry->d_fsdata = ei; - }else { -/* -* Should never happen unless we get here due to being freed. -* Otherwise it means two dentries exist with the same name. -*/ -WARN_ON_ONCE (!ei->is_freed); - dentry =NULL ; - } -mutex_unlock (&eventfs_mutex); + *e_dentry = dentry;// Remove me return dentry; }
@@ -607,79 +462,49 @@ static struct dentry *eventfs_root_looku struct dentry *dentry, unsigned int flags) { -const struct file_operations *fops; -const struct eventfs_entry *entry;struct eventfs_inode *ei_child;struct tracefs_inode *ti;struct eventfs_inode *ei; -struct dentry *ei_dentry =NULL ; -struct dentry *ret =NULL ; -struct dentry *d;const char *name = dentry->d_name.name; -umode_t mode; -void *data; -int idx; -int i; -int r; ti =get_tracefs (dir);if (!(ti->flags &TRACEFS_EVENT_INODE )) -return NULL ; +return ERR_PTR (-EIO ); -/* Grab srcu to prevent the ei from going away */ - idx =srcu_read_lock (&eventfs_srcu); - -/* -* Grab the eventfs_mutex to consistent value from ti->private. -* This s -*/ mutex_lock (&eventfs_mutex); - ei =READ_ONCE (ti->private); -if (ei && !ei->is_freed) - ei_dentry =READ_ONCE (ei->dentry); -mutex_unlock (&eventfs_mutex); -if (!ei || !ei_dentry) + ei = ti->private; +if (!ei || ei->is_freed) goto out; - data = ei->data; - -list_for_each_entry_srcu (ei_child, &ei->children, list, -srcu_read_lock_held (&eventfs_srcu)) { +list_for_each_entry (ei_child, &ei->children, list) {if (strcmp (ei_child->name, name) !=0 )continue ; - ret =simple_lookup (dir, dentry, flags); -if (IS_ERR (ret)) +if (ei_child->is_freed) goto out; - d =create_dir_dentry (ei, ei_child, ei_dentry); -dput (d); +lookup_dir_entry (dentry, ei, ei_child); goto out; } -for (i =0 ; i < ei->nr_entries; i++) { - entry = &ei->entries[i]; -if (strcmp (name, entry->name) ==0 ) { -void *cdata = data; -mutex_lock (&eventfs_mutex); -/* If ei->is_freed, then the event itself may be too */ -if (!ei->is_freed) - r = entry->callback (name, &mode, &cdata, &fops); -else - r =-1 ; -mutex_unlock (&eventfs_mutex); -if (r <=0 ) -continue ; - ret =simple_lookup (dir, dentry, flags); -if (IS_ERR (ret)) - goto out; - d =create_file_dentry (ei, i, ei_dentry, name, mode, cdata, fops); -dput (d); -break ; - } +for (int i =0 ; i < ei->nr_entries; i++) { +void *data; +umode_t mode; +const struct file_operations *fops; +const struct eventfs_entry *entry = &ei->entries[i]; + +if (strcmp (name, entry->name) !=0 ) +continue ; + + data = ei->data; +if (entry->callback (name, &mode, &data, &fops) <=0 ) + goto out; + +lookup_file_dentry (dentry, ei, i, mode, data, fops); + goto out; } out: -srcu_read_unlock (&eventfs_srcu, idx); -return ret; +mutex_unlock (&eventfs_mutex); +return NULL ; }/*
fs/tracefs/inode.c +0 -69
75 lines not on this page · raw message
fs/tracefs/internal.h +0 -3
@@ -80,9 +80,6 @@ struct dentry *tracefs_start_creating(costruct dentry *tracefs_end_creating (struct dentry *dentry);struct dentry *tracefs_failed_creating (struct dentry *dentry);struct inode *tracefs_get_inode (struct super_block *sb); -struct dentry *eventfs_start_creating (const char *name,struct dentry *parent); -struct dentry *eventfs_failed_creating (struct dentry *dentry); -struct dentry *eventfs_end_creating (struct dentry *dentry);void eventfs_set_ei_status_free (struct tracefs_inode *ti,struct dentry *dentry);#endif /* _TRACEFS_INTERNAL_H */
Greg Kroah-Hartman
maintainerPATCH 193/309 eventfs: Remove unused d_parent pointer field
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linus Torvalds <[email protected]>
commit 408600be78cdb8c650a97ecc7ff411cb216811b5 upstream.
It's never used
--- fs/tracefs/event_inode.c | 4 +--- fs/tracefs/internal.h | 2 -- 2 files changed, 1 insertion(+), 5 deletions(-)
fs/tracefs/event_inode.c +1 -3
@@ -680,10 +680,8 @@ struct eventfs_inode *eventfs_create_dirINIT_LIST_HEAD (&ei->list);mutex_lock (&eventfs_mutex); -if (!parent->is_freed) { +if (!parent->is_freed)list_add_tail (&ei->list, &parent->children); - ei->d_parent = parent->dentry; - }mutex_unlock (&eventfs_mutex);/* Was the parent freed? */
fs/tracefs/internal.h +0 -2
@@ -36,7 +36,6 @@ struct eventfs_attr {* @name: the name of the directory to create * @children: link list into the child eventfs_inode * @dentry: the dentry of the directory -* @d_parent: pointer to the parent's dentry * @d_children: The array of dentries to represent the files when created * @entry_attrs: Saved mode and ownership of the @d_children * @attr: Saved mode and ownership of eventfs_inode itself
@@ -51,7 +50,6 @@ struct eventfs_inode {const char *name;struct list_head children;struct dentry *dentry;/* Check is_freed to access */ -struct dentry *d_parent;struct dentry **d_children;struct eventfs_attr *entry_attrs;struct eventfs_attr attr;
Greg Kroah-Hartman
maintainerPATCH 194/309 eventfs: Clean up dentry ops and add revalidate function
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linus Torvalds <[email protected]>
commit 8dce06e98c70a7fcbb4bca7d90faf40522e65c58 upstream.
In order for the dentries to stay up-to-date with the eventfs changes, just add a 'd_revalidate' function that checks the 'is_freed' bit.
Also, clean up the dentry release to actually use d_release() rather than the slightly odd d_iput() function. We don't care about the inode, all we want to do is to get rid of the refcount to the eventfs data added by dentry->d_fsdata.
It would probably be cleaner to make eventfs its own filesystem, or at least set its own dentry ops when looking up eventfs files. But as it is, only eventfs dentries use d_fsdata, so we don't really need to split these things up by use.
Another thing that might be worth doing is to make all eventfs lookups mark their dentries as not worth caching. We could do that with d_delete(), but the DCACHE_DONTCACHE flag would likely be even better.
As it is, the dentries are all freeable, but they only tend to get freed at memory pressure rather than more proactively. But that's a separate issue.
--- fs/tracefs/event_inode.c | 5 ++--- fs/tracefs/inode.c | 27 ++++++++++++++++++--------- fs/tracefs/internal.h | 3 ++- 3 files changed, 22 insertions(+), 13 deletions(-)
fs/tracefs/event_inode.c +2 -3
@@ -378,13 +378,12 @@ static void free_ei(struct eventfs_inode }/** -* eventfs_set_ei_status_free - remove the dentry reference from an eventfs_inode -* @ti: the tracefs_inode of the dentry +* eventfs_d_release - dentry is going away * @dentry: dentry which has the reference to remove. * * Remove the association between a dentry from an eventfs_inode. */ -void eventfs_set_ei_status_free (struct tracefs_inode *ti,struct dentry *dentry) +void eventfs_d_release (struct dentry *dentry) {struct eventfs_inode *ei;int i;
fs/tracefs/inode.c +18 -9
@@ -377,21 +377,30 @@ static const struct super_operations tra .show_options = tracefs_show_options, }; -static void tracefs_dentry_iput (struct dentry *dentry,struct inode *inode) +/* +* It would be cleaner if eventfs had its own dentry ops. +* +* Note that d_revalidate is called potentially under RCU, +* so it can't take the eventfs mutex etc. It's fine - if +* we open a file just as it's marked dead, things will +* still work just fine, and just see the old stale case. +*/ +static void tracefs_d_release (struct dentry *dentry) { -struct tracefs_inode *ti; +if (dentry->d_fsdata) +eventfs_d_release (dentry); +} -if (!dentry || !inode) -return ; +static int tracefs_d_revalidate (struct dentry *dentry,unsigned int flags) +{ +struct eventfs_inode *ei = dentry->d_fsdata; - ti =get_tracefs (inode); -if (ti && ti->flags &TRACEFS_EVENT_INODE ) -eventfs_set_ei_status_free (ti, dentry); -iput (inode); +return !(ei && ei->is_freed); }static const struct dentry_operations tracefs_dentry_operations = { - .d_iput = tracefs_dentry_iput, + .d_revalidate = tracefs_d_revalidate, + .d_release = tracefs_d_release, };static int trace_fill_super (struct super_block *sb,void *data,int silent)
fs/tracefs/internal.h +2 -1
@@ -78,6 +78,7 @@ struct dentry *tracefs_start_creating(costruct dentry *tracefs_end_creating (struct dentry *dentry);struct dentry *tracefs_failed_creating (struct dentry *dentry);struct inode *tracefs_get_inode (struct super_block *sb); -void eventfs_set_ei_status_free (struct tracefs_inode *ti,struct dentry *dentry); + +void eventfs_d_release (struct dentry *dentry);#endif /* _TRACEFS_INTERNAL_H */
Greg Kroah-Hartman
maintainerPATCH 195/309 eventfs: Get rid of dentry pointers without refcounts
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linus Torvalds <[email protected]>
commit 43aa6f97c2d03a52c1ddb86768575fc84344bdbb upstream.
The eventfs inode had pointers to dentries (and child dentries) without actually holding a refcount on said pointer. That is fundamentally broken, and while eventfs tried to then maintain coherence with dentries going away by hooking into the '.d_iput' callback, that doesn't actually work since it's not ordered wrt lookups.
There were two reasonms why eventfs tried to keep a pointer to a dentry:
- the creation of a 'events' directory would actually have a stable dentry pointer that it created with tracefs_start_creating().
And it needed that dentry when tearing it all down again in eventfs_remove_events_dir().
This use is actually ok, because the special top-level events directory dentries are actually stable, not just a temporary cache of the eventfs data structures.
- the 'eventfs_inode' (aka ei) needs to stay around as long as there are dentries that refer to it.
It then used these dentry pointers as a replacement for doing reference counting: it would try to make sure that there was only ever one dentry associated with an event_inode, and keep a child dentry array around to see which dentries might still refer to the parent ei.
This gets rid of the invalid dentry pointer use, and renames the one valid case to a different name to make it clear that it's not just any random dentry.
The magic child dentry array that is kind of a "reverse reference list" is simply replaced by having child dentries take a ref to the ei. As does the directory dentries. That makes the broken use case go away.
--- fs/tracefs/event_inode.c | 248 ++++++++++++++--------------------------------- fs/tracefs/internal.h | 7 - 2 files changed, 78 insertions(+), 177 deletions(-)
fs/tracefs/event_inode.c +75 -173
@@ -62,6 +62,35 @@ enum {#define EVENTFS_MODE_MASK (EVENTFS_SAVE_MODE - 1) +/* +* eventfs_inode reference count management. +* +* NOTE! We count only references from dentries, in the +* form 'dentry->d_fsdata'. There are also references from +* directory inodes ('ti->private'), but the dentry reference +* count is always a superset of the inode reference count. +*/ +static void release_ei (struct kref *ref) +{ + struct eventfs_inode *ei = container_of(ref, struct eventfs_inode, kref); +kfree (ei->entry_attrs); +kfree_const (ei->name); +kfree_rcu (ei, rcu); +} + +static inline void put_ei (struct eventfs_inode *ei) +{ +if (ei) +kref_put (&ei->kref, release_ei); +} + +static inline struct eventfs_inode *get_ei (struct eventfs_inode *ei) +{ +if (ei) +kref_get (&ei->kref); +return ei; +} +static struct dentry *eventfs_root_lookup (struct inode *dir,struct dentry *dentry,unsigned int flags);
@@ -289,7 +318,8 @@ static void update_inode_attr(struct den* directory. The inode.i_private pointer will point to @data in the open() * call. */ -static struct dentry *lookup_file(struct dentry *dentry, +static struct dentry *lookup_file(struct eventfs_inode *parent_ei, + struct dentry *dentry, umode_t mode, struct eventfs_attr *attr, void *data,
@@ -302,7 +332,7 @@ static struct dentry *lookup_file(struct mode |=S_IFREG ;if (WARN_ON_ONCE (!S_ISREG (mode))) -return NULL ; +return ERR_PTR (-EIO ); inode =tracefs_get_inode (dentry->d_sb);if (unlikely (!inode))
@@ -321,9 +351,12 @@ static struct dentry *lookup_file(struct ti =get_tracefs (inode); ti->flags |=TRACEFS_EVENT_INODE ; +// Files have their parent's ei as their fsdata + dentry->d_fsdata =get_ei (parent_ei); +d_add (dentry, inode);fsnotify_create (dentry->d_parent->d_inode, dentry); -return dentry; +return NULL ; };/**
@@ -359,22 +392,29 @@ static struct dentry *lookup_dir_entry(s/* Only directories have ti->private set to an ei, not files */ ti->private = ei; - dentry->d_fsdata = ei; - ei->dentry = dentry;// Remove me! + dentry->d_fsdata =get_ei (ei);inc_nlink (inode);d_add (dentry, inode);inc_nlink (dentry->d_parent->d_inode);fsnotify_mkdir (dentry->d_parent->d_inode, dentry); -return dentry; +return NULL ; } -static void free_ei (struct eventfs_inode *ei) +static inline struct eventfs_inode *alloc_ei (const char *name) { -kfree_const (ei->name); -kfree (ei->d_children); -kfree (ei->entry_attrs); -kfree (ei); +struct eventfs_inode *ei =kzalloc (sizeof (*ei),GFP_KERNEL ); + +if (!ei) +return NULL ; + + ei->name =kstrdup_const (name,GFP_KERNEL ); +if (!ei->name) { +kfree (ei); +return NULL ; + } +kref_init (&ei->kref); +return ei; }/**
@@ -385,39 +425,13 @@ static void free_ei(struct eventfs_inode*/ void eventfs_d_release (struct dentry *dentry) { -struct eventfs_inode *ei; -int i; - -mutex_lock (&eventfs_mutex); - - ei = dentry->d_fsdata; -if (!ei) - goto out; - -/* This could belong to one of the files of the ei */ -if (ei->dentry != dentry) { -for (i =0 ; i < ei->nr_entries; i++) { -if (ei->d_children[i] == dentry) -break ; - } -if (WARN_ON_ONCE (i == ei->nr_entries)) - goto out; - ei->d_children[i] =NULL ; - }else if (ei->is_freed) { -free_ei (ei); - }else { - ei->dentry =NULL ; - } - - dentry->d_fsdata =NULL ; - out: -mutex_unlock (&eventfs_mutex); +put_ei (dentry->d_fsdata); }/** * lookup_file_dentry - create a dentry for a file of an eventfs_inode * @ei: the eventfs_inode that the file will be created under -* @idx: the index into the d_children[] of the @ei +* @idx: the index into the entry_attrs[] of the @ei * @parent: The parent dentry of the created file. * @name: The name of the file to create * @mode: The mode of the file.
@@ -434,17 +448,11 @@ lookup_file_dentry(struct dentry *dentry const struct file_operations *fops) {struct eventfs_attr *attr =NULL ; -struct dentry **e_dentry = &ei->d_children[idx];if (ei->entry_attrs) attr = &ei->entry_attrs[idx]; - dentry->d_fsdata = ei;// NOTE: ei of _parent_ -lookup_file (dentry, mode, attr, data, fops); - - *e_dentry = dentry;// Remove me - -return dentry; +return lookup_file (ei, dentry, mode, attr, data, fops); }/**
@@ -465,6 +473,7 @@ static struct dentry *eventfs_root_lookustruct tracefs_inode *ti;struct eventfs_inode *ei;const char *name = dentry->d_name.name; +struct dentry *result =NULL ; ti =get_tracefs (dir);if (!(ti->flags &TRACEFS_EVENT_INODE ))
@@ -481,7 +490,7 @@ static struct dentry *eventfs_root_lookucontinue ;if (ei_child->is_freed) goto out; -lookup_dir_entry (dentry, ei, ei_child); + result =lookup_dir_entry (dentry, ei, ei_child); goto out; }
@@ -498,12 +507,12 @@ static struct dentry *eventfs_root_lookuif (entry->callback (name, &mode, &data, &fops) <=0 ) goto out; -lookup_file_dentry (dentry, ei, i, mode, data, fops); + result =lookup_file_dentry (dentry, ei, i, mode, data, fops); goto out; } out:mutex_unlock (&eventfs_mutex); -return NULL ; +return result; }/*
@@ -653,25 +662,10 @@ struct eventfs_inode *eventfs_create_dirif (!parent)return ERR_PTR (-EINVAL ); - ei =kzalloc (sizeof (*ei),GFP_KERNEL ); + ei =alloc_ei (name);if (!ei)return ERR_PTR (-ENOMEM ); - ei->name =kstrdup_const (name,GFP_KERNEL ); -if (!ei->name) { -kfree (ei); -return ERR_PTR (-ENOMEM ); - } - -if (size) { - ei->d_children =kcalloc (size,sizeof (*ei->d_children),GFP_KERNEL ); -if (!ei->d_children) { -kfree_const (ei->name); -kfree (ei); -return ERR_PTR (-ENOMEM ); - } - } - ei->entries = entries; ei->nr_entries = size; ei->data = data;
@@ -685,7 +679,7 @@ struct eventfs_inode *eventfs_create_dir/* Was the parent freed? */ if (list_empty (&ei->list)) { -free_ei (ei); +put_ei (ei); ei =NULL ; }return ei;
@@ -720,28 +714,20 @@ struct eventfs_inode *eventfs_create_eveif (IS_ERR (dentry))return ERR_CAST (dentry); - ei =kzalloc (sizeof (*ei),GFP_KERNEL ); + ei =alloc_ei (name);if (!ei) - goto fail_ei; + goto fail; inode =tracefs_get_inode (dentry->d_sb);if (unlikely (!inode)) goto fail; -if (size) { - ei->d_children =kcalloc (size,sizeof (*ei->d_children),GFP_KERNEL ); -if (!ei->d_children) - goto fail; - } - - ei->dentry = dentry; +// Note: we have a ref to the dentry from tracefs_start_creating() + ei->events_dir = dentry; ei->entries = entries; ei->nr_entries = size; ei->is_events =1 ; ei->data = data; - ei->name =kstrdup_const (name,GFP_KERNEL ); -if (!ei->name) - goto fail;/* Save the ownership of this directory */ uid =d_inode (dentry->d_parent)->i_uid;
@@ -772,7 +758,7 @@ struct eventfs_inode *eventfs_create_eve inode->i_op = &eventfs_root_dir_inode_operations; inode->i_fop = &eventfs_file_operations; - dentry->d_fsdata = ei; + dentry->d_fsdata =get_ei (ei);/* directory inodes start off with i_nlink == 2 (for "." entry) */ inc_nlink (inode);
@@ -784,72 +770,11 @@ struct eventfs_inode *eventfs_create_evereturn ei; fail: -kfree (ei->d_children); -kfree (ei); - fail_ei: +put_ei (ei);tracefs_failed_creating (dentry);return ERR_PTR (-ENOMEM ); } -static LLIST_HEAD (free_list); - -static void eventfs_workfn (struct work_struct *work) -{ -struct eventfs_inode *ei, *tmp; -struct llist_node *llnode; - - llnode =llist_del_all (&free_list); -llist_for_each_entry_safe (ei, tmp, llnode, llist) { -/* This dput() matches the dget() from unhook_dentry() */ -for (int i =0 ; i < ei->nr_entries; i++) { -if (ei->d_children[i]) -dput (ei->d_children[i]); - } -/* This should only get here if it had a dentry */ -if (!WARN_ON_ONCE (!ei->dentry)) -dput (ei->dentry); - } -} - -static DECLARE_WORK(eventfs_work, eventfs_workfn); - -static void free_rcu_ei (struct rcu_head *head) -{ - struct eventfs_inode *ei = container_of(head, struct eventfs_inode, rcu); - -if (ei->dentry) { -/* Do not free the ei until all references of dentry are gone */ -if (llist_add (&ei->llist, &free_list)) -queue_work (system_unbound_wq, &eventfs_work); -return ; - } - -/* If the ei doesn't have a dentry, neither should its children */ -for (int i =0 ; i < ei->nr_entries; i++) { -WARN_ON_ONCE (ei->d_children[i]); - } - -free_ei (ei); -} - -static void unhook_dentry (struct dentry *dentry) -{ -if (!dentry) -return ; -/* -* Need to add a reference to the dentry that is expected by -* simple_recursive_removal(), which will include a dput(). -*/ -dget (dentry); - -/* -* Also add a reference for the dput() in eventfs_workfn(). -* That is required as that dput() will free the ei after -* the SRCU grace period is over. -*/ -dget (dentry); -} -/** * eventfs_remove_rec - remove eventfs dir or file from list * @ei: eventfs_inode to be removed.
@@ -862,8 +787,6 @@ static void eventfs_remove_rec(struct ev {struct eventfs_inode *ei_child; -if (!ei) -return ;/* * Check recursion depth. It should never be greater than 3: * 0 - events/
@@ -875,28 +798,12 @@ static void eventfs_remove_rec(struct evreturn ;/* search for nested folders or files */ -list_for_each_entry_srcu (ei_child, &ei->children, list, -lockdep_is_held (&eventfs_mutex)) { -/* Children only have dentry if parent does */ -WARN_ON_ONCE (ei_child->dentry && !ei->dentry); +list_for_each_entry (ei_child, &ei->children, list)eventfs_remove_rec (ei_child, level +1 ); - } - ei->is_freed =1 ; - -for (int i =0 ; i < ei->nr_entries; i++) { -if (ei->d_children[i]) { -/* Children only have dentry if parent does */ -WARN_ON_ONCE (!ei->dentry); -unhook_dentry (ei->d_children[i]); - } - } - -unhook_dentry (ei->dentry); - -list_del_rcu (&ei->list); -call_srcu (&eventfs_srcu, &ei->rcu, free_rcu_ei); +list_del (&ei->list); +put_ei (ei); }/**
@@ -907,22 +814,12 @@ static void eventfs_remove_rec(struct ev*/ void eventfs_remove_dir (struct eventfs_inode *ei) { -struct dentry *dentry; -if (!ei)return ;mutex_lock (&eventfs_mutex); - dentry = ei->dentry;eventfs_remove_rec (ei,0 );mutex_unlock (&eventfs_mutex); - -/* -* If any of the ei children has a dentry, then the ei itself -* must have a dentry. -*/ -if (dentry) -simple_recursive_removal (dentry,NULL ); }/**
@@ -935,7 +832,11 @@ void eventfs_remove_events_dir(struct ev {struct dentry *dentry; - dentry = ei->dentry; + dentry = ei->events_dir; +if (!dentry) +return ; + + ei->events_dir =NULL ;eventfs_remove_dir (ei);/*
@@ -945,5 +846,6 @@ void eventfs_remove_events_dir(struct ev* sticks around while the other ei->dentry are created * and destroyed dynamically. */ +d_invalidate (dentry);dput (dentry); }
fs/tracefs/internal.h +3 -4
@@ -35,8 +35,7 @@ struct eventfs_attr {* @entries: the array of entries representing the files in the directory * @name: the name of the directory to create * @children: link list into the child eventfs_inode -* @dentry: the dentry of the directory -* @d_children: The array of dentries to represent the files when created +* @events_dir: the dentry of the events directory * @entry_attrs: Saved mode and ownership of the @d_children * @attr: Saved mode and ownership of eventfs_inode itself * @data: The private data to pass to the callbacks
@@ -45,12 +44,12 @@ struct eventfs_attr {* @nr_entries: The number of items in @entries */ struct eventfs_inode { +struct kref kref;struct list_head list;const struct eventfs_entry *entries;const char *name;struct list_head children; -struct dentry *dentry;/* Check is_freed to access */ -struct dentry **d_children; +struct dentry *events_dir;struct eventfs_attr *entry_attrs;struct eventfs_attr attr;void *data;
Greg Kroah-Hartman
maintainerPATCH 196/309 eventfs: Warn if an eventfs_inode is freed without is_freed being set
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Steven Rostedt (Google)" <[email protected]>
commit 5a49f996046ba947466bc7461e4b19c4d1daf978 upstream.
There should never be a case where an evenfs_inode is being freed without is_freed being set. Add a WARN_ON_ONCE() if it ever happens. That would mean there was one too many put_ei()s.
--- fs/tracefs/event_inode.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-)
fs/tracefs/event_inode.c +14 -4
@@ -73,6 +73,9 @@ enum {static void release_ei (struct kref *ref) { struct eventfs_inode *ei = container_of(ref, struct eventfs_inode, kref); + +WARN_ON_ONCE (!ei->is_freed); +kfree (ei->entry_attrs);kfree_const (ei->name);kfree_rcu (ei, rcu);
@@ -84,6 +87,14 @@ static inline void put_ei(struct eventfskref_put (&ei->kref, release_ei); } +static inline void free_ei (struct eventfs_inode *ei) +{ +if (ei) { + ei->is_freed =1 ; +put_ei (ei); + } +} +static inline struct eventfs_inode *get_ei (struct eventfs_inode *ei) {if (ei)
@@ -679,7 +690,7 @@ struct eventfs_inode *eventfs_create_dir/* Was the parent freed? */ if (list_empty (&ei->list)) { -put_ei (ei); +free_ei (ei); ei =NULL ; }return ei;
@@ -770,7 +781,7 @@ struct eventfs_inode *eventfs_create_evereturn ei; fail: -put_ei (ei); +free_ei (ei);tracefs_failed_creating (dentry);return ERR_PTR (-ENOMEM ); }
@@ -801,9 +812,8 @@ static void eventfs_remove_rec(struct evlist_for_each_entry (ei_child, &ei->children, list)eventfs_remove_rec (ei_child, level +1 ); - ei->is_freed =1 ;list_del (&ei->list); -put_ei (ei); +free_ei (ei); }/**
Greg Kroah-Hartman
maintainerPATCH 197/309 eventfs: Restructure eventfs_inode structure to be more condensed
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Steven Rostedt (Google)" <[email protected]>
commit 264424dfdd5cbd92bc5b5ddf93944929fc877fac upstream.
Some of the eventfs_inode structure has holes in it. Rework the structure to be a bit more condensed, and also remove the no longer used llist field.
--- fs/tracefs/internal.h | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-)
fs/tracefs/internal.h +12 -15
@@ -32,40 +32,37 @@ struct eventfs_attr {/* * struct eventfs_inode - hold the properties of the eventfs directories. * @list: link list into the parent directory +* @rcu: Union with @list for freeing +* @children: link list into the child eventfs_inode * @entries: the array of entries representing the files in the directory * @name: the name of the directory to create -* @children: link list into the child eventfs_inode * @events_dir: the dentry of the events directory * @entry_attrs: Saved mode and ownership of the @d_children -* @attr: Saved mode and ownership of eventfs_inode itself * @data: The private data to pass to the callbacks +* @attr: Saved mode and ownership of eventfs_inode itself * @is_freed: Flag set if the eventfs is on its way to be freed * Note if is_freed is set, then dentry is corrupted. +* @is_events: Flag set for only the top level "events" directory * @nr_entries: The number of items in @entries +* @ino: The saved inode number */ struct eventfs_inode { -struct kref kref; -struct list_head list; +union { +struct list_head list; +struct rcu_head rcu; + }; +struct list_head children;const struct eventfs_entry *entries;const char *name; -struct list_head children;struct dentry *events_dir;struct eventfs_attr *entry_attrs; -struct eventfs_attr attr;void *data; +struct eventfs_attr attr; +struct kref kref;unsigned int is_freed:1 ;unsigned int is_events:1 ;unsigned int nr_entries:30 ;unsigned int ino; -/* -* Union - used for deletion -* @llist: for calling dput() if needed after RCU -* @rcu: eventfs_inode to delete in RCU -*/ -union { -struct llist_node llist; -struct rcu_head rcu; - }; };static inline struct tracefs_inode *get_tracefs (const struct inode *inode)
Greg Kroah-Hartman
maintainerPATCH 198/309 eventfs: Remove fsnotify*() functions from lookup()
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Steven Rostedt (Google)" <[email protected]>
commit 12d823b31fadf47c8f36ecada7abac5f903cac33 upstream.
The dentries and inodes are created when referenced in the lookup code. There's no reason to call fsnotify_*() functions when they are created by a reference. It doesn't make any sense.
--- fs/tracefs/event_inode.c | 2 -- 1 file changed, 2 deletions(-)
fs/tracefs/event_inode.c +0 -2
@@ -366,7 +366,6 @@ static struct dentry *lookup_file(struct dentry->d_fsdata =get_ei (parent_ei);d_add (dentry, inode); -fsnotify_create (dentry->d_parent->d_inode, dentry);return NULL ; };
@@ -408,7 +407,6 @@ static struct dentry *lookup_dir_entry(sinc_nlink (inode);d_add (dentry, inode);inc_nlink (dentry->d_parent->d_inode); -fsnotify_mkdir (dentry->d_parent->d_inode, dentry);return NULL ; }
Greg Kroah-Hartman
maintainerPATCH 199/309 eventfs: Keep all directory links at 1
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Steven Rostedt (Google)" <[email protected]>
commit ca185770db914869ff9fe773bac5e0e5e4165b83 upstream.
The directory link count in eventfs was somewhat bogus. It was only being updated when a directory child was being looked up and not on creation.
One solution would be to update in get_attr() the link count by iterating the ei->children list and then adding 2. But that could slow down simple stat() calls, especially if it's done on all directories in eventfs.
Another solution would be to add a parent pointer to the eventfs_inode and keep track of the number of sub directories it has on creation. But this adds overhead for something not really worthwhile.
The solution decided upon is to keep all directory links in eventfs as 1. This tells user space not to rely on the hard links of directories. Which in this case it shouldn't.
--- fs/tracefs/event_inode.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)
fs/tracefs/event_inode.c +10 -4
@@ -404,9 +404,7 @@ static struct dentry *lookup_dir_entry(s dentry->d_fsdata =get_ei (ei); -inc_nlink (inode);d_add (dentry, inode); -inc_nlink (dentry->d_parent->d_inode);return NULL ; }
@@ -769,9 +767,17 @@ struct eventfs_inode *eventfs_create_eve dentry->d_fsdata =get_ei (ei); -/* directory inodes start off with i_nlink == 2 (for "." entry) */ -inc_nlink (inode); +/* +* Keep all eventfs directories with i_nlink == 1. +* Due to the dynamic nature of the dentry creations and not +* wanting to add a pointer to the parent eventfs_inode in the +* eventfs_inode structure, keeping the i_nlink in sync with the +* number of directories would cause too much complexity for +* something not worth much. Keeping directory links at 1 +* tells userspace not to trust the link number. +*/ d_instantiate (dentry, inode); +/* The dentry of the "events" parent does keep track though */ inc_nlink (dentry->d_parent->d_inode);fsnotify_mkdir (dentry->d_parent->d_inode, dentry);tracefs_end_creating (dentry);
Greg Kroah-Hartman
maintainerPATCH 200/309 getrusage: move thread_group_cputime_adjusted() outside of lock_task_sighand()
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oleg Nesterov <[email protected]>
commit daa694e4137571b4ebec330f9a9b4d54aa8b8089 upstream.
Patch series "getrusage: use sig->stats_lock", v2.
This patch (of 2):
thread_group_cputime() does its own locking, we can safely shift thread_group_cputime_adjusted() which does another for_each_thread loop outside of ->siglock protected section.
This is also preparation for the next patch which changes getrusage() to use stats_lock instead of siglock, thread_group_cputime() takes the same lock. With the current implementation recursive read_seqbegin_or_lock() is fine, thread_group_cputime() can't enter the slow mode if the caller holds stats_lock, yet this looks more safe and better performance-wise.
--- kernel/sys.c | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-)
kernel/sys.c +20 -16
@@ -1785,17 +1785,19 @@ void getrusage(struct task_struct *p, instruct task_struct *t;unsigned long flags;u64 tgutime, tgstime, utime, stime; -unsigned long maxrss =0 ; +unsigned long maxrss; +struct mm_struct *mm;struct signal_struct *sig = p->signal; -memset ((char *)r,0 ,sizeof (*r)); +memset (r,0 ,sizeof (*r)); utime = stime =0 ; + maxrss =0 ;if (who ==RUSAGE_THREAD ) {task_cputime_adjusted (current, &utime, &stime);accumulate_thread_rusage (p, r); maxrss = sig->maxrss; - goto out; + goto out_thread; }if (!lock_task_sighand (p, &flags))
@@ -1819,9 +1821,6 @@ void getrusage(struct task_struct *p, in fallthrough;case RUSAGE_SELF : -thread_group_cputime_adjusted (p, &tgutime, &tgstime); - utime += tgutime; - stime += tgstime; r->ru_nvcsw += sig->nvcsw; r->ru_nivcsw += sig->nivcsw; r->ru_minflt += sig->min_flt;
@@ -1839,19 +1838,24 @@ void getrusage(struct task_struct *p, in }unlock_task_sighand (p, &flags); -out: - r->ru_utime =ns_to_kernel_old_timeval (utime); - r->ru_stime =ns_to_kernel_old_timeval (stime); - -if (who !=RUSAGE_CHILDREN ) { -struct mm_struct *mm =get_task_mm (p); +if (who ==RUSAGE_CHILDREN ) + goto out_children; -if (mm) { -setmax_mm_hiwater_rss (&maxrss, mm); -mmput (mm); - } +thread_group_cputime_adjusted (p, &tgutime, &tgstime); + utime += tgutime; + stime += tgstime; + +out_thread: + mm =get_task_mm (p); +if (mm) { +setmax_mm_hiwater_rss (&maxrss, mm); +mmput (mm); } + +out_children: r->ru_maxrss = maxrss * (PAGE_SIZE /1024 );/* convert pages to KBs */ + r->ru_utime =ns_to_kernel_old_timeval (utime); + r->ru_stime =ns_to_kernel_old_timeval (stime); } SYSCALL_DEFINE2(getrusage, int, who, struct rusage __user *, ru)
Greg Kroah-Hartman
maintainerPATCH 201/309 getrusage: use sig->stats_lock rather than lock_task_sighand()
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oleg Nesterov <[email protected]>
commit f7ec1cd5cc7ef3ad964b677ba82b8b77f1c93009 upstream.
lock_task_sighand() can trigger a hard lockup. If NR_CPUS threads call getrusage() at the same time and the process has NR_THREADS, spin_lock_irq will spin with irqs disabled O(NR_CPUS * NR_THREADS) time.
Change getrusage() to use sig->stats_lock, it was specifically designed for this type of use. This way it runs lockless in the likely case.
TODO:
- Change do_task_stat() to use sig->stats_lock too, then we can remove spin_lock_irq(siglock) in wait_task_zombie().
- Turn sig->stats_lock into seqcount_rwlock_t, this way the readers in the slow mode won't exclude each other. See
https://lore.kernel.org/all/[email protected]/
- stats_lock has to disable irqs because ->siglock can be taken in irq context, it would be very nice to change __exit_signal() to avoid the siglock->stats_lock dependency.
--- kernel/sys.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-)
kernel/sys.c +13 -3
@@ -1788,7 +1788,9 @@ void getrusage(struct task_struct *p, inunsigned long maxrss;struct mm_struct *mm;struct signal_struct *sig = p->signal; +unsigned int seq =0 ; +retry:memset (r,0 ,sizeof (*r)); utime = stime =0 ; maxrss =0 ;
@@ -1800,8 +1802,7 @@ void getrusage(struct task_struct *p, in goto out_thread; } -if (!lock_task_sighand (p, &flags)) -return ; + flags =read_seqbegin_or_lock_irqsave (&sig->stats_lock, &seq);switch (who) {case RUSAGE_BOTH :
@@ -1829,14 +1830,23 @@ void getrusage(struct task_struct *p, in r->ru_oublock += sig->oublock;if (maxrss < sig->maxrss) maxrss = sig->maxrss; + +rcu_read_lock ();__for_each_thread (sig, t)accumulate_thread_rusage (t, r); +rcu_read_unlock (); +break ;default :BUG (); } -unlock_task_sighand (p, &flags); + +if (need_seqretry (&sig->stats_lock, seq)) { + seq =1 ; + goto retry; + } +done_seqretry_irqrestore (&sig->stats_lock, seq, flags);if (who ==RUSAGE_CHILDREN ) goto out_children;
Greg Kroah-Hartman
maintainerPATCH 202/309 ksmbd: free aux buffer if ksmbd_iov_pin_rsp_read fails
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fedor Pchelkin <[email protected]>
commit 108a020c64434fed4b69762879d78cd24088b4c7 upstream.
ksmbd_iov_pin_rsp_read() doesn't free the provided aux buffer if it fails. Seems to be the caller's responsibility to clear the buffer in error case.
Found by Linux Verification Center (linuxtesting.org).
--- fs/smb/server/smb2pdu.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
fs/smb/server/smb2pdu.c +6 -2
@@ -6173,8 +6173,10 @@ static noinline int smb2_read_pipe(struc err =ksmbd_iov_pin_rsp_read (work, (void *)rsp, offsetof(struct smb2_read_rsp , Buffer), aux_payload_buf, nbytes); -if (err) +if (err) { +kvfree (aux_payload_buf); goto out; + }kvfree (rpc_resp); }else { err = ksmbd_iov_pin_rsp(work, (void *)rsp,
@@ -6384,8 +6386,10 @@ int smb2_read(struct ksmbd_work *work) err =ksmbd_iov_pin_rsp_read (work, (void *)rsp, offsetof(struct smb2_read_rsp , Buffer), aux_payload_buf, nbytes); -if (err) +if (err) { +kvfree (aux_payload_buf); goto out; + }ksmbd_fd_put (work, fp);return 0 ;
Greg Kroah-Hartman
maintainerPATCH 203/309 drm/nouveau: fix several DMA buffer leaks
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Timur Tabi <[email protected]>
commit 042b5f83841fbf7ce39474412db3b5e4765a7ea7 upstream.
Nouveau manages GSP-RM DMA buffers with nvkm_gsp_mem objects. Several of these buffers are never dealloced. Some of them can be deallocated right after GSP-RM is initialized, but the rest need to stay until the driver unloads.
Also futher bullet-proof these objects by poisoning the buffer and clearing the nvkm_gsp_mem object when it is deallocated. Poisoning the buffer should trigger an error (or crash) from GSP-RM if it tries to access the buffer after we've deallocated it, because we were wrong about when it is safe to deallocate.
Finally, change the mem->size field to a size_t because that's the same type that dma_alloc_coherent expects.
--- .../gpu/drm/nouveau/include/nvkm/subdev/gsp.h | 2 +- .../gpu/drm/nouveau/nvkm/subdev/gsp/r535.c | 59 ++++++++++++------- 2 files changed, 39 insertions(+), 22 deletions(-)
drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h +1 -1
@@ -9,7 +9,7 @@#define GSP_PAGE_SIZE BIT(GSP_PAGE_SHIFT)struct nvkm_gsp_mem { -u32 size; +size_t size;void *data;dma_addr_t addr; };
drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c +38 -21
83 lines not on this page · raw message
Signature · 1 line
2.43.2
Greg Kroah-Hartman
maintainerPATCH 204/309 drm/buddy: Fix alloc_range() error handling code
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arunpravin Paneer Selvam <[email protected]>
commit 8746c6c9dfa31d269c65dd52ab42fde0720b7d91 upstream.
Few users have observed display corruption when they boot the machine to KDE Plasma or playing games. We have root caused the problem that whenever alloc_range() couldn't find the required memory blocks the function was returning SUCCESS in some of the corner cases.
The right approach would be if the total allocated size is less than the required size, the function should return -ENOSPC.
--- drivers/gpu/drm/drm_buddy.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/gpu/drm/drm_buddy.c +6 -0
@@ -539,6 +539,12 @@ static int __alloc_range(struct drm_buddy *mm, }while (1 );list_splice_tail (&allocated, blocks); + +if (total_allocated < size) { + err = -ENOSPC ; + goto err_free; + } +return 0 ; err_undo:
Signature · 1 line
2.43.2
Greg Kroah-Hartman
maintainerPATCH 205/309 drm/msm: Wire up tlb ops
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rob Clark <[email protected]>
commit 8c7bfd8262319fd3f127a5380f593ea76f1b88a2 upstream.
The brute force iommu_flush_iotlb_all() was good enough for unmap, but in some cases a map operation could require removing a table pte entry to replace with a block entry. This also requires tlb invalidation. Missing this was resulting an obscure iova fault on what should be a valid buffer address.
Thanks to Robin Murphy for helping me understand the cause of the fault.
Patchwork: https://patchwork.freedesktop.org/patch/578117/
--- drivers/gpu/drm/msm/msm_iommu.c | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-)
drivers/gpu/drm/msm/msm_iommu.c +29 -3
@@ -21,6 +21,8 @@ struct msm_iommu_pagetable {struct msm_mmu base;struct msm_mmu *parent;struct io_pgtable_ops *pgtbl_ops; +const struct iommu_flush_ops *tlb; +struct device *iommu_dev;unsigned long pgsize_bitmap;/* Bitmap of page sizes in use */ phys_addr_t ttbr;u32 asid;
@@ -201,11 +203,33 @@ static const struct msm_mmu_funcs pagetastatic void msm_iommu_tlb_flush_all (void *cookie) { +struct msm_iommu_pagetable *pagetable = cookie; +struct adreno_smmu_priv *adreno_smmu; + +if (!pm_runtime_get_if_in_use (pagetable->iommu_dev)) +return ; + + adreno_smmu =dev_get_drvdata (pagetable->parent->dev); + + pagetable->tlb->tlb_flush_all ((void *)adreno_smmu->cookie); + +pm_runtime_put_autosuspend (pagetable->iommu_dev); }static void msm_iommu_tlb_flush_walk (unsigned long iova,size_t size,size_t granule,void *cookie) { +struct msm_iommu_pagetable *pagetable = cookie; +struct adreno_smmu_priv *adreno_smmu; + +if (!pm_runtime_get_if_in_use (pagetable->iommu_dev)) +return ; + + adreno_smmu =dev_get_drvdata (pagetable->parent->dev); + + pagetable->tlb->tlb_flush_walk (iova, size, granule, (void *)adreno_smmu->cookie); + +pm_runtime_put_autosuspend (pagetable->iommu_dev); } static void msm_iommu_tlb_add_page(struct iommu_iotlb_gather *gather,
@@ -213,7 +237,7 @@ static void msm_iommu_tlb_add_page(struc { } -static const struct iommu_flush_ops null_tlb_ops = { +static const struct iommu_flush_ops tlb_ops = { .tlb_flush_all = msm_iommu_tlb_flush_all, .tlb_flush_walk = msm_iommu_tlb_flush_walk, .tlb_add_page = msm_iommu_tlb_add_page,
@@ -254,10 +278,10 @@ struct msm_mmu *msm_iommu_pagetable_crea/* The incoming cfg will have the TTBR1 quirk enabled */ ttbr0_cfg.quirks &= ~IO_PGTABLE_QUIRK_ARM_TTBR1 ; - ttbr0_cfg.tlb = &null_tlb_ops; + ttbr0_cfg.tlb = &tlb_ops; pagetable->pgtbl_ops =alloc_io_pgtable_ops (ARM_64_LPAE_S1 , - &ttbr0_cfg, iommu->domain); + &ttbr0_cfg, pagetable);if (!pagetable->pgtbl_ops) {kfree (pagetable);
@@ -279,6 +303,8 @@ struct msm_mmu *msm_iommu_pagetable_crea/* Needed later for TLB flush */ pagetable->parent = parent; + pagetable->tlb = ttbr1_cfg->tlb; + pagetable->iommu_dev = ttbr1_cfg->iommu_dev; pagetable->pgsize_bitmap = ttbr0_cfg.pgsize_bitmap; pagetable->ttbr = ttbr0_cfg.arm_lpae_s1_cfg.ttbr;
Greg Kroah-Hartman
maintainerPATCH 206/309 drm/amd/display: Add align done check
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhikai Zhai <[email protected]>
commit 94b38b895dec8c0ef093140a141e191b60ff614c upstream.
[WHY]
We Double-check link status if training successful, but miss the lane align status.
[HOW]
Add the lane align status check
--- drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c +4 -1
@@ -517,6 +517,7 @@ enum link_training_result dp_check_link_ {enum link_training_result status =LINK_TRAINING_SUCCESS ;union lane_status lane_status; +union lane_align_status_updated dpcd_lane_status_updated;uint8_t dpcd_buf[6 ] = {0 };uint32_t lane;
@@ -532,10 +533,12 @@ enum link_training_result dp_check_link_* check lanes status */ lane_status.raw =dp_get_nibble_at_index (&dpcd_buf[2 ], lane); + dpcd_lane_status_updated.raw = dpcd_buf[4 ];if (!lane_status.bits.CHANNEL_EQ_DONE_0 || !lane_status.bits.CR_DONE_0 || - !lane_status.bits.SYMBOL_LOCKED_0) { + !lane_status.bits.SYMBOL_LOCKED_0 || + !dp_is_interlane_aligned (dpcd_lane_status_updated)) {/* if one of the channel equalization, clock * recovery or symbol lock is dropped * consider it as (link has been
Greg Kroah-Hartman
maintainerPATCH 207/309 drm/i915/dp: Limit SST link rate to <=8.1Gbps
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ville Syrjälä <[email protected]>
commit ad26d56d080780bbfcc1696ca0c0cce3e2124ef6 upstream.
Limit the link rate to HBR3 or below (<=8.1Gbps) in SST mode. UHBR (10Gbps+) link rates require 128b/132b channel encoding which we have not yet hooked up into the SST/no-sideband codepaths.
--- drivers/gpu/drm/i915/display/intel_dp.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/gpu/drm/i915/display/intel_dp.c +3 -0
@@ -2275,6 +2275,9 @@ intel_dp_compute_config_limits(struct in limits->min_rate =intel_dp_common_rate (intel_dp,0 ); limits->max_rate =intel_dp_max_link_rate (intel_dp); +/* FIXME 128b/132b SST support missing */ + limits->max_rate =min (limits->max_rate,810000 ); + limits->min_lane_count =1 ; limits->max_lane_count =intel_dp_max_lane_count (intel_dp);
Greg Kroah-Hartman
maintainerPATCH 208/309 drm/prime: Support page array >= 4GB
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Philip Yang <[email protected]>
commit b671cd3d456315f63171a670769356a196cf7fd0 upstream.
Without unsigned long typecast, the size is passed in as zero if page array size >= 4GB, nr_pages >= 0x100000, then sg list converted will have the first and the last chunk lost.
--- drivers/gpu/drm/drm_prime.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/drm_prime.c +1 -1
@@ -820,7 +820,7 @@ struct sg_table *drm_prime_pages_to_sg(sif (max_segment ==0 ) max_segment =UINT_MAX ; err =sg_alloc_table_from_pages_segment (sg, pages, nr_pages,0 , - nr_pages <<PAGE_SHIFT , + (unsigned long )nr_pages <<PAGE_SHIFT , max_segment,GFP_KERNEL );if (err) {kfree (sg);
Greg Kroah-Hartman
maintainerPATCH 209/309 drm/amdgpu/soc21: update VCN 4 max HEVC encoding resolution
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thong <[email protected]>
commit 2f542421a47e8246e9b7d2c6508fe3a6e6c63078 upstream.
Update the maximum resolution reported for HEVC encoding on VCN 4 devices to reflect its 8K encoding capability.
--- drivers/gpu/drm/amd/amdgpu/soc21.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/amd/amdgpu/soc21.c +2 -2
@@ -50,13 +50,13 @@ static const struct amd_ip_funcs soc21_c/* SOC21 */ static const struct amdgpu_video_codec_info vcn_4_0_0_video_codecs_encode_array_vcn0[] = { {codec_info_build (AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC ,4096 ,2304 ,0 )}, - {codec_info_build (AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC ,4096 ,2304 ,0 )}, + {codec_info_build (AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC ,8192 ,4352 ,0 )}, {codec_info_build (AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_AV1 ,8192 ,4352 ,0 )}, };static const struct amdgpu_video_codec_info vcn_4_0_0_video_codecs_encode_array_vcn1[] = { {codec_info_build (AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC ,4096 ,2304 ,0 )}, - {codec_info_build (AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC ,4096 ,2304 ,0 )}, + {codec_info_build (AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC ,8192 ,4352 ,0 )}, };static const struct amdgpu_video_codecs vcn_4_0_0_video_codecs_encode_vcn0 = {
Greg Kroah-Hartman
maintainerPATCH 210/309 drm/amd/display: Fix MST Null Ptr for RV
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fangzhi Zuo <[email protected]>
commit e6a7df96facdcf5b1f71eb3ec26f2f9f6ad61e57 upstream.
The change try to fix below error specific to RV platform:
BUG: kernel NULL pointer dereference, address: 0000000000000008 PGD 0 P4D 0 Oops: 0000 [#1] PREEMPT SMP NOPTI CPU: 4 PID: 917 Comm: sway Not tainted 6.3.9-arch1-1 #1 124dc55df4f5272ccb409f39ef4872fc2b3376a2 Hardware name: LENOVO 20NKS01Y00/20NKS01Y00, BIOS R12ET61W(1.31 ) 07/28/2022 RIP: 0010:drm_dp_atomic_find_time_slots+0x5e/0x260 [drm_display_helper] Code: 01 00 00 48 8b 85 60 05 00 00 48 63 80 88 00 00 00 3b 43 28 0f 8d 2e 01 00 00 48 8b 53 30 48 8d 04 80 48 8d 04 c2 48 8b 40 18 <48> 8> RSP: 0018:ffff960cc2df77d8 EFLAGS: 00010293 RAX: 0000000000000000 RBX: ffff8afb87e81280 RCX: 0000000000000224 RDX: ffff8afb9ee37c00 RSI: ffff8afb8da1a578 RDI: ffff8afb87e81280 RBP: ffff8afb83d67000 R08: 0000000000000001 R09: ffff8afb9652f850 R10: ffff960cc2df7908 R11: 0000000000000002 R12: 0000000000000000 R13: ffff8afb8d7688a0 R14: ffff8afb8da1a578 R15: 0000000000000224 FS: 00007f4dac35ce00(0000) GS:ffff8afe30b00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000008 CR3: 000000010ddc6000 CR4: 00000000003506e0 Call Trace: <TASK> ? __die+0x23/0x70 ? page_fault_oops+0x171/0x4e0 ? plist_add+0xbe/0x100 ? exc_page_fault+0x7c/0x180 ? asm_exc_page_fault+0x26/0x30 ? drm_dp_atomic_find_time_slots+0x5e/0x260 [drm_display_helper 0e67723696438d8e02b741593dd50d80b44c2026] ? drm_dp_atomic_find_time_slots+0x28/0x260 [drm_display_helper 0e67723696438d8e02b741593dd50d80b44c2026] compute_mst_dsc_configs_for_link+0x2ff/0xa40 [amdgpu 62e600d2a75e9158e1cd0a243bdc8e6da040c054] ? fill_plane_buffer_attributes+0x419/0x510 [amdgpu 62e600d2a75e9158e1cd0a243bdc8e6da040c054] compute_mst_dsc_configs_for_state+0x1e1/0x250 [amdgpu 62e600d2a75e9158e1cd0a243bdc8e6da040c054] amdgpu_dm_atomic_check+0xecd/0x1190 [amdgpu 62e600d2a75e9158e1cd0a243bdc8e6da040c054] drm_atomic_check_only+0x5c5/0xa40 drm_mode_atomic_ioctl+0x76e/0xbc0 ? _copy_to_user+0x25/0x30 ? drm_ioctl+0x296/0x4b0 ? __pfx_drm_mode_atomic_ioctl+0x10/0x10 drm_ioctl_kernel+0xcd/0x170 drm_ioctl+0x26d/0x4b0 ? __pfx_drm_mode_atomic_ioctl+0x10/0x10 amdgpu_drm_ioctl+0x4e/0x90 [amdgpu 62e600d2a75e9158e1cd0a243bdc8e6da040c054] __x64_sys_ioctl+0x94/0xd0 do_syscall_64+0x60/0x90 ? do_syscall_64+0x6c/0x90 entry_SYSCALL_64_after_hwframe+0x72/0xdc RIP: 0033:0x7f4dad17f76f Code: 00 48 89 44 24 18 31 c0 48 8d 44 24 60 c7 04 24 10 00 00 00 48 89 44 24 08 48 8d 44 24 20 48 89 44 24 10 b8 10 00 00 00 0f 05 <89> c> RSP: 002b:00007ffd9ae859f0 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 RAX: ffffffffffffffda RBX: 000055e255a55900 RCX: 00007f4dad17f76f RDX: 00007ffd9ae85a90 RSI: 00000000c03864bc RDI: 000000000000000b RBP: 00007ffd9ae85a90 R08: 0000000000000003 R09: 0000000000000003 R10: 0000000000000000 R11: 0000000000000246 R12: 00000000c03864bc R13: 000000000000000b R14: 000055e255a7fc60 R15: 000055e255a01eb0 </TASK> Modules linked in: rfcomm snd_seq_dummy snd_hrtimer snd_seq snd_seq_device ccm cmac algif_hash algif_skcipher af_alg joydev mousedev bnep > typec libphy k10temp ipmi_msghandler roles i2c_scmi acpi_cpufreq mac_hid nft_reject_inet nf_reject_ipv4 nf_reject_ipv6 nft_reject nft_mas> CR2: 0000000000000008 ---[ end trace 0000000000000000 ]--- RIP: 0010:drm_dp_atomic_find_time_slots+0x5e/0x260 [drm_display_helper] Code: 01 00 00 48 8b 85 60 05 00 00 48 63 80 88 00 00 00 3b 43 28 0f 8d 2e 01 00 00 48 8b 53 30 48 8d 04 80 48 8d 04 c2 48 8b 40 18 <48> 8> RSP: 0018:ffff960cc2df77d8 EFLAGS: 00010293 RAX: 0000000000000000 RBX: ffff8afb87e81280 RCX: 0000000000000224 RDX: ffff8afb9ee37c00 RSI: ffff8afb8da1a578 RDI: ffff8afb87e81280 RBP: ffff8afb83d67000 R08: 0000000000000001 R09: ffff8afb9652f850 R10: ffff960cc2df7908 R11: 0000000000000002 R12: 0000000000000000 R13: ffff8afb8d7688a0 R14: ffff8afb8da1a578 R15: 0000000000000224 FS: 00007f4dac35ce00(0000) GS:ffff8afe30b00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000008 CR3: 000000010ddc6000 CR4: 00000000003506e0
With a second DP monitor connected, drm_atomic_state in dm atomic check sequence does not include the connector state for the old/existing/first DP monitor. In such case, dsc determination policy would hit a null ptr when it tries to iterate the old/existing stream that does not have a valid connector state attached to it. When that happens, dm atomic check should call drm_atomic_get_connector_state for a new connector state. Existing dm has already done that, except for RV due to it does not have official support of dsc where .num_dsc is not defined in dcn10 resource cap, that prevent from getting drm_atomic_get_connector_state called. So, skip dsc determination policy for ASICs that don't have DSC support.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +7 -5
@@ -10440,11 +10440,13 @@ static int amdgpu_dm_atomic_check(struct goto fail; } - ret =compute_mst_dsc_configs_for_state (state, dm_state->context, vars); -if (ret) { -DRM_DEBUG_DRIVER ("compute_mst_dsc_configs_for_state() failed\n" ); - ret = -EINVAL ; - goto fail; +if (dc_resource_is_dsc_encoding_supported (dc)) { + ret =compute_mst_dsc_configs_for_state (state, dm_state->context, vars); +if (ret) { +DRM_DEBUG_DRIVER ("compute_mst_dsc_configs_for_state() failed\n" ); + ret = -EINVAL ; + goto fail; + } } ret =dm_update_mst_vcpi_slots_for_dsc (state, dm_state->context, vars);
Greg Kroah-Hartman
maintainerPATCH 211/309 drm/amd/display: Increase frame-larger-than for all display_mode_vba files
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nathan Chancellor <[email protected]>
commit e63e35f0164c43fbc1adb481d6604f253b9f9667 upstream.
After a recent change in LLVM, allmodconfig (which has CONFIG_KCSAN=y and CONFIG_WERROR=y enabled) has a few new instances of -Wframe-larger-than for the mode support and system configuration functions:
drivers/gpu/drm/amd/amdgpu/../display/dc/dml/dcn20/display_mode_vba_20v2.c:3393:6: error: stack frame size (2144) exceeds limit (2048) in 'dml20v2_ModeSupportAndSystemConfigurationFull' [-Werror,-Wframe-larger-than]
3393 | void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_lib)
| ^
1 error generated.
drivers/gpu/drm/amd/amdgpu/../display/dc/dml/dcn21/display_mode_vba_21.c:3520:6: error: stack frame size (2192) exceeds limit (2048) in 'dml21_ModeSupportAndSystemConfigurationFull' [-Werror,-Wframe-larger-than]
3520 | void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_lib)
| ^
1 error generated.
drivers/gpu/drm/amd/amdgpu/../display/dc/dml/dcn20/display_mode_vba_20.c:3286:6: error: stack frame size (2128) exceeds limit (2048) in 'dml20_ModeSupportAndSystemConfigurationFull' [-Werror,-Wframe-larger-than]
3286 | void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_lib)
| ^
1 error generated.
Without the sanitizers enabled, there are no warnings.
This was the catalyst for commit 6740ec97bcdb ("drm/amd/display:
Increase frame warning limit with KASAN or KCSAN in dml2") and that same change was made to dml in commit 5b750b22530f ("drm/amd/display:
Increase frame warning limit with KASAN or KCSAN in dml") but the frame_warn_flag variable was not applied to all files. Do so now to clear up the warnings and make all these files consistent.
--- drivers/gpu/drm/amd/display/dc/dml/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/gpu/drm/amd/display/dc/dml/Makefile +3 -3
@@ -72,11 +72,11 @@ CFLAGS_$(AMDDALPATH)/dc/dml/display_mode CFLAGS_$(AMDDALPATH)/dc/dml/display_mode_vba.o := $(dml_ccflags) CFLAGS_$(AMDDALPATH)/dc/dml/dcn10/dcn10_fpu.o := $(dml_ccflags) CFLAGS_$(AMDDALPATH)/dc/dml/dcn20/dcn20_fpu.o := $(dml_ccflags) -CFLAGS_$(AMDDALPATH)/dc/dml/dcn20/display_mode_vba_20.o := $(dml_ccflags) +CFLAGS_$(AMDDALPATH)/dc/dml/dcn20/display_mode_vba_20.o := $(dml_ccflags) $(frame_warn_flag) CFLAGS_$(AMDDALPATH)/dc/dml/dcn20/display_rq_dlg_calc_20.o := $(dml_ccflags) -CFLAGS_$(AMDDALPATH)/dc/dml/dcn20/display_mode_vba_20v2.o := $(dml_ccflags) +CFLAGS_$(AMDDALPATH)/dc/dml/dcn20/display_mode_vba_20v2.o := $(dml_ccflags) $(frame_warn_flag) CFLAGS_$(AMDDALPATH)/dc/dml/dcn20/display_rq_dlg_calc_20v2.o := $(dml_ccflags) -CFLAGS_$(AMDDALPATH)/dc/dml/dcn21/display_mode_vba_21.o := $(dml_ccflags) +CFLAGS_$(AMDDALPATH)/dc/dml/dcn21/display_mode_vba_21.o := $(dml_ccflags) $(frame_warn_flag) CFLAGS_$(AMDDALPATH)/dc/dml/dcn21/display_rq_dlg_calc_21.o := $(dml_ccflags) CFLAGS_$(AMDDALPATH)/dc/dml/dcn30/display_mode_vba_30.o := $(dml_ccflags) $(frame_warn_flag) CFLAGS_$(AMDDALPATH)/dc/dml/dcn30/display_rq_dlg_calc_30.o := $(dml_ccflags)
Greg Kroah-Hartman
maintainerPATCH 212/309 drm/amd/display: Fix array-index-out-of-bounds in dcn35_clkmgr
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Roman Li <[email protected]>
commit 46806e59a87790760870d216f54951a5b4d545bc upstream.
[Why]
There is a potential memory access violation while iterating through array of dcn35 clks.
[How]
Limit iteration per array size.
--- drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c | 17 +++++++---- 1 file changed, 12 insertions(+), 5 deletions(-)
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c +12 -5
@@ -654,10 +654,13 @@ static void dcn35_clk_mgr_helper_populatstruct clk_limit_table_entry def_max = bw_params->clk_table.entries[bw_params->clk_table.num_entries -1 ];uint32_t max_fclk =0 , min_pstate =0 , max_dispclk =0 , max_dppclk =0 ;uint32_t max_pstate =0 , max_dram_speed_mts =0 , min_dram_speed_mts =0 ; +uint32_t num_memps, num_fclk, num_dcfclk;int i;/* Determine min/max p-state values. */ -for (i =0 ; i < clock_table->NumMemPstatesEnabled; i++) { + num_memps = (clock_table->NumMemPstatesEnabled >NUM_MEM_PSTATE_LEVELS ) ?NUM_MEM_PSTATE_LEVELS : + clock_table->NumMemPstatesEnabled; +for (i =0 ; i < num_memps; i++) {uint32_t dram_speed_mts =calc_dram_speed_mts (&clock_table->MemPstateTable[i]);if (is_valid_clock_value (dram_speed_mts) && dram_speed_mts > max_dram_speed_mts) {
@@ -669,7 +672,7 @@ static void dcn35_clk_mgr_helper_populat min_dram_speed_mts = max_dram_speed_mts; min_pstate = max_pstate; -for (i =0 ; i < clock_table->NumMemPstatesEnabled; i++) { +for (i =0 ; i < num_memps; i++) {uint32_t dram_speed_mts =calc_dram_speed_mts (&clock_table->MemPstateTable[i]);if (is_valid_clock_value (dram_speed_mts) && dram_speed_mts < min_dram_speed_mts) {
@@ -698,9 +701,13 @@ static void dcn35_clk_mgr_helper_populat/* Base the clock table on dcfclk, need at least one entry regardless of pmfw table */ ASSERT (clock_table->NumDcfClkLevelsEnabled >0 ); - max_fclk =find_max_clk_value (clock_table->FclkClocks_Freq, clock_table->NumFclkLevelsEnabled); - -for (i =0 ; i < clock_table->NumDcfClkLevelsEnabled; i++) { + num_fclk = (clock_table->NumFclkLevelsEnabled >NUM_FCLK_DPM_LEVELS ) ?NUM_FCLK_DPM_LEVELS : + clock_table->NumFclkLevelsEnabled; + max_fclk =find_max_clk_value (clock_table->FclkClocks_Freq, num_fclk); + + num_dcfclk = (clock_table->NumFclkLevelsEnabled >NUM_DCFCLK_DPM_LEVELS ) ?NUM_DCFCLK_DPM_LEVELS : + clock_table->NumDcfClkLevelsEnabled; +for (i =0 ; i < num_dcfclk; i++) {int j;/* First search defaults for the clocks we don't read using closest lower or equal default dcfclk */
Greg Kroah-Hartman
maintainerPATCH 213/309 drm/amd/display: Preserve original aspect ratio in create stream
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tom Chung <[email protected]>
commit deb110292180cd501f6fde2a0178d65fcbcabb0c upstream.
[Why]
The original picture aspect ratio in mode struct may have chance be overwritten with wrong aspect ratio data in create_stream_for_sink(). It will create a different VIC output and cause HDMI compliance test failed.
[How]
Preserve the original picture aspect ratio data during create the stream.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +2 -0
@@ -6110,7 +6110,9 @@ create_stream_for_sink(struct drm_connecif (recalculate_timing) { freesync_mode =get_highest_refresh_rate_mode (aconnector, false);drm_mode_copy (&saved_mode, &mode); + saved_mode.picture_aspect_ratio = mode.picture_aspect_ratio;drm_mode_copy (&mode, freesync_mode); + mode.picture_aspect_ratio = saved_mode.picture_aspect_ratio; }else {decide_crtc_timing_for_drm_display_mode ( &mode, preferred_mode, scale);
Greg Kroah-Hartman
maintainerPATCH 214/309 drm/amdgpu: Avoid fetching VRAM vendor info
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lijo Lazar <[email protected]>
commit 55173942a63668bdc1d61812c7c9e0406aefb5bf upstream.
The present way to fetch VRAM vendor information turns out to be not reliable on GFX 9.4.3 dGPUs as well. Avoid using the data.
--- drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | 8 -------- 1 file changed, 8 deletions(-)
drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +0 -8
@@ -1947,14 +1947,6 @@ static int gmc_v9_0_init_mem_ranges(strustatic void gmc_v9_4_3_init_vram_info (struct amdgpu_device *adev) { -static const u32 regBIF_BIOS_SCRATCH_4 =0x50 ; -u32 vram_info; - -/* Only for dGPU, vendor informaton is reliable */ -if (!amdgpu_sriov_vf (adev) && !(adev->flags &AMD_IS_APU )) { - vram_info =RREG32 (regBIF_BIOS_SCRATCH_4); - adev->gmc.vram_vendor = vram_info &0xF ; - } adev->gmc.vram_type =AMDGPU_VRAM_TYPE_HBM ; adev->gmc.vram_width =128 *64 ; }
Greg Kroah-Hartman
maintainerPATCH 215/309 hv_netvsc: Fix race condition between netvsc_probe and netvsc_remove
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Souradeep Chakrabarti <[email protected]>
commit e0526ec5360a48ad3ab2e26e802b0532302a7e11 upstream.
In commit ac5047671758 ("hv_netvsc: Disable NAPI before closing the VMBus channel"), napi_disable was getting called for all channels, including all subchannels without confirming if they are enabled or not.
This caused hv_netvsc getting hung at napi_disable, when netvsc_probe() has finished running but nvdev->subchan_work has not started yet. netvsc_subchan_work() -> rndis_set_subchannel() has not created the sub-channels and because of that netvsc_sc_open() is not running. netvsc_remove() calls cancel_work_sync(&nvdev->subchan_work), for which netvsc_subchan_work did not run.
netif_napi_add() sets the bit NAPI_STATE_SCHED because it ensures NAPI cannot be scheduled. Then netvsc_sc_open() -> napi_enable will clear the NAPIF_STATE_SCHED bit, so it can be scheduled. napi_disable() does the opposite.
Now during netvsc_device_remove(), when napi_disable is called for those subchannels, napi_disable gets stuck on infinite msleep.
This fix addresses this problem by ensuring that napi_disable() is not getting called for non-enabled NAPI struct.
But netif_napi_del() is still necessary for these non-enabled NAPI struct for cleanup purpose.
Call trace: [ 654.559417] task:modprobe state:D stack: 0 pid: 2321 ppid: 1091 flags:0x00004002 [ 654.568030] Call Trace: [ 654.571221] <TASK> [ 654.573790] __schedule+0x2d6/0x960 [ 654.577733] schedule+0x69/0xf0 [ 654.581214] schedule_timeout+0x87/0x140 [ 654.585463] ? __bpf_trace_tick_stop+0x20/0x20 [ 654.590291] msleep+0x2d/0x40 [ 654.593625] napi_disable+0x2b/0x80 [ 654.597437] netvsc_device_remove+0x8a/0x1f0 [hv_netvsc] [ 654.603935] rndis_filter_device_remove+0x194/0x1c0 [hv_netvsc] [ 654.611101] ? do_wait_intr+0xb0/0xb0 [ 654.615753] netvsc_remove+0x7c/0x120 [hv_netvsc] [ 654.621675] vmbus_remove+0x27/0x40 [hv_vmbus]
--- drivers/net/hyperv/netvsc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/net/hyperv/netvsc.c +4 -1
@@ -708,7 +708,10 @@ void netvsc_device_remove(struct hv_devi/* Disable NAPI and disassociate its context from the device. */ for (i =0 ; i < net_device->num_chn; i++) {/* See also vmbus_reset_channel_cb(). */ -napi_disable (&net_device->chan_table[i].napi); +/* only disable enabled NAPI channel */ +if (i < ndev->real_num_rx_queues) +napi_disable (&net_device->chan_table[i].napi); +netif_napi_del (&net_device->chan_table[i].napi); }
Greg Kroah-Hartman
maintainerPATCH 216/309 ring-buffer: Clean ring_buffer_poll_wait() error return
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vincent Donnefort <[email protected]>
commit 66bbea9ed6446b8471d365a22734dc00556c4785 upstream.
The return type for ring_buffer_poll_wait() is __poll_t. This is behind the scenes an unsigned where we can set event bits. In case of a non-allocated CPU, we do return instead -EINVAL (0xffffffea). Lucky us, this ends up setting few error bits (EPOLLERR | EPOLLHUP | EPOLLNVAL), so user-space at least is aware something went wrong.
Nonetheless, this is an incorrect code. Replace that -EINVAL with a proper EPOLLERR to clean that output. As this doesn't change the behaviour, there's no need to treat this change as a bug fix.
--- kernel/trace/ring_buffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/trace/ring_buffer.c +1 -1
@@ -1091,7 +1091,7 @@ __poll_t ring_buffer_poll_wait(struct tr full =0 ; }else {if (!cpumask_test_cpu (cpu, buffer->cpumask)) -return -EINVAL ; +return EPOLLERR ; cpu_buffer = buffer->buffers[cpu]; work = &cpu_buffer->irq_work;
Greg Kroah-Hartman
maintainerPATCH 217/309 net: dsa: mv88e6xxx: Fix failed probe due to unsupported C45 reads
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrew Lunn <[email protected]>
commit 585b40e25dc9ff3d2b03d1495150540849009e5b upstream.
Not all mv88e6xxx device support C45 read/write operations. Those which do not return -EOPNOTSUPP. However, when phylib scans the bus, it considers this fatal, and the probe of the MDIO bus fails, which in term causes the mv88e6xxx probe as a whole to fail.
When there is no device on the bus for a given address, the pull up resistor on the data line results in the read returning 0xffff. The phylib core code understands this when scanning for devices on the bus. C45 allows multiple devices to be supported at one address, so phylib will perform a few reads at each address, so although thought not the most efficient solution, it is a way to avoid fatal errors. Make use of this as a minimal fix for stable to fix the probing problems.
Follow up patches will rework how C45 operates to make it similar to C22 which considers -ENODEV as a none-fatal, and swap mv88e6xxx to using this.
--- drivers/net/dsa/mv88e6xxx/chip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/dsa/mv88e6xxx/chip.c +1 -1
@@ -3545,7 +3545,7 @@ static int mv88e6xxx_mdio_read_c45(strucint err;if (!chip->info->ops->phy_read_c45) -return -EOPNOTSUPP ; +return 0xffff ;mv88e6xxx_reg_lock (chip); err = chip->info->ops->phy_read_c45 (chip, bus, phy, devad, reg, &val);
Greg Kroah-Hartman
maintainerPATCH 218/309 nfp: flower: add hardware offload check for post ct entry
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hui Zhou <[email protected]>
commit cefa98e806fd4e2a5e2047457a11ae5f17b8f621 upstream.
The nfp offload flow pay will not allocate a mask id when the out port is openvswitch internal port. This is because these flows are used to configure the pre_tun table and are never actually send to the firmware as an add-flow message. When a tc rule which action contains ct and the post ct entry's out port is openvswitch internal port, the merge offload flow pay with the wrong mask id of 0 will be send to the firmware. Actually, the nfp can not support hardware offload for this situation, so return EOPNOTSUPP.
--- drivers/net/ethernet/netronome/nfp/flower/conntrack.c | 22 +++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-)
drivers/net/ethernet/netronome/nfp/flower/conntrack.c +21 -1
@@ -1864,10 +1864,30 @@ int nfp_fl_ct_handle_post_ct(struct nfp_ {struct flow_rule *rule =flow_cls_offload_flow_rule (flow);struct nfp_fl_ct_flow_entry *ct_entry; +struct flow_action_entry *ct_goto;struct nfp_fl_ct_zone_entry *zt; +struct flow_action_entry *act;bool wildcarded = false;struct flow_match_ct ct; -struct flow_action_entry *ct_goto; +int i; + +flow_action_for_each (i, act, &rule->action) { +switch (act->id) { +case FLOW_ACTION_REDIRECT : +case FLOW_ACTION_REDIRECT_INGRESS : +case FLOW_ACTION_MIRRED : +case FLOW_ACTION_MIRRED_INGRESS : +if (act->dev->rtnl_link_ops && + !strcmp (act->dev->rtnl_link_ops->kind,"openvswitch" )) { +NL_SET_ERR_MSG_MOD (extack, +"unsupported offload: out port is openvswitch internal port" ); +return -EOPNOTSUPP ; + } +break ; +default : +break ; + } + }flow_rule_match_ct (rule, &ct);if (!ct.mask->ct_zone) {
Greg Kroah-Hartman
maintainerPATCH 219/309 nfp: flower: fix hardware offload for the transfer layer port
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hui Zhou <[email protected]>
commit 3a007b8009b5f8af021021b7a590a6da0dc4c6e0 upstream.
The nfp driver will merge the tp source port and tp destination port into one dword which the offset must be zero to do hardware offload. However, the mangle action for the tp source port and tp destination port is separated for tc ct action. Modify the mangle action for the FLOW_ACT_MANGLE_HDR_TYPE_TCP and FLOW_ACT_MANGLE_HDR_TYPE_UDP to satisfy the nfp driver offload check for the tp port.
The mangle action provides a 4B value for source, and a 4B value for the destination, but only 2B of each contains the useful information. For offload the 2B of each is combined into a single 4B word. Since the incoming mask for the source is '0xFFFF<mask>' the shift-left will throw away the 0xFFFF part. When this gets combined together in the offload it will clear the destination field. Fix this by setting the lower bits back to 0xFFFF, effectively doing a rotate-left operation on the mask.
--- drivers/net/ethernet/netronome/nfp/flower/conntrack.c | 24 ++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-)
drivers/net/ethernet/netronome/nfp/flower/conntrack.c +22 -2
@@ -1424,10 +1424,30 @@ static void nfp_nft_ct_translate_mangle_ mangle_action->mangle.mask = (__force u32 )cpu_to_be32 (mangle_action->mangle.mask);return ; +/* Both struct tcphdr and struct udphdr start with +* __be16 source; +* __be16 dest; +* so we can use the same code for both. +*/ case FLOW_ACT_MANGLE_HDR_TYPE_TCP :case FLOW_ACT_MANGLE_HDR_TYPE_UDP : - mangle_action->mangle.val = (__force u16 )cpu_to_be16 (mangle_action->mangle.val); - mangle_action->mangle.mask = (__force u16 )cpu_to_be16 (mangle_action->mangle.mask); +if (mangle_action->mangle.offset == offsetof(struct tcphdr , source)) { + mangle_action->mangle.val = + (__force u32 )cpu_to_be32 (mangle_action->mangle.val <<16 ); +/* The mask of mangle action is inverse mask, +* so clear the dest tp port with 0xFFFF to +* instead of rotate-left operation. +*/ + mangle_action->mangle.mask = + (__force u32 )cpu_to_be32 (mangle_action->mangle.mask <<16 |0xFFFF ); + } +if (mangle_action->mangle.offset == offsetof(struct tcphdr , dest)) { + mangle_action->mangle.offset =0 ; + mangle_action->mangle.val = + (__force u32 )cpu_to_be32 (mangle_action->mangle.val); + mangle_action->mangle.mask = + (__force u32 )cpu_to_be32 (mangle_action->mangle.mask); + }return ;default :
Greg Kroah-Hartman
maintainerPATCH 220/309 serial: core: Fix atomicity violation in uart_tiocmget
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gui-Dong Han <[email protected]>
commit 30926783a46841c2d1bbf3f74067ba85d304fd0d upstream.
In uart_tiocmget():
result = uport->mctrl;
uart_port_lock_irq(uport);
result |= uport->ops->get_mctrl(uport);
uart_port_unlock_irq(uport);
...
return result;In uart_update_mctrl():
uart_port_lock_irqsave(port, &flags);
...
port->mctrl = (old & ~clear) | set;
...
port->ops->set_mctrl(port, port->mctrl);
...
uart_port_unlock_irqrestore(port, flags);An atomicity violation is identified due to the concurrent execution of uart_tiocmget() and uart_update_mctrl(). After assigning result = uport->mctrl, the mctrl value may change in uart_update_mctrl(), leading to a mismatch between the value returned by uport->ops->get_mctrl(uport) and the mctrl value previously read. This can result in uart_tiocmget() returning an incorrect value.
This possible bug is found by an experimental static analysis tool developed by our team, BassCheck[1]. 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. The above possible bug is reported when our tool analyzes the source code of Linux 5.17.
To address this issue, it is suggested to move the line result = uport->mctrl inside the uart_port_lock block to ensure atomicity and prevent the mctrl value from being altered during the execution of uart_tiocmget(). With this patch applied, our tool no longer reports the bug, with the kernel configuration allyesconfig for x86_64. Due to the absence of the requisite hardware, we are unable to conduct runtime testing of the patch. Therefore, our verification is solely based on code logic analysis.
[1] https://sites.google.com/view/basscheck/
--- drivers/tty/serial/serial_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/tty/serial/serial_core.c +1 -1
@@ -1085,8 +1085,8 @@ static int uart_tiocmget(struct tty_stru goto out;if (!tty_io_error (tty)) { - result = uport->mctrl;uart_port_lock_irq (uport); + result = uport->mctrl; result |= uport->ops->get_mctrl (uport);uart_port_unlock_irq (uport); }
Greg Kroah-Hartman
maintainerPATCH 221/309 serial: max310x: set default value when reading clock ready bit
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hugo Villeneuve <[email protected]>
commit 0419373333c2f2024966d36261fd82a453281e80 upstream.
If regmap_read() returns a non-zero value, the 'val' variable can be left uninitialized.
Clear it before calling regmap_read() to make sure we properly detect the clock ready bit.
--- drivers/tty/serial/max310x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/tty/serial/max310x.c +1 -1
@@ -641,7 +641,7 @@ static u32 max310x_set_ref_clk(struct de/* Wait for crystal */ if (xtal) { -unsigned int val; +unsigned int val =0 ;msleep (10 );regmap_read (s->regmap,MAX310X_STS_IRQSTS_REG , &val);if (!(val &MAX310X_STS_CLKREADY_BIT )) {
Greg Kroah-Hartman
maintainerPATCH 222/309 serial: max310x: improve crystal stable clock detection
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hugo Villeneuve <[email protected]>
commit 93cd256ab224c2519e7c4e5f58bb4f1ac2bf0965 upstream.
Some people are seeing a warning similar to this when using a crystal:
max310x 11-006c: clock is not stable yet
The datasheet doesn't mention the maximum time to wait for the clock to be stable when using a crystal, and it seems that the 10ms delay in the driver is not always sufficient.
Jan Kundrát reported that it took three tries (each separated by 10ms) to get a stable clock.
Modify behavior to check stable clock ready bit multiple times (20), and waiting 10ms between each try.
Note: the first draft of the driver originally used a 50ms delay, without checking the clock stable bit.
Then a loop with 1000 retries was implemented, each time reading the clock stable bit.
--- drivers/tty/serial/max310x.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-)
drivers/tty/serial/max310x.c +16 -5
@@ -237,6 +237,10 @@#define MAX310x_REV_MASK (0xf8)#define MAX310X_WRITE_BIT 0x80 +/* Crystal-related definitions */ +#define MAX310X_XTAL_WAIT_RETRIES 20/* Number of retries */ +#define MAX310X_XTAL_WAIT_DELAY_MS 10/* Delay between retries */ +/* MAX3107 specific */ #define MAX3107_REV_ID (0xa0)
@@ -641,12 +645,19 @@ static u32 max310x_set_ref_clk(struct de/* Wait for crystal */ if (xtal) { -unsigned int val =0 ; -msleep (10 ); -regmap_read (s->regmap,MAX310X_STS_IRQSTS_REG , &val); -if (!(val &MAX310X_STS_CLKREADY_BIT )) { +bool stable = false; +unsigned int try =0 , val =0 ; + +do { +msleep (MAX310X_XTAL_WAIT_DELAY_MS ); +regmap_read (s->regmap,MAX310X_STS_IRQSTS_REG , &val); + +if (val &MAX310X_STS_CLKREADY_BIT ) + stable = true; + }while (!stable && (++try <MAX310X_XTAL_WAIT_RETRIES )); + +if (!stable)dev_warn (dev,"clock is not stable yet\n" ); - } }return bestfreq;
Greg Kroah-Hartman
maintainerPATCH 223/309 serial: max310x: fail probe if clock crystal is unstable
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hugo Villeneuve <[email protected]>
commit 8afa6c6decea37e7cb473d2c60473f37f46cea35 upstream.
A stable clock is really required in order to use this UART, so log an error message and bail out if the chip reports that the clock is not stable.
--- drivers/tty/serial/max310x.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
drivers/tty/serial/max310x.c +9 -3
@@ -587,7 +587,7 @@ static int max310x_update_best_err(unsigreturn 1 ; } -static u32 max310x_set_ref_clk (struct device *dev,struct max310x_port *s, +static s32 max310x_set_ref_clk (struct device *dev,struct max310x_port *s,unsigned long freq,bool xtal) {unsigned int div, clksrc, pllcfg =0 ;
@@ -657,7 +657,8 @@ static u32 max310x_set_ref_clk(struct de }while (!stable && (++try <MAX310X_XTAL_WAIT_RETRIES ));if (!stable) -dev_warn (dev,"clock is not stable yet\n" ); +return dev_err_probe (dev, -EAGAIN , +"clock is not stable\n" ); }return bestfreq;
@@ -1282,7 +1283,7 @@ static int max310x_probe(struct device * {int i, ret, fmin, fmax, freq;struct max310x_port *s; -u32 uartclk =0 ; +s32 uartclk =0 ;bool xtal;for (i =0 ; i < devtype->nr; i++)
@@ -1360,6 +1361,11 @@ static int max310x_probe(struct device * } uartclk =max310x_set_ref_clk (dev, s, freq, xtal); +if (uartclk <0 ) { + ret = uartclk; + goto out_uart; + } +dev_dbg (dev,"Reference clock set to %i Hz\n" , uartclk);for (i =0 ; i < devtype->nr; i++) {
Greg Kroah-Hartman
maintainerPATCH 224/309 serial: max310x: prevent infinite while() loop in port startup
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hugo Villeneuve <[email protected]>
commit b35f8dbbce818b02c730dc85133dc7754266e084 upstream.
If there is a problem after resetting a port, the do/while() loop that checks the default value of DIVLSB register may run forever and spam the I2C bus.
Add a delay before each read of DIVLSB, and a maximum number of tries to prevent that situation from happening.
Also fail probe if port reset is unsuccessful.
--- drivers/tty/serial/max310x.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-)
drivers/tty/serial/max310x.c +18 -2
@@ -237,6 +237,10 @@#define MAX310x_REV_MASK (0xf8)#define MAX310X_WRITE_BIT 0x80 +/* Port startup definitions */ +#define MAX310X_PORT_STARTUP_WAIT_RETRIES 20/* Number of retries */ +#define MAX310X_PORT_STARTUP_WAIT_DELAY_MS 10/* Delay between retries */ +/* Crystal-related definitions */ #define MAX310X_XTAL_WAIT_RETRIES 20/* Number of retries */ #define MAX310X_XTAL_WAIT_DELAY_MS 10/* Delay between retries */
@@ -1346,6 +1350,9 @@ static int max310x_probe(struct device * goto out_clk;for (i =0 ; i < devtype->nr; i++) { +bool started = false; +unsigned int try =0 , val =0 ; +/* Reset port */ regmap_write (regmaps[i],MAX310X_MODE2_REG ,MAX310X_MODE2_RST_BIT );
@@ -1354,8 +1361,17 @@ static int max310x_probe(struct device */* Wait for port startup */ do { -regmap_read (regmaps[i],MAX310X_BRGDIVLSB_REG , &ret); - }while (ret !=0x01 ); +msleep (MAX310X_PORT_STARTUP_WAIT_DELAY_MS ); +regmap_read (regmaps[i],MAX310X_BRGDIVLSB_REG , &val); + +if (val ==0x01 ) + started = true; + }while (!started && (++try <MAX310X_PORT_STARTUP_WAIT_RETRIES )); + +if (!started) { + ret =dev_err_probe (dev, -EAGAIN ,"port reset failed\n" ); + goto out_uart; + }regmap_write (regmaps[i],MAX310X_MODE1_REG , devtype->mode1); }
Greg Kroah-Hartman
maintainerPATCH 225/309 ftrace: Fix DIRECT_CALLS to use SAVE_REGS by default
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Masami Hiramatsu (Google) <[email protected]>
commit a8b9cf62ade1bf17261a979fc97e40c2d7842353 upstream.
The commit 60c8971899f3 ("ftrace: Make DIRECT_CALLS work WITH_ARGS and !WITH_REGS") changed DIRECT_CALLS to use SAVE_ARGS when there are multiple ftrace_ops at the same function, but since the x86 only support to jump to direct_call from ftrace_regs_caller, when we set the function tracer on the same target function on x86, ftrace-direct does not work as below (this actually works on arm64.)
At first, insmod ftrace-direct.ko to put a direct_call on 'wake_up_process()'.
# insmod kernel/samples/ftrace/ftrace-direct.ko
# less trace
...
<idle>-0 [006] ..s1. 564.686958: my_direct_func: waking up rcu_preempt-17
<idle>-0 [007] ..s1. 564.687836: my_direct_func: waking up kcompactd0-63
<idle>-0 [006] ..s1. 564.690926: my_direct_func: waking up rcu_preempt-17
<idle>-0 [006] ..s1. 564.696872: my_direct_func: waking up rcu_preempt-17
<idle>-0 [007] ..s1. 565.191982: my_direct_func: waking up kcompactd0-63Setup a function filter to the 'wake_up_process' too, and enable it.
# cd /sys/kernel/tracing/
# echo wake_up_process > set_ftrace_filter
# echo function > current_tracer
# less trace
...
<idle>-0 [006] ..s3. 686.180972: wake_up_process <-call_timer_fn
<idle>-0 [006] ..s3. 686.186919: wake_up_process <-call_timer_fn
<idle>-0 [002] ..s3. 686.264049: wake_up_process <-call_timer_fn
<idle>-0 [002] d.h6. 686.515216: wake_up_process <-kick_pool
<idle>-0 [002] d.h6. 686.691386: wake_up_process <-kick_poolThen, only function tracer is shown on x86.
But if you enable 'kprobe on ftrace' event (which uses SAVE_REGS flag) on the same function, it is shown again.
# echo 'p wake_up_process' >> dynamic_events
# echo 1 > events/kprobes/p_wake_up_process_0/enable
# echo > trace
# less trace
...
<idle>-0 [006] ..s2. 2710.345919: p_wake_up_process_0: (wake_up_process+0x4/0x20)
<idle>-0 [006] ..s3. 2710.345923: wake_up_process <-call_timer_fn
<idle>-0 [006] ..s1. 2710.345928: my_direct_func: waking up rcu_preempt-17
<idle>-0 [006] ..s2. 2710.349931: p_wake_up_process_0: (wake_up_process+0x4/0x20)
<idle>-0 [006] ..s3. 2710.349934: wake_up_process <-call_timer_fn
<idle>-0 [006] ..s1. 2710.349937: my_direct_func: waking up rcu_preempt-17To fix this issue, use SAVE_REGS flag for multiple ftrace_ops flag of direct_call by default.
--- kernel/trace/ftrace.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
kernel/trace/ftrace.c +10 -0
@@ -5325,7 +5325,17 @@ static LIST_HEAD(ftrace_direct_funcs);static int register_ftrace_function_nolock (struct ftrace_ops *ops); +/* +* If there are multiple ftrace_ops, use SAVE_REGS by default, so that direct +* call will be jumped from ftrace_regs_caller. Only if the architecture does +* not support ftrace_regs_caller but direct_call, use SAVE_ARGS so that it +* jumps from ftrace_caller for multiple ftrace_ops. +*/ +#ifndef HAVE_DYNAMIC_FTRACE_WITH_REGS #define MULTI_FLAGS (FTRACE_OPS_FL_DIRECT | FTRACE_OPS_FL_SAVE_ARGS) +#else +#define MULTI_FLAGS (FTRACE_OPS_FL_DIRECT | FTRACE_OPS_FL_SAVE_REGS) +#endif static int check_direct_multi (struct ftrace_ops *ops) {
Greg Kroah-Hartman
maintainerPATCH 226/309 powerpc/64: Set task pt_regs->link to the LR value on scv entry
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Naveen N Rao <[email protected]>
commit aad98efd0b121f63a2e1c221dcb4d4850128c697 upstream.
Nysal reported that userspace backtraces are missing in offcputime bcc tool. As an example:
$ sudo ./bcc/tools/offcputime.py -uU
Tracing off-CPU time (us) of user threads by user stack... Hit Ctrl-C to end.^C write - python (9107) 8 write - sudo (9105) 9 mmap - python (9107) 16 clock_nanosleep - multipathd (697) 3001604
The offcputime bcc tool attaches a bpf program to a kprobe on finish_task_switch(), which is usually hit on a syscall from userspace. With the switch to system call vectored, we started setting pt_regs->link to zero. This is because system call vectored behaves like a function call with LR pointing to the system call return address, and with no modification to SRR0/SRR1. The LR value does indicate our next instruction, so it is being saved as pt_regs->nip, and pt_regs->link is being set to zero. This is not a problem by itself, but BPF uses perf callchain infrastructure for capturing stack traces, and that stores LR as the second entry in the stack trace. perf has code to cope with the second entry being zero, and skips over it. However, generic userspace unwinders assume that a zero entry indicates end of the stack trace, resulting in a truncated userspace stack trace.
Rather than fixing all userspace unwinders to ignore/skip past the second entry, store the real LR value in pt_regs->link so that there continues to be a valid, though duplicate entry in the stack trace.
With this change:
$ sudo ./bcc/tools/offcputime.py -uU
Tracing off-CPU time (us) of user threads by user stack... Hit Ctrl-C to end.^C write write [unknown] [unknown] [unknown] [unknown] [unknown] PyObject_VectorcallMethod [unknown] [unknown] PyObject_CallOneArg PyFile_WriteObject PyFile_WriteString [unknown] [unknown] PyObject_Vectorcall _PyEval_EvalFrameDefault PyEval_EvalCode [unknown] [unknown] [unknown] _PyRun_SimpleFileObject _PyRun_AnyFileObject Py_RunMain [unknown] Py_BytesMain [unknown] __libc_start_main - python (1293) 7 write write [unknown] sudo_ev_loop_v1 sudo_ev_dispatch_v1 [unknown] [unknown] [unknown] [unknown] __libc_start_main - sudo (1291) 7 syscall syscall bpf_open_perf_buffer_opts [unknown] [unknown] [unknown] [unknown] _PyObject_MakeTpCall PyObject_Vectorcall _PyEval_EvalFrameDefault PyEval_EvalCode [unknown] [unknown] [unknown] _PyRun_SimpleFileObject _PyRun_AnyFileObject Py_RunMain [unknown] Py_BytesMain [unknown] __libc_start_main - python (1293) 11 clock_nanosleep clock_nanosleep nanosleep sleep [unknown] [unknown] __clone - multipathd (698) 3001661
--- arch/powerpc/kernel/interrupt_64.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/powerpc/kernel/interrupt_64.S +2 -2
@@ -52,7 +52,8 @@ _ASM_NOKPROBE_SYMBOL(system_call_vectore mr r10,r1 ld r1,PACAKSAVE(r13) std r10,0(r1) - std r11,_NIP(r1) + std r11,_LINK(r1) + std r11,_NIP(r1) /* Saved LR is also the next instruction */ std r12,_MSR(r1) std r0,GPR0(r1) std r10,GPR1(r1)
@@ -70,7 +71,6 @@ _ASM_NOKPROBE_SYMBOL(system_call_vectore std r9,GPR13(r1) SAVE_NVGPRS(r1) std r11,_XER(r1) - std r11,_LINK(r1) std r11,_CTR(r1) li r11,\trapnr
Greg Kroah-Hartman
maintainerPATCH 227/309 powerpc/cputable: Add missing PPC_FEATURE_BOOKE on PPC64 Book-E
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Engraf <[email protected]>
commit eb6d871f4ba49ac8d0537e051fe983a3a4027f61 upstream.
Commit e320a76db4b0 ("powerpc/cputable: Split cpu_specs[] out of cputable.h") moved the cpu_specs to separate header files. Previously PPC_FEATURE_BOOKE was enabled by CONFIG_PPC_BOOK3E_64. The definition in cpu_specs_e500mc.h for PPC64 no longer enables PPC_FEATURE_BOOKE.
This breaks user space reading the ELF hwcaps and expect PPC_FEATURE_BOOKE. Debugging an application with gdb is no longer working on e5500/e6500 because the 64-bit detection relies on PPC_FEATURE_BOOKE for Book-E.
--- arch/powerpc/kernel/cpu_specs_e500mc.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
arch/powerpc/kernel/cpu_specs_e500mc.h +2 -1
@@ -8,7 +8,8 @@#ifdef CONFIG_PPC64 #define COMMON_USER_BOOKE (PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | \ - PPC_FEATURE_HAS_FPU | PPC_FEATURE_64) + PPC_FEATURE_HAS_FPU | PPC_FEATURE_64 | \ + PPC_FEATURE_BOOKE)#else #define COMMON_USER_BOOKE (PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | \ PPC_FEATURE_BOOKE)
Greg Kroah-Hartman
maintainerPATCH 228/309 powerpc/pseries: fix accuracy of stolen time
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shrikanth Hegde <[email protected]>
commit cbecc9fcbbec60136b0180ba0609c829afed5c81 upstream.
powerVM hypervisor updates the VPA fields with stolen time data. It currently reports enqueue_dispatch_tb and ready_enqueue_tb for this purpose. In linux these two fields are used to report the stolen time.
The VPA fields are updated at the TB frequency. On powerPC its mostly set at 512Mhz. Hence this needs a conversion to ns when reporting it back as rest of the kernel timings are in ns. This conversion is already handled in tb_to_ns function. So use that function to report accurate stolen time.
Observed this issue and used an Capped Shared Processor LPAR(SPLPAR) to simplify the experiments. In all these cases, 100% VP Load is run using stress-ng workload. Values of stolen time is in percentages as reported by mpstat. With the patch values are close to expected.
6.8.rc1 +Patch 12EC/12VP 0.0 0.0 12EC/24VP 25.7 50.2 12EC/36VP 37.3 69.2 12EC/48VP 38.5 78.3
--- arch/powerpc/platforms/pseries/lpar.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
arch/powerpc/platforms/pseries/lpar.c +6 -2
@@ -662,8 +662,12 @@ u64 pseries_paravirt_steal_clock(int cpu {struct lppaca *lppaca = &lppaca_of (cpu); -return be64_to_cpu (READ_ONCE (lppaca->enqueue_dispatch_tb)) + -be64_to_cpu (READ_ONCE (lppaca->ready_enqueue_tb)); +/* +* VPA steal time counters are reported at TB frequency. Hence do a +* conversion to ns before returning +*/ +return tb_to_ns (be64_to_cpu (READ_ONCE (lppaca->enqueue_dispatch_tb)) + +be64_to_cpu (READ_ONCE (lppaca->ready_enqueue_tb))); }#endif
Greg Kroah-Hartman
maintainerPATCH 229/309 serial: core: introduce uart_port_tx_flags()
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiri Slaby (SUSE) <[email protected]>
commit 3ee07964d407411fd578a3bc998de44fd64d266a upstream.
And an enum with a flag: UART_TX_NOSTOP. To NOT call __port->ops->stop_tx() when the circular buffer is empty. mxs-uart needs this (see the next patch).
--- include/linux/serial_core.h | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-)
include/linux/serial_core.h +27 -5
@@ -748,8 +748,17 @@ struct uart_driver {void uart_write_wakeup (struct uart_port *port); -#define __uart_port_tx (uport, ch, tx_ready, put_char, tx_done, for_test, \ - for_post) \ +/** +* enum UART_TX_FLAGS -- flags for uart_port_tx_flags() +* +* @UART_TX_NOSTOP: don't call port->ops->stop_tx() on empty buffer +*/ +enum UART_TX_FLAGS { +UART_TX_NOSTOP =BIT (0 ), +}; + +#define __uart_port_tx (uport, ch, flags, tx_ready, put_char, tx_done, \ + for_test, for_post) \ ({ \ struct uart_port *__port = (uport); \ struct circ_buf *xmit = &__port->state->xmit; \
@@ -777,7 +786,7 @@ void uart_write_wakeup(struct uart_portif (pending <WAKEUP_CHARS ) { \uart_write_wakeup (__port); \ \ -if (pending ==0 ) \ +if (!((flags) &UART_TX_NOSTOP ) && pending ==0 ) \ __port->ops->stop_tx (__port); \ } \ \
@@ -812,7 +821,7 @@ void uart_write_wakeup(struct uart_port*/ #define uart_port_tx_limited (port, ch, count, tx_ready, put_char, tx_done) ({ \ unsigned int __count = (count); \ - __uart_port_tx(port, ch, tx_ready, put_char, tx_done, __count, \ + __uart_port_tx(port, ch, 0, tx_ready, put_char, tx_done, __count, \ __count--); \ })
@@ -826,8 +835,21 @@ void uart_write_wakeup(struct uart_port* See uart_port_tx_limited() for more details. */ #define uart_port_tx (port, ch, tx_ready, put_char) \ - __uart_port_tx(port, ch, tx_ready, put_char, ({}), true, ({})) + __uart_port_tx(port, ch, 0, tx_ready, put_char, ({}), true, ({})) + +/** +* uart_port_tx_flags -- transmit helper for uart_port with flags +* @port: uart port +* @ch: variable to store a character to be written to the HW +* @flags: %UART_TX_NOSTOP or similar +* @tx_ready: can HW accept more data function +* @put_char: function to write a character +* +* See uart_port_tx_limited() for more details. +*/ +#define uart_port_tx_flags (port, ch, flags, tx_ready, put_char) \ + __uart_port_tx(port, ch, flags, tx_ready, put_char, ({}), true, ({}))/* * Baud rate helpers. */
Greg Kroah-Hartman
maintainerPATCH 230/309 serial: mxs-auart: fix tx
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiri Slaby (SUSE) <[email protected]>
commit 7be50f2e8f20fc2299069b28dea59a28e3abe20a upstream.
Emil reports:
After updating Linux on an i.MX28 board, serial communication over AUART broke. When I TX from the board and measure on the TX pin, it seems like the HW fifo is not emptied before the transmission is stopped.
MXS performs weird things with stop_tx(). The driver makes it conditional on uart_tx_stopped().
So the driver needs special handling. Pass the brand new UART_TX_NOSTOP to uart_port_tx_flags() and handle the stop on its own.
--- drivers/tty/serial/mxs-auart.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/tty/serial/mxs-auart.c +4 -1
@@ -605,13 +605,16 @@ static void mxs_auart_tx_chars(struct mxreturn ; } - pending =uart_port_tx (&s->port, ch, + pending =uart_port_tx_flags (&s->port, ch,UART_TX_NOSTOP , !(mxs_read (s,REG_STAT ) &AUART_STAT_TXFF ),mxs_write (ch, s,REG_DATA ));if (pending)mxs_set (AUART_INTR_TXIEN , s,REG_INTR );else mxs_clr (AUART_INTR_TXIEN , s,REG_INTR ); + +if (uart_tx_stopped (&s->port)) +mxs_auart_stop_tx (&s->port); }static void mxs_auart_rx_char (struct mxs_auart_port *s)
Greg Kroah-Hartman
maintainerPATCH 231/309 x86/Kconfig: Transmeta Crusoe is CPU family 5, not 6
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aleksander Mazur <[email protected]>
commit f6a1892585cd19e63c4ef2334e26cd536d5b678d upstream.
The kernel built with MCRUSOE is unbootable on Transmeta Crusoe. It shows the following error message:
This kernel requires an i686 CPU, but only detected an i586 CPU. Unable to boot - please use a kernel appropriate for your CPU.
Remove MCRUSOE from the condition introduced in commit in Fixes, effectively changing X86_MINIMUM_CPU_FAMILY back to 5 on that machine, which matches the CPU family given by CPUID.
[ bp: Massage commit message. ]
--- arch/x86/Kconfig.cpu | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/Kconfig.cpu +1 -1
@@ -375,7 +375,7 @@ config X86_CMOV config X86_MINIMUM_CPU_FAMILY int default "64" if X86_64 - default "6" if X86_32 && (MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MEFFICEON || MATOM || MCRUSOE || MCORE2 || MK7 || MK8) + default "6" if X86_32 && (MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MEFFICEON || MATOM || MCORE2 || MK7 || MK8) default "5" if X86_32 && X86_CMPXCHG64 default "4"
Greg Kroah-Hartman
maintainerPATCH 232/309 x86/fpu: Stop relying on userspace for info to fault in xsave buffer
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrei Vagin <[email protected]>
commit d877550eaf2dc9090d782864c96939397a3c6835 upstream.
Before this change, the expected size of the user space buffer was taken from fx_sw->xstate_size. fx_sw->xstate_size can be changed from user-space, so it is possible construct a sigreturn frame where:
* fx_sw->xstate_size is smaller than the size required by valid bits in fx_sw->xfeatures.
* user-space unmaps parts of the sigrame fpu buffer so that not all of the buffer required by xrstor is accessible.
In this case, xrstor tries to restore and accesses the unmapped area which results in a fault. But fault_in_readable succeeds because buf + fx_sw->xstate_size is within the still mapped area, so it goes back and tries xrstor again. It will spin in this loop forever.
Instead, fault in the maximum size which can be touched by XRSTOR (taken from fpstate->user_size).
[ dhansen: tweak subject / changelog ]
--- arch/x86/kernel/fpu/signal.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-)
arch/x86/kernel/fpu/signal.c +5 -8
@@ -274,12 +274,13 @@ static int __restore_fpregs_from_user(vo* Attempt to restore the FPU registers directly from user memory. * Pagefaults are handled and any errors returned are fatal. */ -static bool restore_fpregs_from_user (void __user *buf,u64 xrestore, -bool fx_only,unsigned int size) +static bool restore_fpregs_from_user (void __user *buf,u64 xrestore,bool fx_only) {struct fpu *fpu = ¤t->thread.fpu;int ret; +/* Restore enabled features only. */ + xrestore &= fpu->fpstate->user_xfeatures; retry:fpregs_lock ();/* Ensure that XFD is up to date */
@@ -309,7 +310,7 @@ retry:if (ret !=X86_TRAP_PF )return false; -if (!fault_in_readable (buf, size)) +if (!fault_in_readable (buf, fpu->fpstate->user_size)) goto retry;return false; }
@@ -339,7 +340,6 @@ static bool __fpu_restore_sig(void __usestruct user_i387_ia32_struct env;bool success, fx_only = false;union fpregs_state *fpregs; -unsigned int state_size;u64 user_xfeatures =0 ;if (use_xsave ()) {
@@ -349,17 +349,14 @@ static bool __fpu_restore_sig(void __usereturn false; fx_only = !fx_sw_user.magic1; - state_size = fx_sw_user.xstate_size; user_xfeatures = fx_sw_user.xfeatures; }else { user_xfeatures =XFEATURE_MASK_FPSSE ; - state_size = fpu->fpstate->user_size; }if (likely (!ia32_fxstate)) {/* Restore the FPU registers directly from user memory. */ -return restore_fpregs_from_user (buf_fx, user_xfeatures, fx_only, - state_size); +return restore_fpregs_from_user (buf_fx, user_xfeatures, fx_only); }/*
Greg Kroah-Hartman
maintainerPATCH 233/309 KVM: x86: make KVM_REQ_NMI request iff NMI pending for vcpu
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Prasad Pandit <[email protected]>
commit 6231c9e1a9f35b535c66709aa8a6eda40dbc4132 upstream.
kvm_vcpu_ioctl_x86_set_vcpu_events() routine makes 'KVM_REQ_NMI' request for a vcpu even when its 'events->nmi.pending' is zero. Ex:
qemu_thread_start
kvm_vcpu_thread_fn
qemu_wait_io_event
qemu_wait_io_event_common
process_queued_cpu_work
do_kvm_cpu_synchronize_post_init/_reset
kvm_arch_put_registers
kvm_put_vcpu_events (cpu, level=[2|3])This leads vCPU threads in QEMU to constantly acquire & release the global mutex lock, delaying the guest boot due to lock contention. Add check to make KVM_REQ_NMI request only if vcpu has NMI pending.
--- arch/x86/kvm/x86.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
arch/x86/kvm/x86.c +2 -1
@@ -5405,7 +5405,8 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_eif (events->flags &KVM_VCPUEVENT_VALID_NMI_PENDING ) { vcpu->arch.nmi_pending =0 ;atomic_set (&vcpu->arch.nmi_queued, events->nmi.pending); -kvm_make_request (KVM_REQ_NMI , vcpu); +if (events->nmi.pending) +kvm_make_request (KVM_REQ_NMI , vcpu); }static_call (kvm_x86_set_nmi_mask)(vcpu, events->nmi.masked);
Greg Kroah-Hartman
maintainerPATCH 234/309 KVM: x86/pmu: Fix type length error when reading pmu->fixed_ctr_ctrl
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mingwei Zhang <[email protected]>
commit 05519c86d6997cfb9bb6c82ce1595d1015b718dc upstream.
Use a u64 instead of a u8 when taking a snapshot of pmu->fixed_ctr_ctrl when reprogramming fixed counters, as truncating the value results in KVM thinking fixed counter 2 is already disabled (the bug also affects fixed counters 3+, but KVM doesn't yet support those). As a result, if the guest disables fixed counter 2, KVM will get a false negative and fail to reprogram/disable emulation of the counter, which can leads to incorrect counts and spurious PMIs in the guest.
--- arch/x86/kvm/vmx/pmu_intel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/kvm/vmx/pmu_intel.c +1 -1
@@ -71,7 +71,7 @@ static int fixed_pmc_events[] = {static void reprogram_fixed_counters (struct kvm_pmu *pmu,u64 data) {struct kvm_pmc *pmc; -u8 old_fixed_ctr_ctrl = pmu->fixed_ctr_ctrl; +u64 old_fixed_ctr_ctrl = pmu->fixed_ctr_ctrl;int i; pmu->fixed_ctr_ctrl = data;
Greg Kroah-Hartman
maintainerPATCH 235/309 x86/mm/ident_map: Use gbpages only where full GB page should be mapped.
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steve Wahl <[email protected]>
commit d794734c9bbfe22f86686dc2909c25f5ffe1a572 upstream.
When ident_pud_init() uses only gbpages to create identity maps, large ranges of addresses not actually requested can be included in the resulting table; a 4K request will map a full GB. On UV systems, this ends up including regions that will cause hardware to halt the system if accessed (these are marked "reserved" by BIOS). Even processor speculation into these regions is enough to trigger the system halt.
Only use gbpages when map creation requests include the full GB page of space. Fall back to using smaller 2M pages when only portions of a GB page are included in the request.
No attempt is made to coalesce mapping requests. If a request requires a map entry at the 2M (pmd) level, subsequent mapping requests within the same 1G region will also be at the pmd level, even if adjacent or overlapping such requests could have been combined to map a full gbpage. Existing usage starts with larger regions and then adds smaller regions, so this should not have any great consequence.
[ dhansen: fix up comment formatting, simplifty changelog ]
--- arch/x86/mm/ident_map.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-)
arch/x86/mm/ident_map.c +18 -5
@@ -26,18 +26,31 @@ static int ident_pud_init(struct x86_mapfor (; addr < end; addr = next) {pud_t *pud = pud_page +pud_index (addr);pmd_t *pmd; +bool use_gbpage; next = (addr &PUD_MASK ) +PUD_SIZE ;if (next > end) next = end; -if (info->direct_gbpages) { -pud_t pudval; +/* if this is already a gbpage, this portion is already mapped */ +if (pud_large (*pud)) +continue ; + +/* Is using a gbpage allowed? */ + use_gbpage = info->direct_gbpages; -if (pud_present (*pud)) -continue ; +/* Don't use gbpage if it maps more than the requested region. */ +/* at the begining: */ + use_gbpage &= ((addr & ~PUD_MASK ) ==0 ); +/* ... or at the end: */ + use_gbpage &= ((next & ~PUD_MASK ) ==0 ); + +/* Never overwrite existing mappings */ + use_gbpage &= !pud_present (*pud); + +if (use_gbpage) { +pud_t pudval; - addr &=PUD_MASK ; pudval =__pud ((addr - info->offset) | info->page_flag);set_pud (pud, pudval);continue ;
Greg Kroah-Hartman
maintainerPATCH 236/309 io_uring/net: fix multishot accept overflow handling
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jens Axboe <[email protected]>
commit a37ee9e117ef73bbc2f5c0b31911afd52d229861 upstream.
If we hit CQ ring overflow when attempting to post a multishot accept completion, we don't properly save the result or return code. This results in losing the accepted fd value.
Instead, we return the result from the poll operation that triggered the accept retry. This is generally POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND which is 0xc3, or 195, which looks like a valid file descriptor, but it really has no connection to that.
Handle this like we do for other multishot completions - assign the result, and return IOU_STOP_MULTISHOT to cancel any further completions from this request when overflow is hit. This preserves the result, as we should, and tells the application that the request needs to be re-armed.
--- io_uring/net.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
io_uring/net.c +3 -2
@@ -1372,7 +1372,7 @@ retry:* has already been done */ if (issue_flags &IO_URING_F_MULTISHOT ) - ret =IOU_ISSUE_SKIP_COMPLETE ; +return IOU_ISSUE_SKIP_COMPLETE ;return ret; }if (ret == -ERESTARTSYS )
@@ -1397,7 +1397,8 @@ retry: ret, IORING_CQE_F_MORE)) goto retry; -return -ECANCELED ; +io_req_set_res (req, ret,0 ); +return IOU_STOP_MULTISHOT ; }int io_socket_prep (struct io_kiocb *req,const struct io_uring_sqe *sqe)
Greg Kroah-Hartman
maintainerPATCH 237/309 mmc: slot-gpio: Allow non-sleeping GPIO ro
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Stein <[email protected]>
commit cc9432c4fb159a3913e0ce3173b8218cd5bad2e0 upstream.
This change uses the appropriate _cansleep or non-sleeping API for reading GPIO read-only state. This allows users with GPIOs that never sleepbeing called in atomic context.
Implement the same mechanism as in commit 52af318c93e97 ("mmc: Allow non-sleeping GPIO cd").
--- drivers/mmc/core/slot-gpio.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/mmc/core/slot-gpio.c +5 -1
@@ -75,11 +75,15 @@ EXPORT_SYMBOL(mmc_gpio_set_cd_irq);int mmc_gpio_get_ro (struct mmc_host *host) {struct mmc_gpio *ctx = host->slot.handler_priv; +int cansleep;if (!ctx || !ctx->ro_gpio)return -ENOSYS ; -return gpiod_get_value_cansleep (ctx->ro_gpio); + cansleep =gpiod_cansleep (ctx->ro_gpio); +return cansleep ? +gpiod_get_value_cansleep (ctx->ro_gpio) : +gpiod_get_value (ctx->ro_gpio); }EXPORT_SYMBOL (mmc_gpio_get_ro);
Greg Kroah-Hartman
maintainerPATCH 238/309 gpiolib: add gpio_device_get_base() stub for !GPIOLIB
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Kozlowski <[email protected]>
commit ebe0c15b135b1e4092c25b95d89e9a5899467499 upstream.
Add empty stub of gpio_device_get_base() when GPIOLIB is not enabled.
--- include/linux/gpio/driver.h | 6 ++++++ 1 file changed, 6 insertions(+)
include/linux/gpio/driver.h +6 -0
@@ -800,6 +800,12 @@ static inline struct gpio_chip *gpiod_toreturn ERR_PTR (-ENODEV ); } +static inline int gpio_device_get_base (struct gpio_device *gdev) +{ +WARN_ON (1 ); +return -ENODEV ; +} +static inline int gpiochip_lock_as_irq (struct gpio_chip *gc,unsigned int offset) {
Greg Kroah-Hartman
maintainerPATCH 239/309 gpiolib: add gpiod_to_gpio_device() stub for !GPIOLIB
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Kozlowski <[email protected]>
commit 6ac86372102b477083db99a9af8246fb916271b5 upstream.
Add empty stub of gpiod_to_gpio_device() when GPIOLIB is not enabled.
--- include/linux/gpio/driver.h | 6 ++++++ 1 file changed, 6 insertions(+)
include/linux/gpio/driver.h +6 -0
@@ -806,6 +806,12 @@ static inline int gpio_device_get_base(sreturn -ENODEV ; } +static inline struct gpio_device *gpiod_to_gpio_device (struct gpio_desc *desc) +{ +WARN_ON (1 ); +return ERR_PTR (-ENODEV ); +} +static inline int gpiochip_lock_as_irq (struct gpio_chip *gc,unsigned int offset) {
Greg Kroah-Hartman
maintainerPATCH 240/309 ALSA: hda/realtek: fix mute/micmute LED For HP mt645
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eniac Zhang <[email protected]>
commit 32f03f4002c5df837fb920eb23fcd2f4af9b0b23 upstream.
The HP mt645 G7 Thin Client uses an ALC236 codec and needs the ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF quirk to make the mute and micmute LEDs work.
There are two variants of the USB-C PD chip on this device. Each uses a different BIOS and board ID, hence the two entries.
--- sound/pci/hda/patch_realtek.c | 2 ++ 1 file changed, 2 insertions(+)
sound/pci/hda/patch_realtek.c +2 -0
@@ -9915,6 +9915,7 @@ static const struct snd_pci_quirk alc269SND_PCI_QUIRK (0x103c ,0x8abb ,"HP ZBook Firefly 14 G9" ,ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED ),SND_PCI_QUIRK (0x103c ,0x8ad1 ,"HP EliteBook 840 14 inch G9 Notebook PC" ,ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED ),SND_PCI_QUIRK (0x103c ,0x8ad2 ,"HP EliteBook 860 16 inch G9 Notebook PC" ,ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED ), +SND_PCI_QUIRK (0x103c ,0x8b0f ,"HP Elite mt645 G7 Mobile Thin Client U81" ,ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF ),SND_PCI_QUIRK (0x103c ,0x8b2f ,"HP 255 15.6 inch G10 Notebook PC" ,ALC236_FIXUP_HP_MUTE_LED_COEFBIT2 ),SND_PCI_QUIRK (0x103c ,0x8b42 ,"HP" ,ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED ), SND_PCI_QUIRK(0x103c, 0x8b43, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
@@ -9922,6 +9923,7 @@ static const struct snd_pci_quirk alc269SND_PCI_QUIRK (0x103c ,0x8b45 ,"HP" ,ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED ),SND_PCI_QUIRK (0x103c ,0x8b46 ,"HP" ,ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED ),SND_PCI_QUIRK (0x103c ,0x8b47 ,"HP" ,ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED ), +SND_PCI_QUIRK (0x103c ,0x8b59 ,"HP Elite mt645 G7 Mobile Thin Client U89" ,ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF ),SND_PCI_QUIRK (0x103c ,0x8b5d ,"HP" ,ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF ),SND_PCI_QUIRK (0x103c ,0x8b5e ,"HP" ,ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF ), SND_PCI_QUIRK(0x103c, 0x8b63, "HP Elite Dragonfly 13.5 inch G4", ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED),
Greg Kroah-Hartman
maintainerPATCH 241/309 ALSA: hda/conexant: Add quirk for SWS JS201D
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: bo liu <[email protected]>
commit 4639c5021029d49fd2f97fa8d74731f167f98919 upstream.
The SWS JS201D need a different pinconfig from windows driver. Add a quirk to use a specific pinconfig to SWS JS201D.
--- sound/pci/hda/patch_conexant.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
sound/pci/hda/patch_conexant.c +18 -0
@@ -344,6 +344,7 @@ enum {CXT_FIXUP_HP_ZBOOK_MUTE_LED ,CXT_FIXUP_HEADSET_MIC ,CXT_FIXUP_HP_MIC_NO_PRESENCE , + CXT_PINCFG_SWS_JS201D, };/* for hda_fixup_thinkpad_acpi() */
@@ -841,6 +842,17 @@ static const struct hda_pintbl cxt_pincf {} }; +/* SuoWoSi/South-holding JS201D with sn6140 */ +static const struct hda_pintbl cxt_pincfg_sws_js201d[] = { + {0x16 ,0x03211040 },/* hp out */ + {0x17 ,0x91170110 },/* SPK/Class_D */ + {0x18 ,0x95a70130 },/* Internal mic */ + {0x19 ,0x03a11020 },/* Headset Mic */ + {0x1a ,0x40f001f0 },/* Not used */ + {0x21 ,0x40f001f0 },/* Not used */ + {} +}; +static const struct hda_fixup cxt_fixups[] = { [CXT_PINCFG_LENOVO_X200 ] = { .type =HDA_FIXUP_PINS ,
@@ -996,6 +1008,10 @@ static const struct hda_fixup cxt_fixups .chained = true, .chain_id = CXT_FIXUP_HEADSET_MIC, }, + [CXT_PINCFG_SWS_JS201D] = { + .type = HDA_FIXUP_PINS, + .v.pins = cxt_pincfg_sws_js201d, + }, }; static const struct snd_pci_quirk cxt5045_fixups[] = {
@@ -1069,6 +1085,7 @@ static const struct snd_pci_quirk cxt506SND_PCI_QUIRK (0x103c ,0x8457 ,"HP Z2 G4 mini" ,CXT_FIXUP_HP_MIC_NO_PRESENCE ),SND_PCI_QUIRK (0x103c ,0x8458 ,"HP Z2 G4 mini premium" ,CXT_FIXUP_HP_MIC_NO_PRESENCE ),SND_PCI_QUIRK (0x1043 ,0x138d ,"Asus" ,CXT_FIXUP_HEADPHONE_MIC_PIN ), +SND_PCI_QUIRK (0x14f1 ,0x0265 ,"SWS JS201D" ,CXT_PINCFG_SWS_JS201D ),SND_PCI_QUIRK (0x152d ,0x0833 ,"OLPC XO-1.5" ,CXT_FIXUP_OLPC_XO ),SND_PCI_QUIRK (0x17aa ,0x20f2 ,"Lenovo T400" ,CXT_PINCFG_LENOVO_TP410 ), SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo T410", CXT_PINCFG_LENOVO_TP410),
@@ -1109,6 +1126,7 @@ static const struct hda_model_fixup cxt5 { .id = CXT_FIXUP_HP_ZBOOK_MUTE_LED, .name = "hp-zbook-mute-led" }, { .id = CXT_FIXUP_HP_MIC_NO_PRESENCE, .name = "hp-mic-fix" }, { .id = CXT_PINCFG_LENOVO_NOTEBOOK, .name = "lenovo-20149" }, + { .id = CXT_PINCFG_SWS_JS201D, .name = "sws-js201d" }, {} };
Greg Kroah-Hartman
maintainerPATCH 242/309 ALSA: hda/realtek: add IDs for Dell dual spk platform
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shuming Fan <[email protected]>
commit fddab35fd064414c677e9488c4fb3a1f67725d37 upstream.
This patch adds another two IDs for the Dell dual speaker platform.
--- sound/pci/hda/patch_realtek.c | 2 ++ 1 file changed, 2 insertions(+)
sound/pci/hda/patch_realtek.c +2 -0
@@ -9724,7 +9724,9 @@ static const struct snd_pci_quirk alc269SND_PCI_QUIRK (0x1028 ,0x0b71 ,"Dell Inspiron 16 Plus 7620" ,ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS ),SND_PCI_QUIRK (0x1028 ,0x0beb ,"Dell XPS 15 9530 (2023)" ,ALC289_FIXUP_DELL_CS35L41_SPI_2 ),SND_PCI_QUIRK (0x1028 ,0x0c03 ,"Dell Precision 5340" ,ALC269_FIXUP_DELL4_MIC_NO_PRESENCE ), +SND_PCI_QUIRK (0x1028 ,0x0c0b ,"Dell Oasis 14 RPL-P" ,ALC289_FIXUP_RTK_AMP_DUAL_SPK ),SND_PCI_QUIRK (0x1028 ,0x0c0d ,"Dell Oasis" ,ALC289_FIXUP_RTK_AMP_DUAL_SPK ), +SND_PCI_QUIRK (0x1028 ,0x0c0e ,"Dell Oasis 16" ,ALC289_FIXUP_RTK_AMP_DUAL_SPK ),SND_PCI_QUIRK (0x1028 ,0x0c19 ,"Dell Precision 3340" ,ALC236_FIXUP_DELL_DUAL_CODECS ),SND_PCI_QUIRK (0x1028 ,0x0c1a ,"Dell Precision 3340" ,ALC236_FIXUP_DELL_DUAL_CODECS ), SND_PCI_QUIRK(0x1028, 0x0c1b, "Dell Precision 3440", ALC236_FIXUP_DELL_DUAL_CODECS),
Greg Kroah-Hartman
maintainerPATCH 243/309 nilfs2: fix data corruption in dsync block recovery for small block sizes
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ryusuke Konishi <[email protected]>
commit 67b8bcbaed4777871bb0dcc888fb02a614a98ab1 upstream.
The helper function nilfs_recovery_copy_block() of nilfs_recovery_dsync_blocks(), which recovers data from logs created by data sync writes during a mount after an unclean shutdown, incorrectly calculates the on-page offset when copying repair data to the file's page cache. In environments where the block size is smaller than the page size, this flaw can cause data corruption and leak uninitialized memory bytes during the recovery process.
Fix these issues by correcting this byte offset calculation on the page.
--- fs/nilfs2/recovery.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
fs/nilfs2/recovery.c +4 -3
@@ -472,9 +472,10 @@ static int nilfs_prepare_segment_for_recstatic int nilfs_recovery_copy_block (struct the_nilfs *nilfs,struct nilfs_recovery_block *rb, -struct page *page) +loff_t pos,struct page *page) {struct buffer_head *bh_org; +size_t from = pos & ~PAGE_MASK ;void *kaddr; bh_org =__bread (nilfs->ns_bdev, rb->blocknr, nilfs->ns_blocksize);
@@ -482,7 +483,7 @@ static int nilfs_recovery_copy_block(strreturn -EIO ; kaddr =kmap_atomic (page); -memcpy (kaddr +bh_offset (bh_org), bh_org->b_data, bh_org->b_size); +memcpy (kaddr + from, bh_org->b_data, bh_org->b_size);kunmap_atomic (kaddr);brelse (bh_org);return 0 ;
@@ -521,7 +522,7 @@ static int nilfs_recover_dsync_blocks(st goto failed_inode; } - err =nilfs_recovery_copy_block (nilfs, rb, page); + err =nilfs_recovery_copy_block (nilfs, rb, pos, page);if (unlikely (err)) goto failed_page;
Greg Kroah-Hartman
maintainerPATCH 244/309 nilfs2: fix hang in nilfs_lookup_dirty_data_buffers()
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ryusuke Konishi <[email protected]>
commit 38296afe3c6ee07319e01bb249aa4bb47c07b534 upstream.
Syzbot reported a hang issue in migrate_pages_batch() called by mbind() and nilfs_lookup_dirty_data_buffers() called in the log writer of nilfs2.
While migrate_pages_batch() locks a folio and waits for the writeback to complete, the log writer thread that should bring the writeback to completion picks up the folio being written back in nilfs_lookup_dirty_data_buffers() that it calls for subsequent log creation and was trying to lock the folio. Thus causing a deadlock.
In the first place, it is unexpected that folios/pages in the middle of writeback will be updated and become dirty. Nilfs2 adds a checksum to verify the validity of the log being written and uses it for recovery at mount, so data changes during writeback are suppressed. Since this is broken, an unclean shutdown could potentially cause recovery to fail.
Investigation revealed that the root cause is that the wait for writeback completion in nilfs_page_mkwrite() is conditional, and if the backing device does not require stable writes, data may be modified without waiting.
Fix these issues by making nilfs_page_mkwrite() wait for writeback to finish regardless of the stable write requirement of the backing device.
--- fs/nilfs2/file.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
fs/nilfs2/file.c +7 -1
@@ -105,7 +105,13 @@ static vm_fault_t nilfs_page_mkwrite(strnilfs_transaction_commit (inode->i_sb); mapped: -wait_for_stable_page (page); +/* +* Since checksumming including data blocks is performed to determine +* the validity of the log to be written and used for recovery, it is +* necessary to wait for writeback to finish here, regardless of the +* stable write requirement of the backing device. +*/ +wait_on_page_writeback (page); out:sb_end_pagefault (inode->i_sb);return vmf_fs_error (ret);
Greg Kroah-Hartman
maintainerPATCH 245/309 crypto: ccp - Fix null pointer dereference in __sev_platform_shutdown_locked
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kim Phillips <[email protected]>
commit ccb88e9549e7cfd8bcd511c538f437e20026e983 upstream.
The SEV platform device can be shutdown with a null psp_master, e.g., using DEBUG_TEST_DRIVER_REMOVE. Found using KASAN:
[ 137.148210] ccp 0000:23:00.1: enabling device (0000 -> 0002) [ 137.162647] ccp 0000:23:00.1: no command queues available [ 137.170598] ccp 0000:23:00.1: sev enabled [ 137.174645] ccp 0000:23:00.1: psp enabled [ 137.178890] general protection fault, probably for non-canonical address 0xdffffc000000001e: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC KASAN NOPTI [ 137.182693] KASAN: null-ptr-deref in range [0x00000000000000f0-0x00000000000000f7] [ 137.182693] CPU: 93 PID: 1 Comm: swapper/0 Not tainted 6.8.0-rc1+ #311 [ 137.182693] RIP: 0010:__sev_platform_shutdown_locked+0x51/0x180 [ 137.182693] Code: 08 80 3c 08 00 0f 85 0e 01 00 00 48 8b 1d 67 b6 01 08 48 b8 00 00 00 00 00 fc ff df 48 8d bb f0 00 00 00 48 89 f9 48 c1 e9 03 <80> 3c 01 00 0f 85 fe 00 00 00 48 8b 9b f0 00 00 00 48 85 db 74 2c [ 137.182693] RSP: 0018:ffffc900000cf9b0 EFLAGS: 00010216 [ 137.182693] RAX: dffffc0000000000 RBX: 0000000000000000 RCX: 000000000000001e [ 137.182693] RDX: 0000000000000000 RSI: 0000000000000008 RDI: 00000000000000f0 [ 137.182693] RBP: ffffc900000cf9c8 R08: 0000000000000000 R09: fffffbfff58f5a66 [ 137.182693] R10: ffffc900000cf9c8 R11: ffffffffac7ad32f R12: ffff8881e5052c28 [ 137.182693] R13: ffff8881e5052c28 R14: ffff8881758e43e8 R15: ffffffffac64abf8 [ 137.182693] FS: 0000000000000000(0000) GS:ffff889de7000000(0000) knlGS:0000000000000000 [ 137.182693] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 137.182693] CR2: 0000000000000000 CR3: 0000001cf7c7e000 CR4: 0000000000350ef0 [ 137.182693] Call Trace: [ 137.182693] <TASK> [ 137.182693] ? show_regs+0x6c/0x80 [ 137.182693] ? __die_body+0x24/0x70 [ 137.182693] ? die_addr+0x4b/0x80 [ 137.182693] ? exc_general_protection+0x126/0x230 [ 137.182693] ? asm_exc_general_protection+0x2b/0x30 [ 137.182693] ? __sev_platform_shutdown_locked+0x51/0x180 [ 137.182693] sev_firmware_shutdown.isra.0+0x1e/0x80 [ 137.182693] sev_dev_destroy+0x49/0x100 [ 137.182693] psp_dev_destroy+0x47/0xb0 [ 137.182693] sp_destroy+0xbb/0x240 [ 137.182693] sp_pci_remove+0x45/0x60 [ 137.182693] pci_device_remove+0xaa/0x1d0 [ 137.182693] device_remove+0xc7/0x170 [ 137.182693] really_probe+0x374/0xbe0 [ 137.182693] ? srso_return_thunk+0x5/0x5f [ 137.182693] __driver_probe_device+0x199/0x460 [ 137.182693] driver_probe_device+0x4e/0xd0 [ 137.182693] __driver_attach+0x191/0x3d0 [ 137.182693] ? __pfx___driver_attach+0x10/0x10 [ 137.182693] bus_for_each_dev+0x100/0x190 [ 137.182693] ? __pfx_bus_for_each_dev+0x10/0x10 [ 137.182693] ? __kasan_check_read+0x15/0x20 [ 137.182693] ? srso_return_thunk+0x5/0x5f [ 137.182693] ? _raw_spin_unlock+0x27/0x50 [ 137.182693] driver_attach+0x41/0x60 [ 137.182693] bus_add_driver+0x2a8/0x580 [ 137.182693] driver_register+0x141/0x480 [ 137.182693] __pci_register_driver+0x1d6/0x2a0 [ 137.182693] ? srso_return_thunk+0x5/0x5f [ 137.182693] ? esrt_sysfs_init+0x1cd/0x5d0 [ 137.182693] ? __pfx_sp_mod_init+0x10/0x10 [ 137.182693] sp_pci_init+0x22/0x30 [ 137.182693] sp_mod_init+0x14/0x30 [ 137.182693] ? __pfx_sp_mod_init+0x10/0x10 [ 137.182693] do_one_initcall+0xd1/0x470 [ 137.182693] ? __pfx_do_one_initcall+0x10/0x10 [ 137.182693] ? parameq+0x80/0xf0 [ 137.182693] ? srso_return_thunk+0x5/0x5f [ 137.182693] ? __kmalloc+0x3b0/0x4e0 [ 137.182693] ? kernel_init_freeable+0x92d/0x1050 [ 137.182693] ? kasan_populate_vmalloc_pte+0x171/0x190 [ 137.182693] ? srso_return_thunk+0x5/0x5f [ 137.182693] kernel_init_freeable+0xa64/0x1050 [ 137.182693] ? __pfx_kernel_init+0x10/0x10 [ 137.182693] kernel_init+0x24/0x160 [ 137.182693] ? __switch_to_asm+0x3e/0x70 [ 137.182693] ret_from_fork+0x40/0x80 [ 137.182693] ? __pfx_kernel_init+0x10/0x10 [ 137.182693] ret_from_fork_asm+0x1b/0x30 [ 137.182693] </TASK> [ 137.182693] Modules linked in: [ 137.538483] ---[ end trace 0000000000000000 ]---
--- drivers/crypto/ccp/sev-dev.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
drivers/crypto/ccp/sev-dev.c +8 -2
@@ -534,10 +534,16 @@ EXPORT_SYMBOL_GPL(sev_platform_init);static int __sev_platform_shutdown_locked (int *error) { -struct sev_device *sev = psp_master->sev_data; +struct psp_device *psp = psp_master; +struct sev_device *sev;int ret; -if (!sev || sev->state ==SEV_STATE_UNINIT ) +if (!psp || !psp->sev_data) +return 0 ; + + sev = psp->sev_data; + +if (sev->state ==SEV_STATE_UNINIT )return 0 ; ret =__sev_do_cmd_locked (SEV_CMD_SHUTDOWN ,NULL , error);
Greg Kroah-Hartman
maintainerPATCH 246/309 crypto: algif_hash - Remove bogus SGL free on zero-length error path
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Herbert Xu <[email protected]>
commit 24c890dd712f6345e382256cae8c97abb0406b70 upstream.
When a zero-length message is hashed by algif_hash, and an error is triggered, it tries to free an SG list that was never allocated in the first place. Fix this by not freeing the SG list on the zero-length error path.
--- crypto/algif_hash.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
crypto/algif_hash.c +3 -2
@@ -91,13 +91,13 @@ static int hash_sendmsg(struct socket *sif (!(msg->msg_flags &MSG_MORE )) { err =hash_alloc_result (sk, ctx);if (err) - goto unlock_free; + goto unlock_free_result;ahash_request_set_crypt (&ctx->req,NULL , ctx->result,0 ); err =crypto_wait_req (crypto_ahash_final (&ctx->req), &ctx->wait);if (err) - goto unlock_free; + goto unlock_free_result; } goto done_more; }
@@ -170,6 +170,7 @@ unlock: unlock_free:af_alg_free_sg (&ctx->sgl); +unlock_free_result:hash_free_result (sk, ctx); ctx->more = false; goto unlock;
Greg Kroah-Hartman
maintainerPATCH 247/309 nfp: use correct macro for LengthSelect in BAR config
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Basilio <[email protected]>
commit b3d4f7f2288901ed2392695919b3c0e24c1b4084 upstream.
The 1st and 2nd expansion BAR configuration registers are configured, when the driver starts up, in variables 'barcfg_msix_general' and 'barcfg_msix_xpb', respectively. The 'LengthSelect' field is ORed in from bit 0, which is incorrect. The 'LengthSelect' field should start from bit 27.
This has largely gone un-noticed because NFP_PCIE_BAR_PCIE2CPP_LengthSelect_32BIT happens to be 0.
--- drivers/net/ethernet/netronome/nfp/nfpcore/nfp6000_pcie.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/net/ethernet/netronome/nfp/nfpcore/nfp6000_pcie.c +4 -2
@@ -537,11 +537,13 @@ static int enable_bars(struct nfp6000_pcconst u32 barcfg_msix_general =NFP_PCIE_BAR_PCIE2CPP_MapType ( NFP_PCIE_BAR_PCIE2CPP_MapType_GENERAL) | - NFP_PCIE_BAR_PCIE2CPP_LengthSelect_32BIT; +NFP_PCIE_BAR_PCIE2CPP_LengthSelect ( + NFP_PCIE_BAR_PCIE2CPP_LengthSelect_32BIT);const u32 barcfg_msix_xpb =NFP_PCIE_BAR_PCIE2CPP_MapType ( NFP_PCIE_BAR_PCIE2CPP_MapType_BULK) | - NFP_PCIE_BAR_PCIE2CPP_LengthSelect_32BIT | +NFP_PCIE_BAR_PCIE2CPP_LengthSelect ( + NFP_PCIE_BAR_PCIE2CPP_LengthSelect_32BIT) |NFP_PCIE_BAR_PCIE2CPP_Target_BaseAddress (NFP_CPP_TARGET_ISLAND_XPB );const u32 barcfg_explicit[4 ] = {
Greg Kroah-Hartman
maintainerPATCH 248/309 nfp: enable NETDEV_XDP_ACT_REDIRECT feature flag
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: James Hershaw <[email protected]>
commit 0f4d6f011bca0df2051532b41b596366aa272019 upstream.
Enable previously excluded xdp feature flag for NFD3 devices. This feature flag is required in order to bind nfp interfaces to an xdp socket and the nfp driver does in fact support the feature.
--- drivers/net/ethernet/netronome/nfp/nfp_net_common.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/ethernet/netronome/nfp/nfp_net_common.c +1 -0
@@ -2588,6 +2588,7 @@ static void nfp_net_netdev_init(struct ncase NFP_NFD_VER_NFD3 : netdev->netdev_ops = &nfp_nfd3_netdev_ops; netdev->xdp_features |=NETDEV_XDP_ACT_XSK_ZEROCOPY ; + netdev->xdp_features |=NETDEV_XDP_ACT_REDIRECT ;break ;case NFP_NFD_VER_NFDK : netdev->netdev_ops = &nfp_nfdk_netdev_ops;
Greg Kroah-Hartman
maintainerPATCH 249/309 nfp: flower: prevent re-adding mac index for bonded port
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel de Villiers <[email protected]>
commit 1a1c13303ff6d64e6f718dc8aa614e580ca8d9b4 upstream.
When physical ports are reset (either through link failure or manually toggled down and up again) that are slaved to a Linux bond with a tunnel endpoint IP address on the bond device, not all tunnel packets arriving on the bond port are decapped as expected.
The bond dev assigns the same MAC address to itself and each of its slaves. When toggling a slave device, the same MAC address is therefore offloaded to the NFP multiple times with different indexes.
The issue only occurs when re-adding the shared mac. The nfp_tunnel_add_shared_mac() function has a conditional check early on that checks if a mac entry already exists and if that mac entry is
global: (entry && nfp_tunnel_is_mac_idx_global(entry->index)). In the case of a bonded device (For example br-ex), the mac index is obtained, and no new index is assigned.
We therefore modify the conditional in nfp_tunnel_add_shared_mac() to check if the port belongs to the LAG along with the existing checks to prevent a new global mac index from being re-assigned to the slave port.
--- drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c +1 -1
@@ -1084,7 +1084,7 @@ nfp_tunnel_add_shared_mac(struct nfp_appu16 nfp_mac_idx =0 ; entry =nfp_tunnel_lookup_offloaded_macs (app, netdev->dev_addr); -if (entry &&nfp_tunnel_is_mac_idx_global (entry->index)) { +if (entry && (nfp_tunnel_is_mac_idx_global (entry->index) ||netif_is_lag_port (netdev))) {if (entry->bridge_count || !nfp_flower_is_supported_bridge (netdev)) { nfp_tunnel_offloaded_macs_inc_ref_and_link(entry,
Greg Kroah-Hartman
maintainerPATCH 250/309 wifi: iwlwifi: fix double-free bug
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <[email protected]>
commit 353d321f63f7dbfc9ef58498cc732c9fe886a596 upstream.
The storage for the TLV PC register data wasn't done like all the other storage in the drv->fw area, which is cleared at the end of deallocation. Therefore, the freeing must also be done differently, explicitly NULL'ing it out after the free, since otherwise there's a nasty double-free bug here if a file fails to load after this has been parsed, and we get another free later (e.g. because no other file exists.) Fix that by adding the missing NULL assignment.
--- drivers/net/wireless/intel/iwlwifi/iwl-drv.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/wireless/intel/iwlwifi/iwl-drv.c +1 -0
@@ -128,6 +128,7 @@ static void iwl_dealloc_ucode(struct iwlkfree (drv->fw.ucode_capa.cmd_versions);kfree (drv->fw.phy_integration_ver);kfree (drv->trans->dbg.pc_data); + drv->trans->dbg.pc_data =NULL ;for (i =0 ; i <IWL_UCODE_TYPE_MAX ; i++)iwl_free_fw_img (drv, drv->fw.img + i);
Greg Kroah-Hartman
maintainerPATCH 251/309 wifi: cfg80211: fix wiphy delayed work queueing
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <[email protected]>
commit b743287d7a0007493f5cada34ed2085d475050b4 upstream.
When a wiphy work is queued with timer, and then again without a delay, it's started immediately but *also* started again after the timer expires. This can lead, for example, to warnings in mac80211's offchannel code as reported by Jouni. Running the same work twice isn't expected, of course. Fix this by deleting the timer at this point, when queuing immediately due to delay=0.
--- net/wireless/core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
net/wireless/core.c +2 -1
@@ -5,7 +5,7 @@* Copyright 2006-2010 Johannes Berg <[email protected]> * Copyright 2013-2014 Intel Mobile Communications GmbH * Copyright 2015-2017 Intel Deutschland GmbH -* Copyright (C) 2018-2023 Intel Corporation +* Copyright (C) 2018-2024 Intel Corporation */ #define pr_fmt (fmt) KBUILD_MODNAME ": " fmt
@@ -1661,6 +1661,7 @@ void wiphy_delayed_work_queue(struct wip unsigned long delay) {if (!delay) { +del_timer (&dwork->timer);wiphy_work_queue (wiphy, &dwork->work);return ; }
Greg Kroah-Hartman
maintainerPATCH 252/309 wifi: mac80211: reload info pointer in ieee80211_tx_dequeue()
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <[email protected]>
commit c98d8836b817d11fdff4ca7749cbbe04ff7f0c64 upstream.
This pointer can change here since the SKB can change, so we actually later open-coded IEEE80211_SKB_CB() again. Reload the pointer where needed, so the monitor-mode case using it gets fixed, and then use info-> later as well.
--- net/mac80211/tx.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
net/mac80211/tx.c +3 -2
@@ -5,7 +5,7 @@* Copyright 2006-2007 Jiri Benc <[email protected]> * Copyright 2007 Johannes Berg <[email protected]> * Copyright 2013-2014 Intel Mobile Communications GmbH -* Copyright (C) 2018-2022 Intel Corporation +* Copyright (C) 2018-2024 Intel Corporation * * Transmit and frame generation functions. */
@@ -3927,6 +3927,7 @@ begin: goto begin; skb =__skb_dequeue (&tx.skbs); + info =IEEE80211_SKB_CB (skb);if (!skb_queue_empty (&tx.skbs)) {spin_lock_bh (&fq->lock);
@@ -3971,7 +3972,7 @@ begin: } encap_out: -IEEE80211_SKB_CB (skb)->control.vif = vif; + info->control.vif = vif;if (tx.sta &&wiphy_ext_feature_isset (local->hw.wiphy,NL80211_EXT_FEATURE_AQL )) {
Greg Kroah-Hartman
maintainerPATCH 253/309 wifi: iwlwifi: mvm: fix a crash when we run out of stations
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Emmanuel Grumbach <[email protected]>
commit b7198383ef2debe748118996f627452281cf27d7 upstream.
A DoS tool that injects loads of authentication frames made our AP crash. The iwl_mvm_is_dup() function couldn't find the per-queue dup_data which was not allocated.
The root cause for that is that we ran out of stations in the firmware and we didn't really add the station to the firmware, yet we didn't return an error to mac80211.
Mac80211 was thinking that we have the station and because of that, sta_info::uploaded was set to 1. This allowed ieee80211_find_sta_by_ifaddr() to return a valid station object, but that ieee80211_sta didn't have any iwl_mvm_sta object initialized and that caused the crash mentioned earlier when we got Rx on that station.
--- drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 3 +++ drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 4 ++++ 2 files changed, 7 insertions(+)
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +3 -0
@@ -3673,6 +3673,9 @@ iwl_mvm_sta_state_notexist_to_none(struc NL80211_TDLS_SETUP); } +if (ret) +return ret; +for_each_sta_active_link (vif, sta, link_sta, i) link_sta->agg.max_rc_amsdu_len =1 ;
drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c +4 -0
@@ -505,6 +505,10 @@ static bool iwl_mvm_is_dup(struct ieee80return false; mvm_sta =iwl_mvm_sta_from_mac80211 (sta); + +if (WARN_ON_ONCE (!mvm_sta->dup_data)) +return false; + dup_data = &mvm_sta->dup_data[queue];/*
Greg Kroah-Hartman
maintainerPATCH 254/309 PCI: dwc: Fix a 64bit bug in dw_pcie_ep_raise_msix_irq()
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
commit b5d1b4b46f856da1473c7ba9a5cdfcb55c9b2478 upstream.
The "msg_addr" variable is u64. However, the "aligned_offset" is an unsigned int. This means that when the code does:
msg_addr &= ~aligned_offset;
it will unintentionally zero out the high 32 bits. Use ALIGN_DOWN() to do the alignment instead.
--- drivers/pci/controller/dwc/pcie-designware-ep.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/pci/controller/dwc/pcie-designware-ep.c +2 -1
@@ -6,6 +6,7 @@* Author: Kishon Vijay Abraham I <[email protected]> */ +#include <linux/align.h> #include <linux/bitfield.h> #include <linux/of.h> #include <linux/platform_device.h>
@@ -615,7 +616,7 @@ int dw_pcie_ep_raise_msix_irq(struct dw_ } aligned_offset = msg_addr & (epc->mem->window.page_size -1 ); - msg_addr &= ~aligned_offset; + msg_addr =ALIGN_DOWN (msg_addr, epc->mem->window.page_size); ret =dw_pcie_ep_map_addr (epc, func_no,0 , ep->msi_mem_phys, msg_addr, epc->mem->window.page_size);if (ret)
Greg Kroah-Hartman
maintainerPATCH 255/309 irqchip/irq-brcmstb-l2: Add write memory barrier before exit
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Doug Berger <[email protected]>
commit b0344d6854d25a8b3b901c778b1728885dd99007 upstream.
It was observed on Broadcom devices that use GIC v3 architecture L1 interrupt controllers as the parent of brcmstb-l2 interrupt controllers that the deactivation of the parent interrupt could happen before the brcmstb-l2 deasserted its output. This would lead the GIC to reactivate the interrupt only to find that no L2 interrupt was pending. The result was a spurious interrupt invoking handle_bad_irq() with its associated messaging. While this did not create a functional problem it is a waste of cycles.
The hazard exists because the memory mapped bus writes to the brcmstb-l2 registers are buffered and the GIC v3 architecture uses a very efficient system register write to deactivate the interrupt.
Add a write memory barrier prior to invoking chained_irq_exit() to introduce a dsb(st) on those systems to ensure the system register write cannot be executed until the memory mapped writes are visible to the system.
[ florian: Added Fixes tag ]
--- drivers/irqchip/irq-brcmstb-l2.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/irqchip/irq-brcmstb-l2.c +4 -1
@@ -2,7 +2,7 @@/* * Generic Broadcom Set Top Box Level 2 Interrupt controller driver * -* Copyright (C) 2014-2017 Broadcom +* Copyright (C) 2014-2024 Broadcom */ #define pr_fmt (fmt) KBUILD_MODNAME ": " fmt
@@ -112,6 +112,9 @@ static void brcmstb_l2_intc_irq_handle(sgeneric_handle_domain_irq (b->domain, irq); }while (status); out: +/* Don't ack parent before all device writes are done */ +wmb (); +chained_irq_exit (chip, desc); }
Greg Kroah-Hartman
maintainerPATCH 256/309 irqchip/gic-v3-its: Restore quirk probing for ACPI-based systems
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marc Zyngier <[email protected]>
commit 8b02da04ad978827e5ccd675acf170198f747a7a upstream.
While refactoring the way the ITSs are probed, the handling of quirks applicable to ACPI-based platforms was lost. As a result, systems such as HIP07 lose their GICv4 functionnality, and some other may even fail to boot, unless they are configured to boot with DT.
Move the enabling of quirks into its_probe_one(), making it common to all firmware implementations.
--- drivers/irqchip/irq-gic-v3-its.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/irqchip/irq-gic-v3-its.c +2 -1
@@ -5091,6 +5091,8 @@ static int __init its_probe_one(struct iu32 ctlr;int err; +its_enable_quirks (its); +if (is_v4 (its)) {if (!(its->typer &GITS_TYPER_VMOVP )) { err =its_compute_its_list_map (its);
@@ -5442,7 +5444,6 @@ static int __init its_of_probe(struct deif (!its)return -ENOMEM ; -its_enable_quirks (its); err =its_probe_one (its);if (err) {its_node_destroy (its);
Greg Kroah-Hartman
maintainerPATCH 257/309 irqchip/gic-v3-its: Fix GICv4.1 VPE affinity update
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marc Zyngier <[email protected]>
commit af9acbfc2c4b72c378d0b9a2ee023ed01055d3e2 upstream.
When updating the affinity of a VPE, the VMOVP command is currently skipped if the two CPUs are part of the same VPE affinity.
But this is wrong, as the doorbell corresponding to this VPE is still delivered on the 'old' CPU, which screws up the balancing. Furthermore, offlining that 'old' CPU results in doorbell interrupts generated for this VPE being discarded.
The harsh reality is that VMOVP cannot be elided when a set_affinity() request occurs. It needs to be obeyed, and if an optimisation is to be made, it is at the point where the affinity change request is made (such as in KVM).
Drop the VMOVP elision altogether, and only use the vpe_table_mask to try and stay within the same ITS affinity group if at all possible.
--- drivers/irqchip/irq-gic-v3-its.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-)
drivers/irqchip/irq-gic-v3-its.c +13 -9
@@ -3826,8 +3826,9 @@ static int its_vpe_set_affinity(struct i bool force) {struct its_vpe *vpe =irq_data_get_irq_chip_data (d); -int from, cpu =cpumask_first (mask_val); +struct cpumask common, *table_mask;unsigned long flags; +int from, cpu;/* * Changing affinity is mega expensive, so let's be as lazy as
@@ -3843,19 +3844,22 @@ static int its_vpe_set_affinity(struct i* taken on any vLPI handling path that evaluates vpe->col_idx. */ from =vpe_to_cpuid_lock (vpe, &flags); -if (from == cpu) - goto out; - - vpe->col_idx = cpu; + table_mask =gic_data_rdist_cpu (from)->vpe_table_mask;/* -* GICv4.1 allows us to skip VMOVP if moving to a cpu whose RD -* is sharing its VPE table with the current one. +* If we are offered another CPU in the same GICv4.1 ITS +* affinity, pick this one. Otherwise, any CPU will do. */ -if (gic_data_rdist_cpu (cpu)->vpe_table_mask && -cpumask_test_cpu (from,gic_data_rdist_cpu (cpu)->vpe_table_mask)) +if (table_mask &&cpumask_and (&common, mask_val, table_mask)) + cpu =cpumask_test_cpu (from, &common) ? from :cpumask_first (&common); +else + cpu =cpumask_first (mask_val); + +if (from == cpu) goto out; + vpe->col_idx = cpu; +its_send_vmovp (vpe);its_vpe_db_proxy_move (vpe, from, cpu);
Greg Kroah-Hartman
maintainerPATCH 258/309 thunderbolt: Fix setting the CNS bit in ROUTER_CS_5
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mohammad Rahimi <[email protected]>
commit ec4d82f855ce332de26fe080892483de98cc1a19 upstream.
The bit 23, CM TBT3 Not Supported (CNS), in ROUTER_CS_5 indicates whether a USB4 Connection Manager is TBT3-Compatible and should be:
0b for TBT3-Compatible
1b for Not TBT3-Compatible
--- drivers/thunderbolt/tb_regs.h | 2 +- drivers/thunderbolt/usb4.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
drivers/thunderbolt/tb_regs.h +1 -1
@@ -203,7 +203,7 @@ struct tb_regs_switch_header {#define ROUTER_CS_5_WOP BIT(1)#define ROUTER_CS_5_WOU BIT(2)#define ROUTER_CS_5_WOD BIT(3) -#define ROUTER_CS_5_C3S BIT(23) +#define ROUTER_CS_5_CNS BIT(23)#define ROUTER_CS_5_PTO BIT(24)#define ROUTER_CS_5_UTO BIT(25)#define ROUTER_CS_5_HCO BIT(26)
drivers/thunderbolt/usb4.c +1 -1
@@ -290,7 +290,7 @@ int usb4_switch_setup(struct tb_switch * }/* TBT3 supported by the CM */ - val |=ROUTER_CS_5_C3S ; + val &= ~ROUTER_CS_5_CNS ;return tb_sw_write (sw, &val,TB_CFG_SWITCH ,ROUTER_CS_5 ,1 ); }
Greg Kroah-Hartman
maintainerPATCH 259/309 smb: client: set correct id, uid and cruid for multiuser automounts
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paulo Alcantara <[email protected]>
commit 4508ec17357094e2075f334948393ddedbb75157 upstream.
When uid, gid and cruid are not specified, we need to dynamically set them into the filesystem context used for automounting otherwise they'll end up reusing the values from the parent mount.
--- fs/smb/client/namespace.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
fs/smb/client/namespace.c +16 -0
@@ -168,6 +168,21 @@ static char *automount_fullpath(struct dreturn s; } +static void fs_context_set_ids (struct smb3_fs_context *ctx) +{ +kuid_t uid =current_fsuid (); +kgid_t gid =current_fsgid (); + +if (ctx->multiuser) { +if (!ctx->uid_specified) + ctx->linux_uid = uid; +if (!ctx->gid_specified) + ctx->linux_gid = gid; + } +if (!ctx->cruid_specified) + ctx->cred_uid = uid; +} +/* * Create a vfsmount that we can automount */
@@ -205,6 +220,7 @@ static struct vfsmount *cifs_do_automoun tmp.leaf_fullpath =NULL ; tmp.UNC = tmp.prepath =NULL ; tmp.dfs_root_ses =NULL ; +fs_context_set_ids (&tmp); rc =smb3_fs_context_dup (ctx, &tmp);if (rc) {
Greg Kroah-Hartman
maintainerPATCH 260/309 smb: Fix regression in writes when non-standard maximum write size negotiated
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steve French <[email protected]>
commit 4860abb91f3d7fbaf8147d54782149bb1fc45892 upstream.
The conversion to netfs in the 6.3 kernel caused a regression when maximum write size is set by the server to an unexpected value which is not a multiple of 4096 (similarly if the user overrides the maximum write size by setting mount parm "wsize", but sets it to a value that is not a multiple of 4096). When negotiated write size is not a multiple of 4096 the netfs code can skip the end of the final page when doing large sequential writes, causing data corruption.
This section of code is being rewritten/removed due to a large netfs change, but until that point (ie for the 6.3 kernel until now) we can not support non-standard maximum write sizes.
Add a warning if a user specifies a wsize on mount that is not a multiple of 4096 (and round down), also add a change where we round down the maximum write size if the server negotiates a value that is not a multiple of 4096 (we also have to check to make sure that we do not round it down to zero).
--- fs/smb/client/connect.c | 14 ++++++++++++-- fs/smb/client/fs_context.c | 11 +++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-)
fs/smb/client/connect.c +12 -2
@@ -3425,8 +3425,18 @@ int cifs_mount_get_tcon(struct cifs_moun* the user on mount */ if ((cifs_sb->ctx->wsize ==0 ) || - (cifs_sb->ctx->wsize > server->ops->negotiate_wsize (tcon, ctx))) - cifs_sb->ctx->wsize = server->ops->negotiate_wsize (tcon, ctx); + (cifs_sb->ctx->wsize > server->ops->negotiate_wsize (tcon, ctx))) { + cifs_sb->ctx->wsize = +round_down (server->ops->negotiate_wsize (tcon, ctx),PAGE_SIZE ); +/* +* in the very unlikely event that the server sent a max write size under PAGE_SIZE, +* (which would get rounded down to 0) then reset wsize to absolute minimum eg 4096 +*/ +if (cifs_sb->ctx->wsize ==0 ) { + cifs_sb->ctx->wsize =PAGE_SIZE ; +cifs_dbg (VFS ,"wsize too small, reset to minimum ie PAGE_SIZE, usually 4096\n" ); + } + }if ((cifs_sb->ctx->rsize ==0 ) || (cifs_sb->ctx->rsize > server->ops->negotiate_rsize (tcon, ctx))) cifs_sb->ctx->rsize = server->ops->negotiate_rsize (tcon, ctx);
fs/smb/client/fs_context.c +11 -0
@@ -1107,6 +1107,17 @@ static int smb3_fs_context_parse_param(scase Opt_wsize: ctx->wsize = result.uint_32; ctx->got_wsize = true; +if (ctx->wsize %PAGE_SIZE !=0 ) { + ctx->wsize =round_down (ctx->wsize,PAGE_SIZE ); +if (ctx->wsize ==0 ) { + ctx->wsize =PAGE_SIZE ; +cifs_dbg (VFS ,"wsize too small, reset to minimum %ld\n" ,PAGE_SIZE ); + }else { +cifs_dbg (VFS , +"wsize rounded down to %d to multiple of PAGE_SIZE %ld\n" , + ctx->wsize,PAGE_SIZE ); + } + }break ;case Opt_acregmax: ctx->acregmax =HZ * result.uint_32;
Greg Kroah-Hartman
maintainerPATCH 261/309 KVM: s390: vsie: fix race during shadow creation
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Borntraeger <[email protected]>
commit fe752331d4b361d43cfd0b89534b4b2176057c32 upstream.
Right now it is possible to see gmap->private being zero in kvm_s390_vsie_gmap_notifier resulting in a crash. This is due to the fact that we add gmap->private == kvm after creation:
static int acquire_gmap_shadow(struct kvm_vcpu *vcpu,
struct vsie_page *vsie_page)
{
[...]
gmap = gmap_shadow(vcpu->arch.gmap, asce, edat);
if (IS_ERR(gmap))
return PTR_ERR(gmap);
gmap->private = vcpu->kvm;Let children inherit the private field of the parent.
--- arch/s390/kvm/vsie.c | 1 - arch/s390/mm/gmap.c | 1 + 2 files changed, 1 insertion(+), 1 deletion(-)
arch/s390/kvm/vsie.c +0 -1
@@ -1220,7 +1220,6 @@ static int acquire_gmap_shadow(struct kv gmap =gmap_shadow (vcpu->arch.gmap, asce, edat);if (IS_ERR (gmap))return PTR_ERR (gmap); - gmap->private = vcpu->kvm; vcpu->kvm->stat.gmap_shadow_create++;WRITE_ONCE (vsie_page->gmap, gmap);return 0 ;
arch/s390/mm/gmap.c +1 -0
@@ -1691,6 +1691,7 @@ struct gmap *gmap_shadow(struct gmap *pareturn ERR_PTR (-ENOMEM ); new->mm = parent->mm; new->parent =gmap_get (parent); + new->private = parent->private; new->orig_asce = asce; new->edat_level = edat_level; new->initialized = false;
Greg Kroah-Hartman
maintainerPATCH 262/309 KVM: arm64: Fix circular locking dependency
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sebastian Ene <[email protected]>
commit 10c02aad111df02088d1a81792a709f6a7eca6cc upstream.
The rule inside kvm enforces that the vcpu->mutex is taken *inside* kvm->lock. The rule is violated by the pkvm_create_hyp_vm() which acquires the kvm->lock while already holding the vcpu->mutex lock from kvm_vcpu_ioctl(). Avoid the circular locking dependency altogether by protecting the hyp vm handle with the config_lock, much like we already do for other forms of VM-scoped data.
--- arch/arm64/kvm/pkvm.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-)
arch/arm64/kvm/pkvm.c +17 -10
@@ -101,6 +101,17 @@ void __init kvm_hyp_reserve(void) hyp_mem_base); } +static void __pkvm_destroy_hyp_vm (struct kvm *host_kvm) +{ +if (host_kvm->arch.pkvm.handle) { +WARN_ON (kvm_call_hyp_nvhe (__pkvm_teardown_vm, + host_kvm->arch.pkvm.handle)); + } + + host_kvm->arch.pkvm.handle =0 ; +free_hyp_memcache (&host_kvm->arch.pkvm.teardown_mc); +} +/* * Allocates and donates memory for hypervisor VM structs at EL2. *
@@ -181,7 +192,7 @@ static int __pkvm_create_hyp_vm(struct kreturn 0 ; destroy_vm: -pkvm_destroy_hyp_vm (host_kvm); +__pkvm_destroy_hyp_vm (host_kvm);return ret; free_vm:free_pages_exact (hyp_vm, hyp_vm_sz);
@@ -194,23 +205,19 @@ int pkvm_create_hyp_vm(struct kvm *host_ {int ret =0 ; -mutex_lock (&host_kvm->lock); +mutex_lock (&host_kvm->arch.config_lock);if (!host_kvm->arch.pkvm.handle) ret =__pkvm_create_hyp_vm (host_kvm); -mutex_unlock (&host_kvm->lock); +mutex_unlock (&host_kvm->arch.config_lock);return ret; }void pkvm_destroy_hyp_vm (struct kvm *host_kvm) { -if (host_kvm->arch.pkvm.handle) { -WARN_ON (kvm_call_hyp_nvhe (__pkvm_teardown_vm, - host_kvm->arch.pkvm.handle)); - } - - host_kvm->arch.pkvm.handle =0 ; -free_hyp_memcache (&host_kvm->arch.pkvm.teardown_mc); +mutex_lock (&host_kvm->arch.config_lock); +__pkvm_destroy_hyp_vm (host_kvm); +mutex_unlock (&host_kvm->arch.config_lock); }int pkvm_init_host_vm (struct kvm *host_kvm)
Greg Kroah-Hartman
maintainerPATCH 263/309 zonefs: Improve error handling
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Damien Le Moal <[email protected]>
commit 14db5f64a971fce3d8ea35de4dfc7f443a3efb92 upstream.
Write error handling is racy and can sometime lead to the error recovery path wrongly changing the inode size of a sequential zone file to an incorrect value which results in garbage data being readable at the end of a file. There are 2 problems:
1) zonefs_file_dio_write() updates a zone file write pointer offset after issuing a direct IO with iomap_dio_rw(). This update is done only if the IO succeed for synchronous direct writes. However, for asynchronous direct writes, the update is done without waiting for the IO completion so that the next asynchronous IO can be immediately issued. However, if an asynchronous IO completes with a failure right before the i_truncate_mutex lock protecting the update, the update may change the value of the inode write pointer offset that was corrected by the error path (zonefs_io_error() function).
2) zonefs_io_error() is called when a read or write error occurs. This function executes a report zone operation using the callback function zonefs_io_error_cb(), which does all the error recovery handling based on the current zone condition, write pointer position and according to the mount options being used. However, depending on the zoned device being used, a report zone callback may be executed in a context that is different from the context of __zonefs_io_error(). As a result, zonefs_io_error_cb() may be executed without the inode truncate mutex lock held, which can lead to invalid error processing.
Fix both problems as follows:
- Problem 1: Perform the inode write pointer offset update before a direct write is issued with iomap_dio_rw(). This is safe to do as partial direct writes are not supported (IOMAP_DIO_PARTIAL is not set) and any failed IO will trigger the execution of zonefs_io_error() which will correct the inode write pointer offset to reflect the current state of the one on the device.
- Problem 2: Change zonefs_io_error_cb() into zonefs_handle_io_error() and call this function directly from __zonefs_io_error() after obtaining the zone information using blkdev_report_zones() with a simple callback function that copies to a local stack variable the struct blk_zone obtained from the device. This ensures that error handling is performed holding the inode truncate mutex. This change also simplifies error handling for conventional zone files by bypassing the execution of report zones entirely. This is safe to do because the condition of conventional zones cannot be read-only or offline and conventional zone files are always fully mapped with a constant file size.
--- fs/zonefs/file.c | 42 +++++++++++++++++++++------------ fs/zonefs/super.c | 68 ++++++++++++++++++++++++++++++------------------------ 2 files changed, 66 insertions(+), 44 deletions(-)
fs/zonefs/file.c +27 -15
@@ -348,7 +348,12 @@ static int zonefs_file_write_dio_end_io(struct zonefs_inode_info *zi =ZONEFS_I (inode);if (error) { -zonefs_io_error (inode, true); +/* +* For Sync IOs, error recovery is called from +* zonefs_file_dio_write(). +*/ +if (!is_sync_kiocb (iocb)) +zonefs_io_error (inode, true);return error; }
@@ -491,6 +496,14 @@ static ssize_t zonefs_file_dio_write(str ret = -EINVAL ; goto inode_unlock; } +/* +* Advance the zone write pointer offset. This assumes that the +* IO will succeed, which is OK to do because we do not allow +* partial writes (IOMAP_DIO_PARTIAL is not set) and if the IO +* fails, the error path will correct the write pointer offset. +*/ + z->z_wpoffset += count; +zonefs_inode_account_active (inode);mutex_unlock (&zi->i_truncate_mutex); }
@@ -504,20 +517,19 @@ static ssize_t zonefs_file_dio_write(strif (ret == -ENOTBLK ) ret = -EBUSY ; -if (zonefs_zone_is_seq (z) && - (ret >0 || ret == -EIOCBQUEUED )) { -if (ret >0 ) - count = ret; - -/* -* Update the zone write pointer offset assuming the write -* operation succeeded. If it did not, the error recovery path -* will correct it. Also do active seq file accounting. -*/ -mutex_lock (&zi->i_truncate_mutex); - z->z_wpoffset += count; -zonefs_inode_account_active (inode); -mutex_unlock (&zi->i_truncate_mutex); +/* +* For a failed IO or partial completion, trigger error recovery +* to update the zone write pointer offset to a correct value. +* For asynchronous IOs, zonefs_file_write_dio_end_io() may already +* have executed error recovery if the IO already completed when we +* reach here. However, we cannot know that and execute error recovery +* again (that will not change anything). +*/ +if (zonefs_zone_is_seq (z)) { +if (ret >0 && ret != count) + ret = -EIO ; +if (ret <0 && ret != -EIOCBQUEUED ) +zonefs_io_error (inode, true); } inode_unlock:
fs/zonefs/super.c +39 -29
113 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 264/309 mmc: sdhci-pci-o2micro: Fix a warm reboot issue that disk cant be detected by BIOS
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fred Ai <[email protected]>
commit 58aeb5623c2ebdadefe6352b14f8076a7073fea0 upstream.
Driver shall switch clock source from DLL clock to OPE clock when power off card to ensure that card can be identified with OPE clock by BIOS.
--- drivers/mmc/host/sdhci-pci-o2micro.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+)
drivers/mmc/host/sdhci-pci-o2micro.c +30 -0
@@ -693,6 +693,35 @@ static int sdhci_pci_o2_init_sd_express(return 0 ; } +static void sdhci_pci_o2_set_power (struct sdhci_host *host,unsigned char mode,unsigned short vdd) +{ +struct sdhci_pci_chip *chip; +struct sdhci_pci_slot *slot =sdhci_priv (host); +u32 scratch_32 =0 ; +u8 scratch_8 =0 ; + + chip = slot->chip; + +if (mode ==MMC_POWER_OFF ) { +/* UnLock WP */ +pci_read_config_byte (chip->pdev,O2_SD_LOCK_WP , &scratch_8); + scratch_8 &=0x7f ; +pci_write_config_byte (chip->pdev,O2_SD_LOCK_WP , scratch_8); + +/* Set PCR 0x354[16] to switch Clock Source back to OPE Clock */ +pci_read_config_dword (chip->pdev,O2_SD_OUTPUT_CLK_SOURCE_SWITCH , &scratch_32); + scratch_32 &= ~(O2_SD_SEL_DLL ); +pci_write_config_dword (chip->pdev,O2_SD_OUTPUT_CLK_SOURCE_SWITCH , scratch_32); + +/* Lock WP */ +pci_read_config_byte (chip->pdev,O2_SD_LOCK_WP , &scratch_8); + scratch_8 |=0x80 ; +pci_write_config_byte (chip->pdev,O2_SD_LOCK_WP , scratch_8); + } + +sdhci_set_power (host, mode, vdd); +} +static int sdhci_pci_o2_probe_slot (struct sdhci_pci_slot *slot) {struct sdhci_pci_chip *chip;
@@ -1051,6 +1080,7 @@ static const struct sdhci_ops sdhci_pci_ .set_bus_width = sdhci_set_bus_width, .reset = sdhci_reset, .set_uhs_signaling = sdhci_set_uhs_signaling, + .set_power = sdhci_pci_o2_set_power, };const struct sdhci_pci_fixes sdhci_o2 = {
Greg Kroah-Hartman
maintainerPATCH 265/309 arm64/signal: Dont assume that TIF_SVE means we saved SVE state
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mark Brown <[email protected]>
commit 61da7c8e2a602f66be578cbbcebe8638c10e0f48 upstream.
When we are in a syscall we will only save the FPSIMD subset even though the task still has access to the full register set, and on context switch we will only remove TIF_SVE when loading the register state. This means that the signal handling code should not assume that TIF_SVE means that the register state is stored in SVE format, it should instead check the format that was recorded during save.
--- arch/arm64/kernel/fpsimd.c | 2 +- arch/arm64/kernel/signal.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-)
arch/arm64/kernel/fpsimd.c +1 -1
@@ -1628,7 +1628,7 @@ void fpsimd_preserve_current_state(void)void fpsimd_signal_preserve_current_state (void ) {fpsimd_preserve_current_state (); -if (test_thread_flag (TIF_SVE )) +if (current->thread.fp_type ==FP_STATE_SVE )sve_to_fpsimd (current); }
arch/arm64/kernel/signal.c +2 -2
@@ -242,7 +242,7 @@ static int preserve_sve_context(struct s vl =task_get_sme_vl (current); vq =sve_vq_from_vl (vl); flags |=SVE_SIG_FLAG_SM ; - }else if (test_thread_flag (TIF_SVE )) { + }else if (current->thread.fp_type ==FP_STATE_SVE ) { vq =sve_vq_from_vl (vl); }
@@ -878,7 +878,7 @@ static int setup_sigframe_layout(structif (system_supports_sve () ||system_supports_sme ()) {unsigned int vq =0 ; -if (add_all ||test_thread_flag (TIF_SVE ) || +if (add_all || current->thread.fp_type ==FP_STATE_SVE ||thread_sm_enabled (¤t->thread)) {int vl =max (sve_max_vl (),sme_max_vl ());
Greg Kroah-Hartman
maintainerPATCH 266/309 arm64: Subscribe Microsoft Azure Cobalt 100 to ARM Neoverse N2 errata
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Easwar Hariharan <[email protected]>
commit fb091ff394792c018527b3211bbdfae93ea4ac02 upstream.
Add the MIDR value of Microsoft Azure Cobalt 100, which is a Microsoft implemented CPU based on r0p0 of the ARM Neoverse N2 CPU, and therefore suffers from all the same errata.
--- Documentation/arch/arm64/silicon-errata.rst | 7 +++++++ arch/arm64/include/asm/cputype.h | 4 ++++ arch/arm64/kernel/cpu_errata.c | 3 +++ 3 files changed, 14 insertions(+)
Documentation/arch/arm64/silicon-errata.rst +7 -0
@@ -235,3 +235,10 @@ stable kernels. +----------------+-----------------+-----------------+-----------------------------+ | ASR | ASR8601 | #8601001 | N/A | +----------------+-----------------+-----------------+-----------------------------+ ++----------------+-----------------+-----------------+-----------------------------+ +| Microsoft | Azure Cobalt 100| #2139208 | ARM64_ERRATUM_2139208 | ++----------------+-----------------+-----------------+-----------------------------+ +| Microsoft | Azure Cobalt 100| #2067961 | ARM64_ERRATUM_2067961 | ++----------------+-----------------+-----------------+-----------------------------+ +| Microsoft | Azure Cobalt 100| #2253138 | ARM64_ERRATUM_2253138 | ++----------------+-----------------+-----------------+-----------------------------+
arch/arm64/include/asm/cputype.h +4 -0
@@ -61,6 +61,7 @@#define ARM_CPU_IMP_HISI 0x48#define ARM_CPU_IMP_APPLE 0x61#define ARM_CPU_IMP_AMPERE 0xC0 +#define ARM_CPU_IMP_MICROSOFT 0x6D#define ARM_CPU_PART_AEM_V8 0xD0F#define ARM_CPU_PART_FOUNDATION 0xD00
@@ -135,6 +136,8 @@#define AMPERE_CPU_PART_AMPERE1 0xAC3 +#define MICROSOFT_CPU_PART_AZURE_COBALT_100 0xD49/* Based on r0p0 of ARM Neoverse N2 */ +#define MIDR_CORTEX_A53 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53)#define MIDR_CORTEX_A57 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57)#define MIDR_CORTEX_A72 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A72)
@@ -193,6 +196,7 @@#define MIDR_APPLE_M2_BLIZZARD_MAX MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_BLIZZARD_MAX)#define MIDR_APPLE_M2_AVALANCHE_MAX MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_AVALANCHE_MAX)#define MIDR_AMPERE1 MIDR_CPU_MODEL(ARM_CPU_IMP_AMPERE, AMPERE_CPU_PART_AMPERE1) +#define MIDR_MICROSOFT_AZURE_COBALT_100 MIDR_CPU_MODEL(ARM_CPU_IMP_MICROSOFT, MICROSOFT_CPU_PART_AZURE_COBALT_100)/* Fujitsu Erratum 010001 affects A64FX 1.0 and 1.1, (v0r0 and v1r0) */ #define MIDR_FUJITSU_ERRATUM_010001 MIDR_FUJITSU_A64FX
arch/arm64/kernel/cpu_errata.c +3 -0
@@ -374,6 +374,7 @@ static const struct midr_range erratum_1static const struct midr_range trbe_overwrite_fill_mode_cpus[] = { #ifdef CONFIG_ARM64_ERRATUM_2139208MIDR_ALL_VERSIONS (MIDR_NEOVERSE_N2 ), +MIDR_ALL_VERSIONS (MIDR_MICROSOFT_AZURE_COBALT_100 ), #endif #ifdef CONFIG_ARM64_ERRATUM_2119858 MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
@@ -387,6 +388,7 @@ static const struct midr_range trbe_overstatic const struct midr_range tsb_flush_fail_cpus[] = { #ifdef CONFIG_ARM64_ERRATUM_2067961MIDR_ALL_VERSIONS (MIDR_NEOVERSE_N2 ), +MIDR_ALL_VERSIONS (MIDR_MICROSOFT_AZURE_COBALT_100 ), #endif #ifdef CONFIG_ARM64_ERRATUM_2054223 MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
@@ -399,6 +401,7 @@ static const struct midr_range tsb_flushstatic struct midr_range trbe_write_out_of_range_cpus[] = { #ifdef CONFIG_ARM64_ERRATUM_2253138MIDR_ALL_VERSIONS (MIDR_NEOVERSE_N2 ), +MIDR_ALL_VERSIONS (MIDR_MICROSOFT_AZURE_COBALT_100 ), #endif #ifdef CONFIG_ARM64_ERRATUM_2224489 MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
Greg Kroah-Hartman
maintainerPATCH 267/309 ASoC: SOF: IPC3: fix message bounds on ipc ops
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Curtis Malainey <[email protected]>
commit fcbe4873089c84da641df75cda9cac2e9addbb4b upstream.
commit 74ad8ed65121 ("ASoC: SOF: ipc3: Implement rx_msg IPC ops") introduced a new allocation before the upper bounds check in do_rx_work. As a result A DSP can cause bad allocations if spewing garbage.
--- sound/soc/sof/ipc3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/soc/sof/ipc3.c +1 -1
@@ -1067,7 +1067,7 @@ static void sof_ipc3_rx_msg(struct snd_sreturn ; } -if (hdr.size <sizeof (hdr)) { +if (hdr.size <sizeof (hdr) || hdr.size >SOF_IPC_MSG_MAX_SIZE ) {dev_err (sdev->dev,"The received message size is invalid\n" );return ; }
Greg Kroah-Hartman
maintainerPATCH 268/309 ASoC: tas2781: add module parameter to tascodec_init()
In reply to Greg Kroah-Hartman6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gergo Koteles <[email protected]>
commit 34a1066981a967eab619938e7b35a9be6b4c34e1 upstream.
The tascodec_init() of the snd-soc-tas2781-comlib module is called from snd-soc-tas2781-i2c and snd-hda-scodec-tas2781-i2c modules. It calls request_firmware_nowait() with parameter THIS_MODULE and a cont/callback from the latter modules.
The latter modules can be removed while their callbacks are running, resulting in a general protection failure.
Add module parameter to tascodec_init() so request_firmware_nowait() can be called with the module of the callback.
--- include/sound/tas2781.h | 1 + sound/pci/hda/tas2781_hda_i2c.c | 2 +- sound/soc/codecs/tas2781-comlib.c | 3 ++- sound/soc/codecs/tas2781-i2c.c | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-)
include/sound/tas2781.h +1 -0
@@ -135,6 +135,7 @@ struct tasdevice_priv {void tas2781_reset (struct tasdevice_priv *tas_dev);int tascodec_init (struct tasdevice_priv *tas_priv,void *codec, +struct module *module,void (*cont)(const struct firmware *fw,void *context));struct tasdevice_priv *tasdevice_kzalloc (struct i2c_client *i2c);int tasdevice_init (struct tasdevice_priv *tas_priv);
sound/pci/hda/tas2781_hda_i2c.c +1 -1
@@ -627,7 +627,7 @@ static int tas2781_hda_bind(struct devicstrscpy (comps->name,dev_name (dev),sizeof (comps->name)); - ret =tascodec_init (tas_hda->priv, codec, tasdev_fw_ready); + ret =tascodec_init (tas_hda->priv, codec,THIS_MODULE , tasdev_fw_ready);if (!ret) comps->playback_hook = tas2781_hda_playback_hook;
sound/soc/codecs/tas2781-comlib.c +2 -1
@@ -267,6 +267,7 @@ void tas2781_reset(struct tasdevice_privEXPORT_SYMBOL_GPL (tas2781_reset);int tascodec_init (struct tasdevice_priv *tas_priv,void *codec, +struct module *module,void (*cont)(const struct firmware *fw,void *context)) {int ret =0 ;
@@ -280,7 +281,7 @@ int tascodec_init(struct tasdevice_priv tas_priv->dev_name, tas_priv->ndev);crc8_populate_msb (tas_priv->crc8_lkp_tbl,TASDEVICE_CRC8_POLYNOMIAL ); tas_priv->codec = codec; - ret =request_firmware_nowait (THIS_MODULE ,FW_ACTION_UEVENT , + ret =request_firmware_nowait (module,FW_ACTION_UEVENT , tas_priv->rca_binaryname, tas_priv->dev,GFP_KERNEL , tas_priv, cont);if (ret)
sound/soc/codecs/tas2781-i2c.c +1 -1
@@ -564,7 +564,7 @@ static int tasdevice_codec_probe(struct {struct tasdevice_priv *tas_priv =snd_soc_component_get_drvdata (codec); -return tascodec_init (tas_priv, codec, tasdevice_fw_ready); +return tascodec_init (tas_priv, codec,THIS_MODULE , tasdevice_fw_ready); }static void tasdevice_deinit (void *context)