6.6.3-rc1 review
Subsystems (8)
Greg Kroah-Hartman
maintainerPATCH 321/530 mmc: vub300: fix an error code
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
commit b44f9da81783fda72632ef9b0d05ea3f3ca447a5 upstream.
This error path should return -EINVAL instead of success.
--- drivers/mmc/host/vub300.c | 1 + 1 file changed, 1 insertion(+)
drivers/mmc/host/vub300.c +1 -0
@@ -2309,6 +2309,7 @@ static int vub300_probe(struct usb_inter vub300->read_only = (0x0010 & vub300->system_port_status.port_flags) ?1 :0 ; }else { + retval = -EINVAL ; goto error5; }usb_set_intfdata (interface, vub300);
Greg Kroah-Hartman
maintainerPATCH 322/530 mmc: sdhci_am654: fix start loop index for TAP value parsing
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nitin Yadav <[email protected]>
commit 71956d0cb56c1e5f9feeb4819db87a076418e930 upstream.
ti,otap-del-sel-legacy/ti,itap-del-sel-legacy passed from DT are currently ignored for all SD/MMC and eMMC modes. Fix this by making start loop index to MMC_TIMING_LEGACY.
--- drivers/mmc/host/sdhci_am654.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/mmc/host/sdhci_am654.c +1 -1
@@ -598,7 +598,7 @@ static int sdhci_am654_get_otap_delay(streturn 0 ; } -for (i =MMC_TIMING_MMC_HS ; i <=MMC_TIMING_MMC_HS400 ; i++) { +for (i =MMC_TIMING_LEGACY ; i <=MMC_TIMING_MMC_HS400 ; i++) { ret =device_property_read_u32 (dev, td[i].otap_binding, &sdhci_am654->otap_del_sel[i]);
Greg Kroah-Hartman
maintainerPATCH 323/530 mmc: Add quirk MMC_QUIRK_BROKEN_CACHE_FLUSH for Micron eMMC Q2J54A
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bean Huo <[email protected]>
commit ed9009ad300c0f15a3ecfe9613547b1962bde02c upstream.
Micron MTFC4GACAJCN eMMC supports cache but requires that flush cache operation be allowed only after a write has occurred. Otherwise, the cache flush command or subsequent commands will time out.
--- drivers/mmc/core/block.c | 4 +++- drivers/mmc/core/card.h | 4 ++++ drivers/mmc/core/mmc.c | 8 ++++++-- drivers/mmc/core/quirks.h | 7 ++++--- include/linux/mmc/card.h | 2 ++ 5 files changed, 19 insertions(+), 6 deletions(-)
drivers/mmc/core/block.c +3 -1
@@ -2381,8 +2381,10 @@ enum mmc_issued mmc_blk_mq_issue_rq(stru } ret =mmc_blk_cqe_issue_flush (mq, req);break ; -case REQ_OP_READ :case REQ_OP_WRITE : + card->written_flag = true; + fallthrough; +case REQ_OP_READ :if (host->cqe_enabled) ret =mmc_blk_cqe_issue_rw_rq (mq, req);else
drivers/mmc/core/card.h +4 -0
@@ -280,4 +280,8 @@ static inline int mmc_card_broken_sd_cac return c->quirks & MMC_QUIRK_BROKEN_SD_CACHE; } +static inline int mmc_card_broken_cache_flush (const struct mmc_card *c) +{ +return c->quirks &MMC_QUIRK_BROKEN_CACHE_FLUSH ; +}#endif
drivers/mmc/core/mmc.c +6 -2
@@ -2081,13 +2081,17 @@ static int _mmc_flush_cache(struct mmc_h {int err =0 ; +if (mmc_card_broken_cache_flush (host->card) && !host->card->written_flag) +return 0 ; +if (_mmc_cache_enabled (host)) { err =mmc_switch (host->card,EXT_CSD_CMD_SET_NORMAL ,EXT_CSD_FLUSH_CACHE ,1 ,CACHE_FLUSH_TIMEOUT_MS );if (err) -pr_err ("%s: cache flush error %d\n" , -mmc_hostname (host), err); +pr_err ("%s: cache flush error %d\n" ,mmc_hostname (host), err); +else + host->card->written_flag = false; }return err;
drivers/mmc/core/quirks.h +4 -3
@@ -110,11 +110,12 @@ static const struct mmc_fixup __maybe_un MMC_QUIRK_TRIM_BROKEN),/* -* Micron MTFC4GACAJCN-1M advertises TRIM but it does not seems to -* support being used to offload WRITE_ZEROES. +* Micron MTFC4GACAJCN-1M supports TRIM but does not appear to support +* WRITE_ZEROES offloading. It also supports caching, but the cache can +* only be flushed after a write has occurred. */ MMC_FIXUP ("Q2J54A" ,CID_MANFID_MICRON ,0x014e , add_quirk_mmc, - MMC_QUIRK_TRIM_BROKEN), + MMC_QUIRK_TRIM_BROKEN | MMC_QUIRK_BROKEN_CACHE_FLUSH),/* * Kingston EMMC04G-M627 advertises TRIM but it does not seems to
include/linux/mmc/card.h +2 -0
@@ -295,7 +295,9 @@ struct mmc_card {#define MMC_QUIRK_BROKEN_HPI (1<<13)/* Disable broken HPI support */ #define MMC_QUIRK_BROKEN_SD_DISCARD (1<<14)/* Disable broken SD discard support */ #define MMC_QUIRK_BROKEN_SD_CACHE (1<<15)/* Disable broken SD cache support */ +#define MMC_QUIRK_BROKEN_CACHE_FLUSH (1<<16)/* Don't flush cache until the write has occurred */ +bool written_flag;/* Indicates eMMC has been written since power on */ bool reenable_cmdq;/* Re-enable Command Queue */ unsigned int erase_size;/* erase size in sectors */
Greg Kroah-Hartman
maintainerPATCH 324/530 PCI: qcom-ep: Add dedicated callback for writing to DBI2 registers
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Manivannan Sadhasivam <[email protected]>
commit a07d2497ed657eb2efeb967af47e22f573dcd1d6 upstream.
The DWC core driver exposes the write_dbi2() callback for writing to the DBI2 registers in a vendor-specific way.
On the Qcom EP platforms, the DBI_CS2 bit in the ELBI region needs to be asserted before writing to any DBI2 registers and deasserted once done.
So, let's implement the callback for the Qcom PCIe EP driver so that the DBI2 writes are correctly handled in the hardware.
Without this callback, the DBI2 register writes like BAR size won't go through and as a result, the default BAR size is set for all BARs.
--- drivers/pci/controller/dwc/pcie-qcom-ep.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
drivers/pci/controller/dwc/pcie-qcom-ep.c +17 -0
@@ -123,6 +123,7 @@/* ELBI registers */ #define ELBI_SYS_STTS 0x08 +#define ELBI_CS2_ENABLE 0xa4/* DBI registers */ #define DBI_CON_STATUS 0x44
@@ -263,6 +264,21 @@ static void qcom_pcie_dw_stop_link(strucdisable_irq (pcie_ep->perst_irq); } +static void qcom_pcie_dw_write_dbi2 (struct dw_pcie *pci,void __iomem *base, +u32 reg,size_t size,u32 val) +{ +struct qcom_pcie_ep *pcie_ep =to_pcie_ep (pci); +int ret; + +writel (1 , pcie_ep->elbi +ELBI_CS2_ENABLE ); + + ret =dw_pcie_write (pci->dbi_base2 + reg, size, val); +if (ret) +dev_err (pci->dev,"Failed to write DBI2 register (0x%x): %d\n" , reg, ret); + +writel (0 , pcie_ep->elbi +ELBI_CS2_ENABLE ); +} +static void qcom_pcie_ep_icc_update (struct qcom_pcie_ep *pcie_ep) {struct dw_pcie *pci = &pcie_ep->pci;
@@ -519,6 +535,7 @@ static const struct dw_pcie_ops pci_ops .link_up = qcom_pcie_dw_link_up, .start_link = qcom_pcie_dw_start_link, .stop_link = qcom_pcie_dw_stop_link, + .write_dbi2 = qcom_pcie_dw_write_dbi2, }; static int qcom_pcie_ep_get_io_resources(struct platform_device *pdev,
Greg Kroah-Hartman
maintainerPATCH 325/530 PCI/ASPM: Fix L1 substate handling in aspm_attr_store_common()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Heiner Kallweit <[email protected]>
commit 8e37372ad0bea4c9b4712d9943f6ae96cff9491f upstream.
aspm_attr_store_common(), which handles sysfs control of ASPM, has the same problem as fb097dcd5a28 ("PCI/ASPM: Disable only ASPM_STATE_L1 when driver disables L1"): disabling L1 adds only ASPM_L1 (but not any of the L1.x substates) to the "aspm_disable" mask.
Enabling one substate, e.g., L1.1, via sysfs removes ASPM_L1 from the disable mask. Since disabling L1 via sysfs doesn't add any of the substates to the disable mask, enabling L1.1 actually enables *all* the substates.
In this scenario:
- Write 0 to "l1_aspm" to disable L1
- Write 1 to "l1_1_aspm" to enable L1.1
the intention is to disable L1 and all L1.x substates, then enable just L1.1, but in fact, *all* L1.x substates are enabled.
Fix this by explicitly disabling all the L1.x substates when disabling L1.
--- drivers/pci/pcie/aspm.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/pci/pcie/aspm.c +2 -0
@@ -1248,6 +1248,8 @@ static ssize_t aspm_attr_store_common(st link->aspm_disable &= ~ASPM_STATE_L1 ; }else { link->aspm_disable |= state; +if (state &ASPM_STATE_L1 ) + link->aspm_disable |=ASPM_STATE_L1SS ; }pcie_config_aspm_link (link,policy_to_aspm_state (link));
Greg Kroah-Hartman
maintainerPATCH 326/530 PCI: kirin: Dont discard .remove() callback
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Uwe Kleine-König <[email protected]>
commit 3064ef2e88c1629c1e67a77d7bc20020b35846f2 upstream.
With CONFIG_PCIE_KIRIN=y and kirin_pcie_remove() marked with __exit, the function is discarded from the driver. In this case a bound device can still get unbound, e.g via sysfs. Then no cleanup code is run resulting in resource leaks or worse.
The right thing to do is do always have the remove callback available. This fixes the following warning by modpost:
drivers/pci/controller/dwc/pcie-kirin: section mismatch in reference: kirin_pcie_driver+0x8 (section: .data) -> kirin_pcie_remove (section: .exit.text)
(with ARCH=x86_64 W=1 allmodconfig).
--- drivers/pci/controller/dwc/pcie-kirin.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/pci/controller/dwc/pcie-kirin.c +2 -2
@@ -741,7 +741,7 @@ err:return ret; } -static int __exit kirin_pcie_remove(struct platform_device *pdev) +static int kirin_pcie_remove (struct platform_device *pdev) {struct kirin_pcie *kirin_pcie =platform_get_drvdata (pdev);
@@ -818,7 +818,7 @@ static int kirin_pcie_probe(struct platfstatic struct platform_driver kirin_pcie_driver = { .probe = kirin_pcie_probe, - .remove =__exit_p (kirin_pcie_remove), + .remove = kirin_pcie_remove, .driver = { .name ="kirin-pcie" , .of_match_table = kirin_pcie_match,
Greg Kroah-Hartman
maintainerPATCH 327/530 PCI: exynos: Dont discard .remove() callback
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Uwe Kleine-König <[email protected]>
commit 83a939f0fdc208ff3639dd3d42ac9b3c35607fd2 upstream.
With CONFIG_PCI_EXYNOS=y and exynos_pcie_remove() marked with __exit, the function is discarded from the driver. In this case a bound device can still get unbound, e.g via sysfs. Then no cleanup code is run resulting in resource leaks or worse.
The right thing to do is do always have the remove callback available. This fixes the following warning by modpost:
WARNING: modpost: drivers/pci/controller/dwc/pci-exynos: section mismatch in reference: exynos_pcie_driver+0x8 (section: .data) -> exynos_pcie_remove (section: .exit.text)
(with ARCH=x86_64 W=1 allmodconfig).
--- drivers/pci/controller/dwc/pci-exynos.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/pci/controller/dwc/pci-exynos.c +2 -2
@@ -375,7 +375,7 @@ fail_probe:return ret; } -static int __exit exynos_pcie_remove(struct platform_device *pdev) +static int exynos_pcie_remove (struct platform_device *pdev) {struct exynos_pcie *ep =platform_get_drvdata (pdev);
@@ -431,7 +431,7 @@ static const struct of_device_id exynos_static struct platform_driver exynos_pcie_driver = { .probe = exynos_pcie_probe, - .remove =__exit_p (exynos_pcie_remove), + .remove = exynos_pcie_remove, .driver = { .name ="exynos-pcie" , .of_match_table = exynos_pcie_of_match,
Greg Kroah-Hartman
maintainerPATCH 328/530 PCI: Lengthen reset delay for VideoPropulsion Torrent QN16e card
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lukas Wunner <[email protected]>
commit c9260693aa0c1e029ed23693cfd4d7814eee6624 upstream.
Commit ac91e6980563 ("PCI: Unify delay handling for reset and resume") shortened an unconditional 1 sec delay after a Secondary Bus Reset to 100 msec for PCIe (per PCIe r6.1 sec 6.6.1). The 1 sec delay is only required for Conventional PCI.
But it turns out that there are PCIe devices which require a longer delay than prescribed before first config space access after reset recovery or resume from D3cold:
Chad reports that a "VideoPropulsion Torrent QN16e" MPEG QAM Modulator "raises a PCI system error (PERR), as reported by the IPMI event log, and the hardware itself would suffer a catastrophic event, cycling the server" unless the longer delay is observed.
The card is specified to conform to PCIe r1.0 and indeed only supports Gen1 speed (2.5 GT/s) according to lspci. PCIe r1.0 sec 7.6 prescribes the same 100 msec delay as PCIe r6.1 sec 6.6.1:
To allow components to perform internal initialization, system software must wait for at least 100 ms from the end of a reset (cold/warm/hot) before it is permitted to issue Configuration Requests
The behavior of the Torrent QN16e card thus appears to be a quirk. Treat it as such and lengthen the reset delay for this specific device.
--- drivers/pci/quirks.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
drivers/pci/quirks.c +12 -0
@@ -6211,3 +6211,15 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_IDECLARE_PCI_FIXUP_FINAL (PCI_VENDOR_ID_XILINX ,0x5020 , of_pci_make_dev_node);DECLARE_PCI_FIXUP_FINAL (PCI_VENDOR_ID_XILINX ,0x5021 , of_pci_make_dev_node);DECLARE_PCI_FIXUP_FINAL (PCI_VENDOR_ID_REDHAT ,0x0005 , of_pci_make_dev_node); + +/* +* Devices known to require a longer delay before first config space access +* after reset recovery or resume from D3cold: +* +* VideoPropulsion (aka Genroco) Torrent QN16e MPEG QAM Modulator +*/ +static void pci_fixup_d3cold_delay_1sec (struct pci_dev *pdev) +{ + pdev->d3cold_delay =1000 ; +} +DECLARE_PCI_FIXUP_FINAL (0x5555 ,0x0004 , pci_fixup_d3cold_delay_1sec);
Greg Kroah-Hartman
maintainerPATCH 329/530 wifi: wilc1000: use vmm_table as array in wilc struct
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ajay Singh <[email protected]>
commit 05ac1a198a63ad66bf5ae8b7321407c102d40ef3 upstream.
Enabling KASAN and running some iperf tests raises some memory issues with vmm_table:
BUG: KASAN: slab-out-of-bounds in wilc_wlan_handle_txq+0x6ac/0xdb4 Write of size 4 at addr c3a61540 by task wlan0-tx/95
KASAN detects that we are writing data beyond range allocated to vmm_table. There is indeed a mismatch between the size passed to allocator in wilc_wlan_init, and the range of possible indexes used later: allocation size is missing a multiplication by sizeof(u32)
--- drivers/net/wireless/microchip/wilc1000/wlan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/microchip/wilc1000/wlan.c +1 -1
@@ -1492,7 +1492,7 @@ int wilc_wlan_init(struct net_device *de }if (!wilc->vmm_table) - wilc->vmm_table =kzalloc (WILC_VMM_TBL_SIZE ,GFP_KERNEL ); + wilc->vmm_table =kcalloc (WILC_VMM_TBL_SIZE ,sizeof (u32),GFP_KERNEL );if (!wilc->vmm_table) { ret = -ENOBUFS ;
Greg Kroah-Hartman
maintainerPATCH 330/530 svcrdma: Drop connection after an RDMA Read error
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
commit 197115ebf358cb440c73e868b2a0a5ef728decc6 upstream.
When an RPC Call message cannot be pulled from the client, that is a message loss, by definition. Close the connection to trigger the client to resend.
--- net/sunrpc/xprtrdma/svc_rdma_recvfrom.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
net/sunrpc/xprtrdma/svc_rdma_recvfrom.c +2 -1
@@ -852,7 +852,8 @@ out_readfail:if (ret == -EINVAL )svc_rdma_send_error (rdma_xprt, ctxt, ret);svc_rdma_recv_ctxt_put (rdma_xprt, ctxt); -return ret; +svc_xprt_deferred_close (xprt); +return -ENOTCONN ; out_backchannel:svc_rdma_handle_bc_reply (rqstp, ctxt);
Greg Kroah-Hartman
maintainerPATCH 331/530 rcu/tree: Defer setting of jiffies during stall reset
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joel Fernandes (Google) <[email protected]>
commit b96e7a5fa0ba9cda32888e04f8f4bac42d49a7f8 upstream.
There are instances where rcu_cpu_stall_reset() is called when jiffies did not get a chance to update for a long time. Before jiffies is updated, the CPU stall detector can go off triggering false-positives where a just-started grace period appears to be ages old. In the past, we disabled stall detection in rcu_cpu_stall_reset() however this got changed [1]. This is resulting in false-positives in KGDB usecase [2].
Fix this by deferring the update of jiffies to the third run of the FQS loop. This is more robust, as, even if rcu_cpu_stall_reset() is called just before jiffies is read, we would end up pushing out the jiffies read by 3 more FQS loops. Meanwhile the CPU stall detection will be delayed and we will not get any false positives.
[1] https://lore.kernel.org/all/[email protected]/
[2] https://lore.kernel.org/all/[email protected]/
Tested with rcutorture.cpu_stall option as well to verify stall behavior with/without patch.
--- kernel/rcu/tree.c | 12 ++++++++++++ kernel/rcu/tree.h | 4 ++++ kernel/rcu/tree_stall.h | 20 ++++++++++++++++++-- 3 files changed, 34 insertions(+), 2 deletions(-)
kernel/rcu/tree.c +12 -0
@@ -1556,10 +1556,22 @@ static bool rcu_gp_fqs_check_wake(int *g*/ static void rcu_gp_fqs (bool first_time) { +int nr_fqs =READ_ONCE (rcu_state.nr_fqs_jiffies_stall);struct rcu_node *rnp =rcu_get_root ();WRITE_ONCE (rcu_state.gp_activity, jiffies);WRITE_ONCE (rcu_state.n_force_qs, rcu_state.n_force_qs +1 ); + +WARN_ON_ONCE (nr_fqs >3 ); +/* Only countdown nr_fqs for stall purposes if jiffies moves. */ +if (nr_fqs) { +if (nr_fqs ==1 ) { +WRITE_ONCE (rcu_state.jiffies_stall, + jiffies +rcu_jiffies_till_stall_check ()); + } +WRITE_ONCE (rcu_state.nr_fqs_jiffies_stall, --nr_fqs); + } +if (first_time) {/* Collect dyntick-idle snapshots. */ force_qs_rnp (dyntick_save_progress_counter);
kernel/rcu/tree.h +4 -0
@@ -386,6 +386,10 @@ struct rcu_state {/* in jiffies. */ unsigned long jiffies_stall;/* Time at which to check */ /* for CPU stalls. */ +int nr_fqs_jiffies_stall;/* Number of fqs loops after +* which read jiffies and set +* jiffies_stall. Stall +* warnings disabled if !0. */ unsigned long jiffies_resched;/* Time at which to resched */ /* a reluctant CPU. */ unsigned long n_force_qs_gpstart;/* Snapshot of n_force_qs at */
kernel/rcu/tree_stall.h +18 -2
@@ -149,12 +149,17 @@ static void panic_on_rcu_stall(void)/** * rcu_cpu_stall_reset - restart stall-warning timeout for current grace period * +* To perform the reset request from the caller, disable stall detection until +* 3 fqs loops have passed. This is required to ensure a fresh jiffies is +* loaded. It should be safe to do from the fqs loop as enough timer +* interrupts and context switches should have passed. +* * The caller must disable hard irqs. */ void rcu_cpu_stall_reset (void ) { -WRITE_ONCE (rcu_state.jiffies_stall, - jiffies +rcu_jiffies_till_stall_check ()); +WRITE_ONCE (rcu_state.nr_fqs_jiffies_stall,3 ); +WRITE_ONCE (rcu_state.jiffies_stall,ULONG_MAX ); }//////////////////////////////////////////////////////////////////////////////
@@ -170,6 +175,7 @@ static void record_gp_stall_check_time(vWRITE_ONCE (rcu_state.gp_start, j); j1 =rcu_jiffies_till_stall_check ();smp_mb ();// ->gp_start before ->jiffies_stall and caller's ->gp_seq. +WRITE_ONCE (rcu_state.nr_fqs_jiffies_stall,0 );WRITE_ONCE (rcu_state.jiffies_stall, j + j1); rcu_state.jiffies_resched = j + j1 /2 ; rcu_state.n_force_qs_gpstart =READ_ONCE (rcu_state.n_force_qs);
@@ -725,6 +731,16 @@ static void check_cpu_stall(struct rcu_d !rcu_gp_in_progress())return ;rcu_stall_kick_kthreads (); + +/* +* Check if it was requested (via rcu_cpu_stall_reset()) that the FQS +* loop has to set jiffies to ensure a non-stale jiffies value. This +* is required to have good jiffies value after coming out of long +* breaks of jiffies updates. Not doing so can cause false positives. +*/ +if (READ_ONCE (rcu_state.nr_fqs_jiffies_stall) >0 ) +return ; + j = jiffies;/*
Greg Kroah-Hartman
maintainerPATCH 332/530 arm64: dts: qcom: ipq6018: Fix hwlock index for SMEM
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vignesh Viswanathan <[email protected]>
commit 95d97b111e1e184b0c8656137033ed64f2cf21e4 upstream.
SMEM uses lock index 3 of the TCSR Mutex hwlock for allocations in SMEM region shared by the Host and FW.
Fix the SMEM hwlock index to 3 for IPQ6018.
--- arch/arm64/boot/dts/qcom/ipq6018.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/qcom/ipq6018.dtsi +1 -1
@@ -211,7 +211,7 @@ smem { compatible = "qcom,smem"; memory-region = <&smem_region>; - hwlocks = <&tcsr_mutex 0>; + hwlocks = <&tcsr_mutex 3>; }; soc: soc@0 {
Greg Kroah-Hartman
maintainerPATCH 333/530 dt-bindings: timer: renesas,rz-mtu3: Fix overflow/underflow interrupt names
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Biju Das <[email protected]>
commit b7a8f1f7a8a25e09aaefebb6251a77f44cda638b upstream.
As per R01UH0914EJ0130 Rev.1.30 HW manual the MTU3 overflow/underflow interrupt names starts with 'tci' instead of 'tgi'.
Fix this documentation issue by replacing below overflow/underflow interrupt names:
- tgiv0->tciv0
- tgiv1->tciv1
- tgiu1->tciu1
- tgiv2->tciv2
- tgiu2->tciu2
- tgiv3->tciv3
- tgiv4->tciv4
- tgiv6->tciv6
- tgiv7->tciv7
- tgiv8->tciv8
- tgiu8->tciu8
--- Documentation/devicetree/bindings/timer/renesas,rz-mtu3.yaml | 38 +++++------ 1 file changed, 19 insertions(+), 19 deletions(-)
Documentation/devicetree/bindings/timer/renesas,rz-mtu3.yaml +19 -19
@@ -169,27 +169,27 @@ properties: - const: tgib0 - const: tgic0 - const: tgid0 - - const: tgiv0 + - const: tciv0 - const: tgie0 - const: tgif0 - const: tgia1 - const: tgib1 - - const: tgiv1 - - const: tgiu1 + - const: tciv1 + - const: tciu1 - const: tgia2 - const: tgib2 - - const: tgiv2 - - const: tgiu2 + - const: tciv2 + - const: tciu2 - const: tgia3 - const: tgib3 - const: tgic3 - const: tgid3 - - const: tgiv3 + - const: tciv3 - const: tgia4 - const: tgib4 - const: tgic4 - const: tgid4 - - const: tgiv4 + - const: tciv4 - const: tgiu5 - const: tgiv5 - const: tgiw5
@@ -197,18 +197,18 @@ properties: - const: tgib6 - const: tgic6 - const: tgid6 - - const: tgiv6 + - const: tciv6 - const: tgia7 - const: tgib7 - const: tgic7 - const: tgid7 - - const: tgiv7 + - const: tciv7 - const: tgia8 - const: tgib8 - const: tgic8 - const: tgid8 - - const: tgiv8 - - const: tgiu8 + - const: tciv8 + - const: tciu8 clocks: maxItems: 1
@@ -285,16 +285,16 @@ examples: <GIC_SPI 211 IRQ_TYPE_EDGE_RISING>, <GIC_SPI 212 IRQ_TYPE_EDGE_RISING>, <GIC_SPI 213 IRQ_TYPE_EDGE_RISING>; - interrupt-names = "tgia0", "tgib0", "tgic0", "tgid0", "tgiv0", "tgie0", + interrupt-names = "tgia0", "tgib0", "tgic0", "tgid0", "tciv0", "tgie0", "tgif0", - "tgia1", "tgib1", "tgiv1", "tgiu1", - "tgia2", "tgib2", "tgiv2", "tgiu2", - "tgia3", "tgib3", "tgic3", "tgid3", "tgiv3", - "tgia4", "tgib4", "tgic4", "tgid4", "tgiv4", + "tgia1", "tgib1", "tciv1", "tciu1", + "tgia2", "tgib2", "tciv2", "tciu2", + "tgia3", "tgib3", "tgic3", "tgid3", "tciv3", + "tgia4", "tgib4", "tgic4", "tgid4", "tciv4", "tgiu5", "tgiv5", "tgiw5", - "tgia6", "tgib6", "tgic6", "tgid6", "tgiv6", - "tgia7", "tgib7", "tgic7", "tgid7", "tgiv7", - "tgia8", "tgib8", "tgic8", "tgid8", "tgiv8", "tgiu8"; + "tgia6", "tgib6", "tgic6", "tgid6", "tciv6", + "tgia7", "tgib7", "tgic7", "tgid7", "tciv7", + "tgia8", "tgib8", "tgic8", "tgid8", "tciv8", "tciu8"; clocks = <&cpg CPG_MOD R9A07G044_MTU_X_MCK_MTU3>; power-domains = <&cpg>; resets = <&cpg R9A07G044_MTU_X_PRESET_MTU3>;
Greg Kroah-Hartman
maintainerPATCH 334/530 PM: hibernate: Use __get_safe_page() rather than touching the list
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Brian Geffon <[email protected]>
commit f0c7183008b41e92fa676406d87f18773724b48b upstream.
We found at least one situation where the safe pages list was empty and get_buffer() would gladly try to use a NULL pointer.
--- kernel/power/snapshot.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
kernel/power/snapshot.c +6 -4
@@ -2545,8 +2545,9 @@ static void *get_highmem_page_buffer(str pbe->copy_page = tmp; }else {/* Copy of the page will be stored in normal memory */ - kaddr = safe_pages_list; - safe_pages_list = safe_pages_list->next; + kaddr =__get_safe_page (ca->gfp_mask); +if (!kaddr) +return ERR_PTR (-ENOMEM ); pbe->copy_page =virt_to_page (kaddr); } pbe->next = highmem_pblist;
@@ -2750,8 +2751,9 @@ static void *get_buffer(struct memory_bireturn ERR_PTR (-ENOMEM ); } pbe->orig_address =page_address (page); - pbe->address = safe_pages_list; - safe_pages_list = safe_pages_list->next; + pbe->address =__get_safe_page (ca->gfp_mask); +if (!pbe->address) +return ERR_PTR (-ENOMEM ); pbe->next = restore_pblist; restore_pblist = pbe;return pbe->address;
Greg Kroah-Hartman
maintainerPATCH 335/530 PM: hibernate: Clean up sync_read handling in snapshot_write_next()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Brian Geffon <[email protected]>
commit d08970df1980476f27936e24d452550f3e9e92e1 upstream.
In snapshot_write_next(), sync_read is set and unset in three different spots unnecessiarly. As a result there is a subtle bug where the first page after the meta data has been loaded unconditionally sets sync_read to 0. If this first PFN was actually a highmem page, then the returned buffer will be the global "buffer," and the page needs to be loaded synchronously.
That is, I'm not sure we can always assume the following to be safe:
handle->buffer = get_buffer(&orig_bm, &ca); handle->sync_read = 0;
Because get_buffer() can call get_highmem_page_buffer() which can return 'buffer'.
The easiest way to address this is just set sync_read before snapshot_write_next() returns if handle->buffer == buffer.
--- kernel/power/snapshot.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-)
kernel/power/snapshot.c +1 -5
@@ -2785,8 +2785,6 @@ next:if (handle->cur >1 && handle->cur > nr_meta_pages + nr_copy_pages + nr_zero_pages)return 0 ; - handle->sync_read =1 ; -if (!handle->cur) {if (!buffer)/* This makes the buffer be freed by swsusp_free() */
@@ -2829,7 +2827,6 @@ next:memory_bm_position_reset (&zero_bm); restore_pblist =NULL ; handle->buffer =get_buffer (&orig_bm, &ca); - handle->sync_read =0 ;if (IS_ERR (handle->buffer))return PTR_ERR (handle->buffer); }
@@ -2839,9 +2836,8 @@ next: handle->buffer =get_buffer (&orig_bm, &ca);if (IS_ERR (handle->buffer))return PTR_ERR (handle->buffer); -if (handle->buffer != buffer) - handle->sync_read =0 ; } + handle->sync_read = (handle->buffer == buffer); handle->cur++;/* Zero pages were not included in the image, memset it and move on. */
Greg Kroah-Hartman
maintainerPATCH 336/530 rcu: kmemleak: Ignore kmemleak false positives when RCU-freeing objects
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Catalin Marinas <[email protected]>
commit 5f98fd034ca6fd1ab8c91a3488968a0e9caaabf6 upstream.
Since the actual slab freeing is deferred when calling kvfree_rcu(), so is the kmemleak_free() callback informing kmemleak of the object deletion. From the perspective of the kvfree_rcu() caller, the object is freed and it may remove any references to it. Since kmemleak does not scan RCU internal data storing the pointer, it will report such objects as leaks during the grace period.
Tell kmemleak to ignore such objects on the kvfree_call_rcu() path. Note that the tiny RCU implementation does not have such issue since the objects can be tracked from the rcu_ctrlblk structure.
--- kernel/rcu/tree.c | 9 +++++++++ 1 file changed, 9 insertions(+)
kernel/rcu/tree.c +9 -0
@@ -31,6 +31,7 @@#include <linux/bitops.h> #include <linux/export.h> #include <linux/completion.h> +#include <linux/kmemleak.h> #include <linux/moduleparam.h> #include <linux/panic.h> #include <linux/panic_notifier.h>
@@ -3401,6 +3402,14 @@ void kvfree_call_rcu(struct rcu_head *he success = true; } +/* +* The kvfree_rcu() caller considers the pointer freed at this point +* and likely removes any references to it. Since the actual slab +* freeing (and kmemleak_free()) is deferred, tell kmemleak to ignore +* this object (no scanning or false positives reporting). +*/ +kmemleak_ignore (ptr); +// Set timer to drain after KFREE_DRAIN_JIFFIES. if (rcu_scheduler_active ==RCU_SCHEDULER_RUNNING )schedule_delayed_monitor_work (krcp);
Greg Kroah-Hartman
maintainerPATCH 337/530 btrfs: dont arbitrarily slow down delalloc if were committing
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <[email protected]>
commit 11aeb97b45ad2e0040cbb2a589bc403152526345 upstream.
We have a random schedule_timeout() if the current transaction is committing, which seems to be a holdover from the original delalloc reservation code.
Remove this, we have the proper flushing stuff, we shouldn't be hoping for random timing things to make everything work. This just induces latency for no reason.
--- fs/btrfs/delalloc-space.c | 3 --- 1 file changed, 3 deletions(-)
fs/btrfs/delalloc-space.c +0 -3
@@ -322,9 +322,6 @@ int btrfs_delalloc_reserve_metadata(stru }else {if (current->journal_info) flush =BTRFS_RESERVE_FLUSH_LIMIT ; - -if (btrfs_transaction_in_commit (fs_info)) -schedule_timeout (1 ); } num_bytes =ALIGN (num_bytes, fs_info->sectorsize);
Greg Kroah-Hartman
maintainerPATCH 338/530 thermal: intel: powerclamp: fix mismatch in get function for max_idle
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Arcari <[email protected]>
commit fae633cfb729da2771b5433f6b84ae7e8b4aa5f7 upstream.
KASAN reported this
[ 444.853098] BUG: KASAN: global-out-of-bounds in param_get_int+0x77/0x90
[ 444.853111] Read of size 4 at addr ffffffffc16c9220 by task cat/2105
...
[ 444.853442] The buggy address belongs to the variable:
[ 444.853443] max_idle+0x0/0xffffffffffffcde0 [intel_powerclamp]There is a mismatch between the param_get_int and the definition of max_idle. Replacing param_get_int with param_get_byte resolves this issue.
--- drivers/thermal/intel/intel_powerclamp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/thermal/intel/intel_powerclamp.c +1 -1
@@ -256,7 +256,7 @@ skip_limit_set:static const struct kernel_param_ops max_idle_ops = { .set = max_idle_set, - .get = param_get_int, + .get = param_get_byte, };module_param_cb (max_idle, &max_idle_ops, &max_idle,0644 );
Greg Kroah-Hartman
maintainerPATCH 339/530 arm64: dts: qcom: ipq5332: Fix hwlock index for SMEM
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vignesh Viswanathan <[email protected]>
commit d08afd80158399a081b478a19902364e3dd0f84c upstream.
SMEM uses lock index 3 of the TCSR Mutex hwlock for allocations in SMEM region shared by the Host and FW.
Fix the SMEM hwlock index to 3 for IPQ5332.
--- arch/arm64/boot/dts/qcom/ipq5332.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/qcom/ipq5332.dtsi +1 -1
@@ -135,7 +135,7 @@ reg = <0x0 0x4a800000 0x0 0x100000>; no-map; - hwlocks = <&tcsr_mutex 0>; + hwlocks = <&tcsr_mutex 3>; }; };
Greg Kroah-Hartman
maintainerPATCH 340/530 arm64: dts: qcom: ipq8074: Fix hwlock index for SMEM
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vignesh Viswanathan <[email protected]>
commit 8a781d04e580705d36f7db07f5c80e748100b69d upstream.
SMEM uses lock index 3 of the TCSR Mutex hwlock for allocations in SMEM region shared by the Host and FW.
Fix the SMEM hwlock index to 3 for IPQ8074.
--- arch/arm64/boot/dts/qcom/ipq8074.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/qcom/ipq8074.dtsi +1 -1
@@ -101,7 +101,7 @@ reg = <0x0 0x4ab00000 0x0 0x100000>; no-map; - hwlocks = <&tcsr_mutex 0>; + hwlocks = <&tcsr_mutex 3>; }; memory@4ac00000 {
Greg Kroah-Hartman
maintainerPATCH 341/530 firmware: qcom_scm: use 64-bit calling convention only when client is 64-bit
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kathiravan Thirumoorthy <[email protected]>
commit 3337a6fea25370d3d244ec6bb38c71ee86fcf837 upstream.
Per the "SMC calling convention specification", the 64-bit calling convention can only be used when the client is 64-bit. Whereas the 32-bit calling convention can be used by either a 32-bit or a 64-bit client.
Currently during SCM probe, irrespective of the client, 64-bit calling convention is made, which is incorrect and may lead to the undefined behaviour when the client is 32-bit. Let's fix it.
--- drivers/firmware/qcom_scm.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/firmware/qcom_scm.c +7 -0
@@ -168,6 +168,12 @@ static enum qcom_scm_convention __get_coreturn qcom_scm_convention;/* +* Per the "SMC calling convention specification", the 64-bit calling +* convention can only be used when the client is 64-bit, otherwise +* system will encounter the undefined behaviour. +*/ +#if IS_ENABLED (CONFIG_ARM64 ) +/* * Device isn't required as there is only one argument - no device * needed to dma_map_single to secure world */
@@ -187,6 +193,7 @@ static enum qcom_scm_convention __get_co forced = true; goto found; } +#endif probed_convention =SMC_CONVENTION_ARM_32 ; ret =__scm_smc_call (NULL , &desc, probed_convention, &res, true);
Greg Kroah-Hartman
maintainerPATCH 342/530 ACPI: FPDT: properly handle invalid FPDT subtables
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vasily Khoruzhick <[email protected]>
commit a83c68a3bf7c418c9a46693c63c638852b0c1f4e upstream.
Buggy BIOSes may have invalid FPDT subtables, e.g. on my hardware:
S3PT subtable:
7F20FE30: 53 33 50 54 24 00 00 00-00 00 00 00 00 00 18 01 *S3PT$...........* 7F20FE40: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 *................* 7F20FE50: 00 00 00 00
Here the first record has zero length.
FBPT subtable:
7F20FE50: 46 42 50 54-3C 00 00 00 46 42 50 54 *....FBPT<...FBPT* 7F20FE60: 02 00 30 02 00 00 00 00-00 00 00 00 00 00 00 00 *..0.............* 7F20FE70: 2A A6 BC 6E 0B 00 00 00-1A 44 41 70 0B 00 00 00 **..n.....DAp....* 7F20FE80: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 *................*
And here FBPT table has FBPT signature repeated instead of the first record.
Current code will be looping indefinitely due to zero length records, so break out of the loop if record length is zero.
While we are here, add proper handling for fpdt_process_subtable() failures.
--- drivers/acpi/acpi_fpdt.c | 45 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 8 deletions(-)
drivers/acpi/acpi_fpdt.c +37 -8
@@ -194,12 +194,19 @@ static int fpdt_process_subtable(u64 add record_header = (void *)subtable_header + offset; offset += record_header->length; +if (!record_header->length) { +pr_err (FW_BUG "Zero-length record found in FPTD.\n" ); + result = -EINVAL ; + goto err; + } +switch (record_header->type) {case RECORD_S3_RESUME :if (subtable_type !=SUBTABLE_S3PT ) {pr_err (FW_BUG "Invalid record %d for subtable %s\n" , record_header->type, signature); -return -EINVAL ; + result = -EINVAL ; + goto err; }if (record_resume) {pr_err ("Duplicate resume performance record found.\n" );
@@ -208,7 +215,7 @@ static int fpdt_process_subtable(u64 add record_resume = (struct resume_performance_record *)record_header; result =sysfs_create_group (fpdt_kobj, &resume_attr_group);if (result) -return result; + goto err;break ;case RECORD_S3_SUSPEND :if (subtable_type !=SUBTABLE_S3PT ) {
@@ -223,13 +230,14 @@ static int fpdt_process_subtable(u64 add record_suspend = (struct suspend_performance_record *)record_header; result =sysfs_create_group (fpdt_kobj, &suspend_attr_group);if (result) -return result; + goto err;break ;case RECORD_BOOT :if (subtable_type !=SUBTABLE_FBPT ) {pr_err (FW_BUG "Invalid %d for subtable %s\n" , record_header->type, signature); -return -EINVAL ; + result = -EINVAL ; + goto err; }if (record_boot) {pr_err ("Duplicate boot performance record found.\n" );
@@ -238,7 +246,7 @@ static int fpdt_process_subtable(u64 add record_boot = (struct boot_performance_record *)record_header; result =sysfs_create_group (fpdt_kobj, &boot_attr_group);if (result) -return result; + goto err;break ;default :
@@ -247,6 +255,18 @@ static int fpdt_process_subtable(u64 add } }return 0 ; + +err: +if (record_boot) +sysfs_remove_group (fpdt_kobj, &boot_attr_group); + +if (record_suspend) +sysfs_remove_group (fpdt_kobj, &suspend_attr_group); + +if (record_resume) +sysfs_remove_group (fpdt_kobj, &resume_attr_group); + +return result; }static int __init acpi_init_fpdt (void )
@@ -255,6 +275,7 @@ static int __init acpi_init_fpdt(void)struct acpi_table_header *header;struct fpdt_subtable_entry *subtable;u32 offset =sizeof (*header); +int result; status =acpi_get_table (ACPI_SIG_FPDT ,0 , &header);
@@ -263,8 +284,8 @@ static int __init acpi_init_fpdt(void) fpdt_kobj =kobject_create_and_add ("fpdt" , acpi_kobj);if (!fpdt_kobj) { -acpi_put_table (header); -return -ENOMEM ; + result = -ENOMEM ; + goto err_nomem; }while (offset < header->length) {
@@ -272,8 +293,10 @@ static int __init acpi_init_fpdt(void)switch (subtable->type) {case SUBTABLE_FBPT :case SUBTABLE_S3PT : -fpdt_process_subtable (subtable->address, + result =fpdt_process_subtable (subtable->address, subtable->type); +if (result) + goto err_subtable;break ;default :/* Other types are reserved in ACPI 6.4 spec. */
@@ -282,6 +305,12 @@ static int __init acpi_init_fpdt(void) offset +=sizeof (*subtable); }return 0 ; +err_subtable: +kobject_put (fpdt_kobj); + +err_nomem: +acpi_put_table (header); +return result; }fs_initcall (acpi_init_fpdt);
Greg Kroah-Hartman
maintainerPATCH 343/530 arm64: dts: qcom: ipq9574: Fix hwlock index for SMEM
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vignesh Viswanathan <[email protected]>
commit 5fe8508e2bc8eb4208b0434b6c1ca306c1519ade upstream.
SMEM uses lock index 3 of the TCSR Mutex hwlock for allocations in SMEM region shared by the Host and FW.
Fix the SMEM hwlock index to 3 for IPQ9574.
--- arch/arm64/boot/dts/qcom/ipq9574.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/qcom/ipq9574.dtsi +1 -1
@@ -195,7 +195,7 @@ smem@4aa00000 { compatible = "qcom,smem"; reg = <0x0 0x4aa00000 0x0 0x100000>; - hwlocks = <&tcsr_mutex 0>; + hwlocks = <&tcsr_mutex 3>; no-map; }; };
Greg Kroah-Hartman
maintainerPATCH 344/530 arm64: dts: qcom: ipq6018: Fix tcsr_mutex register size
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vignesh Viswanathan <[email protected]>
commit 72fc3d58b87b0d622039c6299b89024fbb7b420f upstream.
IPQ6018's TCSR Mutex HW lock register has 32 locks of size 4KB each. Total size of the TCSR Mutex registers is 128KB.
Fix size of the tcsr_mutex hwlock register to 0x20000.
Changes in v2:
- Drop change to remove qcom,ipq6018-tcsr-mutex compatible string
- Added Fixes and stable tags
--- arch/arm64/boot/dts/qcom/ipq6018.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/qcom/ipq6018.dtsi +1 -1
@@ -393,7 +393,7 @@ tcsr_mutex: hwlock@1905000 { compatible = "qcom,ipq6018-tcsr-mutex", "qcom,tcsr-mutex"; - reg = <0x0 0x01905000 0x0 0x1000>; + reg = <0x0 0x01905000 0x0 0x20000>; #hwlock-cells = <1>; };
Greg Kroah-Hartman
maintainerPATCH 345/530 leds: trigger: netdev: Move size check in set_device_name
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Marangi <[email protected]>
commit 259e33cbb1712a7dd844fc9757661cc47cb0e39b upstream.
GCC 13.2 complains about array subscript 17 is above array bounds of 'char[16]' with IFNAMSIZ set to 16.
The warning is correct but this scenario is impossible. set_device_name is called by device_name_store (store sysfs entry) and netdev_trig_activate.
device_name_store already check if size is >= of IFNAMSIZ and return -EINVAL. (making the warning scenario impossible)
netdev_trig_activate works on already defined interface, where the name has already been checked and should already follow the condition of strlen() < IFNAMSIZ.
Aside from the scenario being impossible, set_device_name can be improved to both mute the warning and make the function safer. To make it safer, move size check from device_name_store directly to set_device_name and prevent any out of bounds scenario.
--- drivers/leds/trigger/ledtrig-netdev.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/leds/trigger/ledtrig-netdev.c +3 -3
@@ -221,6 +221,9 @@ static ssize_t device_name_show(struct dstatic int set_device_name (struct led_netdev_data *trigger_data,const char *name,size_t size) { +if (size >=IFNAMSIZ ) +return -EINVAL ; +cancel_delayed_work_sync (&trigger_data->work);mutex_lock (&trigger_data->lock);
@@ -263,9 +266,6 @@ static ssize_t device_name_store(structstruct led_netdev_data *trigger_data =led_trigger_get_drvdata (dev);int ret; -if (size >=IFNAMSIZ ) -return -EINVAL ; - ret =set_device_name (trigger_data, buf, size);if (ret <0 )
Greg Kroah-Hartman
maintainerPATCH 346/530 mfd: qcom-spmi-pmic: Fix reference leaks in revid helper
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
commit a0fa44c261e448c531f9adb3a5189a3520f3e316 upstream.
The Qualcomm SPMI PMIC revid implementation is broken in multiple ways.
First, it totally ignores struct device_node reference counting and leaks references to the parent bus node as well as each child it iterates over using an open-coded for_each_child_of_node().
Second, it leaks references to each spmi device on the bus that it iterates over by failing to drop the reference taken by the spmi_device_from_of() helper.
Fix the struct device_node leaks by reimplementing the lookup using for_each_child_of_node() and adding the missing reference count decrements. Fix the sibling struct device leaks by dropping the unnecessary lookups of devices with the wrong USID.
Note that this still leaves one struct device reference leak in case a base device is found but it is not the parent of the device used for the lookup. This will be addressed in a follow-on patch.
--- drivers/mfd/qcom-spmi-pmic.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-)
drivers/mfd/qcom-spmi-pmic.c +19 -13
@@ -81,7 +81,7 @@ static struct spmi_device *qcom_pmic_getstruct spmi_device *sdev;struct qcom_spmi_dev *ctx;struct device_node *spmi_bus; -struct device_node *other_usid =NULL ; +struct device_node *child;int function_parent_usid, ret;u32 pmic_addr;
@@ -105,28 +105,34 @@ static struct spmi_device *qcom_pmic_get* device for USID 2. */ spmi_bus =of_get_parent (sdev->dev.of_node); -do { - other_usid =of_get_next_child (spmi_bus, other_usid); - - ret =of_property_read_u32_index (other_usid,"reg" ,0 , &pmic_addr); -if (ret) -return ERR_PTR (ret); + sdev =ERR_PTR (-ENODATA ); +for_each_child_of_node (spmi_bus, child) { + ret =of_property_read_u32_index (child,"reg" ,0 , &pmic_addr); +if (ret) { +of_node_put (child); + sdev =ERR_PTR (ret); +break ; + } - sdev =spmi_device_from_of (other_usid);if (pmic_addr == function_parent_usid - (ctx->num_usids -1 )) { -if (!sdev) + sdev =spmi_device_from_of (child); +if (!sdev) {/* * If the base USID for this PMIC hasn't probed yet * but the secondary USID has, then we need to defer * the function driver so that it will attempt to * probe again when the base USID is ready. */ -return ERR_PTR (-EPROBE_DEFER ); -return sdev; + sdev =ERR_PTR (-EPROBE_DEFER ); + } +of_node_put (child); +break ; } - }while (other_usid->sibling); + } + +of_node_put (spmi_bus); -return ERR_PTR (-ENODATA ); +return sdev; } static int pmic_spmi_load_revid(struct regmap *map, struct device *dev,
Greg Kroah-Hartman
maintainerPATCH 347/530 mfd: qcom-spmi-pmic: Fix revid implementation
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
commit 7b439aaa62fee474a0d84d67a25f4984467e7b95 upstream.
The Qualcomm SPMI PMIC revid implementation is broken in multiple ways.
First, it assumes that just because the sibling base device has been registered that means that it is also bound to a driver, which may not be the case (e.g. due to probe deferral or asynchronous probe). This could trigger a NULL-pointer dereference when attempting to access the driver data of the unbound device.
Second, it accesses driver data of a sibling device directly and without any locking, which means that the driver data may be freed while it is being accessed (e.g. on driver unbind).
Third, it leaks a struct device reference to the sibling device which is looked up using the spmi_device_from_of() every time a function (child) device is calling the revid function (e.g. on probe).
Fix this mess by reimplementing the revid lookup so that it is done only at probe of the PMIC device; the base device fetches the revid info from the hardware, while any secondary SPMI device fetches the information from the base device and caches it so that it can be accessed safely from its children. If the base device has not been probed yet then probe of a secondary device is deferred.
--- drivers/mfd/qcom-spmi-pmic.c | 69 +++++++++++++++++++++++++++++++++---------- 1 file changed, 53 insertions(+), 16 deletions(-)
drivers/mfd/qcom-spmi-pmic.c +53 -16
@@ -30,6 +30,8 @@ struct qcom_spmi_dev {struct qcom_spmi_pmic pmic; }; +static DEFINE_MUTEX (pmic_spmi_revid_lock); +#define N_USIDS (n) ((void *)n)static const struct of_device_id pmic_spmi_id_table[] = {
@@ -76,24 +78,21 @@ static const struct of_device_id pmic_sp* * This only supports PMICs with 1 or 2 USIDs. */ -static struct spmi_device *qcom_pmic_get_base_usid (struct device *dev) +static struct spmi_device *qcom_pmic_get_base_usid (struct spmi_device *sdev,struct qcom_spmi_dev *ctx) { -struct spmi_device *sdev; -struct qcom_spmi_dev *ctx;struct device_node *spmi_bus;struct device_node *child;int function_parent_usid, ret;u32 pmic_addr; - sdev =to_spmi_device (dev); - ctx =dev_get_drvdata (&sdev->dev); -/* * Quick return if the function device is already in the base * USID. This will always be hit for PMICs with only 1 USID. */ -if (sdev->usid % ctx->num_usids ==0 ) +if (sdev->usid % ctx->num_usids ==0 ) { +get_device (&sdev->dev);return sdev; + } function_parent_usid = sdev->usid;
@@ -118,10 +117,8 @@ static struct spmi_device *qcom_pmic_get sdev =spmi_device_from_of (child);if (!sdev) {/* -* If the base USID for this PMIC hasn't probed yet -* but the secondary USID has, then we need to defer -* the function driver so that it will attempt to -* probe again when the base USID is ready. +* If the base USID for this PMIC hasn't been +* registered yet then we need to defer. */ sdev =ERR_PTR (-EPROBE_DEFER ); }
@@ -135,6 +132,35 @@ static struct spmi_device *qcom_pmic_getreturn sdev; } +static int pmic_spmi_get_base_revid (struct spmi_device *sdev,struct qcom_spmi_dev *ctx) +{ +struct qcom_spmi_dev *base_ctx; +struct spmi_device *base; +int ret =0 ; + + base =qcom_pmic_get_base_usid (sdev, ctx); +if (IS_ERR (base)) +return PTR_ERR (base); + +/* +* Copy revid info from base device if it has probed and is still +* bound to its driver. +*/ +mutex_lock (&pmic_spmi_revid_lock); + base_ctx =spmi_device_get_drvdata (base); +if (!base_ctx) { + ret = -EPROBE_DEFER ; + goto out_unlock; + } +memcpy (&ctx->pmic, &base_ctx->pmic,sizeof (ctx->pmic)); +out_unlock: +mutex_unlock (&pmic_spmi_revid_lock); + +put_device (&base->dev); + +return ret; +} +static int pmic_spmi_load_revid (struct regmap *map,struct device *dev,struct qcom_spmi_pmic *pmic) {
@@ -210,11 +236,7 @@ const struct qcom_spmi_pmic *qcom_pmic_gif (!of_match_device (pmic_spmi_id_table, dev->parent))return ERR_PTR (-EINVAL ); - sdev =qcom_pmic_get_base_usid (dev->parent); - -if (IS_ERR (sdev)) -return ERR_CAST (sdev); - + sdev =to_spmi_device (dev->parent); spmi =dev_get_drvdata (&sdev->dev);return &spmi->pmic;
@@ -249,16 +271,31 @@ static int pmic_spmi_probe(struct spmi_d ret =pmic_spmi_load_revid (regmap, &sdev->dev, &ctx->pmic);if (ret <0 )return ret; + }else { + ret =pmic_spmi_get_base_revid (sdev, ctx); +if (ret) +return ret; } + +mutex_lock (&pmic_spmi_revid_lock);spmi_device_set_drvdata (sdev, ctx); +mutex_unlock (&pmic_spmi_revid_lock);return devm_of_platform_populate (&sdev->dev); } +static void pmic_spmi_remove (struct spmi_device *sdev) +{ +mutex_lock (&pmic_spmi_revid_lock); +spmi_device_set_drvdata (sdev,NULL ); +mutex_unlock (&pmic_spmi_revid_lock); +} +MODULE_DEVICE_TABLE (of, pmic_spmi_id_table);static struct spmi_driver pmic_spmi_driver = { .probe = pmic_spmi_probe, + .remove = pmic_spmi_remove, .driver = { .name ="pmic-spmi" , .of_match_table = pmic_spmi_id_table,
Greg Kroah-Hartman
maintainerPATCH 348/530 ima: annotate iint mutex to avoid lockdep false positive warnings
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Amir Goldstein <[email protected]>
commit e044374a8a0a99e46f4e6d6751d3042b6d9cc12e upstream.
It is not clear that IMA should be nested at all, but as long is it measures files both on overlayfs and on underlying fs, we need to annotate the iint mutex to avoid lockdep false positives related to IMA + overlayfs, same as overlayfs annotates the inode mutex.
--- security/integrity/iint.c | 48 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 11 deletions(-)
security/integrity/iint.c +37 -11
@@ -66,9 +66,32 @@ struct integrity_iint_cache *integrity_ireturn iint; } -static void iint_free (struct integrity_iint_cache *iint) +#define IMA_MAX_NESTING (FILESYSTEM_MAX_STACK_DEPTH+1) + +/* +* It is not clear that IMA should be nested at all, but as long is it measures +* files both on overlayfs and on underlying fs, we need to annotate the iint +* mutex to avoid lockdep false positives related to IMA + overlayfs. +* See ovl_lockdep_annotate_inode_mutex_key() for more details. +*/ +static inline void iint_lockdep_annotate (struct integrity_iint_cache *iint, +struct inode *inode) +{ +#ifdef CONFIG_LOCKDEP +static struct lock_class_key iint_mutex_key[IMA_MAX_NESTING ]; + +int depth = inode->i_sb->s_stack_depth; + +if (WARN_ON_ONCE (depth <0 || depth >=IMA_MAX_NESTING )) + depth =0 ; + +lockdep_set_class (&iint->mutex, &iint_mutex_key[depth]); +#endif +} + +static void iint_init_always (struct integrity_iint_cache *iint, +struct inode *inode) { -kfree (iint->ima_hash); iint->ima_hash =NULL ; iint->version =0 ; iint->flags =0UL ;
@@ -80,6 +103,14 @@ static void iint_free(struct integrity_i iint->ima_creds_status =INTEGRITY_UNKNOWN ; iint->evm_status =INTEGRITY_UNKNOWN ; iint->measured_pcrs =0 ; +mutex_init (&iint->mutex); +iint_lockdep_annotate (iint, inode); +} + +static void iint_free (struct integrity_iint_cache *iint) +{ +kfree (iint->ima_hash); +mutex_destroy (&iint->mutex);kmem_cache_free (iint_cache, iint); }
@@ -104,6 +135,8 @@ struct integrity_iint_cache *integrity_iif (!iint)return NULL ; +iint_init_always (iint, inode); +write_lock (&integrity_iint_lock); p = &integrity_iint_tree.rb_node;
@@ -153,25 +186,18 @@ void integrity_inode_free(struct inode *iint_free (iint); } -static void init_once (void *foo) +static void iint_init_once (void *foo) {struct integrity_iint_cache *iint = (struct integrity_iint_cache *) foo;memset (iint,0 ,sizeof (*iint)); - iint->ima_file_status =INTEGRITY_UNKNOWN ; - iint->ima_mmap_status =INTEGRITY_UNKNOWN ; - iint->ima_bprm_status =INTEGRITY_UNKNOWN ; - iint->ima_read_status =INTEGRITY_UNKNOWN ; - iint->ima_creds_status =INTEGRITY_UNKNOWN ; - iint->evm_status =INTEGRITY_UNKNOWN ; -mutex_init (&iint->mutex); }static int __init integrity_iintcache_init (void ) { iint_cache =kmem_cache_create ("iint_cache" ,sizeof (struct integrity_iint_cache ), -0 ,SLAB_PANIC , init_once); +0 ,SLAB_PANIC , iint_init_once);return 0 ; }DEFINE_LSM (integrity) = {
Greg Kroah-Hartman
maintainerPATCH 349/530 ima: detect changes to the backing overlay file
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mimi Zohar <[email protected]>
commit b836c4d29f2744200b2af41e14bf50758dddc818 upstream.
Commit 18b44bc5a672 ("ovl: Always reevaluate the file signature for IMA") forced signature re-evaulation on every file access.
Instead of always re-evaluating the file's integrity, detect a change to the backing file, by comparing the cached file metadata with the backing file's metadata. Verifying just the i_version has not changed is insufficient. In addition save and compare the i_ino and s_dev as well.
--- fs/overlayfs/super.c | 2 +- security/integrity/ima/ima_api.c | 5 +++++ security/integrity/ima/ima_main.c | 16 +++++++++++++++- security/integrity/integrity.h | 2 ++ 4 files changed, 23 insertions(+), 2 deletions(-)
fs/overlayfs/super.c +1 -1
@@ -1489,7 +1489,7 @@ int ovl_fill_super(struct super_block *s ovl_trusted_xattr_handlers; sb->s_fs_info = ofs; sb->s_flags |=SB_POSIXACL ; - sb->s_iflags |=SB_I_SKIP_SYNC |SB_I_IMA_UNVERIFIABLE_SIGNATURE ; + sb->s_iflags |=SB_I_SKIP_SYNC ; err = -ENOMEM ; root_dentry =ovl_get_root (sb, ctx->upper.dentry, oe);
security/integrity/ima/ima_api.c +5 -0
@@ -243,6 +243,7 @@ int ima_collect_measurement(struct integ {const char *audit_cause ="failed" ;struct inode *inode =file_inode (file); +struct inode *real_inode =d_real_inode (file_dentry (file));const char *filename = file->f_path.dentry->d_name.name;struct ima_max_digest_data hash;struct kstat stat;
@@ -302,6 +303,10 @@ int ima_collect_measurement(struct integ iint->ima_hash = tmpbuf;memcpy (iint->ima_hash, &hash, length); iint->version = i_version; +if (real_inode != inode) { + iint->real_ino = real_inode->i_ino; + iint->real_dev = real_inode->i_sb->s_dev; + }/* Possibly temporary failure due to type of read (eg. O_DIRECT) */ if (!result)
security/integrity/ima/ima_main.c +15 -1
@@ -25,6 +25,7 @@#include <linux/xattr.h> #include <linux/ima.h> #include <linux/fs.h> +#include <linux/iversion.h> #include "ima.h"
@@ -207,7 +208,7 @@ static int process_measurement(struct fi u32 secid, char *buf, loff_t size, int mask, enum ima_hooks func) { - struct inode *inode = file_inode(file); + struct inode *backing_inode, *inode = file_inode(file);struct integrity_iint_cache *iint =NULL ;struct ima_template_desc *template_desc =NULL ;char *pathbuf =NULL ;
@@ -284,6 +285,19 @@ static int process_measurement(struct fi iint->measured_pcrs =0 ; } +/* Detect and re-evaluate changes made to the backing file. */ + backing_inode =d_real_inode (file_dentry (file)); +if (backing_inode != inode && + (action &IMA_DO_MASK ) && (iint->flags &IMA_DONE_MASK )) { +if (!IS_I_VERSION (backing_inode) || + backing_inode->i_sb->s_dev != iint->real_dev || + backing_inode->i_ino != iint->real_ino || + !inode_eq_iversion (backing_inode, iint->version)) { + iint->flags &= ~IMA_DONE_MASK ; + iint->measured_pcrs =0 ; + } + } +/* Determine if already appraised/measured based on bitmask * (IMA_MEASURE, IMA_MEASURED, IMA_XXXX_APPRAISE, IMA_XXXX_APPRAISED, * IMA_AUDIT, IMA_AUDITED)
security/integrity/integrity.h +2 -0
@@ -164,6 +164,8 @@ struct integrity_iint_cache {unsigned long flags;unsigned long measured_pcrs;unsigned long atomic_flags; +unsigned long real_ino; +dev_t real_dev; enum integrity_status ima_file_status:4; enum integrity_status ima_mmap_status:4; enum integrity_status ima_bprm_status:4;
Greg Kroah-Hartman
maintainerPATCH 350/530 netfilter: nf_tables: remove catchall element in GC sync path
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pablo Neira Ayuso <[email protected]>
[ Upstream commit 93995bf4af2c5a99e2a87f0cd5ce547d31eb7630 ]
The expired catchall element is not deactivated and removed from GC sync path. This path holds mutex so just call nft_setelem_data_deactivate() and nft_setelem_catchall_remove() before queueing the GC work.
--- net/netfilter/nf_tables_api.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-)
net/netfilter/nf_tables_api.c +21 -5
@@ -6464,6 +6464,12 @@ static int nft_setelem_deactivate(const struct net *net,return ret; } +static void nft_setelem_catchall_destroy (struct nft_set_elem_catchall *catchall) +{ +list_del_rcu (&catchall->list); +kfree_rcu (catchall, rcu); +} +static void nft_setelem_catchall_remove (const struct net *net,const struct nft_set *set,const struct nft_set_elem *elem)
@@ -6472,8 +6478,7 @@ static void nft_setelem_catchall_remove(const struct net *net,list_for_each_entry_safe (catchall, next, &set->catchall_list, list) {if (catchall->elem == elem->priv) { -list_del_rcu (&catchall->list); -kfree_rcu (catchall, rcu); +nft_setelem_catchall_destroy (catchall);break ; } }
@@ -9639,11 +9644,12 @@ static struct nft_trans_gc *nft_trans_gc_catchall(struct nft_trans_gc *gc, unsigned int gc_seq, bool sync) { -struct nft_set_elem_catchall *catchall; +struct nft_set_elem_catchall *catchall, *next;const struct nft_set *set = gc->set; +struct nft_elem_priv *elem_priv;struct nft_set_ext *ext; -list_for_each_entry_rcu (catchall, &set->catchall_list, list) { +list_for_each_entry_safe (catchall, next, &set->catchall_list, list) { ext =nft_set_elem_ext (set, catchall->elem);if (!nft_set_elem_expired (ext))
@@ -9661,7 +9667,17 @@ static struct nft_trans_gc *nft_trans_gc_catchall(struct nft_trans_gc *gc,if (!gc)return NULL ; -nft_trans_gc_elem_add (gc, catchall->elem); + elem_priv = catchall->elem; +if (sync) { +struct nft_set_elem elem = { + .priv = elem_priv, + }; + +nft_setelem_data_deactivate (gc->net, gc->set, &elem); +nft_setelem_catchall_destroy (catchall); + } + +nft_trans_gc_elem_add (gc, elem_priv); }return gc;
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 351/530 netfilter: nf_tables: split async and sync catchall in two functions
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pablo Neira Ayuso <[email protected]>
[ Upstream commit 8837ba3e58ea1e3d09ae36db80b1e80853aada95 ]
list_for_each_entry_safe() does not work for the async case which runs under RCU, therefore, split GC logic for catchall in two functions instead, one for each of the sync and async GC variants.
The catchall sync GC variant never sees a _DEAD bit set on ever, thus, this handling is removed in such case, moreover, allocate GC sync batch via GFP_KERNEL.
--- net/netfilter/nf_tables_api.c | 61 ++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 29 deletions(-)
net/netfilter/nf_tables_api.c +32 -29
@@ -9640,16 +9640,14 @@ void nft_trans_gc_queue_sync_done(struct nft_trans_gc *trans)call_rcu (&trans->rcu, nft_trans_gc_trans_free); } -static struct nft_trans_gc *nft_trans_gc_catchall (struct nft_trans_gc *gc, -unsigned int gc_seq, -bool sync) +struct nft_trans_gc *nft_trans_gc_catchall_async (struct nft_trans_gc *gc, +unsigned int gc_seq) { -struct nft_set_elem_catchall *catchall, *next; +struct nft_set_elem_catchall *catchall;const struct nft_set *set = gc->set; -struct nft_elem_priv *elem_priv;struct nft_set_ext *ext; -list_for_each_entry_safe (catchall, next, &set->catchall_list, list) { +list_for_each_entry_rcu (catchall, &set->catchall_list, list) { ext =nft_set_elem_ext (set, catchall->elem);if (!nft_set_elem_expired (ext))
@@ -9659,39 +9657,44 @@ static struct nft_trans_gc *nft_trans_gc_catchall(struct nft_trans_gc *gc,nft_set_elem_dead (ext); dead_elem: -if (sync) - gc =nft_trans_gc_queue_sync (gc,GFP_ATOMIC ); -else - gc =nft_trans_gc_queue_async (gc, gc_seq,GFP_ATOMIC ); - + gc =nft_trans_gc_queue_async (gc, gc_seq,GFP_ATOMIC );if (!gc)return NULL ; - elem_priv = catchall->elem; -if (sync) { -struct nft_set_elem elem = { - .priv = elem_priv, - }; - -nft_setelem_data_deactivate (gc->net, gc->set, &elem); -nft_setelem_catchall_destroy (catchall); - } - -nft_trans_gc_elem_add (gc, elem_priv); +nft_trans_gc_elem_add (gc, catchall->elem); }return gc; } -struct nft_trans_gc *nft_trans_gc_catchall_async (struct nft_trans_gc *gc, -unsigned int gc_seq) -{ -return nft_trans_gc_catchall (gc, gc_seq, false); -} -struct nft_trans_gc *nft_trans_gc_catchall_sync (struct nft_trans_gc *gc) { -return nft_trans_gc_catchall (gc,0 , true); +struct nft_set_elem_catchall *catchall, *next; +const struct nft_set *set = gc->set; +struct nft_set_elem elem; +struct nft_set_ext *ext; + +WARN_ON_ONCE (!lockdep_commit_lock_is_held (gc->net)); + +list_for_each_entry_safe (catchall, next, &set->catchall_list, list) { + ext =nft_set_elem_ext (set, catchall->elem); + +if (!nft_set_elem_expired (ext)) +continue ; + + gc =nft_trans_gc_queue_sync (gc,GFP_KERNEL ); +if (!gc) +return NULL ; + +memset (&elem,0 ,sizeof (elem)); + elem.priv = catchall->elem; + +nft_setelem_data_deactivate (gc->net, gc->set, &elem); +nft_setelem_catchall_destroy (catchall); +nft_trans_gc_elem_add (gc, elem.priv); + } + +return gc; }static void nf_tables_module_autoload_cleanup (struct net *net)
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 352/530 ASoC: soc-dai: add flag to mute and unmute stream during trigger
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Srinivas Kandagatla <[email protected]>
commit f0220575e65abe09c09cd17826a3cdea76e8d58f upstream.
In some setups like Speaker amps which are very sensitive, ex: keeping them unmute without actual data stream for very short duration results in a static charge and results in pop and clicks. To minimize this, provide a way to mute and unmute such codecs during trigger callbacks.
--- include/sound/soc-dai.h | 1 + sound/soc/soc-dai.c | 7 +++++++ sound/soc/soc-pcm.c | 12 ++++++++---- 3 files changed, 16 insertions(+), 4 deletions(-)
include/sound/soc-dai.h +1 -0
@@ -370,6 +370,7 @@ struct snd_soc_dai_ops {/* bit field */ unsigned int no_capture_mute:1; + unsigned int mute_unmute_on_trigger:1; };struct snd_soc_cdai_ops {
sound/soc/soc-dai.c +7 -0
@@ -658,6 +658,10 @@ int snd_soc_pcm_dai_trigger(struct snd_p ret =soc_dai_trigger (dai, substream, cmd);if (ret <0 )break ; + +if (dai->driver->ops && dai->driver->ops->mute_unmute_on_trigger) +snd_soc_dai_digital_mute (dai,0 , substream->stream); +soc_dai_mark_push (dai, substream, trigger); }break ;
@@ -668,6 +672,9 @@ int snd_soc_pcm_dai_trigger(struct snd_pif (rollback && !soc_dai_mark_match (dai, substream, trigger))continue ; +if (dai->driver->ops && dai->driver->ops->mute_unmute_on_trigger) +snd_soc_dai_digital_mute (dai,1 , substream->stream); + r =soc_dai_trigger (dai, substream, cmd);if (r <0 ) ret = r;/* use last ret */
sound/soc/soc-pcm.c +8 -4
@@ -896,8 +896,10 @@ static int __soc_pcm_prepare(struct snd_snd_soc_dapm_stream_event (rtd, substream->stream,SND_SOC_DAPM_STREAM_START ); -for_each_rtd_dais (rtd, i, dai) -snd_soc_dai_digital_mute (dai,0 , substream->stream); +for_each_rtd_dais (rtd, i, dai) { +if (dai->driver->ops && !dai->driver->ops->mute_unmute_on_trigger) +snd_soc_dai_digital_mute (dai,0 , substream->stream); + } out:return soc_pcm_ret (rtd, ret);
@@ -939,8 +941,10 @@ static int soc_pcm_hw_clean(struct snd_sif (snd_soc_dai_active (dai) ==1 )soc_pcm_set_dai_params (dai,NULL ); -if (snd_soc_dai_stream_active (dai, substream->stream) ==1 ) -snd_soc_dai_digital_mute (dai,1 , substream->stream); +if (snd_soc_dai_stream_active (dai, substream->stream) ==1 ) { +if (dai->driver->ops && !dai->driver->ops->mute_unmute_on_trigger) +snd_soc_dai_digital_mute (dai,1 , substream->stream); + } }/* run the stream event */
Greg Kroah-Hartman
maintainerPATCH 353/530 ASoC: codecs: wsa883x: make use of new mute_unmute_on_trigger flag
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Srinivas Kandagatla <[email protected]>
commit 805ce81826c896dd3c351a32814b28557f9edf54 upstream.
In the current setup the PA is left unmuted even when the Soundwire ports are not started streaming. This can lead to click and pop sounds during start.
There is a same issue in the reverse order where in the PA is left unmute even after the data stream is stopped, the time between data stream stopping and port closing is long enough to accumulate DC on the line resulting in Click/Pop noise during end of stream.
making use of new mute_unmute_on_trigger flag is helping a lot with this Click/Pop issues reported on this Codec
--- sound/soc/codecs/wsa883x.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-)
sound/soc/codecs/wsa883x.c +1 -6
@@ -1203,9 +1203,6 @@ static int wsa883x_spkr_event(struct sndbreak ; } -snd_soc_component_write_field (component,WSA883X_DRE_CTL_1 , -WSA883X_DRE_GAIN_EN_MASK , -WSA883X_DRE_GAIN_FROM_CSR );if (wsa883x->port_enable[WSA883X_PORT_COMP ]) snd_soc_component_write_field(component, WSA883X_DRE_CTL_0, WSA883X_DRE_OFFSET_MASK,
@@ -1218,9 +1215,6 @@ static int wsa883x_spkr_event(struct sndsnd_soc_component_write_field (component,WSA883X_PDM_WD_CTL ,WSA883X_PDM_EN_MASK ,WSA883X_PDM_ENABLE ); -snd_soc_component_write_field (component,WSA883X_PA_FSM_CTL , -WSA883X_GLOBAL_PA_EN_MASK , -WSA883X_GLOBAL_PA_ENABLE );break ;case SND_SOC_DAPM_PRE_PMD :
@@ -1346,6 +1340,7 @@ static const struct snd_soc_dai_ops wsa8 .hw_free = wsa883x_hw_free, .mute_stream = wsa883x_digital_mute, .set_stream = wsa883x_set_sdw_stream, + .mute_unmute_on_trigger = true, };static struct snd_soc_dai_driver wsa883x_dais[] = {
Greg Kroah-Hartman
maintainerPATCH 354/530 selftests/resctrl: Fix uninitialized .sa_flags
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ilpo Järvinen <[email protected]>
commit beb7f471847663559bd0fe60af1d70e05a1d7c6c upstream.
signal_handler_unregister() calls sigaction() with uninitializing sa_flags in the struct sigaction.
Make sure sa_flags is always initialized in signal_handler_unregister() by initializing the struct sigaction when declaring it. Also add the initialization to signal_handler_register() even if there are no know bugs in there because correctness is then obvious from the code itself.
--- tools/testing/selftests/resctrl/resctrl_val.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
tools/testing/selftests/resctrl/resctrl_val.c +2 -2
@@ -482,7 +482,7 @@ void ctrlc_handler(int signum, siginfo_t*/ int signal_handler_register (void ) { -struct sigaction sigact; +struct sigaction sigact = {};int ret =0 ; sigact.sa_sigaction = ctrlc_handler;
@@ -504,7 +504,7 @@ int signal_handler_register(void)*/ void signal_handler_unregister (void ) { -struct sigaction sigact; +struct sigaction sigact = {}; sigact.sa_handler =SIG_DFL ;sigemptyset (&sigact.sa_mask);
Greg Kroah-Hartman
maintainerPATCH 355/530 selftests/resctrl: Remove duplicate feature check from CMT test
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ilpo Järvinen <[email protected]>
commit 030b48fb2cf045dead8ee2c5ead560930044c029 upstream.
The test runner run_cmt_test() in resctrl_tests.c checks for CMT feature and does not run cmt_resctrl_val() if CMT is not supported. Then cmt_resctrl_val() also check is CMT is supported.
Remove the duplicated feature check for CMT from cmt_resctrl_val().
--- tools/testing/selftests/resctrl/cmt_test.c | 3 --- 1 file changed, 3 deletions(-)
tools/testing/selftests/resctrl/cmt_test.c +0 -3
@@ -76,9 +76,6 @@ int cmt_resctrl_val(int cpu_no, int n, cint count_of_bits;int ret; -if (!validate_resctrl_feature_request (CMT_STR )) -return -1 ; - ret =get_cbm_mask ("L3" , cbm_mask);if (ret)return ret;
Greg Kroah-Hartman
maintainerPATCH 356/530 selftests/resctrl: Move _GNU_SOURCE define into Makefile
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ilpo Järvinen <[email protected]>
commit 3a1e4a91aa454a1c589a9824d54179fdbfccde45 upstream.
_GNU_SOURCE is defined in resctrl.h. Defining _GNU_SOURCE has a large impact on what gets defined when including headers either before or after it. This can result in compile failures if .c file decides to include a standard header file before resctrl.h.
It is safer to define _GNU_SOURCE in Makefile so it is always defined regardless of in which order includes are done.
--- tools/testing/selftests/resctrl/Makefile | 2 +- tools/testing/selftests/resctrl/resctrl.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-)
tools/testing/selftests/resctrl/Makefile +1 -1
@@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 -CFLAGS = -g -Wall -O2 -D_FORTIFY_SOURCE=2 +CFLAGS = -g -Wall -O2 -D_FORTIFY_SOURCE=2 -D_GNU_SOURCE CFLAGS += $(KHDR_INCLUDES) TEST_GEN_PROGS := resctrl_tests
tools/testing/selftests/resctrl/resctrl.h +0 -1
@@ -1,5 +1,4 @@/* SPDX-License-Identifier: GPL-2.0 */ -#define _GNU_SOURCE#ifndef RESCTRL_H #define RESCTRL_H #include <stdio.h>
Greg Kroah-Hartman
maintainerPATCH 357/530 selftests/resctrl: Refactor feature check to use resource and feature name
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ilpo Järvinen <[email protected]>
commit d56e5da0e0f557a206bace16bbbdad00a5800e34 upstream.
Feature check in validate_resctrl_feature_request() takes in the test name string and maps that to what to check per test.
Pass resource and feature names to validate_resctrl_feature_request() directly rather than deriving them from the test name inside the function which makes the feature check easier to extend for new test cases.
Use !! in the return statement to make the boolean conversion more obvious even if it is not strictly necessary from correctness point of view (to avoid it looking like the function is returning a freed pointer).
--- tools/testing/selftests/resctrl/resctrl.h | 6 -- tools/testing/selftests/resctrl/resctrl_tests.c | 10 ++- tools/testing/selftests/resctrl/resctrlfs.c | 69 +++++++++--------------- 3 files changed, 34 insertions(+), 51 deletions(-)
tools/testing/selftests/resctrl/resctrl.h +1 -5
@@ -27,10 +27,6 @@#define RESCTRL_PATH "/sys/fs/resctrl"#define PHYS_ID_PATH "/sys/devices/system/cpu/cpu"#define INFO_PATH "/sys/fs/resctrl/info" -#define L3_PATH "/sys/fs/resctrl/info/L3" -#define MB_PATH "/sys/fs/resctrl/info/MB" -#define L3_MON_PATH "/sys/fs/resctrl/info/L3_MON" -#define L3_MON_FEATURES_PATH "/sys/fs/resctrl/info/L3_MON/mon_features"#define ARCH_INTEL 1#define ARCH_AMD 2
@@ -85,7 +81,7 @@ int get_resource_id(int cpu_no, int *resint mount_resctrlfs (void );int umount_resctrlfs (void );int validate_bw_report_request (char *bw_report); -bool validate_resctrl_feature_request (const char *resctrl_val); +bool validate_resctrl_feature_request (const char *resource,const char *feature);char *fgrep (FILE *inf,const char *str);int taskset_benchmark (pid_t bm_pid,int cpu_no);void run_benchmark (int signum,siginfo_t *info,void *ucontext);
tools/testing/selftests/resctrl/resctrl_tests.c +6 -4
@@ -83,7 +83,9 @@ static void run_mbm_test(char **benchmarreturn ; } -if (!validate_resctrl_feature_request (MBM_STR ) || (get_vendor () !=ARCH_INTEL )) { +if (!validate_resctrl_feature_request ("L3_MON" ,"mbm_total_bytes" ) || + !validate_resctrl_feature_request ("L3_MON" ,"mbm_local_bytes" ) || + (get_vendor () !=ARCH_INTEL )) {ksft_test_result_skip ("Hardware does not support MBM or MBM is disabled\n" ); goto umount; }
@@ -109,7 +111,7 @@ static void run_mba_test(char **benchmarreturn ; } -if (!validate_resctrl_feature_request (MBA_STR ) || (get_vendor () !=ARCH_INTEL )) { +if (!validate_resctrl_feature_request ("MB" ,NULL ) || (get_vendor () !=ARCH_INTEL )) {ksft_test_result_skip ("Hardware does not support MBA or MBA is disabled\n" ); goto umount; }
@@ -133,7 +135,7 @@ static void run_cmt_test(char **benchmarreturn ; } -if (!validate_resctrl_feature_request (CMT_STR )) { +if (!validate_resctrl_feature_request ("L3_MON" ,"llc_occupancy" )) {ksft_test_result_skip ("Hardware does not support CMT or CMT is disabled\n" ); goto umount; }
@@ -159,7 +161,7 @@ static void run_cat_test(int cpu_no, intreturn ; } -if (!validate_resctrl_feature_request (CAT_STR )) { +if (!validate_resctrl_feature_request ("L3" ,NULL )) {ksft_test_result_skip ("Hardware does not support CAT or CAT is disabled\n" ); goto umount; }
tools/testing/selftests/resctrl/resctrlfs.c +27 -42
96 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 358/530 selftests/resctrl: Fix feature checks
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ilpo Järvinen <[email protected]>
commit 06035f019422ba17e85c11e70d6d8bdbe9fa1afd upstream.
The MBA and CMT tests expect support of other features to be able to run.
When platform only supports MBA but not MBM, MBA test will fail with:
Failed to open total bw file: No such file or directory
When platform only supports CMT but not CAT, CMT test will fail with:
Failed to open bit mask file '/sys/fs/resctrl/info/L3/cbm_mask': No such file or directory
It leads to the test reporting test fail (even if no test was run at all).
Extend feature checks to cover these two conditions to show these tests were skipped rather than failed.
--- tools/testing/selftests/resctrl/resctrl_tests.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
tools/testing/selftests/resctrl/resctrl_tests.c +5 -2
@@ -111,7 +111,9 @@ static void run_mba_test(char **benchmarreturn ; } -if (!validate_resctrl_feature_request ("MB" ,NULL ) || (get_vendor () !=ARCH_INTEL )) { +if (!validate_resctrl_feature_request ("MB" ,NULL ) || + !validate_resctrl_feature_request ("L3_MON" ,"mbm_local_bytes" ) || + (get_vendor () !=ARCH_INTEL )) {ksft_test_result_skip ("Hardware does not support MBA or MBA is disabled\n" ); goto umount; }
@@ -135,7 +137,8 @@ static void run_cmt_test(char **benchmarreturn ; } -if (!validate_resctrl_feature_request ("L3_MON" ,"llc_occupancy" )) { +if (!validate_resctrl_feature_request ("L3_MON" ,"llc_occupancy" ) || + !validate_resctrl_feature_request ("L3" ,NULL )) {ksft_test_result_skip ("Hardware does not support CMT or CMT is disabled\n" ); goto umount; }
Greg Kroah-Hartman
maintainerPATCH 359/530 selftests/resctrl: Reduce failures due to outliers in MBA/MBM tests
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ilpo Järvinen <[email protected]>
commit ef43c30858754d99373a63dff33280a9969b49bc upstream.
The initial value of 5% chosen for the maximum allowed percentage difference between resctrl mbm value and IMC mbm value in
commit 06bd03a57f8c ("selftests/resctrl: Fix MBA/MBM results reporting
format") was "randomly chosen value" (as admitted by the changelog).
When running tests in our lab across a large number platforms, 5% difference upper bound for success seems a bit on the low side for the MBA and MBM tests. Some platforms produce outliers that are slightly above that, typically 6-7%, which leads MBA/MBM test frequently failing.
Replace the "randomly chosen value" with a success bound that is based on those measurements across large number of platforms by relaxing the MBA/MBM success bound to 8%. The relaxed bound removes the failures due the frequent outliers.
Fixed commit description style error during merge:
Shuah Khan <[email protected]>
--- tools/testing/selftests/resctrl/mba_test.c | 2 +- tools/testing/selftests/resctrl/mbm_test.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
tools/testing/selftests/resctrl/mba_test.c +1 -1
@@ -12,7 +12,7 @@#define RESULT_FILE_NAME "result_mba"#define NUM_OF_RUNS 5 -#define MAX_DIFF_PERCENT 5 +#define MAX_DIFF_PERCENT 8#define ALLOCATION_MAX 100#define ALLOCATION_MIN 10#define ALLOCATION_STEP 10
tools/testing/selftests/resctrl/mbm_test.c +1 -1
@@ -11,7 +11,7 @@#include "resctrl.h" #define RESULT_FILE_NAME "result_mbm" -#define MAX_DIFF_PERCENT 5 +#define MAX_DIFF_PERCENT 8#define NUM_OF_RUNS 5 static int
Greg Kroah-Hartman
maintainerPATCH 360/530 hid: lenovo: Resend all settings on reset_resume for compact keyboards
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jamie Lentin <[email protected]>
commit 2f2bd7cbd1d1548137b351040dc4e037d18cdfdc upstream.
The USB Compact Keyboard variant requires a reset_resume function to restore keyboard configuration after a suspend in some situations. Move configuration normally done on probe to lenovo_features_set_cptkbd(), then recycle this for use on reset_resume.
Without, the keyboard and driver would end up in an inconsistent state, breaking middle-button scrolling amongst other problems, and twiddling sysfs values wouldn't help as the middle-button mode won't be set until the driver is reloaded.
Tested on a USB and Bluetooth Thinkpad Compact Keyboard.
--- drivers/hid/hid-lenovo.c | 50 +++++++++++++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 16 deletions(-)
drivers/hid/hid-lenovo.c +34 -16
@@ -526,6 +526,19 @@ static void lenovo_features_set_cptkbd(sint ret;struct lenovo_drvdata *cptkbd_data =hid_get_drvdata (hdev); +/* +* Tell the keyboard a driver understands it, and turn F7, F9, F11 into +* regular keys +*/ + ret =lenovo_send_cmd_cptkbd (hdev,0x01 ,0x03 ); +if (ret) +hid_warn (hdev,"Failed to switch F7/9/11 mode: %d\n" , ret); + +/* Switch middle button to native mode */ + ret =lenovo_send_cmd_cptkbd (hdev,0x09 ,0x01 ); +if (ret) +hid_warn (hdev,"Failed to switch middle button: %d\n" , ret); + ret =lenovo_send_cmd_cptkbd (hdev,0x05 , cptkbd_data->fn_lock);if (ret)hid_err (hdev,"Fn-lock setting failed: %d\n" , ret);
@@ -1148,22 +1161,6 @@ static int lenovo_probe_cptkbd(struct hi }hid_set_drvdata (hdev, cptkbd_data); -/* -* Tell the keyboard a driver understands it, and turn F7, F9, F11 into -* regular keys (Compact only) -*/ -if (hdev->product ==USB_DEVICE_ID_LENOVO_CUSBKBD || - hdev->product ==USB_DEVICE_ID_LENOVO_CBTKBD ) { - ret =lenovo_send_cmd_cptkbd (hdev,0x01 ,0x03 ); -if (ret) -hid_warn (hdev,"Failed to switch F7/9/11 mode: %d\n" , ret); - } - -/* Switch middle button to native mode */ - ret =lenovo_send_cmd_cptkbd (hdev,0x09 ,0x01 ); -if (ret) -hid_warn (hdev,"Failed to switch middle button: %d\n" , ret); -/* Set keyboard settings to known state */ cptkbd_data->middlebutton_state =0 ; cptkbd_data->fn_lock = true;
@@ -1286,6 +1283,24 @@ err:return ret; } +#ifdef CONFIG_PM +static int lenovo_reset_resume (struct hid_device *hdev) +{ +switch (hdev->product) { +case USB_DEVICE_ID_LENOVO_CUSBKBD : +case USB_DEVICE_ID_LENOVO_TPIIUSBKBD : +if (hdev->type ==HID_TYPE_USBMOUSE ) +lenovo_features_set_cptkbd (hdev); + +break ; +default : +break ; + } + +return 0 ; +} +#endif +static void lenovo_remove_tpkbd (struct hid_device *hdev) {struct lenovo_drvdata *data_pointer =hid_get_drvdata (hdev);
@@ -1402,6 +1417,9 @@ static struct hid_driver lenovo_driver = .raw_event = lenovo_raw_event, .event = lenovo_event, .report_fixup = lenovo_report_fixup, +#ifdef CONFIG_PM + .reset_resume = lenovo_reset_resume, +#endif };module_hid_driver (lenovo_driver);
Greg Kroah-Hartman
maintainerPATCH 361/530 ASoC: codecs: wsa-macro: fix uninitialized stack variables with name prefix
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Kozlowski <[email protected]>
commit 72151ad0cba8a07df90130ff62c979520d71f23b upstream.
Driver compares widget name in wsa_macro_spk_boost_event() widget event callback, however it does not handle component's name prefix. This leads to using uninitialized stack variables as registers and register values. Handle gracefully such case.
--- sound/soc/codecs/lpass-wsa-macro.c | 3 +++ 1 file changed, 3 insertions(+)
sound/soc/codecs/lpass-wsa-macro.c +3 -0
@@ -1685,6 +1685,9 @@ static int wsa_macro_spk_boost_event(str boost_path_cfg1 =CDC_WSA_RX1_RX_PATH_CFG1 ; reg =CDC_WSA_RX1_RX_PATH_CTL ; reg_mix =CDC_WSA_RX1_RX_PATH_MIX_CTL ; + }else { +dev_warn (component->dev,"Incorrect widget name in the driver\n" ); +return -EINVAL ; }switch (event) {
Greg Kroah-Hartman
maintainerPATCH 362/530 jbd2: fix potential data lost in recovering journal raced with synchronizing fs bdev
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhihao Cheng <[email protected]>
commit 61187fce8600e8ef90e601be84f9d0f3222c1206 upstream.
JBD2 makes sure journal data is fallen on fs device by sync_blockdev(), however, other process could intercept the EIO information from bdev's mapping, which leads journal recovering successful even EIO occurs during data written back to fs device.
We found this problem in our product, iscsi + multipath is chosen for block device of ext4. Unstable network may trigger kpartx to rescan partitions in device mapper layer. Detailed process is shown as following:
mount kpartx irqjbd2_journal_recover
do_one_pass
memcpy(nbh->b_data, obh->b_data) // copy data to fs dev from journal mark_buffer_dirty // mark bh dirty
vfs_read
generic_file_read_iter // dio
filemap_write_and_wait_range
__filemap_fdatawrite_range
do_writepages
block_write_full_folio
submit_bh_wbc
>> EIO occurs in disk <<
end_buffer_async_write
mark_buffer_write_io_error
mapping_set_error
set_bit(AS_EIO, &mapping->flags) // set!
filemap_check_errors
test_and_clear_bit(AS_EIO, &mapping->flags) // clear!
err2 = sync_blockdev
filemap_write_and_wait
filemap_check_errors
test_and_clear_bit(AS_EIO, &mapping->flags) // false
err2 = 0
Filesystem is mounted successfully even data from journal is failed written into disk, and ext4/ocfs2 could become corrupted.
Fix it by comparing the wb_err state in fs block device before recovering and after recovering.
A reproducer can be found in the kernel bugzilla referenced below.
--- fs/jbd2/recovery.c | 8 ++++++++ 1 file changed, 8 insertions(+)
fs/jbd2/recovery.c +8 -0
@@ -289,6 +289,8 @@ int jbd2_journal_recover(journal_t *jourjournal_superblock_t * sb;struct recovery_info info; +errseq_t wb_err; +struct address_space *mapping;memset (&info,0 ,sizeof (info)); sb = journal->j_superblock;
@@ -306,6 +308,9 @@ int jbd2_journal_recover(journal_t *jourreturn 0 ; } + wb_err =0 ; + mapping = journal->j_fs_dev->bd_inode->i_mapping; +errseq_check_and_advance (&mapping->wb_err, &wb_err); err =do_one_pass (journal, &info,PASS_SCAN );if (!err) err =do_one_pass (journal, &info,PASS_REVOKE );
@@ -329,6 +334,9 @@ int jbd2_journal_recover(journal_t *jour err2 =sync_blockdev (journal->j_fs_dev);if (!err) err = err2; + err2 =errseq_check_and_advance (&mapping->wb_err, &wb_err); +if (!err) + err = err2;/* Make sure all replayed data is on permanent storage */ if (journal->j_flags &JBD2_BARRIER ) { err2 =blkdev_issue_flush (journal->j_fs_dev);
Greg Kroah-Hartman
maintainerPATCH 363/530 quota: explicitly forbid quota files from being encrypted
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Biggers <[email protected]>
commit d3cc1b0be258191d6360c82ea158c2972f8d3991 upstream.
Since commit d7e7b9af104c ("fscrypt: stop using keyrings subsystem for fscrypt_master_key"), xfstest generic/270 causes a WARNING when run on f2fs with test_dummy_encryption in the mount options:
$ kvm-xfstests -c f2fs/encrypt generic/270 [...] WARNING: CPU: 1 PID: 2453 at fs/crypto/keyring.c:240 fscrypt_destroy_keyring+0x1f5/0x260
The cause of the WARNING is that not all encrypted inodes have been evicted before fscrypt_destroy_keyring() is called, which violates an assumption. This happens because the test uses an external quota file, which gets automatically encrypted due to test_dummy_encryption.
Encryption of quota files has never really been supported. On ext4, ext4_quota_read() does not decrypt the data, so encrypted quota files are always considered invalid on ext4. On f2fs, f2fs_quota_read() uses the pagecache, so trying to use an encrypted quota file gets farther, resulting in the issue described above being possible. But this was never intended to be possible, and there is no use case for it.
Therefore, make the quota support layer explicitly reject using IS_ENCRYPTED inodes when quotaon is attempted.
Message-Id: <[email protected]>
--- fs/quota/dquot.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
fs/quota/dquot.c +14 -0
@@ -2351,6 +2351,20 @@ static int vfs_setup_quota_inode(structif (sb_has_quota_loaded (sb, type))return -EBUSY ; +/* +* Quota files should never be encrypted. They should be thought of as +* filesystem metadata, not user data. New-style internal quota files +* cannot be encrypted by users anyway, but old-style external quota +* files could potentially be incorrectly created in an encrypted +* directory, hence this explicit check. Some reasons why encrypted +* quota files don't work include: (1) some filesystems that support +* encryption don't handle it in their quota_read and quota_write, and +* (2) cleaning up encrypted quota files at unmount would need special +* consideration, as quota files are cleaned up later than user files. +*/ +if (IS_ENCRYPTED (inode)) +return -EINVAL ; + dqopt->files[type] =igrab (inode);if (!dqopt->files[type])return -EIO ;
Greg Kroah-Hartman
maintainerPATCH 364/530 kernel/reboot: emergency_restart: Set correct system_state
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Benjamin Bara <[email protected]>
commit 60466c067927abbcaff299845abd4b7069963139 upstream.
As the emergency restart does not call kernel_restart_prepare(), the system_state stays in SYSTEM_RUNNING.
Since bae1d3a05a8b, this hinders i2c_in_atomic_xfer_mode() from becoming active, and therefore might lead to avoidable warnings in the restart handlers, e.g.:
[ 12.667612] WARNING: CPU: 1 PID: 1 at kernel/rcu/tree_plugin.h:318 rcu_note_context_switch+0x33c/0x6b0 [ 12.676926] Voluntary context switch within RCU read-side critical section! ... [ 12.742376] schedule_timeout from wait_for_completion_timeout+0x90/0x114 [ 12.749179] wait_for_completion_timeout from tegra_i2c_wait_completion+0x40/0x70 ... [ 12.994527] atomic_notifier_call_chain from machine_restart+0x34/0x58 [ 13.001050] machine_restart from panic+0x2a8/0x32c
Avoid these by setting the correct system_state.
--- kernel/reboot.c | 1 + 1 file changed, 1 insertion(+)
kernel/reboot.c +1 -0
@@ -74,6 +74,7 @@ void __weak (*pm_power_off)(void);void emergency_restart (void ) {kmsg_dump (KMSG_DUMP_EMERG ); + system_state =SYSTEM_RESTART ;machine_emergency_restart (); }EXPORT_SYMBOL_GPL (emergency_restart);
Greg Kroah-Hartman
maintainerPATCH 365/530 scripts/gdb/vmalloc: disable on no-MMU
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ben Wolsieffer <[email protected]>
commit 6620999f0d41e4fd6f047727936a964c3399d249 upstream.
vmap_area does not exist on no-MMU, therefore the GDB scripts fail to load:
Traceback (most recent call last):
File "<...>/vmlinux-gdb.py", line 51, in <module>
import linux.vmalloc
File "<...>/scripts/gdb/linux/vmalloc.py", line 14, in <module>
vmap_area_ptr_type = vmap_area_type.get_type().pointer()
^^^^^^^^^^^^^^^^^^^^^^^^^
File "<...>/scripts/gdb/linux/utils.py", line 28, in get_type
self._type = gdb.lookup_type(self._name)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
gdb.error: No struct type named vmap_area.
To fix this, disable the command and add an informative error message if CONFIG_MMU is not defined, following the example of lx-slabinfo.
--- scripts/gdb/linux/constants.py.in | 1 + scripts/gdb/linux/vmalloc.py | 8 ++++++-- 2 files changed, 7 insertions(+), 2 deletions(-)
scripts/gdb/linux/constants.py.in +1 -0
@@ -158,3 +158,4 @@ LX_CONFIG(CONFIG_STACKDEPOT) LX_CONFIG(CONFIG_PAGE_OWNER) LX_CONFIG(CONFIG_SLUB_DEBUG) LX_CONFIG(CONFIG_SLAB_FREELIST_HARDENED) +LX_CONFIG(CONFIG_MMU)
scripts/gdb/linux/vmalloc.py +6 -2
@@ -10,8 +10,9 @@ import gdb import re from linux import lists, utils, stackdepot, constants, mm -vmap_area_type = utils.CachedType('struct vmap_area') -vmap_area_ptr_type = vmap_area_type.get_type().pointer() +if constants.LX_CONFIG_MMU: + vmap_area_type = utils.CachedType('struct vmap_area') + vmap_area_ptr_type = vmap_area_type.get_type().pointer() def is_vmalloc_addr(x): pg_ops = mm.page_ops().ops
@@ -25,6 +26,9 @@ class LxVmallocInfo(gdb.Command): super(LxVmallocInfo, self).__init__("lx-vmallocinfo", gdb.COMMAND_DATA) def invoke(self, arg, from_tty): + if not constants.LX_CONFIG_MMU: + raise gdb.GdbError("Requires MMU support") + vmap_area_list = gdb.parse_and_eval('vmap_area_list') for vmap_area in lists.list_for_each_entry(vmap_area_list, vmap_area_ptr_type, "list"): if not vmap_area['vm']:
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 366/530 fs: use nth_page() in place of direct struct page manipulation
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zi Yan <[email protected]>
commit 8db0ec791f7788cd21e7f91ee5ff42c1c458d0e7 upstream.
When dealing with hugetlb pages, struct page is not guaranteed to be contiguous on SPARSEMEM without VMEMMAP. Use nth_page() to handle it properly.
Without the fix, a wrong subpage might be checked for HWPoison, causing wrong number of bytes of a page copied to user space. No bug is reported. The fix comes from code inspection.
--- fs/hugetlbfs/inode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
fs/hugetlbfs/inode.c +2 -2
@@ -295,7 +295,7 @@ static size_t adjust_range_hwpoison(struct page *page, size_t offset, size_t bytsize_t res =0 ;/* First subpage to start the loop. */ - page += offset /PAGE_SIZE ; + page =nth_page (page, offset /PAGE_SIZE ); offset %=PAGE_SIZE ;while (1 ) {if (is_raw_hwpoison_page_in_hugepage (page))
@@ -309,7 +309,7 @@ static size_t adjust_range_hwpoison(struct page *page, size_t offset, size_t bytbreak ; offset += n;if (offset ==PAGE_SIZE ) { - page++; + page =nth_page (page,1 ); offset =0 ; } }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 367/530 mips: use nth_page() in place of direct struct page manipulation
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zi Yan <[email protected]>
commit aa5fe31b6b59210cb4ea28a59e68781f48eeca74 upstream.
__flush_dcache_pages() is called during hugetlb migration via migrate_pages() -> migrate_hugetlbs() -> unmap_and_move_huge_page() -> move_to_new_folio() -> flush_dcache_folio(). And with hugetlb and without sparsemem vmemmap, struct page is not guaranteed to be contiguous beyond a section. Use nth_page() instead.
Without the fix, a wrong address might be used for data cache page flush. No bug is reported. The fix comes from code inspection.
--- arch/mips/mm/cache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/mips/mm/cache.c +1 -1
@@ -117,7 +117,7 @@ void __flush_dcache_pages(struct page *p* get faulted into the tlb (and thus flushed) anyways. */ for (i =0 ; i < nr; i++) { - addr = (unsigned long )kmap_local_page (page + i); + addr = (unsigned long )kmap_local_page (nth_page (page, i));flush_data_cache_page (addr);kunmap_local ((void *)addr); }
Greg Kroah-Hartman
maintainerPATCH 368/530 i2c: core: Run atomic i2c xfer when !preemptible
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Benjamin Bara <[email protected]>
commit aa49c90894d06e18a1ee7c095edbd2f37c232d02 upstream.
Since bae1d3a05a8b, i2c transfers are non-atomic if preemption is disabled. However, non-atomic i2c transfers require preemption (e.g. in wait_for_completion() while waiting for the DMA).
panic() calls preempt_disable_notrace() before calling emergency_restart(). Therefore, if an i2c device is used for the restart, the xfer should be atomic. This avoids warnings like:
[ 12.667612] WARNING: CPU: 1 PID: 1 at kernel/rcu/tree_plugin.h:318 rcu_note_context_switch+0x33c/0x6b0 [ 12.676926] Voluntary context switch within RCU read-side critical section! ... [ 12.742376] schedule_timeout from wait_for_completion_timeout+0x90/0x114 [ 12.749179] wait_for_completion_timeout from tegra_i2c_wait_completion+0x40/0x70 ... [ 12.994527] atomic_notifier_call_chain from machine_restart+0x34/0x58 [ 13.001050] machine_restart from panic+0x2a8/0x32c
Use !preemptible() instead, which is basically the same check as pre-v5.2.
--- drivers/i2c/i2c-core.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/i2c/i2c-core.h +1 -1
@@ -29,7 +29,7 @@ int i2c_dev_irq_from_resources(const str*/ static inline bool i2c_in_atomic_xfer_mode (void ) { -return system_state >SYSTEM_RUNNING &&irqs_disabled (); +return system_state >SYSTEM_RUNNING && !preemptible (); }static inline int __i2c_lock_bus_helper (struct i2c_adapter *adap)
Greg Kroah-Hartman
maintainerPATCH 369/530 selftests/clone3: Fix broken test under !CONFIG_TIME_NS
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tiezhu Yang <[email protected]>
commit fc7f04dc23db50206bee7891516ed4726c3f64cf upstream.
When execute the following command to test clone3 under !CONFIG_TIME_NS:
# make headers && cd tools/testing/selftests/clone3 && make && ./clone3
we can see the following error info:
# [7538] Trying clone3() with flags 0x80 (size 0) # Invalid argument - Failed to create new process # [7538] clone3() with flags says: -22 expected 0 not ok 18 [7538] Result (-22) is different than expected (0)
...
# Totals: pass:18 fail:1 xfail:0 xpass:0 skip:0 error:0
This is because if CONFIG_TIME_NS is not set, but the flag CLONE_NEWTIME (0x80) is used to clone a time namespace, it will return -EINVAL in copy_time_ns().
If kernel does not support CONFIG_TIME_NS, /proc/self/ns/time will be not exist, and then we should skip clone3() test with CLONE_NEWTIME.
With this patch under !CONFIG_TIME_NS:
# make headers && cd tools/testing/selftests/clone3 && make && ./clone3 ... # Time namespaces are not supported ok 18 # SKIP Skipping clone3() with CLONE_NEWTIME ... # Totals: pass:18 fail:0 xfail:0 xpass:0 skip:1 error:0
--- tools/testing/selftests/clone3/clone3.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
tools/testing/selftests/clone3/clone3.c +6 -1
@@ -196,7 +196,12 @@ int main(int argc, char *argv[]) CLONE3_ARGS_NO_TEST);/* Do a clone3() in a new time namespace */ -test_clone3 (CLONE_NEWTIME ,0 ,0 ,CLONE3_ARGS_NO_TEST ); +if (access ("/proc/self/ns/time" ,F_OK ) ==0 ) { +test_clone3 (CLONE_NEWTIME ,0 ,0 ,CLONE3_ARGS_NO_TEST ); + }else { +ksft_print_msg ("Time namespaces are not supported\n" ); +ksft_test_result_skip ("Skipping clone3() with CLONE_NEWTIME\n" ); + }/* Do a clone3() with exit signal (SIGCHLD) in flags */ test_clone3 (SIGCHLD ,0 , -EINVAL ,CLONE3_ARGS_NO_TEST );
Greg Kroah-Hartman
maintainerPATCH 370/530 tracing: Have the user copy of synthetic event address use correct context
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt (Google) <[email protected]>
commit 4f7969bcd6d33042d62e249b41b5578161e4c868 upstream.
A synthetic event is created by the synthetic event interface that can read both user or kernel address memory. In reality, it reads any arbitrary memory location from within the kernel. If the address space is in USER (where CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE is set) then it uses strncpy_from_user_nofault() to copy strings otherwise it uses strncpy_from_kernel_nofault().
But since both functions use the same variable there's no annotation to what that variable is (ie. __user). This makes sparse complain.
Quiet sparse by typecasting the strncpy_from_user_nofault() variable to a __user pointer.
--- kernel/trace/trace_events_synth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/trace/trace_events_synth.c +1 -1
@@ -452,7 +452,7 @@ static unsigned int trace_string(struct#ifdef CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE if ((unsigned long )str_val <TASK_SIZE ) - ret =strncpy_from_user_nofault (str_field, str_val,STR_VAR_LEN_MAX ); + ret =strncpy_from_user_nofault (str_field, (const void __user *)str_val,STR_VAR_LEN_MAX ); else#endif ret =strncpy_from_kernel_nofault (str_field, str_val,STR_VAR_LEN_MAX );
Greg Kroah-Hartman
maintainerPATCH 371/530 driver core: Release all resources during unbind before updating device links
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Saravana Kannan <[email protected]>
commit 2e84dc37920012b458e9458b19fc4ed33f81bc74 upstream.
This commit fixes a bug in commit 9ed9895370ae ("driver core: Functional dependencies tracking support") where the device link status was incorrectly updated in the driver unbind path before all the device's resources were released.
--- drivers/base/dd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/base/dd.c +1 -1
@@ -1274,8 +1274,8 @@ static void __device_release_driver(struif (dev->bus && dev->bus->dma_cleanup) dev->bus->dma_cleanup (dev); -device_links_driver_cleanup (dev);device_unbind_cleanup (dev); +device_links_driver_cleanup (dev);klist_remove (&dev->p->knode_driver);device_pm_check_callbacks (dev);
Greg Kroah-Hartman
maintainerPATCH 372/530 mcb: fix error handling for different scenarios when parsing
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sanjuán García, Jorge <[email protected]>
commit 63ba2d07b4be72b94216d20561f43e1150b25d98 upstream.
chameleon_parse_gdd() may fail for different reasons and end up in the err tag. Make sure we at least always free the mcb_device allocated with mcb_alloc_dev().
If mcb_device_register() fails, make sure to give up the reference in the same place the device was added.
--- drivers/mcb/mcb-core.c | 1 + drivers/mcb/mcb-parse.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-)
drivers/mcb/mcb-core.c +1 -0
@@ -246,6 +246,7 @@ int mcb_device_register(struct mcb_bus *bus, struct mcb_device *dev)return 0 ; out: +put_device (&dev->dev);return ret; }
drivers/mcb/mcb-parse.c +1 -1
@@ -106,7 +106,7 @@ static int chameleon_parse_gdd(struct mcb_bus *bus,return 0 ; err: -put_device (&mdev->dev); +mcb_free_dev (mdev);return ret; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 373/530 powerpc/pseries/iommu: enable_ddw incorrectly returns direct mapping for SR-IOV device
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gaurav Batra <[email protected]>
commit 3bf983e4e93ce8e6d69e9d63f52a66ec0856672e upstream.
When a device is initialized, the driver invokes dma_supported() twice - first for streaming mappings followed by coherent mappings. For an SR-IOV device, default window is deleted and DDW created. With vPMEM enabled, TCE mappings are dynamically created for both vPMEM and SR-IOV device. There are no direct mappings.
First time when dma_supported() is called with 64 bit mask, DDW is created and marked as dynamic window. The second time dma_supported() is called, enable_ddw() finds existing window for the device and incorrectly returns it as "direct mapping".
This only happens when size of DDW is big enough to map max LPAR memory.
This results in streaming TCEs to not get dynamically mapped, since code incorrently assumes these are already pre-mapped. The adapter initially comes up but goes down due to EEH.
--- arch/powerpc/platforms/pseries/iommu.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
arch/powerpc/platforms/pseries/iommu.c +4 -4
@@ -914,7 +914,8 @@ static int remove_ddw(struct device_nodereturn 0 ; } -static bool find_existing_ddw (struct device_node *pdn,u64 *dma_addr,int *window_shift) +static bool find_existing_ddw (struct device_node *pdn,u64 *dma_addr,int *window_shift, +bool *direct_mapping) {struct dma_win *window;const struct dynamic_dma_window_prop *dma64;
@@ -927,6 +928,7 @@ static bool find_existing_ddw(struct dev dma64 = window->prop; *dma_addr =be64_to_cpu (dma64->dma_base); *window_shift =be32_to_cpu (dma64->window_shift); + *direct_mapping = window->direct; found = true;break ; }
@@ -1270,10 +1272,8 @@ static bool enable_ddw(struct pci_dev *dmutex_lock (&dma_win_init_mutex); -if (find_existing_ddw (pdn, &dev->dev.archdata.dma_offset, &len)) { - direct_mapping = (len >= max_ram_len); +if (find_existing_ddw (pdn, &dev->dev.archdata.dma_offset, &len, &direct_mapping)) goto out_unlock; - }/* * If we already went through this for a previous function of
Greg Kroah-Hartman
maintainerPATCH 374/530 dmaengine: stm32-mdma: correct desc prep when channel running
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alain Volmat <[email protected]>
commit 03f25d53b145bc2f7ccc82fc04e4482ed734f524 upstream.
In case of the prep descriptor while the channel is already running, the CCR register value stored into the channel could already have its EN bit set. This would lead to a bad transfer since, at start transfer time, enabling the channel while other registers aren't yet properly set. To avoid this, ensure to mask the CCR_EN bit when storing the ccr value into the mdma channel structure.
--- drivers/dma/stm32-mdma.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/dma/stm32-mdma.c +2 -2
@@ -489,7 +489,7 @@ static int stm32_mdma_set_xfer_param(str src_maxburst = chan->dma_config.src_maxburst; dst_maxburst = chan->dma_config.dst_maxburst; - ccr =stm32_mdma_read (dmadev,STM32_MDMA_CCR (chan->id)); + ccr =stm32_mdma_read (dmadev,STM32_MDMA_CCR (chan->id)) & ~STM32_MDMA_CCR_EN ; ctcr =stm32_mdma_read (dmadev,STM32_MDMA_CTCR (chan->id)); ctbr =stm32_mdma_read (dmadev,STM32_MDMA_CTBR (chan->id));
@@ -965,7 +965,7 @@ stm32_mdma_prep_dma_memcpy(struct dma_chif (!desc)return NULL ; - ccr =stm32_mdma_read (dmadev,STM32_MDMA_CCR (chan->id)); + ccr =stm32_mdma_read (dmadev,STM32_MDMA_CCR (chan->id)) & ~STM32_MDMA_CCR_EN ; ctcr =stm32_mdma_read (dmadev,STM32_MDMA_CTCR (chan->id)); ctbr =stm32_mdma_read (dmadev,STM32_MDMA_CTBR (chan->id)); cbndtr =stm32_mdma_read (dmadev,STM32_MDMA_CBNDTR (chan->id));
Greg Kroah-Hartman
maintainerPATCH 375/530 s390/mm: add missing arch_set_page_dat() call to vmem_crst_alloc()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Heiko Carstens <[email protected]>
commit 09cda0a400519b1541591c506e54c9c48e3101bf upstream.
If the cmma no-dat feature is available all pages that are not used for dynamic address translation are marked as "no-dat" with the ESSA instruction. This information is visible to the hypervisor, so that the hypervisor can optimize purging of guest TLB entries. This also means that pages which are used for dynamic address translation must not be marked as "no-dat", since the hypervisor may then incorrectly not purge guest TLB entries.
Region and segment tables allocated via vmem_crst_alloc() are incorrectly marked as "no-dat", as soon as slab_is_available() returns true.
Such tables are allocated e.g. when kernel page tables are split, memory is hotplugged, or a DCSS segment is loaded.
Fix this by adding the missing arch_set_page_dat() call.
--- arch/s390/mm/vmem.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
arch/s390/mm/vmem.c +6 -2
@@ -12,6 +12,7 @@#include <linux/hugetlb.h> #include <linux/slab.h> #include <linux/sort.h> +#include <asm/page-states.h> #include <asm/cacheflush.h> #include <asm/nospec-branch.h> #include <asm/pgalloc.h>
@@ -45,8 +46,11 @@ void *vmem_crst_alloc(unsigned long val)unsigned long *table; table =vmem_alloc_pages (CRST_ALLOC_ORDER ); -if (table) -crst_table_init (table, val); +if (!table) +return NULL ; +crst_table_init (table, val); +if (slab_is_available ()) +arch_set_page_dat (virt_to_page (table),CRST_ALLOC_ORDER );return table; }
Greg Kroah-Hartman
maintainerPATCH 376/530 s390/mm: add missing arch_set_page_dat() call to gmap allocations
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Heiko Carstens <[email protected]>
commit 1954da4a2b621a3328a63382cae7e5f5e2af502c upstream.
If the cmma no-dat feature is available all pages that are not used for dynamic address translation are marked as "no-dat" with the ESSA instruction. This information is visible to the hypervisor, so that the hypervisor can optimize purging of guest TLB entries. This also means that pages which are used for dynamic address translation must not be marked as "no-dat", since the hypervisor may then incorrectly not purge guest TLB entries.
Region, segment, and page tables allocated within the gmap code are incorrectly marked as "no-dat", since an explicit call to arch_set_page_dat() is missing, which would remove the "no-dat" mark.
In order to fix this add a new gmap_alloc_crst() function which should be used to allocate region and segment tables, and which also calls arch_set_page_dat().
Also add the arch_set_page_dat() call to page_table_alloc_pgste().
--- arch/s390/mm/gmap.c | 24 ++++++++++++++++++------ arch/s390/mm/pgalloc.c | 1 + 2 files changed, 19 insertions(+), 6 deletions(-)
arch/s390/mm/gmap.c +18 -6
@@ -21,10 +21,22 @@#include <asm/pgalloc.h> #include <asm/gmap.h> +#include <asm/page.h> #include <asm/tlb.h> #define GMAP_SHADOW_FAKE_TABLE 1ULL +static struct page *gmap_alloc_crst (void ) +{ +struct page *page; + + page =alloc_pages (GFP_KERNEL_ACCOUNT ,CRST_ALLOC_ORDER ); +if (!page) +return NULL ; +arch_set_page_dat (page,CRST_ALLOC_ORDER ); +return page; +} +/** * gmap_alloc - allocate and initialize a guest address space * @limit: maximum address of the gmap address space
@@ -67,7 +79,7 @@ static struct gmap *gmap_alloc(unsignedspin_lock_init (&gmap->guest_table_lock);spin_lock_init (&gmap->shadow_lock);refcount_set (&gmap->ref_count,1 ); - page =alloc_pages (GFP_KERNEL_ACCOUNT ,CRST_ALLOC_ORDER ); + page =gmap_alloc_crst ();if (!page) goto out_free; page->index =0 ;
@@ -308,7 +320,7 @@ static int gmap_alloc_table(struct gmapunsigned long *new;/* since we dont free the gmap table until gmap_free we can unlock */ - page =alloc_pages (GFP_KERNEL_ACCOUNT ,CRST_ALLOC_ORDER ); + page =gmap_alloc_crst ();if (!page)return -ENOMEM ; new =page_to_virt (page);
@@ -1759,7 +1771,7 @@ int gmap_shadow_r2t(struct gmap *sg, unsBUG_ON (!gmap_is_shadow (sg));/* Allocate a shadow region second table */ - page =alloc_pages (GFP_KERNEL_ACCOUNT ,CRST_ALLOC_ORDER ); + page =gmap_alloc_crst ();if (!page)return -ENOMEM ; page->index = r2t & _REGION_ENTRY_ORIGIN;
@@ -1843,7 +1855,7 @@ int gmap_shadow_r3t(struct gmap *sg, unsBUG_ON (!gmap_is_shadow (sg));/* Allocate a shadow region second table */ - page =alloc_pages (GFP_KERNEL_ACCOUNT ,CRST_ALLOC_ORDER ); + page =gmap_alloc_crst ();if (!page)return -ENOMEM ; page->index = r3t & _REGION_ENTRY_ORIGIN;
@@ -1927,7 +1939,7 @@ int gmap_shadow_sgt(struct gmap *sg, unsBUG_ON (!gmap_is_shadow (sg) || (sgt & _REGION3_ENTRY_LARGE));/* Allocate a shadow segment table */ - page =alloc_pages (GFP_KERNEL_ACCOUNT ,CRST_ALLOC_ORDER ); + page =gmap_alloc_crst ();if (!page)return -ENOMEM ; page->index = sgt & _REGION_ENTRY_ORIGIN;
@@ -2855,7 +2867,7 @@ int s390_replace_asce(struct gmap *gmap)if ((gmap->asce & _ASCE_TYPE_MASK) == _ASCE_TYPE_SEGMENT)return -EINVAL ; - page =alloc_pages (GFP_KERNEL_ACCOUNT ,CRST_ALLOC_ORDER ); + page =gmap_alloc_crst ();if (!page)return -ENOMEM ; page->index =0 ;
arch/s390/mm/pgalloc.c +1 -0
@@ -146,6 +146,7 @@ struct page *page_table_alloc_pgste(stru ptdesc =pagetable_alloc (GFP_KERNEL ,0 );if (ptdesc) { table = (u64 *)ptdesc_to_virt (ptdesc); +arch_set_page_dat (virt_to_page (table),0 );memset64 (table, _PAGE_INVALID,PTRS_PER_PTE );memset64 (table +PTRS_PER_PTE ,0 ,PTRS_PER_PTE ); }
Greg Kroah-Hartman
maintainerPATCH 377/530 s390/cmma: fix initial kernel address space page table walk
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Heiko Carstens <[email protected]>
commit 16ba44826a04834d3eeeda4b731c2ea3481062b7 upstream.
If the cmma no-dat feature is available the kernel page tables are walked to identify and mark all pages which are used for address translation (all region, segment, and page tables). In a subsequent loop all other pages are marked as "no-dat" pages with the ESSA instruction.
This information is visible to the hypervisor, so that the hypervisor can optimize purging of guest TLB entries. The initial loop however does not cover the complete kernel address space. This can result in pages being marked as not being used for dynamic address translation, even though they are. In turn guest TLB entries incorrectly may not be purged.
Fix this by adjusting the end address of the kernel address range being walked.
--- arch/s390/mm/page-states.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
arch/s390/mm/page-states.c +10 -3
@@ -151,15 +151,22 @@ static void mark_kernel_p4d(pgd_t *pgd,static void mark_kernel_pgd (void ) { -unsigned long addr, next; +unsigned long addr, next, max_addr;struct page *page;pgd_t *pgd;int i; addr =0 ; +/* +* Figure out maximum virtual address accessible with the +* kernel ASCE. This is required to keep the page table walker +* from accessing non-existent entries. +*/ + max_addr = (S390_lowcore.kernel_asce.val & _ASCE_TYPE_MASK) >>2 ; + max_addr =1UL << (max_addr *11 +31 ); pgd =pgd_offset_k (addr); do { - next = pgd_addr_end(addr, MODULES_END); + next = pgd_addr_end(addr, max_addr); if (pgd_none(*pgd)) continue; if (!pgd_folded(*pgd)) {
@@ -168,7 +175,7 @@ static void mark_kernel_pgd(void)set_bit (PG_arch_1, &page[i].flags); }mark_kernel_p4d (pgd, addr, next); - }while (pgd++, addr = next, addr !=MODULES_END ); + }while (pgd++, addr = next, addr != max_addr); }void __init cmma_init_nodat (void )
Greg Kroah-Hartman
maintainerPATCH 378/530 s390/cmma: fix detection of DAT pages
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Heiko Carstens <[email protected]>
commit 44d93045247661acbd50b1629e62f415f2747577 upstream.
If the cmma no-dat feature is available the kernel page tables are walked to identify and mark all pages which are used for address translation (all region, segment, and page tables). In a subsequent loop all other pages are marked as "no-dat" pages with the ESSA instruction.
This information is visible to the hypervisor, so that the hypervisor can optimize purging of guest TLB entries. The initial loop however is
incorrect: only the first three of the four pages which belong to segment and region tables will be marked as being used for DAT. The last page is incorrectly marked as no-dat.
This can result in incorrect guest TLB flushes.
Fix this by simply marking all four pages.
--- arch/s390/mm/page-states.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
arch/s390/mm/page-states.c +3 -3
@@ -121,7 +121,7 @@ static void mark_kernel_pud(p4d_t *p4d,continue ;if (!pud_folded (*pud)) { page =phys_to_page (pud_val (*pud)); -for (i =0 ; i <3 ; i++) +for (i =0 ; i <4 ; i++)set_bit (PG_arch_1, &page[i].flags); }mark_kernel_pmd (pud, addr, next);
@@ -142,7 +142,7 @@ static void mark_kernel_p4d(pgd_t *pgd,continue ;if (!p4d_folded (*p4d)) { page =phys_to_page (p4d_val (*p4d)); -for (i =0 ; i <3 ; i++) +for (i =0 ; i <4 ; i++)set_bit (PG_arch_1, &page[i].flags); }mark_kernel_pud (p4d, addr, next);
@@ -171,7 +171,7 @@ static void mark_kernel_pgd(void)continue ;if (!pgd_folded (*pgd)) { page =phys_to_page (pgd_val (*pgd)); -for (i =0 ; i <3 ; i++) +for (i =0 ; i <4 ; i++)set_bit (PG_arch_1, &page[i].flags); }mark_kernel_p4d (pgd, addr, next);
Greg Kroah-Hartman
maintainerPATCH 379/530 s390/cmma: fix handling of swapper_pg_dir and invalid_pg_dir
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Heiko Carstens <[email protected]>
commit 84bb41d5df48868055d159d9247b80927f1f70f9 upstream.
If the cmma no-dat feature is available the kernel page tables are walked to identify and mark all pages which are used for address translation (all region, segment, and page tables). In a subsequent loop all other pages are marked as "no-dat" pages with the ESSA instruction.
This information is visible to the hypervisor, so that the hypervisor can optimize purging of guest TLB entries. All pages used for swapper_pg_dir and invalid_pg_dir are incorrectly marked as no-dat, which in turn can result in incorrect guest TLB flushes.
Fix this by marking those pages correctly as being used for DAT.
--- arch/s390/mm/page-states.c | 6 ++++++ 1 file changed, 6 insertions(+)
arch/s390/mm/page-states.c +6 -0
@@ -188,6 +188,12 @@ void __init cmma_init_nodat(void)return ;/* Mark pages used in kernel page tables */ mark_kernel_pgd (); + page =virt_to_page (&swapper_pg_dir); +for (i =0 ; i <4 ; i++) +set_bit (PG_arch_1, &page[i].flags); + page =virt_to_page (&invalid_pg_dir); +for (i =0 ; i <4 ; i++) +set_bit (PG_arch_1, &page[i].flags);/* Set all kernel pages not used for page tables to stable/no-dat */ for_each_mem_pfn_range (i,MAX_NUMNODES , &start, &end,NULL ) {
Greg Kroah-Hartman
maintainerPATCH 380/530 mm/cma: use nth_page() in place of direct struct page manipulation
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zi Yan <[email protected]>
commit 2e7cfe5cd5b6b0b98abf57a3074885979e187c1c upstream.
Patch series "Use nth_page() in place of direct struct page manipulation", v3.
On SPARSEMEM without VMEMMAP, struct page is not guaranteed to be contiguous, since each memory section's memmap might be allocated independently. hugetlb pages can go beyond a memory section size, thus direct struct page manipulation on hugetlb pages/subpages might give wrong struct page. Kernel provides nth_page() to do the manipulation properly. Use that whenever code can see hugetlb pages.
This patch (of 5):
When dealing with hugetlb pages, manipulating struct page pointers directly can get to wrong struct page, since struct page is not guaranteed to be contiguous on SPARSEMEM without VMEMMAP. Use nth_page() to handle it properly.
Without the fix, page_kasan_tag_reset() could reset wrong page tags, causing a wrong kasan result. No related bug is reported. The fix comes from code inspection.
--- mm/cma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
mm/cma.c +1 -1
@@ -505,7 +505,7 @@ struct page *cma_alloc(struct cma *cma,*/ if (page) {for (i =0 ; i < count; i++) -page_kasan_tag_reset (page + i); +page_kasan_tag_reset (nth_page (page, i)); }if (ret && !no_warn) {
Greg Kroah-Hartman
maintainerPATCH 381/530 mm/hugetlb: use nth_page() in place of direct struct page manipulation
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zi Yan <[email protected]>
commit 426056efe835cf4864ccf4c328fe3af9146fc539 upstream.
When dealing with hugetlb pages, manipulating struct page pointers directly can get to wrong struct page, since struct page is not guaranteed to be contiguous on SPARSEMEM without VMEMMAP. Use nth_page() to handle it properly.
A wrong or non-existing page might be tried to be grabbed, either leading to a non freeable page or kernel memory access errors. No bug is reported. It comes from code inspection.
--- mm/hugetlb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
mm/hugetlb.c +1 -1
@@ -6520,7 +6520,7 @@ struct page *hugetlb_follow_page_mask(st } } - page += ((address & ~huge_page_mask (h)) >>PAGE_SHIFT ); + page =nth_page (page, ((address & ~huge_page_mask (h)) >>PAGE_SHIFT ));/* * Note that page may be a sub-page, and with vmemmap
Greg Kroah-Hartman
maintainerPATCH 382/530 mm/memory_hotplug: use pfn math in place of direct struct page manipulation
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zi Yan <[email protected]>
commit 1640a0ef80f6d572725f5b0330038c18e98ea168 upstream.
When dealing with hugetlb pages, manipulating struct page pointers directly can get to wrong struct page, since struct page is not guaranteed to be contiguous on SPARSEMEM without VMEMMAP. Use pfn calculation to handle it properly.
Without the fix, a wrong number of page might be skipped. Since skip cannot be negative, scan_movable_page() will end early and might miss a movable page with -ENOENT. This might fail offline_pages(). No bug is reported. The fix comes from code inspection.
--- mm/memory_hotplug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
mm/memory_hotplug.c +1 -1
@@ -1689,7 +1689,7 @@ static int scan_movable_pages(unsigned l*/ if (HPageMigratable (head)) goto found; - skip =compound_nr (head) - (page - head); + skip =compound_nr (head) - (pfn -page_to_pfn (head)); pfn += skip -1 ; }return -ENOENT ;
Greg Kroah-Hartman
maintainerPATCH 383/530 mm: make PR_MDWE_REFUSE_EXEC_GAIN an unsigned long
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florent Revest <[email protected]>
commit 0da668333fb07805c2836d5d50e26eda915b24a1 upstream.
Defining a prctl flag as an int is a footgun because on a 64 bit machine and with a variadic implementation of prctl (like in musl and glibc), when used directly as a prctl argument, it can get casted to long with garbage upper bits which would result in unexpected behaviors.
This patch changes the constant to an unsigned long to eliminate that possibilities. This does not break UAPI.
I think that a stable backport would be "nice to have": to reduce the chances that users build binaries that could end up with garbage bits in their MDWE prctl arguments. We are not aware of anyone having yet encountered this corner case with MDWE prctls but a backport would reduce the likelihood it happens, since this sort of issues has happened with other prctls. But If this is perceived as a backporting burden, I suppose we could also live without a stable backport.
--- include/uapi/linux/prctl.h | 2 +- tools/include/uapi/linux/prctl.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
include/uapi/linux/prctl.h +1 -1
@@ -283,7 +283,7 @@ struct prctl_mm_map {/* Memory deny write / execute */ #define PR_SET_MDWE 65 -# define PR_MDWE_REFUSE_EXEC_GAIN 1 +# define PR_MDWE_REFUSE_EXEC_GAIN (1UL << 0)#define PR_GET_MDWE 66
tools/include/uapi/linux/prctl.h +1 -1
@@ -283,7 +283,7 @@ struct prctl_mm_map {/* Memory deny write / execute */ #define PR_SET_MDWE 65 -# define PR_MDWE_REFUSE_EXEC_GAIN 1 +# define PR_MDWE_REFUSE_EXEC_GAIN (1UL << 0)#define PR_GET_MDWE 66
Greg Kroah-Hartman
maintainerPATCH 384/530 mtd: cfi_cmdset_0001: Byte swap OTP info
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linus Walleij <[email protected]>
commit 565fe150624ee77dc63a735cc1b3bff5101f38a3 upstream.
Currently the offset into the device when looking for OTP bits can go outside of the address of the MTD NOR devices, and if that memory isn't readable, bad things happen on the IXP4xx (added prints that illustrate the problem before the crash):
cfi_intelext_otp_walk walk OTP on chip 0 start at reg_prot_offset 0x00000100 ixp4xx_copy_from copy from 0x00000100 to 0xc880dd78 cfi_intelext_otp_walk walk OTP on chip 0 start at reg_prot_offset 0x12000000 ixp4xx_copy_from copy from 0x12000000 to 0xc880dd78
8<--- cut here ---
Unable to handle kernel paging request at virtual address db000000
[db000000] *pgd=00000000
(...)
This happens in this case because the IXP4xx is big endian and the 32- and 16-bit fields in the struct cfi_intelext_otpinfo are not properly byteswapped. Compare to how the code in read_pri_intelext() byteswaps the fields in struct cfi_pri_intelext.
Adding a small byte swapping loop for the OTP in read_pri_intelext() and the crash goes away.
The problem went unnoticed for many years until I enabled CONFIG_MTD_OTP on the IXP4xx as well, triggering the bug.
--- drivers/mtd/chips/cfi_cmdset_0001.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-)
drivers/mtd/chips/cfi_cmdset_0001.c +18 -2
@@ -422,9 +422,25 @@ read_pri_intelext(struct map_info *map, extra_size =0 ;/* Protection Register info */ -if (extp->NumProtectionFields) +if (extp->NumProtectionFields) { +struct cfi_intelext_otpinfo *otp = + (struct cfi_intelext_otpinfo *)&extp->extra[0 ]; + extra_size += (extp->NumProtectionFields -1 ) * -sizeof (struct cfi_intelext_otpinfo ); +sizeof (struct cfi_intelext_otpinfo ); + +if (extp_size >=sizeof (*extp) + extra_size) { +int i; + +/* Do some byteswapping if necessary */ +for (i =0 ; i < extp->NumProtectionFields -1 ; i++) { + otp->ProtRegAddr =le32_to_cpu (otp->ProtRegAddr); + otp->FactGroups =le16_to_cpu (otp->FactGroups); + otp->UserGroups =le16_to_cpu (otp->UserGroups); + otp++; + } + } + } }if (extp->MinorVersion >='1' ) {
Greg Kroah-Hartman
maintainerPATCH 385/530 cxl/region: Do not try to cleanup after cxl_region_setup_targets() fails
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jim Harris <[email protected]>
commit 0718588c7aaa7a1510b4de972370535b61dddd0d upstream.
Commit 5e42bcbc3fef ("cxl/region: decrement ->nr_targets on error in cxl_region_attach()") tried to avoid 'eiw' initialization errors when ->nr_targets exceeded 16, by just decrementing ->nr_targets when cxl_region_setup_targets() failed.
Commit 86987c766276 ("cxl/region: Cleanup target list on attach error") extended that cleanup to also clear cxled->pos and p->targets[pos]. The initialization error was incidentally fixed separately by:
Commit 8d4285425714 ("cxl/region: Fix port setup uninitialized variable warnings") which was merged a few days after 5e42bcbc3fef.
But now the original cleanup when cxl_region_setup_targets() fails prevents endpoint and switch decoder resources from being reused:
1) the cleanup does not set the decoder's region to NULL, which results in future dpa_size_store() calls returning -EBUSY
2) the decoder is not properly freed, which results in future commit errors associated with the upstream switch
Now that the initialization errors were fixed separately, the proper cleanup for this case is to just return immediately. Then the resources associated with this target get cleanup up as normal when the failed region is deleted.
The ->nr_targets decrement in the error case also helped prevent a p->targets[] array overflow, so add a new check to prevent against that overflow.
Tested by trying to create an invalid region for a 2 switch * 2 endpoint topology, and then following up with creating a valid region.
--- drivers/cxl/core/region.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
drivers/cxl/core/region.c +7 -7
@@ -1675,6 +1675,12 @@ static int cxl_region_attach(struct cxl_return -ENXIO ; } +if (p->nr_targets >= p->interleave_ways) { +dev_dbg (&cxlr->dev,"region already has %d endpoints\n" , + p->nr_targets); +return -EINVAL ; + } + ep_port =cxled_to_port (cxled); root_port =cxlrd_to_port (cxlrd); dport =cxl_find_dport_by_dev (root_port, ep_port->host_bridge);
@@ -1767,7 +1773,7 @@ static int cxl_region_attach(struct cxl_if (p->nr_targets == p->interleave_ways) { rc =cxl_region_setup_targets (cxlr);if (rc) - goto err_decrement; +return rc; p->state =CXL_CONFIG_ACTIVE ; }
@@ -1799,12 +1805,6 @@ static int cxl_region_attach(struct cxl_ }return 0 ; - -err_decrement: - p->nr_targets--; - cxled->pos =-1 ; - p->targets[pos] =NULL ; -return rc; }static int cxl_region_detach (struct cxl_endpoint_decoder *cxled)
Greg Kroah-Hartman
maintainerPATCH 386/530 i3c: master: cdns: Fix reading status register
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joshua Yeong <[email protected]>
commit 4bd8405257da717cd556f99e5fb68693d12c9766 upstream.
IBIR_DEPTH and CMDR_DEPTH should read from status0 instead of status1.
--- drivers/i3c/master/i3c-master-cdns.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/i3c/master/i3c-master-cdns.c +3 -3
@@ -191,7 +191,7 @@#define SLV_STATUS1_HJ_DIS BIT(18)#define SLV_STATUS1_MR_DIS BIT(17)#define SLV_STATUS1_PROT_ERR BIT(16) -#define SLV_STATUS1_DA (x) (((s) & GENMASK(15, 9)) >> 9) +#define SLV_STATUS1_DA (s) (((s) & GENMASK(15, 9)) >> 9)#define SLV_STATUS1_HAS_DA BIT(8)#define SLV_STATUS1_DDR_RX_FULL BIT(7)#define SLV_STATUS1_DDR_TX_FULL BIT(6)
@@ -1623,13 +1623,13 @@ static int cdns_i3c_master_probe(struct/* Device ID0 is reserved to describe this master. */ master->maxdevs =CONF_STATUS0_DEVS_NUM (val); master->free_rr_slots =GENMASK (master->maxdevs,1 ); + master->caps.ibirfifodepth =CONF_STATUS0_IBIR_DEPTH (val); + master->caps.cmdrfifodepth =CONF_STATUS0_CMDR_DEPTH (val); val =readl (master->regs +CONF_STATUS1 ); master->caps.cmdfifodepth =CONF_STATUS1_CMD_DEPTH (val); master->caps.rxfifodepth =CONF_STATUS1_RX_DEPTH (val); master->caps.txfifodepth =CONF_STATUS1_TX_DEPTH (val); - master->caps.ibirfifodepth =CONF_STATUS0_IBIR_DEPTH (val); - master->caps.cmdrfifodepth =CONF_STATUS0_CMDR_DEPTH (val);spin_lock_init (&master->ibi.lock); master->ibi.num_slots =CONF_STATUS1_IBI_HW_RES (val);
Greg Kroah-Hartman
maintainerPATCH 387/530 i3c: master: svc: fix race condition in ibi work thread
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Frank Li <[email protected]>
commit 6bf3fc268183816856c96b8794cd66146bc27b35 upstream.
The ibi work thread operates asynchronously with other transfers, such as svc_i3c_master_priv_xfers(). Introduce mutex protection to ensure the completion of the entire i3c/i2c transaction.
--- drivers/i3c/master/svc-i3c-master.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
drivers/i3c/master/svc-i3c-master.c +14 -0
@@ -175,6 +175,7 @@ struct svc_i3c_regs_save {* @ibi.slots: Available IBI slots * @ibi.tbq_slot: To be queued IBI slot * @ibi.lock: IBI lock +* @lock: Transfer lock, protect between IBI work thread and callbacks from master */ struct svc_i3c_master {struct i3c_master_controller base;
@@ -203,6 +204,7 @@ struct svc_i3c_master {/* Prevent races within IBI handlers */ spinlock_t lock; } ibi; +struct mutex lock; };/**
@@ -384,6 +386,7 @@ static void svc_i3c_master_ibi_work(struu32 status, val;int ret; +mutex_lock (&master->lock);/* Acknowledge the incoming interrupt with the AUTOIBI mechanism */ writel(SVC_I3C_MCTRL_REQUEST_AUTO_IBI | SVC_I3C_MCTRL_IBIRESP_AUTO,
@@ -460,6 +463,7 @@ static void svc_i3c_master_ibi_work(stru reenable_ibis:svc_i3c_master_enable_interrupts (master,SVC_I3C_MINT_SLVSTART ); +mutex_unlock (&master->lock); }static irqreturn_t svc_i3c_master_irq_handler (int irq,void *dev_id)
@@ -1204,9 +1208,11 @@ static int svc_i3c_master_send_bdcast_cc cmd->read_len =0 ; cmd->continued = false; +mutex_lock (&master->lock);svc_i3c_master_enqueue_xfer (master, xfer);if (!wait_for_completion_timeout (&xfer->comp,msecs_to_jiffies (1000 )))svc_i3c_master_dequeue_xfer (master, xfer); +mutex_unlock (&master->lock); ret = xfer->ret;kfree (buf);
@@ -1250,9 +1256,11 @@ static int svc_i3c_master_send_direct_cc cmd->read_len = read_len; cmd->continued = false; +mutex_lock (&master->lock);svc_i3c_master_enqueue_xfer (master, xfer);if (!wait_for_completion_timeout (&xfer->comp,msecs_to_jiffies (1000 )))svc_i3c_master_dequeue_xfer (master, xfer); +mutex_unlock (&master->lock);if (cmd->read_len != xfer_len) ccc->dests[0 ].payload.len = cmd->read_len;
@@ -1309,9 +1317,11 @@ static int svc_i3c_master_priv_xfers(str cmd->continued = (i +1 ) < nxfers; } +mutex_lock (&master->lock);svc_i3c_master_enqueue_xfer (master, xfer);if (!wait_for_completion_timeout (&xfer->comp,msecs_to_jiffies (1000 )))svc_i3c_master_dequeue_xfer (master, xfer); +mutex_unlock (&master->lock); ret = xfer->ret;svc_i3c_master_free_xfer (xfer);
@@ -1347,9 +1357,11 @@ static int svc_i3c_master_i2c_xfers(stru cmd->continued = (i +1 < nxfers); } +mutex_lock (&master->lock);svc_i3c_master_enqueue_xfer (master, xfer);if (!wait_for_completion_timeout (&xfer->comp,msecs_to_jiffies (1000 )))svc_i3c_master_dequeue_xfer (master, xfer); +mutex_unlock (&master->lock); ret = xfer->ret;svc_i3c_master_free_xfer (xfer);
@@ -1540,6 +1552,8 @@ static int svc_i3c_master_probe(struct pINIT_WORK (&master->hj_work, svc_i3c_master_hj_work);INIT_WORK (&master->ibi_work, svc_i3c_master_ibi_work); +mutex_init (&master->lock); + ret =devm_request_irq (dev, master->irq, svc_i3c_master_irq_handler,IRQF_NO_SUSPEND ,"svc-i3c-irq" , master);if (ret)
Greg Kroah-Hartman
maintainerPATCH 388/530 i3c: master: svc: fix wrong data return when IBI happen during start frame
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Frank Li <[email protected]>
commit 5e5e3c92e748a6d859190e123b9193cf4911fcca upstream.
┌─────┐ ┏──┐ ┏──┐ ┏──┐ ┏──┐ ┏──┐ ┏──┐ ┏──┐ ┏──┐ ┌─────
SCL: ┘ └─────┛ └──┛ └──┛ └──┛ └──┛ └──┛ └──┛ └──┛ └──┘
───┐ ┌─────┐ ┌─────┐ ┌───────────┐
SDA: └───────────────────────┘ └─────┘ └─────┘ └─────
xxx╱ ╲╱ ╲╱ ╲╱ ╲╱ ╲
: xxx╲IBI ╱╲ Addr(0x0a) ╱╲ RW ╱╲NACK╱╲ S ╱If an In-Band Interrupt (IBI) occurs and IBI work thread is not immediately scheduled, when svc_i3c_master_priv_xfers() initiates the I3C transfer and attempts to send address 0x7e, the target interprets it as an IBI handler and returns the target address 0x0a.
However, svc_i3c_master_priv_xfers() does not handle this case and proceeds with other transfers, resulting in incorrect data being returned.
Add IBIWON check in svc_i3c_master_xfer(). In case this situation occurs, return a failure to the driver.
--- drivers/i3c/master/svc-i3c-master.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+)
drivers/i3c/master/svc-i3c-master.c +20 -0
@@ -1011,6 +1011,9 @@ static int svc_i3c_master_xfer(struct svu32 reg;int ret; +/* clean SVC_I3C_MINT_IBIWON w1c bits */ +writel (SVC_I3C_MINT_IBIWON , master->regs +SVC_I3C_MSTATUS ); + writel(SVC_I3C_MCTRL_REQUEST_START_ADDR | xfer_type | SVC_I3C_MCTRL_IBIRESP_NACK |
@@ -1028,6 +1031,23 @@ static int svc_i3c_master_xfer(struct sv ret = -ENXIO ; goto emit_stop; } + +/* +* According to I3C spec ver 1.1.1, 5.1.2.2.3 Consequence of Controller Starting a Frame +* with I3C Target Address. +* +* The I3C Controller normally should start a Frame, the Address may be arbitrated, and so +* the Controller shall monitor to see whether an In-Band Interrupt request, a Controller +* Role Request (i.e., Secondary Controller requests to become the Active Controller), or +* a Hot-Join Request has been made. +* +* If missed IBIWON check, the wrong data will be return. When IBIWON happen, return failure +* and yield the above events handler. +*/ +if (SVC_I3C_MSTATUS_IBIWON (reg)) { + ret = -ENXIO ; + goto emit_stop; + }if (rnw) ret =svc_i3c_master_read (master, in, xfer_len);
Greg Kroah-Hartman
maintainerPATCH 389/530 i3c: master: svc: fix ibi may not return mandatory data byte
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Frank Li <[email protected]>
commit c85e209b799f12d18a90ae6353b997b1bb1274a5 upstream.
MSTATUS[RXPEND] is only updated after the data transfer cycle started. This creates an issue when the I3C clock is slow, and the CPU is running fast enough that MSTATUS[RXPEND] may not be updated when the code reaches checking point. As a result, mandatory data can be missed.
Add a wait for MSTATUS[COMPLETE] to ensure that all mandatory data is already in FIFO. It also works without mandatory data.
--- drivers/i3c/master/svc-i3c-master.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/i3c/master/svc-i3c-master.c +8 -0
@@ -333,6 +333,7 @@ static int svc_i3c_master_handle_ibi(strstruct i3c_ibi_slot *slot;unsigned int count;u32 mdatactrl; +int ret, val;u8 *buf; slot =i3c_generic_ibi_get_free_slot (data->ibi_pool);
@@ -342,6 +343,13 @@ static int svc_i3c_master_handle_ibi(str slot->len =0 ; buf = slot->data; + ret =readl_relaxed_poll_timeout (master->regs +SVC_I3C_MSTATUS , val, +SVC_I3C_MSTATUS_COMPLETE (val),0 ,1000 ); +if (ret) { +dev_err (master->dev,"Timeout when polling for COMPLETE\n" ); +return ret; + } +while (SVC_I3C_MSTATUS_RXPEND (readl (master->regs +SVC_I3C_MSTATUS )) && slot->len <SVC_I3C_FIFO_SIZE ) { mdatactrl =readl (master->regs +SVC_I3C_MDATACTRL );
Greg Kroah-Hartman
maintainerPATCH 390/530 i3c: master: svc: fix check wrong status register in irq handler
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Frank Li <[email protected]>
commit 225d5ef048c4ed01a475c95d94833bd7dd61072d upstream.
svc_i3c_master_irq_handler() wrongly checks register SVC_I3C_MINTMASKED. It should be SVC_I3C_MSTATUS.
--- drivers/i3c/master/svc-i3c-master.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/i3c/master/svc-i3c-master.c +1 -1
@@ -477,7 +477,7 @@ reenable_ibis:static irqreturn_t svc_i3c_master_irq_handler (int irq,void *dev_id) {struct svc_i3c_master *master = (struct svc_i3c_master *)dev_id; -u32 active =readl (master->regs +SVC_I3C_MINTMASKED ); +u32 active =readl (master->regs +SVC_I3C_MSTATUS );if (!SVC_I3C_MSTATUS_SLVSTART (active))return IRQ_NONE ;
Greg Kroah-Hartman
maintainerPATCH 391/530 i3c: master: svc: fix SDA keep low when polling IBIWON timeout happen
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Frank Li <[email protected]>
commit dfd7cd6aafdb1f5ba93828e97e56b38304b23a05 upstream.
Upon IBIWON timeout, the SDA line will always be kept low if we don't emit a stop. Calling svc_i3c_master_emit_stop() there will let the bus return to idle state.
--- drivers/i3c/master/svc-i3c-master.c | 1 + 1 file changed, 1 insertion(+)
drivers/i3c/master/svc-i3c-master.c +1 -0
@@ -405,6 +405,7 @@ static void svc_i3c_master_ibi_work(stru SVC_I3C_MSTATUS_IBIWON(val), 0, 1000);if (ret) {dev_err (master->dev,"Timeout when polling for IBIWON\n" ); +svc_i3c_master_emit_stop (master); goto reenable_ibis; }
Greg Kroah-Hartman
maintainerPATCH 392/530 i3c: master: svc: fix random hot join failure since timeout error
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Frank Li <[email protected]>
commit 9aaeef113c55248ecf3ab941c2e4460aaa8b8b9a upstream.
master side report:
silvaco-i3c-master 44330000.i3c-master: Error condition: MSTATUS 0x020090c7, MERRWARN 0x00100000
BIT 20: TIMEOUT error
The module has stalled too long in a frame. This happens when:
- The TX FIFO or RX FIFO is not handled and the bus is stuck in the
middle of a message,
- No STOP was issued and between messages,
- IBI manual is used and no decision was made.
The maximum stall period is 100 μs.
This can be considered as being just a warning as the system IRQ latency can easily be greater than 100us.
--- drivers/i3c/master/svc-i3c-master.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/i3c/master/svc-i3c-master.c +9 -0
@@ -93,6 +93,7 @@#define SVC_I3C_MINTMASKED 0x098#define SVC_I3C_MERRWARN 0x09C#define SVC_I3C_MERRWARN_NACK BIT(2) +#define SVC_I3C_MERRWARN_TIMEOUT BIT(20)#define SVC_I3C_MDMACTRL 0x0A0#define SVC_I3C_MDATACTRL 0x0AC#define SVC_I3C_MDATACTRL_FLUSHTB BIT(0)
@@ -227,6 +228,14 @@ static bool svc_i3c_master_error(structif (SVC_I3C_MSTATUS_ERRWARN (mstatus)) { merrwarn =readl (master->regs +SVC_I3C_MERRWARN );writel (merrwarn, master->regs +SVC_I3C_MERRWARN ); + +/* Ignore timeout error */ +if (merrwarn &SVC_I3C_MERRWARN_TIMEOUT ) { +dev_dbg (master->dev,"Warning condition: MSTATUS 0x%08x, MERRWARN 0x%08x\n" , + mstatus, merrwarn); +return false; + } +dev_err (master->dev,"Error condition: MSTATUS 0x%08x, MERRWARN 0x%08x\n" , mstatus, merrwarn);
Greg Kroah-Hartman
maintainerPATCH 393/530 cxl/region: Fix x1 root-decoder granularity calculations
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jim Harris <[email protected]>
commit 98a04c7aced2b43b3ac4befe216c4eecc7257d4b upstream.
Root decoder granularity must match value from CFWMS, which may not be the region's granularity for non-interleaved root decoders.
So when calculating granularities for host bridge decoders, use the region's granularity instead of the root decoder's granularity to ensure the correct granularities are set for the host bridge decoders and any downstream switch decoders.
Test configuration is 1 host bridge * 2 switches * 2 endpoints per switch.
Region created with 2048 granularity using following command line:
cxl create-region -m -d decoder0.0 -w 4 mem0 mem2 mem1 mem3 \ -g 2048 -s 2048M
Use "cxl list -PDE | grep granularity" to get a view of the granularity set at each level of the topology.
Before this patch:
"interleave_granularity":2048,
"interleave_granularity":2048,
"interleave_granularity":512,
"interleave_granularity":2048,
"interleave_granularity":2048,
"interleave_granularity":512,"interleave_granularity":256,
After:
"interleave_granularity":2048,
"interleave_granularity":2048,
"interleave_granularity":4096,
"interleave_granularity":2048,
"interleave_granularity":2048,
"interleave_granularity":4096,"interleave_granularity":2048,
--- drivers/cxl/core/region.c | 9 ++++++++- tools/testing/cxl/test/cxl.c | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-)
drivers/cxl/core/region.c +8 -1
@@ -1127,7 +1127,14 @@ static int cxl_port_setup_targets(struct }if (is_cxl_root (parent_port)) { - parent_ig = cxlrd->cxlsd.cxld.interleave_granularity; +/* +* Root decoder IG is always set to value in CFMWS which +* may be different than this region's IG. We can use the +* region's IG here since interleave_granularity_store() +* does not allow interleaved host-bridges with +* root IG != region IG. +*/ + parent_ig = p->interleave_granularity; parent_iw = cxlrd->cxlsd.cxld.interleave_ways;/* * For purposes of address bit routing, use power-of-2 math for
tools/testing/cxl/test/cxl.c +1 -1
@@ -831,7 +831,7 @@ static void mock_init_hdm_decoder(struct cxld->interleave_ways =2 ; else cxld->interleave_ways = 1; - cxld->interleave_granularity =256 ; + cxld->interleave_granularity =4096 ; cxld->hpa_range = (struct range ) { .start = base, .end = base + size -1 ,
Greg Kroah-Hartman
maintainerPATCH 394/530 cxl/port: Fix delete_endpoint() vs parent unregistration race
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Williams <[email protected]>
commit 8d2ad999ca3c64cb08cf6a58d227b9d9e746d708 upstream.
The CXL subsystem, at cxl_mem ->probe() time, establishes a lineage of ports (struct cxl_port objects) between an endpoint and the root of a CXL topology. Each port including the endpoint port is attached to the cxl_port driver.
Given that setup, it follows that when either any port in that lineage goes through a cxl_port ->remove() event, or the memdev goes through a cxl_mem ->remove() event. The hierarchy below the removed port, or the entire hierarchy if the memdev is removed needs to come down.
The delete_endpoint() callback is careful to check whether it is being called to tear down the hierarchy, or if it is only being called to teardown the memdev because an ancestor port is going through ->remove().
That care needs to take the device_lock() of the endpoint's parent. Which requires 2 bugs to be fixed:
1/ A reference on the parent is needed to prevent use-after-free
scenarios like this signature:
BUG: spinlock bad magic on CPU#0, kworker/u56:0/11
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS edk2-20230524-3.fc38 05/24/2023
Workqueue: cxl_port detach_memdev [cxl_core]
RIP: 0010:spin_bug+0x65/0xa0
Call Trace:
do_raw_spin_lock+0x69/0xa0
__mutex_lock+0x695/0xb80
delete_endpoint+0xad/0x150 [cxl_core]
devres_release_all+0xb8/0x110
device_unbind_cleanup+0xe/0x70
device_release_driver_internal+0x1d2/0x210
detach_memdev+0x15/0x20 [cxl_core]
process_one_work+0x1e3/0x4c0
worker_thread+0x1dd/0x3d02/ In the case of RCH topologies, the parent device that needs to be
locked is not always @port->dev as returned by cxl_mem_find_port(), use endpoint->dev.parent instead.
--- drivers/cxl/core/port.c | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-)
drivers/cxl/core/port.c +19 -15
@@ -1242,35 +1242,39 @@ static struct device *grandparent(structreturn NULL ; } +static struct device *endpoint_host (struct cxl_port *endpoint) +{ +struct cxl_port *port =to_cxl_port (endpoint->dev.parent); + +if (is_cxl_root (port)) +return port->uport_dev; +return &port->dev; +} +static void delete_endpoint (void *data) {struct cxl_memdev *cxlmd = data;struct cxl_port *endpoint = cxlmd->endpoint; -struct cxl_port *parent_port; -struct device *parent; +struct device *host =endpoint_host (endpoint); - parent_port =cxl_mem_find_port (cxlmd,NULL ); -if (!parent_port) - goto out; - parent = &parent_port->dev; - -device_lock (parent); -if (parent->driver && !endpoint->dead) { -devm_release_action (parent, cxl_unlink_parent_dport, endpoint); -devm_release_action (parent, cxl_unlink_uport, endpoint); -devm_release_action (parent, unregister_port, endpoint); +device_lock (host); +if (host->driver && !endpoint->dead) { +devm_release_action (host, cxl_unlink_parent_dport, endpoint); +devm_release_action (host, cxl_unlink_uport, endpoint); +devm_release_action (host, unregister_port, endpoint); } cxlmd->endpoint =NULL ; -device_unlock (parent); -put_device (parent); -out: +device_unlock (host);put_device (&endpoint->dev); +put_device (host); }int cxl_endpoint_autoremove (struct cxl_memdev *cxlmd,struct cxl_port *endpoint) { +struct device *host =endpoint_host (endpoint);struct device *dev = &cxlmd->dev; +get_device (host);get_device (&endpoint->dev); cxlmd->endpoint = endpoint; cxlmd->depth = endpoint->depth;
Greg Kroah-Hartman
maintainerPATCH 395/530 apparmor: Fix kernel-doc warnings in apparmor/audit.c
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gaosheng Cui <[email protected]>
[ Upstream commit 26c9ecb34f5f5fa43c041a220de01d7cbea97dd0 ]
Fix kernel-doc warnings:
security/apparmor/audit.c:150: warning: Function parameter or member 'type' not described in 'aa_audit_msg'
Stable-dep-of: 157a3537d6bc ("apparmor: Fix regression in mount mediation")
--- security/apparmor/audit.c | 1 + 1 file changed, 1 insertion(+)
security/apparmor/audit.c +1 -0
@@ -142,6 +142,7 @@ static void audit_pre(struct audit_buffer *ab, void *ca)/** * aa_audit_msg - Log a message to the audit subsystem +* @type: audit type for the message * @sa: audit event structure (NOT NULL) * @cb: optional callback fn for type specific fields (MAYBE NULL) */
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 396/530 apparmor: Fix kernel-doc warnings in apparmor/lib.c
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gaosheng Cui <[email protected]>
[ Upstream commit 8921482286116af193980f04f2f2755775a410a5 ]
Fix kernel-doc warnings:
security/apparmor/lib.c:33: warning: Excess function parameter 'str' description in 'aa_free_str_table' security/apparmor/lib.c:33: warning: Function parameter or member 't' not described in 'aa_free_str_table' security/apparmor/lib.c:94: warning: Function parameter or member 'n' not described in 'skipn_spaces' security/apparmor/lib.c:390: warning: Excess function parameter 'deny' description in 'aa_check_perms'
Stable-dep-of: 157a3537d6bc ("apparmor: Fix regression in mount mediation")
--- security/apparmor/lib.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
security/apparmor/lib.c +2 -2
@@ -27,7 +27,7 @@ struct aa_perms allperms = { .allow = ALL_PERMS_MASK,/** * aa_free_str_table - free entries str table -* @str: the string table to free (MAYBE NULL) +* @t: the string table to free (MAYBE NULL) */ void aa_free_str_table (struct aa_str_table *t) {
@@ -85,6 +85,7 @@ char *aa_split_fqname(char *fqname, char **ns_name)/** * skipn_spaces - Removes leading whitespace from @str. * @str: The string to be stripped. +* @n: length of str to parse, will stop at \0 if encountered before n * * Returns a pointer to the first non-whitespace character in @str. * if all whitespace will return NULL
@@ -371,7 +372,6 @@ int aa_profile_label_perm(struct aa_profile *profile, struct aa_profile *target,* @profile: profile being checked * @perms: perms computed for the request * @request: requested perms -* @deny: Returns: explicit deny set * @sa: initialized audit structure (MAY BE NULL if not auditing) * @cb: callback fn for type specific fields (MAY BE NULL) *
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 397/530 apparmor: Fix kernel-doc warnings in apparmor/resource.c
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gaosheng Cui <[email protected]>
[ Upstream commit 13c1748e217078d437727eef333cb0387d13bc0e ]
Fix kernel-doc warnings:
security/apparmor/resource.c:111: warning: Function parameter or member 'label' not described in 'aa_task_setrlimit' security/apparmor/resource.c:111: warning: Function parameter or member 'new_rlim' not described in 'aa_task_setrlimit' security/apparmor/resource.c:111: warning: Function parameter or member 'resource' not described in 'aa_task_setrlimit' security/apparmor/resource.c:111: warning: Function parameter or member 'task' not described in 'aa_task_setrlimit'
Stable-dep-of: 157a3537d6bc ("apparmor: Fix regression in mount mediation")
--- security/apparmor/resource.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
security/apparmor/resource.c +4 -4
@@ -97,10 +97,10 @@ static int profile_setrlimit(struct aa_profile *profile, unsigned int resource,/** * aa_task_setrlimit - test permission to set an rlimit -* @label - label confining the task (NOT NULL) -* @task - task the resource is being set on -* @resource - the resource being set -* @new_rlim - the new resource limit (NOT NULL) +* @label: label confining the task (NOT NULL) +* @task: task the resource is being set on +* @resource: the resource being set +* @new_rlim: the new resource limit (NOT NULL) * * Control raising the processes hard limit. *
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 398/530 apparmor: Fix kernel-doc warnings in apparmor/policy.c
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gaosheng Cui <[email protected]>
[ Upstream commit 25ff0ff2d6286928dc516c74b879809c691c2dd8 ]
Fix kernel-doc warnings:
security/apparmor/policy.c:294: warning: Function parameter or member 'proxy' not described in 'aa_alloc_profile' security/apparmor/policy.c:785: warning: Function parameter or member 'label' not described in 'aa_policy_view_capable' security/apparmor/policy.c:785: warning: Function parameter or member 'ns' not described in 'aa_policy_view_capable' security/apparmor/policy.c:847: warning: Function parameter or member 'ns' not described in 'aa_may_manage_policy' security/apparmor/policy.c:964: warning: Function parameter or member 'hname' not described in '__lookup_replace' security/apparmor/policy.c:964: warning: Function parameter or member 'info' not described in '__lookup_replace' security/apparmor/policy.c:964: warning: Function parameter or member 'noreplace' not described in '__lookup_replace' security/apparmor/policy.c:964: warning: Function parameter or member 'ns' not described in '__lookup_replace' security/apparmor/policy.c:964: warning: Function parameter or member 'p' not described in '__lookup_replace'
Stable-dep-of: 157a3537d6bc ("apparmor: Fix regression in mount mediation")
--- security/apparmor/policy.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-)
security/apparmor/policy.c +10 -7
@@ -286,6 +286,7 @@ void aa_free_profile(struct aa_profile *profile)/** * aa_alloc_profile - allocate, initialize and return a new profile * @hname: name of the profile (NOT NULL) +* @proxy: proxy to use OR null if to allocate a new one * @gfp: allocation type * * Returns: refcount profile or NULL on failure
@@ -775,8 +776,9 @@ static int policy_ns_capable(struct aa_label *label,/** * aa_policy_view_capable - check if viewing policy in at @ns is allowed -* label: label that is trying to view policy in ns -* ns: namespace being viewed by @label (may be NULL if @label's ns) +* @label: label that is trying to view policy in ns +* @ns: namespace being viewed by @label (may be NULL if @label's ns) +* * Returns: true if viewing policy is allowed * * If @ns is NULL then the namespace being viewed is assumed to be the
@@ -840,6 +842,7 @@ bool aa_current_policy_admin_capable(struct aa_ns *ns)/** * aa_may_manage_policy - can the current task manage policy * @label: label to check if it can manage policy +* @ns: namespace being managed by @label (may be NULL if @label's ns) * @mask: contains the policy manipulation operation being done * * Returns: 0 if the task is allowed to manipulate policy else error
@@ -951,11 +954,11 @@ static void __replace_profile(struct aa_profile *old, struct aa_profile *new)/** * __lookup_replace - lookup replacement information for a profile -* @ns - namespace the lookup occurs in -* @hname - name of profile to lookup -* @noreplace - true if not replacing an existing profile -* @p - Returns: profile to be replaced -* @info - Returns: info string on why lookup failed +* @ns: namespace the lookup occurs in +* @hname: name of profile to lookup +* @noreplace: true if not replacing an existing profile +* @p: Returns - profile to be replaced +* @info: Returns - info string on why lookup failed * * Returns: profile to replace (no ref) on success else ptr error */
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 399/530 apparmor: combine common_audit_data and apparmor_audit_data
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: John Johansen <[email protected]>
[ Upstream commit bd7bd201ca46c211c3ab251ca9854787d1331a2f ]
Everywhere where common_audit_data is used apparmor audit_data is also used. We can simplify the code and drop the use of the aad macro everywhere by combining the two structures.
Stable-dep-of: 157a3537d6bc ("apparmor: Fix regression in mount mediation")
--- security/apparmor/audit.c | 70 +++++++++++++++---------------- security/apparmor/capability.c | 24 +++++------ security/apparmor/file.c | 68 +++++++++++++++--------------- security/apparmor/include/audit.h | 34 ++++++++------- security/apparmor/include/net.h | 13 +++--- security/apparmor/include/perms.h | 4 +- security/apparmor/ipc.c | 39 ++++++++--------- security/apparmor/lib.c | 47 +++++++++++---------- security/apparmor/lsm.c | 12 +++--- security/apparmor/mount.c | 41 +++++++++--------- security/apparmor/net.c | 44 +++++++++---------- security/apparmor/policy.c | 19 +++++---- security/apparmor/policy_unpack.c | 29 ++++++------- security/apparmor/resource.c | 23 +++++----- security/apparmor/task.c | 35 ++++++++-------- 15 files changed, 257 insertions(+), 245 deletions(-)
security/apparmor/audit.c +35 -35
@@ -85,37 +85,36 @@ static const char *const aa_class_names[] = {/** * audit_pre() - core AppArmor function. * @ab: audit buffer to fill (NOT NULL) -* @ca: audit structure containing data to audit (NOT NULL) +* @va: audit structure containing data to audit (NOT NULL) * -* Record common AppArmor audit data from @sa +* Record common AppArmor audit data from @va */ -static void audit_pre (struct audit_buffer *ab,void *ca) +static void audit_pre (struct audit_buffer *ab,void *va) { -struct common_audit_data *sa = ca; +struct apparmor_audit_data *ad =aad_of_va (va);if (aa_g_audit_header) {audit_log_format (ab,"apparmor=\"%s\"" , - aa_audit_type[aad (sa)->type]); + aa_audit_type[ad->type]); } -if (aad (sa)->op) { -audit_log_format (ab," operation=\"%s\"" ,aad (sa)->op); - } +if (ad->op) +audit_log_format (ab," operation=\"%s\"" , ad->op); -if (aad (sa)->class) +if (ad->class)audit_log_format (ab," class=\"%s\"" , -aad (sa)->class <=AA_CLASS_LAST ? - aa_class_names[aad (sa)->class] : + ad->class <=AA_CLASS_LAST ? + aa_class_names[ad->class] :"unknown" ); -if (aad (sa)->info) { -audit_log_format (ab," info=\"%s\"" ,aad (sa)->info); -if (aad (sa)->error) -audit_log_format (ab," error=%d" ,aad (sa)->error); +if (ad->info) { +audit_log_format (ab," info=\"%s\"" , ad->info); +if (ad->error) +audit_log_format (ab," error=%d" , ad->error); } -if (aad (sa)->label) { -struct aa_label *label =aad (sa)->label; +if (ad->label) { +struct aa_label *label = ad->label;if (label_isprofile (label)) {struct aa_profile *profile =labels_profile (label);
@@ -134,43 +133,44 @@ static void audit_pre(struct audit_buffer *ab, void *ca) } } -if (aad (sa)->name) { +if (ad->name) {audit_log_format (ab," name=" ); -audit_log_untrustedstring (ab,aad (sa)->name); +audit_log_untrustedstring (ab, ad->name); } }/** * aa_audit_msg - Log a message to the audit subsystem * @type: audit type for the message -* @sa: audit event structure (NOT NULL) +* @ad: audit event structure (NOT NULL) * @cb: optional callback fn for type specific fields (MAYBE NULL) */ -void aa_audit_msg (int type,struct common_audit_data *sa, +void aa_audit_msg (int type,struct apparmor_audit_data *ad,void (*cb) (struct audit_buffer *,void *)) { -aad (sa)->type = type; -common_lsm_audit (sa, audit_pre, cb); + ad->type = type; +common_lsm_audit (&ad->common, audit_pre, cb); }/** * aa_audit - Log a profile based audit event to the audit subsystem * @type: audit type for the message * @profile: profile to check against (NOT NULL) -* @sa: audit event (NOT NULL) +* @ad: audit event (NOT NULL) * @cb: optional callback fn for type specific fields (MAYBE NULL) * * Handle default message switching based off of audit mode flags * * Returns: error on failure */ -int aa_audit (int type,struct aa_profile *profile,struct common_audit_data *sa, +int aa_audit (int type,struct aa_profile *profile, +struct apparmor_audit_data *ad,void (*cb) (struct audit_buffer *,void *)) {AA_BUG (!profile);if (type ==AUDIT_APPARMOR_AUTO ) { -if (likely (!aad (sa)->error)) { +if (likely (!ad->error)) {if (AUDIT_MODE (profile) !=AUDIT_ALL )return 0 ; type =AUDIT_APPARMOR_AUDIT ;
@@ -182,24 +182,24 @@ int aa_audit(int type, struct aa_profile *profile, struct common_audit_data *sa,if (AUDIT_MODE (profile) ==AUDIT_QUIET || (type ==AUDIT_APPARMOR_DENIED &&AUDIT_MODE (profile) ==AUDIT_QUIET_DENIED )) -return aad (sa)->error; +return ad->error;if (KILL_MODE (profile) && type ==AUDIT_APPARMOR_DENIED ) type =AUDIT_APPARMOR_KILL ; -aad (sa)->label = &profile->label; + ad->label = &profile->label; -aa_audit_msg (type, sa, cb); +aa_audit_msg (type, ad, cb); -if (aad (sa)->type ==AUDIT_APPARMOR_KILL ) +if (ad->type ==AUDIT_APPARMOR_KILL ) (void )send_sig_info (SIGKILL ,NULL , - sa->type ==LSM_AUDIT_DATA_TASK && sa->u.tsk ? - sa->u.tsk : current); + ad->common.type ==LSM_AUDIT_DATA_TASK && + ad->common.u.tsk ? ad->common.u.tsk : current); -if (aad (sa)->type ==AUDIT_APPARMOR_ALLOWED ) -return complain_error (aad (sa)->error); +if (ad->type ==AUDIT_APPARMOR_ALLOWED ) +return complain_error (ad->error); -return aad (sa)->error; +return ad->error; }struct aa_audit_rule {
security/apparmor/capability.c +12 -12
@@ -51,7 +51,7 @@ static void audit_cb(struct audit_buffer *ab, void *va)/** * audit_caps - audit a capability -* @sa: audit data +* @as: audit data * @profile: profile being tested for confinement (NOT NULL) * @cap: capability tested * @error: error code returned by test
@@ -59,9 +59,9 @@ static void audit_cb(struct audit_buffer *ab, void *va)* Do auditing of capability and handle, audit/complain/kill modes switching * and duplicate message elimination. * -* Returns: 0 or sa->error on success, error code on failure +* Returns: 0 or ad->error on success, error code on failure */ -static int audit_caps (struct common_audit_data *sa,struct aa_profile *profile, +static int audit_caps (struct apparmor_audit_data *ad,struct aa_profile *profile,int cap,int error) { struct aa_ruleset *rules = list_first_entry(&profile->rules,
@@ -69,7 +69,7 @@ static int audit_caps(struct common_audit_data *sa, struct aa_profile *profile,struct audit_cache *ent;int type =AUDIT_APPARMOR_AUTO ; -aad (sa)->error = error; + ad->error = error;if (likely (!error)) {/* test if auditing is being forced */
@@ -101,7 +101,7 @@ static int audit_caps(struct common_audit_data *sa, struct aa_profile *profile, }put_cpu_var (audit_cache); -return aa_audit (type, profile, sa, audit_cb); +return aa_audit (type, profile, ad, audit_cb); }/**
@@ -109,12 +109,12 @@ static int audit_caps(struct common_audit_data *sa, struct aa_profile *profile,* @profile: profile being enforced (NOT NULL, NOT unconfined) * @cap: capability to test if allowed * @opts: CAP_OPT_NOAUDIT bit determines whether audit record is generated -* @sa: audit data (MAY BE NULL indicating no auditing) +* @ad: audit data (MAY BE NULL indicating no auditing) * * Returns: 0 if allowed else -EPERM */ static int profile_capable (struct aa_profile *profile,int cap, -unsigned int opts,struct common_audit_data *sa) +unsigned int opts,struct apparmor_audit_data *ad) {struct aa_ruleset *rules =list_first_entry (&profile->rules,typeof (*rules), list);
@@ -132,10 +132,10 @@ static int profile_capable(struct aa_profile *profile, int cap,/* audit the cap request in complain mode but note that it * should be optional. */ -aad (sa)->info ="optional: no audit" ; + ad->info ="optional: no audit" ; } -return audit_caps (sa, profile, cap, error); +return audit_caps (ad, profile, cap, error); }/**
@@ -152,11 +152,11 @@ int aa_capable(struct aa_label *label, int cap, unsigned int opts) {struct aa_profile *profile;int error =0 ; -DEFINE_AUDIT_DATA (sa,LSM_AUDIT_DATA_CAP ,AA_CLASS_CAP ,OP_CAPABLE ); +DEFINE_AUDIT_DATA (ad,LSM_AUDIT_DATA_CAP ,AA_CLASS_CAP ,OP_CAPABLE ); - sa.u.cap = cap; + ad.common.u.cap = cap; error =fn_for_each_confined (label, profile, -profile_capable (profile, cap, opts, &sa)); +profile_capable (profile, cap, opts, &ad));return error; }
security/apparmor/file.c +34 -34
117 lines not on this page · raw message
security/apparmor/include/audit.h +18 -16
@@ -152,33 +152,35 @@ struct apparmor_audit_data {unsigned long flags; } mnt; }; + +struct common_audit_data common; };/* macros for dealing with apparmor_audit_data structure */ -#define aad (SA ) ((SA)->apparmor_audit_data) +#define aad (SA ) (container_of(SA, struct apparmor_audit_data, common)) +#define aad_of_va (VA ) aad((struct common_audit_data *)(VA)) +#define DEFINE_AUDIT_DATA (NAME ,T ,C ,X ) \/* TODO: cleanup audit init so we don't need _aad = {0,} */ \ - struct apparmor_audit_data NAME ## _aad = { \ + struct apparmor_audit_data NAME = { \ .class = (C), \ .op = (X), \ - }; \ - struct common_audit_data NAME = \ - { \ - .type = (T), \ - .u.tsk = NULL, \ - }; \ - NAME.apparmor_audit_data = &(NAME ## _aad) - -void aa_audit_msg (int type,struct common_audit_data *sa, + .common.type = (T), \ + .common.u.tsk = NULL, \ + .common.apparmor_audit_data = &NAME, \ + }; + +void aa_audit_msg (int type,struct apparmor_audit_data *ad,void (*cb) (struct audit_buffer *,void *)); -int aa_audit (int type,struct aa_profile *profile,struct common_audit_data *sa, +int aa_audit (int type,struct aa_profile *profile, +struct apparmor_audit_data *ad,void (*cb) (struct audit_buffer *,void *)); -#define aa_audit_error (ERROR ,SA ,CB ) \ +#define aa_audit_error (ERROR ,AD ,CB ) \ ({ \ - aad((SA))->error = (ERROR); \ - aa_audit_msg(AUDIT_APPARMOR_ERROR, (SA), (CB)); \ - aad((SA))->error; \ + (AD)->error = (ERROR); \ + aa_audit_msg(AUDIT_APPARMOR_ERROR, (AD), (CB)); \ + (AD)->error; \ })
security/apparmor/include/net.h +7 -6
@@ -61,9 +61,9 @@ struct aa_sk_ctx {LSM_AUDIT_DATA_NONE , \AA_CLASS_NET , \ OP); \ - NAME.u.net = &(NAME ## _net); \ -aad (&NAME )->net.type = (T ); \ - aad(&NAME)->net.protocol = (P) + NAME.common.u.net = &(NAME ## _net); \ +NAME .net.type = (T ); \ + NAME.net.protocol = (P)#define DEFINE_AUDIT_SK (NAME ,OP ,SK ) \ DEFINE_AUDIT_NET(NAME, OP, SK, (SK)->sk_family, (SK)->sk_type, \
@@ -90,16 +90,17 @@ struct aa_secmark {extern struct aa_sfs_entry aa_sfs_entry_network[];void audit_net_cb (struct audit_buffer *ab,void *va); -int aa_profile_af_perm (struct aa_profile *profile,struct common_audit_data *sa, +int aa_profile_af_perm (struct aa_profile *profile, +struct apparmor_audit_data *ad,u32 request,u16 family,int type);int aa_af_perm (struct aa_label *label,const char *op,u32 request,u16 family,int type,int protocol);static inline int aa_profile_af_sk_perm (struct aa_profile *profile, -struct common_audit_data *sa, +struct apparmor_audit_data *ad,u32 request,struct sock *sk) { -return aa_profile_af_perm (profile, sa, request, sk->sk_family, +return aa_profile_af_perm (profile, ad, request, sk->sk_family, sk->sk_type); }int aa_sk_perm (const char *op,u32 request,struct sock *sk);
security/apparmor/include/perms.h +2 -2
@@ -212,8 +212,8 @@ void aa_profile_match_label(struct aa_profile *profile, int type, u32 request, struct aa_perms *perms);int aa_profile_label_perm (struct aa_profile *profile,struct aa_profile *target,u32 request,int type,u32 *deny, -struct common_audit_data *sa); +struct apparmor_audit_data *ad);int aa_check_perms (struct aa_profile *profile,struct aa_perms *perms, -u32 request,struct common_audit_data *sa, +u32 request,struct apparmor_audit_data *ad,void (*cb)(struct audit_buffer *,void *));#endif /* __AA_PERM_H */
security/apparmor/ipc.c +20 -19
@@ -52,31 +52,32 @@ static const char *audit_signal_mask(u32 mask)static void audit_signal_cb (struct audit_buffer *ab,void *va) {struct common_audit_data *sa = va; +struct apparmor_audit_data *ad =aad (sa); -if (aad (sa)->request &AA_SIGNAL_PERM_MASK ) { +if (ad->request &AA_SIGNAL_PERM_MASK ) {audit_log_format (ab," requested_mask=\"%s\"" , -audit_signal_mask (aad (sa)->request)); -if (aad (sa)->denied &AA_SIGNAL_PERM_MASK ) { +audit_signal_mask (ad->request)); +if (ad->denied &AA_SIGNAL_PERM_MASK ) {audit_log_format (ab," denied_mask=\"%s\"" , -audit_signal_mask (aad (sa)->denied)); +audit_signal_mask (ad->denied)); } } -if (aad (sa)->signal ==SIGUNKNOWN ) +if (ad->signal ==SIGUNKNOWN )audit_log_format (ab,"signal=unknown(%d)" , -aad (sa)->unmappedsig); -else if (aad (sa)->signal <MAXMAPPED_SIGNAME ) -audit_log_format (ab," signal=%s" , sig_names[aad (sa)->signal]); + ad->unmappedsig); +else if (ad->signal <MAXMAPPED_SIGNAME ) +audit_log_format (ab," signal=%s" , sig_names[ad->signal]);else audit_log_format (ab," signal=rtmin+%d" , -aad (sa)->signal -SIGRT_BASE ); + ad->signal -SIGRT_BASE );audit_log_format (ab," peer=" ); -aa_label_xaudit (ab,labels_ns (aad (sa)->label),aad (sa)->peer, +aa_label_xaudit (ab,labels_ns (ad->label), ad->peer,FLAGS_NONE ,GFP_ATOMIC ); }static int profile_signal_perm (struct aa_profile *profile,struct aa_label *peer,u32 request, -struct common_audit_data *sa) +struct apparmor_audit_data *ad) {struct aa_ruleset *rules =list_first_entry (&profile->rules,typeof (*rules), list);
@@ -87,24 +88,24 @@ static int profile_signal_perm(struct aa_profile *profile, !ANY_RULE_MEDIATES(&profile->rules, AA_CLASS_SIGNAL))return 0 ; -aad (sa)->peer = peer; + ad->peer = peer;/* TODO: secondary cache check <profile, profile, perm> */ state =aa_dfa_next (rules->policy.dfa, rules->policy.start[AA_CLASS_SIGNAL ], -aad (sa)->signal); + ad->signal);aa_label_match (profile, rules, peer, state, false, request, &perms);aa_apply_modes_to_perms (profile, &perms); -return aa_check_perms (profile, &perms, request, sa, audit_signal_cb); +return aa_check_perms (profile, &perms, request, ad, audit_signal_cb); }int aa_may_signal (struct aa_label *sender,struct aa_label *target,int sig) {struct aa_profile *profile; -DEFINE_AUDIT_DATA (sa,LSM_AUDIT_DATA_NONE ,AA_CLASS_SIGNAL ,OP_SIGNAL ); +DEFINE_AUDIT_DATA (ad,LSM_AUDIT_DATA_NONE ,AA_CLASS_SIGNAL ,OP_SIGNAL ); -aad (&sa)->signal =map_signal_num (sig); -aad (&sa)->unmappedsig = sig; + ad.signal =map_signal_num (sig); + ad.unmappedsig = sig;return xcheck_labels (sender, target, profile, -profile_signal_perm (profile, target,MAY_WRITE , &sa), -profile_signal_perm (profile, sender,MAY_READ , &sa)); +profile_signal_perm (profile, target,MAY_WRITE , &ad), +profile_signal_perm (profile, sender,MAY_READ , &ad)); }
security/apparmor/lib.c +24 -23
113 lines not on this page · raw message
security/apparmor/lsm.c +6 -6
@@ -662,7 +662,7 @@ static int apparmor_setprocattr(const char *name, void *value,char *command, *largs =NULL , *args = value;size_t arg_size;int error; -DEFINE_AUDIT_DATA (sa,LSM_AUDIT_DATA_NONE ,AA_CLASS_NONE , +DEFINE_AUDIT_DATA (ad,LSM_AUDIT_DATA_NONE ,AA_CLASS_NONE ,OP_SETPROCATTR );if (size ==0 )
@@ -722,11 +722,11 @@ static int apparmor_setprocattr(const char *name, void *value,return error; fail: -aad (&sa)->label =begin_current_label_crit_section (); -aad (&sa)->info = name; -aad (&sa)->error = error = -EINVAL ; -aa_audit_msg (AUDIT_APPARMOR_DENIED , &sa,NULL ); -end_current_label_crit_section (aad (&sa)->label); + ad.label =begin_current_label_crit_section (); + ad.info = name; + ad.error = error = -EINVAL ; +aa_audit_msg (AUDIT_APPARMOR_DENIED , &ad,NULL ); +end_current_label_crit_section (ad.label); goto out; }
security/apparmor/mount.c +21 -20
72 lines not on this page · raw message
security/apparmor/net.c +23 -21
115 lines not on this page · raw message
security/apparmor/policy.c +10 -9
@@ -723,10 +723,11 @@ static int replacement_allowed(struct aa_profile *profile, int noreplace,static void audit_cb (struct audit_buffer *ab,void *va) {struct common_audit_data *sa = va; +struct apparmor_audit_data *ad =aad (sa); -if (aad (sa)->iface.ns) { +if (ad->iface.ns) {audit_log_format (ab," ns=" ); -audit_log_untrustedstring (ab,aad (sa)->iface.ns); +audit_log_untrustedstring (ab, ad->iface.ns); } }
@@ -745,15 +746,15 @@ static int audit_policy(struct aa_label *label, const char *op, const char *ns_name, const char *name, const char *info, int error) { -DEFINE_AUDIT_DATA (sa ,LSM_AUDIT_DATA_NONE ,AA_CLASS_NONE ,op ); +DEFINE_AUDIT_DATA (ad ,LSM_AUDIT_DATA_NONE ,AA_CLASS_NONE ,op ); -aad (&sa)->iface.ns = ns_name; -aad (&sa)->name = name; -aad (&sa)->info = info; -aad (&sa)->error = error; -aad (&sa)->label = label; + ad.iface.ns = ns_name; + ad.name = name; + ad.info = info; + ad.error = error; + ad.label = label; -aa_audit_msg (AUDIT_APPARMOR_STATUS , &sa, audit_cb); +aa_audit_msg (AUDIT_APPARMOR_STATUS , &ad, audit_cb);return error; }
security/apparmor/policy_unpack.c +15 -14
@@ -34,17 +34,18 @@static void audit_cb (struct audit_buffer *ab,void *va) {struct common_audit_data *sa = va; +struct apparmor_audit_data *ad =aad (sa); -if (aad (sa)->iface.ns) { +if (ad->iface.ns) {audit_log_format (ab," ns=" ); -audit_log_untrustedstring (ab,aad (sa)->iface.ns); +audit_log_untrustedstring (ab, ad->iface.ns); } -if (aad (sa)->name) { +if (ad->name) {audit_log_format (ab," name=" ); -audit_log_untrustedstring (ab,aad (sa)->name); +audit_log_untrustedstring (ab, ad->name); } -if (aad (sa)->iface.pos) -audit_log_format (ab," offset=%ld" ,aad (sa)->iface.pos); +if (ad->iface.pos) +audit_log_format (ab," offset=%ld" , ad->iface.pos); }/**
@@ -63,18 +64,18 @@ static int audit_iface(struct aa_profile *new, const char *ns_name, int error) {struct aa_profile *profile =labels_profile (aa_current_raw_label ()); -DEFINE_AUDIT_DATA (sa,LSM_AUDIT_DATA_NONE ,AA_CLASS_NONE ,NULL ); +DEFINE_AUDIT_DATA (ad,LSM_AUDIT_DATA_NONE ,AA_CLASS_NONE ,NULL );if (e) -aad (&sa)->iface.pos = e->pos - e->start; -aad (&sa)->iface.ns = ns_name; + ad.iface.pos = e->pos - e->start; + ad.iface.ns = ns_name;if (new) -aad (&sa)->name = new->base.hname; + ad.name = new->base.hname;else -aad (&sa)->name = name; -aad (&sa)->info = info; -aad (&sa)->error = error; + ad.name = name; + ad.info = info; + ad.error = error; -return aa_audit (AUDIT_APPARMOR_STATUS , profile, &sa, audit_cb); +return aa_audit (AUDIT_APPARMOR_STATUS , profile, &ad, audit_cb); }void __aa_loaddata_update (struct aa_loaddata *data,long revision)
security/apparmor/resource.c +12 -11
@@ -30,12 +30,13 @@ struct aa_sfs_entry aa_sfs_entry_rlimit[] = {static void audit_cb (struct audit_buffer *ab,void *va) {struct common_audit_data *sa = va; +struct apparmor_audit_data *ad =aad (sa);audit_log_format (ab," rlimit=%s value=%lu" , - rlim_names[aad (sa)->rlim.rlim],aad (sa)->rlim.max); -if (aad (sa)->peer) { + rlim_names[ad->rlim.rlim], ad->rlim.max); +if (ad->peer) {audit_log_format (ab," peer=" ); -aa_label_xaudit (ab,labels_ns (aad (sa)->label),aad (sa)->peer, +aa_label_xaudit (ab,labels_ns (ad->label), ad->peer,FLAGS_NONE ,GFP_ATOMIC ); } }
@@ -49,22 +50,22 @@ static void audit_cb(struct audit_buffer *ab, void *va)* @info: info being auditing * @error: error value * -* Returns: 0 or sa->error else other error code on failure +* Returns: 0 or ad->error else other error code on failure */ static int audit_resource (struct aa_profile *profile,unsigned int resource,unsigned long value,struct aa_label *peer,const char *info,int error) { -DEFINE_AUDIT_DATA (sa,LSM_AUDIT_DATA_NONE ,AA_CLASS_RLIMITS , +DEFINE_AUDIT_DATA (ad,LSM_AUDIT_DATA_NONE ,AA_CLASS_RLIMITS ,OP_SETRLIMIT ); -aad (&sa)->rlim.rlim = resource; -aad (&sa)->rlim.max = value; -aad (&sa)->peer = peer; -aad (&sa)->info = info; -aad (&sa)->error = error; + ad.rlim.rlim = resource; + ad.rlim.max = value; + ad.peer = peer; + ad.info = info; + ad.error = error; -return aa_audit (AUDIT_APPARMOR_AUTO , profile, &sa, audit_cb); +return aa_audit (AUDIT_APPARMOR_AUTO , profile, &ad, audit_cb); }/**
security/apparmor/task.c +18 -17
@@ -208,18 +208,19 @@ static const char *audit_ptrace_mask(u32 mask)static void audit_ptrace_cb (struct audit_buffer *ab,void *va) {struct common_audit_data *sa = va; +struct apparmor_audit_data *ad =aad (sa); -if (aad (sa)->request &AA_PTRACE_PERM_MASK ) { +if (ad->request &AA_PTRACE_PERM_MASK ) {audit_log_format (ab," requested_mask=\"%s\"" , -audit_ptrace_mask (aad (sa)->request)); +audit_ptrace_mask (ad->request)); -if (aad (sa)->denied &AA_PTRACE_PERM_MASK ) { +if (ad->denied &AA_PTRACE_PERM_MASK ) {audit_log_format (ab," denied_mask=\"%s\"" , -audit_ptrace_mask (aad (sa)->denied)); +audit_ptrace_mask (ad->denied)); } }audit_log_format (ab," peer=" ); -aa_label_xaudit (ab,labels_ns (aad (sa)->label),aad (sa)->peer, +aa_label_xaudit (ab,labels_ns (ad->label), ad->peer,FLAGS_NONE ,GFP_ATOMIC ); }
@@ -227,51 +228,51 @@ static void audit_ptrace_cb(struct audit_buffer *ab, void *va)/* TODO: conditionals */ static int profile_ptrace_perm (struct aa_profile *profile,struct aa_label *peer,u32 request, -struct common_audit_data *sa) +struct apparmor_audit_data *ad) {struct aa_ruleset *rules =list_first_entry (&profile->rules,typeof (*rules), list);struct aa_perms perms = { }; -aad (sa)->peer = peer; + ad->peer = peer;aa_profile_match_label (profile, rules, peer,AA_CLASS_PTRACE , request, &perms);aa_apply_modes_to_perms (profile, &perms); -return aa_check_perms (profile, &perms, request, sa, audit_ptrace_cb); +return aa_check_perms (profile, &perms, request, ad, audit_ptrace_cb); }static int profile_tracee_perm (struct aa_profile *tracee,struct aa_label *tracer,u32 request, -struct common_audit_data *sa) +struct apparmor_audit_data *ad) {if (profile_unconfined (tracee) ||unconfined (tracer) || !ANY_RULE_MEDIATES (&tracee->rules,AA_CLASS_PTRACE ))return 0 ; -return profile_ptrace_perm (tracee, tracer, request, sa); +return profile_ptrace_perm (tracee, tracer, request, ad); }static int profile_tracer_perm (struct aa_profile *tracer,struct aa_label *tracee,u32 request, -struct common_audit_data *sa) +struct apparmor_audit_data *ad) {if (profile_unconfined (tracer))return 0 ;if (ANY_RULE_MEDIATES (&tracer->rules,AA_CLASS_PTRACE )) -return profile_ptrace_perm (tracer, tracee, request, sa); +return profile_ptrace_perm (tracer, tracee, request, ad);/* profile uses the old style capability check for ptrace */ if (&tracer->label == tracee)return 0 ; -aad (sa)->label = &tracer->label; -aad (sa)->peer = tracee; -aad (sa)->request =0 ; -aad (sa)->error =aa_capable (&tracer->label,CAP_SYS_PTRACE , + ad->label = &tracer->label; + ad->peer = tracee; + ad->request =0 ; + ad->error =aa_capable (&tracer->label,CAP_SYS_PTRACE ,CAP_OPT_NONE ); -return aa_audit (AUDIT_APPARMOR_AUTO , tracer, sa, audit_ptrace_cb); +return aa_audit (AUDIT_APPARMOR_AUTO , tracer, ad, audit_ptrace_cb); }/**
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 400/530 apparmor: rename audit_data->label to audit_data->subj_label
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: John Johansen <[email protected]>
[ Upstream commit d20f5a1a6e792d22199c9989ec7ab9e95c48d60c ]
rename audit_data's label field to subj_label to better reflect its use. Also at the same time drop unneeded assignments to ->subj_label as the later call to aa_check_perms will do the assignment if needed.
Stable-dep-of: 157a3537d6bc ("apparmor: Fix regression in mount mediation")
--- security/apparmor/audit.c | 6 +++--- security/apparmor/file.c | 2 +- security/apparmor/include/audit.h | 2 +- security/apparmor/ipc.c | 2 +- security/apparmor/lib.c | 5 ++--- security/apparmor/lsm.c | 4 ++-- security/apparmor/net.c | 2 +- security/apparmor/policy.c | 6 +++--- security/apparmor/resource.c | 2 +- security/apparmor/task.c | 4 ++-- 10 files changed, 17 insertions(+), 18 deletions(-)
security/apparmor/audit.c +3 -3
@@ -113,8 +113,8 @@ static void audit_pre(struct audit_buffer *ab, void *va)audit_log_format (ab," error=%d" , ad->error); } -if (ad->label) { -struct aa_label *label = ad->label; +if (ad->subj_label) { +struct aa_label *label = ad->subj_label;if (label_isprofile (label)) {struct aa_profile *profile =labels_profile (label);
@@ -187,7 +187,7 @@ int aa_audit(int type, struct aa_profile *profile,if (KILL_MODE (profile) && type ==AUDIT_APPARMOR_DENIED ) type =AUDIT_APPARMOR_KILL ; - ad->label = &profile->label; + ad->subj_label = &profile->label;aa_audit_msg (type, ad, cb);
security/apparmor/file.c +1 -1
@@ -67,7 +67,7 @@ static void file_audit_cb(struct audit_buffer *ab, void *va)if (ad->peer) {audit_log_format (ab," target=" ); -aa_label_xaudit (ab,labels_ns (ad->label), ad->peer, +aa_label_xaudit (ab,labels_ns (ad->subj_label), ad->peer,FLAG_VIEW_SUBNS ,GFP_KERNEL ); }else if (ad->fs.target) {audit_log_format (ab," target=" );
security/apparmor/include/audit.h +1 -1
@@ -109,7 +109,7 @@ struct apparmor_audit_data {int type;u16 class;const char *op; -struct aa_label *label; +struct aa_label *subj_label;const char *name;const char *info;u32 request;
security/apparmor/ipc.c +1 -1
@@ -71,7 +71,7 @@ static void audit_signal_cb(struct audit_buffer *ab, void *va)audit_log_format (ab," signal=rtmin+%d" , ad->signal -SIGRT_BASE );audit_log_format (ab," peer=" ); -aa_label_xaudit (ab,labels_ns (ad->label), ad->peer, +aa_label_xaudit (ab,labels_ns (ad->subj_label), ad->peer,FLAGS_NONE ,GFP_ATOMIC ); }
security/apparmor/lib.c +2 -3
@@ -297,7 +297,7 @@ static void aa_audit_perms_cb(struct audit_buffer *ab, void *va) PERMS_NAMES_MASK); }audit_log_format (ab," peer=" ); -aa_label_xaudit (ab,labels_ns (ad->label), ad->peer, +aa_label_xaudit (ab,labels_ns (ad->subj_label), ad->peer,FLAGS_NONE ,GFP_ATOMIC ); }
@@ -357,7 +357,6 @@ int aa_profile_label_perm(struct aa_profile *profile, struct aa_profile *target, typeof(*rules), list);struct aa_perms perms; - ad->label = &profile->label; ad->peer = &target->label; ad->request = request;
@@ -419,7 +418,7 @@ int aa_check_perms(struct aa_profile *profile, struct aa_perms *perms, }if (ad) { - ad->label = &profile->label; + ad->subj_label = &profile->label; ad->request = request; ad->denied = denied; ad->error = error;
security/apparmor/lsm.c +2 -2
@@ -722,11 +722,11 @@ static int apparmor_setprocattr(const char *name, void *value,return error; fail: - ad.label =begin_current_label_crit_section (); + ad.subj_label =begin_current_label_crit_section (); ad.info = name; ad.error = error = -EINVAL ;aa_audit_msg (AUDIT_APPARMOR_DENIED , &ad,NULL ); -end_current_label_crit_section (ad.label); +end_current_label_crit_section (ad.subj_label); goto out; }
security/apparmor/net.c +1 -1
@@ -100,7 +100,7 @@ void audit_net_cb(struct audit_buffer *ab, void *va) }if (ad->peer) {audit_log_format (ab," peer=" ); -aa_label_xaudit (ab,labels_ns (ad->label), ad->peer, +aa_label_xaudit (ab,labels_ns (ad->subj_label), ad->peer,FLAGS_NONE ,GFP_ATOMIC ); } }
security/apparmor/policy.c +3 -3
@@ -733,7 +733,7 @@ static void audit_cb(struct audit_buffer *ab, void *va)/** * audit_policy - Do auditing of policy changes -* @label: label to check if it can manage policy +* @subj_label: label to check if it can manage policy * @op: policy operation being performed * @ns_name: name of namespace being manipulated * @name: name of profile being manipulated (NOT NULL)
@@ -742,7 +742,7 @@ static void audit_cb(struct audit_buffer *ab, void *va)* * Returns: the error to be returned after audit is done */ -static int audit_policy (struct aa_label *label,const char *op, +static int audit_policy (struct aa_label *subj_label,const char *op,const char *ns_name,const char *name,const char *info,int error) {
@@ -752,7 +752,7 @@ static int audit_policy(struct aa_label *label, const char *op, ad.name = name; ad.info = info; ad.error = error; - ad.label = label; + ad.subj_label = subj_label;aa_audit_msg (AUDIT_APPARMOR_STATUS , &ad, audit_cb);
security/apparmor/resource.c +1 -1
@@ -36,7 +36,7 @@ static void audit_cb(struct audit_buffer *ab, void *va) rlim_names[ad->rlim.rlim], ad->rlim.max);if (ad->peer) {audit_log_format (ab," peer=" ); -aa_label_xaudit (ab,labels_ns (ad->label), ad->peer, +aa_label_xaudit (ab,labels_ns (ad->subj_label), ad->peer,FLAGS_NONE ,GFP_ATOMIC ); } }
security/apparmor/task.c +2 -2
@@ -220,7 +220,7 @@ static void audit_ptrace_cb(struct audit_buffer *ab, void *va) } }audit_log_format (ab," peer=" ); -aa_label_xaudit (ab,labels_ns (ad->label), ad->peer, +aa_label_xaudit (ab,labels_ns (ad->subj_label), ad->peer,FLAGS_NONE ,GFP_ATOMIC ); }
@@ -266,7 +266,7 @@ static int profile_tracer_perm(struct aa_profile *tracer,if (&tracer->label == tracee)return 0 ; - ad->label = &tracer->label; + ad->subj_label = &tracer->label; ad->peer = tracee; ad->request =0 ; ad->error = aa_capable(&tracer->label, CAP_SYS_PTRACE,
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 401/530 apparmor: pass cred through to audit info.
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: John Johansen <[email protected]>
[ Upstream commit 90c436a64a6e20482a9a613c47eb4af2e8a5328e ]
The cred is needed to properly audit some messages, and will be needed in the future for uid conditional mediation. So pass it through to where the apparmor_audit_data struct gets defined.
Stable-dep-of: 157a3537d6bc ("apparmor: Fix regression in mount mediation")
--- security/apparmor/apparmorfs.c | 11 ++- security/apparmor/capability.c | 5 +- security/apparmor/domain.c | 97 +++++++++++------- security/apparmor/file.c | 131 +++++++++++++++++-------- security/apparmor/include/audit.h | 1 + security/apparmor/include/capability.h | 3 +- security/apparmor/include/file.h | 17 ++-- security/apparmor/include/ipc.h | 4 +- security/apparmor/include/mount.h | 21 ++-- security/apparmor/include/net.h | 6 +- security/apparmor/include/policy.h | 9 +- security/apparmor/include/resource.h | 3 +- security/apparmor/include/task.h | 3 +- security/apparmor/ipc.c | 14 ++- security/apparmor/lsm.c | 85 +++++++++------- security/apparmor/mount.c | 85 ++++++++++------ security/apparmor/net.c | 17 ++-- security/apparmor/policy.c | 33 ++++--- security/apparmor/resource.c | 23 +++-- security/apparmor/task.c | 31 +++--- 20 files changed, 388 insertions(+), 211 deletions(-)
security/apparmor/apparmorfs.c +7 -4
@@ -423,7 +423,7 @@ static ssize_t policy_update(u32 mask, const char __user *buf, size_t size,/* high level check about policy management - fine grained in * below after unpack */ - error =aa_may_manage_policy (label, ns, mask); + error =aa_may_manage_policy (current_cred (), label, ns, mask);if (error) goto end_section;
@@ -486,7 +486,8 @@ static ssize_t profile_remove(struct file *f, const char __user *buf,/* high level check about policy management - fine grained in * below after unpack */ - error =aa_may_manage_policy (label, ns,AA_MAY_REMOVE_POLICY ); + error =aa_may_manage_policy (current_cred (), label, ns, +AA_MAY_REMOVE_POLICY );if (error) goto out;
@@ -1805,7 +1806,8 @@ static int ns_mkdir_op(struct mnt_idmap *idmap, struct inode *dir,int error; label =begin_current_label_crit_section (); - error =aa_may_manage_policy (label,NULL ,AA_MAY_LOAD_POLICY ); + error =aa_may_manage_policy (current_cred (), label,NULL , +AA_MAY_LOAD_POLICY );end_current_label_crit_section (label);if (error)return error;
@@ -1854,7 +1856,8 @@ static int ns_rmdir_op(struct inode *dir, struct dentry *dentry)int error; label =begin_current_label_crit_section (); - error =aa_may_manage_policy (label,NULL ,AA_MAY_LOAD_POLICY ); + error =aa_may_manage_policy (current_cred (), label,NULL , +AA_MAY_LOAD_POLICY );end_current_label_crit_section (label);if (error)return error;
security/apparmor/capability.c +4 -1
@@ -140,6 +140,7 @@ static int profile_capable(struct aa_profile *profile, int cap,/** * aa_capable - test permission to use capability +* @subj_cread: cred we are testing capability against * @label: label being tested for capability (NOT NULL) * @cap: capability to be tested * @opts: CAP_OPT_NOAUDIT bit determines whether audit record is generated
@@ -148,12 +149,14 @@ static int profile_capable(struct aa_profile *profile, int cap,* * Returns: 0 on success, or else an error code. */ -int aa_capable (struct aa_label *label,int cap,unsigned int opts) +int aa_capable (const struct cred *subj_cred,struct aa_label *label, +int cap,unsigned int opts) {struct aa_profile *profile;int error =0 ;DEFINE_AUDIT_DATA (ad,LSM_AUDIT_DATA_CAP ,AA_CLASS_CAP ,OP_CAPABLE ); + ad.subj_cred = subj_cred; ad.common.u.cap = cap; error =fn_for_each_confined (label, profile,profile_capable (profile, cap, opts, &ad));
security/apparmor/domain.c +64 -33
325 lines not on this page · raw message
security/apparmor/file.c +88 -43
345 lines not on this page · raw message
security/apparmor/include/audit.h +1 -0
@@ -109,6 +109,7 @@ struct apparmor_audit_data {int type;u16 class;const char *op; +const struct cred *subj_cred;struct aa_label *subj_label;const char *name;const char *info;
security/apparmor/include/capability.h +2 -1
@@ -36,7 +36,8 @@ struct aa_caps {extern struct aa_sfs_entry aa_sfs_entry_caps[]; -int aa_capable (struct aa_label *label,int cap,unsigned int opts); +int aa_capable (const struct cred *subj_cred,struct aa_label *label, +int cap,unsigned int opts);static inline void aa_free_cap_rules (struct aa_caps *caps) {
security/apparmor/include/file.h +10 -7
@@ -108,7 +108,8 @@ struct path_cond {#define COMBINED_PERM_MASK (X ) ((X).allow | (X).audit | (X).quiet | (X).kill) -int aa_audit_file (struct aa_profile *profile,struct aa_perms *perms, +int aa_audit_file (const struct cred *cred, +struct aa_profile *profile,struct aa_perms *perms,const char *op,u32 request,const char *name,const char *target,struct aa_label *tlabel,kuid_t ouid,const char *info,int error);
@@ -119,14 +120,16 @@ aa_state_t aa_str_perms(struct aa_policydb *file_rules, aa_state_t start, const char *name, struct path_cond *cond, struct aa_perms *perms); -int aa_path_perm (const char *op,struct aa_label *label, -const struct path *path,int flags,u32 request, -struct path_cond *cond); +int aa_path_perm (const char *op,const struct cred *subj_cred, +struct aa_label *label,const struct path *path, +int flags,u32 request,struct path_cond *cond); -int aa_path_link (struct aa_label *label,struct dentry *old_dentry, -const struct path *new_dir,struct dentry *new_dentry); +int aa_path_link (const struct cred *subj_cred,struct aa_label *label, +struct dentry *old_dentry,const struct path *new_dir, +struct dentry *new_dentry); -int aa_file_perm (const char *op,struct aa_label *label,struct file *file, +int aa_file_perm (const char *op,const struct cred *subj_cred, +struct aa_label *label,struct file *file,u32 request,bool in_atomic);void aa_inherit_files (const struct cred *cred,struct files_struct *files);
security/apparmor/include/ipc.h +3 -1
@@ -13,6 +13,8 @@#include <linux/sched.h> -int aa_may_signal (struct aa_label *sender,struct aa_label *target,int sig); +int aa_may_signal (const struct cred *subj_cred,struct aa_label *sender, +const struct cred *target_cred,struct aa_label *target, +int sig);#endif /* __AA_IPC_H */
security/apparmor/include/mount.h +14 -7
@@ -25,26 +25,33 @@#define AA_MS_IGNORE_MASK (MS_KERNMOUNT | MS_NOSEC | MS_ACTIVE | MS_BORN) -int aa_remount (struct aa_label *label,const struct path *path, +int aa_remount (const struct cred *subj_cred, +struct aa_label *label,const struct path *path,unsigned long flags,void *data); -int aa_bind_mount (struct aa_label *label,const struct path *path, +int aa_bind_mount (const struct cred *subj_cred, +struct aa_label *label,const struct path *path,const char *old_name,unsigned long flags); -int aa_mount_change_type (struct aa_label *label,const struct path *path, +int aa_mount_change_type (const struct cred *subj_cred, +struct aa_label *label,const struct path *path,unsigned long flags); -int aa_move_mount (struct aa_label *label,const struct path *path, +int aa_move_mount (const struct cred *subj_cred, +struct aa_label *label,const struct path *path,const char *old_name); -int aa_new_mount (struct aa_label *label,const char *dev_name, +int aa_new_mount (const struct cred *subj_cred, +struct aa_label *label,const char *dev_name,const struct path *path,const char *type,unsigned long flags,void *data); -int aa_umount (struct aa_label *label,struct vfsmount *mnt,int flags); +int aa_umount (const struct cred *subj_cred, +struct aa_label *label,struct vfsmount *mnt,int flags); -int aa_pivotroot (struct aa_label *label,const struct path *old_path, +int aa_pivotroot (const struct cred *subj_cred, +struct aa_label *label,const struct path *old_path,const struct path *new_path);#endif /* __AA_MOUNT_H */
security/apparmor/include/net.h +4 -2
@@ -93,7 +93,8 @@ void audit_net_cb(struct audit_buffer *ab, void *va);int aa_profile_af_perm (struct aa_profile *profile,struct apparmor_audit_data *ad,u32 request,u16 family,int type); -int aa_af_perm (struct aa_label *label,const char *op,u32 request,u16 family, +int aa_af_perm (const struct cred *subj_cred,struct aa_label *label, +const char *op,u32 request,u16 family,int type,int protocol); static inline int aa_profile_af_sk_perm(struct aa_profile *profile, struct apparmor_audit_data *ad,
@@ -105,7 +106,8 @@ static inline int aa_profile_af_sk_perm(struct aa_profile *profile, }int aa_sk_perm (const char *op,u32 request,struct sock *sk); -int aa_sock_file_perm (struct aa_label *label,const char *op,u32 request, +int aa_sock_file_perm (const struct cred *subj_cred,struct aa_label *label, +const char *op,u32 request,struct socket *sock); int apparmor_secmark_check(struct aa_label *label, char *op, u32 request,
security/apparmor/include/policy.h +6 -3
@@ -370,9 +370,12 @@ static inline int AUDIT_MODE(struct aa_profile *profile)return profile->audit; } -bool aa_policy_view_capable (struct aa_label *label,struct aa_ns *ns); -bool aa_policy_admin_capable (struct aa_label *label,struct aa_ns *ns); -int aa_may_manage_policy (struct aa_label *label,struct aa_ns *ns, +bool aa_policy_view_capable (const struct cred *subj_cred, +struct aa_label *label,struct aa_ns *ns); +bool aa_policy_admin_capable (const struct cred *subj_cred, +struct aa_label *label,struct aa_ns *ns); +int aa_may_manage_policy (const struct cred *subj_cred, +struct aa_label *label,struct aa_ns *ns,u32 mask);bool aa_current_policy_view_capable (struct aa_ns *ns);bool aa_current_policy_admin_capable (struct aa_ns *ns);
security/apparmor/include/resource.h +2 -1
@@ -33,7 +33,8 @@ struct aa_rlimit {extern struct aa_sfs_entry aa_sfs_entry_rlimit[];int aa_map_resource (int resource); -int aa_task_setrlimit (struct aa_label *label,struct task_struct *task, +int aa_task_setrlimit (const struct cred *subj_cred,struct aa_label *label, +struct task_struct *task,unsigned int resource,struct rlimit *new_rlim);void __aa_transition_rlimits (struct aa_label *old,struct aa_label *new);
security/apparmor/include/task.h +2 -1
@@ -91,7 +91,8 @@ static inline void aa_clear_task_ctx_trans(struct aa_task_ctx *ctx)"segv usr2 pipe alrm term stkflt chld cont stop stp ttin ttou urg " \"xcpu xfsz vtalrm prof winch io pwr sys emt lost" -int aa_may_ptrace(struct aa_label *tracer, struct aa_label *tracee, +int aa_may_ptrace(const struct cred *tracer_cred, struct aa_label *tracer, + const struct cred *tracee_cred, struct aa_label *tracee, u32 request);
security/apparmor/ipc.c +10 -4
@@ -75,7 +75,8 @@ static void audit_signal_cb(struct audit_buffer *ab, void *va) FLAGS_NONE, GFP_ATOMIC); } -static int profile_signal_perm (struct aa_profile *profile, +static int profile_signal_perm (const struct cred *cred, +struct aa_profile *profile,struct aa_label *peer,u32 request,struct apparmor_audit_data *ad) {
@@ -88,6 +89,7 @@ static int profile_signal_perm(struct aa_profile *profile, !ANY_RULE_MEDIATES(&profile->rules, AA_CLASS_SIGNAL))return 0 ; + ad->subj_cred = cred; ad->peer = peer;/* TODO: secondary cache check <profile, profile, perm> */ state = aa_dfa_next(rules->policy.dfa,
@@ -98,7 +100,9 @@ static int profile_signal_perm(struct aa_profile *profile,return aa_check_perms (profile, &perms, request, ad, audit_signal_cb); } -int aa_may_signal (struct aa_label *sender,struct aa_label *target,int sig) +int aa_may_signal (const struct cred *subj_cred,struct aa_label *sender, +const struct cred *target_cred,struct aa_label *target, +int sig) {struct aa_profile *profile;DEFINE_AUDIT_DATA (ad,LSM_AUDIT_DATA_NONE ,AA_CLASS_SIGNAL ,OP_SIGNAL );
@@ -106,6 +110,8 @@ int aa_may_signal(struct aa_label *sender, struct aa_label *target, int sig) ad.signal =map_signal_num (sig); ad.unmappedsig = sig;return xcheck_labels (sender, target, profile, -profile_signal_perm (profile, target,MAY_WRITE , &ad), -profile_signal_perm (profile, sender,MAY_READ , &ad)); +profile_signal_perm (subj_cred, profile, target, +MAY_WRITE , &ad), +profile_signal_perm (target_cred, profile, sender, +MAY_READ , &ad)); }
security/apparmor/lsm.c +52 -33
208 lines not on this page · raw message
security/apparmor/mount.c +55 -30
248 lines not on this page · raw message
security/apparmor/net.c +10 -7
@@ -135,8 +135,8 @@ int aa_profile_af_perm(struct aa_profile *profile,return aa_check_perms (profile, &perms, request, ad, audit_net_cb); } -int aa_af_perm (struct aa_label *label,const char *op,u32 request,u16 family, -int type,int protocol) +int aa_af_perm (const struct cred *subj_cred,struct aa_label *label, +const char *op,u32 request,u16 family,int type,int protocol) {struct aa_profile *profile;DEFINE_AUDIT_NET (ad, op,NULL , family, type, protocol);
@@ -146,7 +146,9 @@ int aa_af_perm(struct aa_label *label, const char *op, u32 request, u16 family, type)); } -static int aa_label_sk_perm (struct aa_label *label,const char *op,u32 request, +static int aa_label_sk_perm (const struct cred *subj_cred, +struct aa_label *label, +const char *op,u32 request,struct sock *sk) {struct aa_sk_ctx *ctx =SK_CTX (sk);
@@ -159,6 +161,7 @@ static int aa_label_sk_perm(struct aa_label *label, const char *op, u32 request,struct aa_profile *profile;DEFINE_AUDIT_SK (ad, op, sk); + ad.subj_cred = subj_cred; error =fn_for_each_confined (label, profile,aa_profile_af_sk_perm (profile, &ad, request, sk)); }
@@ -176,21 +179,21 @@ int aa_sk_perm(const char *op, u32 request, struct sock *sk)/* TODO: switch to begin_current_label ???? */ label =begin_current_label_crit_section (); - error =aa_label_sk_perm (label, op, request, sk); + error =aa_label_sk_perm (current_cred (), label, op, request, sk);end_current_label_crit_section (label);return error; } -int aa_sock_file_perm (struct aa_label *label,const char *op,u32 request, -struct socket *sock) +int aa_sock_file_perm (const struct cred *subj_cred,struct aa_label *label, +const char *op,u32 request,struct socket *sock) {AA_BUG (!label);AA_BUG (!sock);AA_BUG (!sock->sk); -return aa_label_sk_perm (label, op, request, sock->sk); +return aa_label_sk_perm (subj_cred, label, op, request, sock->sk); }#ifdef CONFIG_NETWORK_SECMARK
security/apparmor/policy.c +20 -13
@@ -762,21 +762,23 @@ static int audit_policy(struct aa_label *subj_label, const char *op,/* don't call out to other LSMs in the stack for apparmor policy admin * permissions */ -static int policy_ns_capable (struct aa_label *label, +static int policy_ns_capable (const struct cred *subj_cred, +struct aa_label *label,struct user_namespace *userns,int cap) {int err;/* check for MAC_ADMIN cap in cred */ - err =cap_capable (current_cred (), userns, cap,CAP_OPT_NONE ); + err =cap_capable (subj_cred, userns, cap,CAP_OPT_NONE );if (!err) - err =aa_capable (label, cap,CAP_OPT_NONE ); + err =aa_capable (subj_cred, label, cap,CAP_OPT_NONE );return err; }/** * aa_policy_view_capable - check if viewing policy in at @ns is allowed +* @subj_cred: cred of subject * @label: label that is trying to view policy in ns * @ns: namespace being viewed by @label (may be NULL if @label's ns) *
@@ -785,9 +787,10 @@ static int policy_ns_capable(struct aa_label *label,* If @ns is NULL then the namespace being viewed is assumed to be the * tasks current namespace. */ -bool aa_policy_view_capable (struct aa_label *label,struct aa_ns *ns) +bool aa_policy_view_capable (const struct cred *subj_cred, +struct aa_label *label,struct aa_ns *ns) { -struct user_namespace *user_ns =current_user_ns (); +struct user_namespace *user_ns = subj_cred->user_ns;struct aa_ns *view_ns =labels_view (label);bool root_in_user_ns =uid_eq (current_euid (),make_kuid (user_ns,0 )) ||in_egroup_p (make_kgid (user_ns,0 ));
@@ -804,15 +807,17 @@ bool aa_policy_view_capable(struct aa_label *label, struct aa_ns *ns)return response; } -bool aa_policy_admin_capable (struct aa_label *label,struct aa_ns *ns) +bool aa_policy_admin_capable (const struct cred *subj_cred, +struct aa_label *label,struct aa_ns *ns) { -struct user_namespace *user_ns =current_user_ns (); -bool capable =policy_ns_capable (label, user_ns,CAP_MAC_ADMIN ) ==0 ; +struct user_namespace *user_ns = subj_cred->user_ns; +bool capable =policy_ns_capable (subj_cred, label, user_ns, +CAP_MAC_ADMIN ) ==0 ;AA_DEBUG ("cap_mac_admin? %d\n" , capable);AA_DEBUG ("policy locked? %d\n" , aa_g_lock_policy); -return aa_policy_view_capable (label, ns) && capable && +return aa_policy_view_capable (subj_cred, label, ns) && capable && !aa_g_lock_policy; }
@@ -822,7 +827,7 @@ bool aa_current_policy_view_capable(struct aa_ns *ns)bool res; label =__begin_current_label_crit_section (); - res =aa_policy_view_capable (label, ns); + res =aa_policy_view_capable (current_cred (), label, ns);__end_current_label_crit_section (label);return res;
@@ -834,7 +839,7 @@ bool aa_current_policy_admin_capable(struct aa_ns *ns)bool res; label =__begin_current_label_crit_section (); - res =aa_policy_admin_capable (label, ns); + res =aa_policy_admin_capable (current_cred (), label, ns);__end_current_label_crit_section (label);return res;
@@ -842,13 +847,15 @@ bool aa_current_policy_admin_capable(struct aa_ns *ns)/** * aa_may_manage_policy - can the current task manage policy +* @subj_cred; subjects cred * @label: label to check if it can manage policy * @ns: namespace being managed by @label (may be NULL if @label's ns) * @mask: contains the policy manipulation operation being done * * Returns: 0 if the task is allowed to manipulate policy else error */ -int aa_may_manage_policy (struct aa_label *label,struct aa_ns *ns,u32 mask) +int aa_may_manage_policy (const struct cred *subj_cred,struct aa_label *label, +struct aa_ns *ns,u32 mask) {const char *op;
@@ -864,7 +871,7 @@ int aa_may_manage_policy(struct aa_label *label, struct aa_ns *ns, u32 mask)return audit_policy (label, op,NULL ,NULL ,"policy_locked" , -EACCES ); -if (!aa_policy_admin_capable (label, ns)) +if (!aa_policy_admin_capable (subj_cred, label, ns))return audit_policy (label, op,NULL ,NULL ,"not policy admin" , -EACCES );
security/apparmor/resource.c +15 -8
@@ -43,6 +43,7 @@ static void audit_cb(struct audit_buffer *ab, void *va)/** * audit_resource - audit setting resource limit +* @subj_cred: cred setting the resource * @profile: profile being enforced (NOT NULL) * @resource: rlimit being auditing * @value: value being set
@@ -52,13 +53,15 @@ static void audit_cb(struct audit_buffer *ab, void *va)* * Returns: 0 or ad->error else other error code on failure */ -static int audit_resource (struct aa_profile *profile,unsigned int resource, +static int audit_resource (const struct cred *subj_cred, +struct aa_profile *profile,unsigned int resource,unsigned long value,struct aa_label *peer,const char *info,int error) {DEFINE_AUDIT_DATA (ad,LSM_AUDIT_DATA_NONE ,AA_CLASS_RLIMITS ,OP_SETRLIMIT ); + ad.subj_cred = subj_cred; ad.rlim.rlim = resource; ad.rlim.max = value; ad.peer = peer;
@@ -82,7 +85,8 @@ int aa_map_resource(int resource)return rlim_map[resource]; } -static int profile_setrlimit (struct aa_profile *profile,unsigned int resource, +static int profile_setrlimit (const struct cred *subj_cred, +struct aa_profile *profile,unsigned int resource,struct rlimit *new_rlim) { struct aa_ruleset *rules = list_first_entry(&profile->rules,
@@ -92,12 +96,13 @@ static int profile_setrlimit(struct aa_profile *profile, unsigned int resource,if (rules->rlimits.mask & (1 << resource) && new_rlim->rlim_max > rules->rlimits.limits[resource].rlim_max) e = -EACCES ; -return audit_resource (profile, resource, new_rlim->rlim_max,NULL ,NULL , - e); +return audit_resource (subj_cred, profile, resource, new_rlim->rlim_max, +NULL ,NULL , e); }/** * aa_task_setrlimit - test permission to set an rlimit +* @subj_cred: cred setting the limit * @label: label confining the task (NOT NULL) * @task: task the resource is being set on * @resource: the resource being set
@@ -107,7 +112,8 @@ static int profile_setrlimit(struct aa_profile *profile, unsigned int resource,* * Returns: 0 or error code if setting resource failed */ -int aa_task_setrlimit (struct aa_label *label,struct task_struct *task, +int aa_task_setrlimit (const struct cred *subj_cred,struct aa_label *label, +struct task_struct *task,unsigned int resource,struct rlimit *new_rlim) {struct aa_profile *profile;
@@ -126,14 +132,15 @@ int aa_task_setrlimit(struct aa_label *label, struct task_struct *task,*/ if (label != peer && -aa_capable (label,CAP_SYS_RESOURCE ,CAP_OPT_NOAUDIT ) !=0 ) +aa_capable (subj_cred, label,CAP_SYS_RESOURCE ,CAP_OPT_NOAUDIT ) !=0 ) error =fn_for_each (label, profile, -audit_resource (profile, resource, +audit_resource (subj_cred, profile, resource, new_rlim->rlim_max, peer,"cap_sys_resource" , -EACCES ));else error =fn_for_each_confined (label, profile, -profile_setrlimit (profile, resource, new_rlim)); +profile_setrlimit (subj_cred, profile, resource, + new_rlim));aa_put_label (peer);return error;
security/apparmor/task.c +19 -12
@@ -226,14 +226,16 @@ static void audit_ptrace_cb(struct audit_buffer *ab, void *va)/* assumes check for RULE_MEDIATES is already done */ /* TODO: conditionals */ -static int profile_ptrace_perm (struct aa_profile *profile, -struct aa_label *peer,u32 request, -struct apparmor_audit_data *ad) +static int profile_ptrace_perm (const struct cred *cred, +struct aa_profile *profile, +struct aa_label *peer,u32 request, +struct apparmor_audit_data *ad) {struct aa_ruleset *rules =list_first_entry (&profile->rules,typeof (*rules), list);struct aa_perms perms = { }; + ad->subj_cred = cred; ad->peer = peer;aa_profile_match_label (profile, rules, peer,AA_CLASS_PTRACE , request, &perms);
@@ -241,7 +243,8 @@ static int profile_ptrace_perm(struct aa_profile *profile,return aa_check_perms (profile, &perms, request, ad, audit_ptrace_cb); } -static int profile_tracee_perm (struct aa_profile *tracee, +static int profile_tracee_perm (const struct cred *cred, +struct aa_profile *tracee,struct aa_label *tracer,u32 request,struct apparmor_audit_data *ad) {
@@ -249,10 +252,11 @@ static int profile_tracee_perm(struct aa_profile *tracee, !ANY_RULE_MEDIATES(&tracee->rules, AA_CLASS_PTRACE))return 0 ; -return profile_ptrace_perm (tracee, tracer, request, ad); +return profile_ptrace_perm (cred, tracee, tracer, request, ad); } -static int profile_tracer_perm (struct aa_profile *tracer, +static int profile_tracer_perm (const struct cred *cred, +struct aa_profile *tracer,struct aa_label *tracee,u32 request,struct apparmor_audit_data *ad) {
@@ -260,7 +264,7 @@ static int profile_tracer_perm(struct aa_profile *tracer,return 0 ;if (ANY_RULE_MEDIATES (&tracer->rules,AA_CLASS_PTRACE )) -return profile_ptrace_perm (tracer, tracee, request, ad); +return profile_ptrace_perm (cred, tracer, tracee, request, ad);/* profile uses the old style capability check for ptrace */ if (&tracer->label == tracee)
@@ -269,8 +273,8 @@ static int profile_tracer_perm(struct aa_profile *tracer, ad->subj_label = &tracer->label; ad->peer = tracee; ad->request =0 ; - ad->error =aa_capable (&tracer->label,CAP_SYS_PTRACE , -CAP_OPT_NONE ); + ad->error =aa_capable (cred, &tracer->label,CAP_SYS_PTRACE , +CAP_OPT_NONE );return aa_audit (AUDIT_APPARMOR_AUTO , tracer, ad, audit_ptrace_cb); }
@@ -283,7 +287,8 @@ static int profile_tracer_perm(struct aa_profile *tracer,* * Returns: %0 else error code if permission denied or error */ -int aa_may_ptrace (struct aa_label *tracer,struct aa_label *tracee, +int aa_may_ptrace (const struct cred *tracer_cred,struct aa_label *tracer, +const struct cred *tracee_cred,struct aa_label *tracee,u32 request) {struct aa_profile *profile;
@@ -291,6 +296,8 @@ int aa_may_ptrace(struct aa_label *tracer, struct aa_label *tracee,DEFINE_AUDIT_DATA (sa,LSM_AUDIT_DATA_NONE ,AA_CLASS_PTRACE ,OP_PTRACE );return xcheck_labels (tracer, tracee, profile, -profile_tracer_perm (profile, tracee, request, &sa), -profile_tracee_perm (profile, tracer, xrequest, &sa)); +profile_tracer_perm (tracer_cred, profile, tracee, + request, &sa), +profile_tracee_perm (tracee_cred, profile, tracer, + xrequest, &sa)); }
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 402/530 apparmor: Fix regression in mount mediation
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: John Johansen <[email protected]>
[ Upstream commit 157a3537d6bc28ceb9a11fc8cb67f2152d860146 ]
commit 2db154b3ea8e ("vfs: syscall: Add move_mount(2) to move mounts around")
introduced a new move_mount(2) system call and a corresponding new LSM security_move_mount hook but did not implement this hook for any existing LSM. This creates a regression for AppArmor mediation of mount. This patch provides a base mapping of the move_mount syscall to the existing mount mediation. In the future we may introduce additional mediations around the new mount calls.
--- security/apparmor/include/mount.h | 7 +++-- security/apparmor/lsm.c | 20 ++++++++++++-- security/apparmor/mount.c | 46 +++++++++++++++++++------------ 3 files changed, 51 insertions(+), 22 deletions(-)
security/apparmor/include/mount.h +5 -2
@@ -38,9 +38,12 @@ int aa_mount_change_type(const struct cred *subj_cred, struct aa_label *label, const struct path *path, unsigned long flags); +int aa_move_mount_old (const struct cred *subj_cred, +struct aa_label *label,const struct path *path, +const char *old_name);int aa_move_mount (const struct cred *subj_cred, -struct aa_label *label,const struct path *path, -const char *old_name); +struct aa_label *label,const struct path *from_path, +const struct path *to_path); int aa_new_mount(const struct cred *subj_cred, struct aa_label *label, const char *dev_name,
security/apparmor/lsm.c +18 -2
@@ -607,8 +607,8 @@ static int apparmor_sb_mount(const char *dev_name, const struct path *path, error =aa_mount_change_type (current_cred (), label, path, flags); else if (flags & MS_MOVE) - error =aa_move_mount (current_cred (), label, path, - dev_name); + error =aa_move_mount_old (current_cred (), label, path, + dev_name); else error =aa_new_mount (current_cred (), label, dev_name, path, type, flags, data);
@@ -618,6 +618,21 @@ static int apparmor_sb_mount(const char *dev_name, const struct path *path,return error; } +static int apparmor_move_mount (const struct path *from_path, +const struct path *to_path) +{ +struct aa_label *label; +int error =0 ; + + label =__begin_current_label_crit_section (); +if (!unconfined (label)) + error =aa_move_mount (current_cred (), label, from_path, + to_path); +__end_current_label_crit_section (label); + +return error; +} +static int apparmor_sb_umount (struct vfsmount *mnt,int flags) {struct aa_label *label;
@@ -1240,6 +1255,7 @@ static struct security_hook_list apparmor_hooks[] __ro_after_init = {LSM_HOOK_INIT (capget, apparmor_capget),LSM_HOOK_INIT (capable, apparmor_capable), +LSM_HOOK_INIT (move_mount, apparmor_move_mount),LSM_HOOK_INIT (sb_mount, apparmor_sb_mount),LSM_HOOK_INIT (sb_umount, apparmor_sb_umount), LSM_HOOK_INIT(sb_pivotroot, apparmor_sb_pivotroot),
security/apparmor/mount.c +28 -18
64 lines not on this page · raw message
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 403/530 Bluetooth: btusb: Add RTW8852BE device 13d3:3570 to device tables
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Masum Reza <[email protected]>
[ Upstream commit 02be109d3a405dbc4d53fb4b4473d7a113548088 ]
This device is used in TP-Link TX20E WiFi+Bluetooth adapter.
Relevant information in /sys/kernel/debug/usb/devices about the Bluetooth device is listed as the below.
T: Bus=01 Lev=01 Prnt=01 Port=08 Cnt=01 Dev#= 2 Spd=12 MxCh= 0 D: Ver= 1.00 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=13d3 ProdID=3570 Rev= 0.00 S: Manufacturer=Realtek S: Product=Bluetooth Radio S: SerialNumber=00e04c000001 C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=500mA I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms
Stable-dep-of: da06ff1f585e ("Bluetooth: btusb: Add 0bda:b85b for Fn-Link RTL8852BE")
--- drivers/bluetooth/btusb.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/bluetooth/btusb.c +2 -0
@@ -543,6 +543,8 @@ static const struct usb_device_id quirks_table[] = { BTUSB_WIDEBAND_SPEECH }, { USB_DEVICE(0x0bda, 0x887b), .driver_info = BTUSB_REALTEK | BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x13d3, 0x3570), .driver_info = BTUSB_REALTEK | + BTUSB_WIDEBAND_SPEECH }, { USB_DEVICE(0x13d3, 0x3571), .driver_info = BTUSB_REALTEK | BTUSB_WIDEBAND_SPEECH },
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 404/530 Bluetooth: btusb: Add 0bda:b85b for Fn-Link RTL8852BE
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guan Wentao <[email protected]>
[ Upstream commit da06ff1f585ea784c79f80e7fab0e0c4ebb49c1c ]
Add PID/VID 0bda:b85b for Realtek RTL8852BE USB bluetooth part. The PID/VID was reported by the patch last year. [1] Some SBCs like rockpi 5B A8 module contains the device. And it`s founded in website. [2] [3]
Here is the device tables in /sys/kernel/debug/usb/devices .
T: Bus=07 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#= 2 Spd=12 MxCh= 0 D: Ver= 1.00 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=0bda ProdID=b85b Rev= 0.00 S: Manufacturer=Realtek S: Product=Bluetooth Radio S: SerialNumber=00e04c000001 C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=500mA I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms
--- drivers/bluetooth/btusb.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/bluetooth/btusb.c +2 -0
@@ -543,6 +543,8 @@ static const struct usb_device_id quirks_table[] = { BTUSB_WIDEBAND_SPEECH }, { USB_DEVICE(0x0bda, 0x887b), .driver_info = BTUSB_REALTEK | BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x0bda, 0xb85b), .driver_info = BTUSB_REALTEK | + BTUSB_WIDEBAND_SPEECH }, { USB_DEVICE(0x13d3, 0x3570), .driver_info = BTUSB_REALTEK | BTUSB_WIDEBAND_SPEECH }, { USB_DEVICE(0x13d3, 0x3571), .driver_info = BTUSB_REALTEK |
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 405/530 drm/amd/display: enable dsc_clk even if dsc_pg disabled
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Muhammad Ahmed <[email protected]>
[ Upstream commit 40255df370e94d44f0f0a924400d68db0ee31bec ]
[why]
need to enable dsc_clk regardless dsc_pg
--- drivers/gpu/drm/amd/display/dc/core/dc.c | 8 ++++---- drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c | 3 +++ 2 files changed, 7 insertions(+), 4 deletions(-)
drivers/gpu/drm/amd/display/dc/core/dc.c +4 -4
@@ -1843,7 +1843,7 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *cif (dc->hwss.subvp_pipe_control_lock) dc->hwss.subvp_pipe_control_lock (dc, context, true, true,NULL , subvp_prev_use); -if (dc->debug.enable_double_buffered_dsc_pg_support) +if (dc->hwss.update_dsc_pg) dc->hwss.update_dsc_pg (dc, context, false);disable_dangling_plane (dc, context);
@@ -1950,7 +1950,7 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c dc->hwss.optimize_bandwidth (dc, context); } -if (dc->debug.enable_double_buffered_dsc_pg_support) +if (dc->hwss.update_dsc_pg) dc->hwss.update_dsc_pg (dc, context, true);if (dc->ctx->dce_version >=DCE_VERSION_MAX )
@@ -2197,7 +2197,7 @@ void dc_post_update_surfaces_to_stream(struct dc *dc) dc->hwss.optimize_bandwidth (dc, context); -if (dc->debug.enable_double_buffered_dsc_pg_support) +if (dc->hwss.update_dsc_pg) dc->hwss.update_dsc_pg (dc, context, true); }
@@ -3533,7 +3533,7 @@ static void commit_planes_for_stream(struct dc *dc,if (get_seamless_boot_stream_count (context) ==0 ) dc->hwss.prepare_bandwidth (dc, context); -if (dc->debug.enable_double_buffered_dsc_pg_support) +if (dc->hwss.update_dsc_pg) dc->hwss.update_dsc_pg (dc, context, false);context_clock_trace (dc, context);
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c +3 -0
@@ -77,6 +77,9 @@ void dcn32_dsc_pg_control(if (hws->ctx->dc->debug.disable_dsc_power_gate)return ; +if (!hws->ctx->dc->debug.enable_double_buffered_dsc_pg_support) +return ; +REG_GET (DC_IP_REQUEST_CNTL ,IP_REQUEST_EN , &org_ip_request_cntl);if (org_ip_request_cntl ==0 )REG_SET (DC_IP_REQUEST_CNTL ,0 ,IP_REQUEST_EN ,1 );
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 406/530 torture: Make torture_hrtimeout_ns() take an hrtimer mode parameter
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paul E. McKenney <[email protected]>
[ Upstream commit a741deac787f0d2d7068638c067db20af9e63752 ]
The current torture-test sleeps are waiting for a duration, but there are situations where it is better to wait for an absolute time, for example, when ending a stutter interval. This commit therefore adds an hrtimer mode parameter to torture_hrtimeout_ns(). Why not also the other torture_hrtimeout_*() functions? The theory is that most absolute times will be in nanoseconds, especially not (say) jiffies.
Stable-dep-of: cca42bd8eb1b ("rcutorture: Fix stuttering races and other issues")
--- include/linux/torture.h | 3 ++- kernel/torture.c | 13 +++++++------ 2 files changed, 9 insertions(+), 7 deletions(-)
include/linux/torture.h +2 -1
@@ -81,7 +81,8 @@ static inline void torture_random_init(struct torture_random_state *trsp) }/* Definitions for high-resolution-timer sleeps. */ -int torture_hrtimeout_ns (ktime_t baset_ns,u32 fuzzt_ns,struct torture_random_state *trsp); +int torture_hrtimeout_ns (ktime_t baset_ns,u32 fuzzt_ns,const enum hrtimer_mode mode, +struct torture_random_state *trsp);int torture_hrtimeout_us (u32 baset_us,u32 fuzzt_ns,struct torture_random_state *trsp);int torture_hrtimeout_ms (u32 baset_ms,u32 fuzzt_us,struct torture_random_state *trsp);int torture_hrtimeout_jiffies (u32 baset_j,struct torture_random_state *trsp);
kernel/torture.c +7 -6
@@ -87,14 +87,15 @@ EXPORT_SYMBOL_GPL(verbose_torout_sleep);* nanosecond random fuzz. This function and its friends desynchronize * testing from the timer wheel. */ -int torture_hrtimeout_ns (ktime_t baset_ns,u32 fuzzt_ns,struct torture_random_state *trsp) +int torture_hrtimeout_ns (ktime_t baset_ns,u32 fuzzt_ns,const enum hrtimer_mode mode, +struct torture_random_state *trsp) {ktime_t hto = baset_ns;if (trsp) hto +=torture_random (trsp) % fuzzt_ns;set_current_state (TASK_IDLE ); -return schedule_hrtimeout (&hto,HRTIMER_MODE_REL ); +return schedule_hrtimeout (&hto, mode); }EXPORT_SYMBOL_GPL (torture_hrtimeout_ns);
@@ -106,7 +107,7 @@ int torture_hrtimeout_us(u32 baset_us, u32 fuzzt_ns, struct torture_random_state {ktime_t baset_ns = baset_us *NSEC_PER_USEC ; -return torture_hrtimeout_ns (baset_ns, fuzzt_ns, trsp); +return torture_hrtimeout_ns (baset_ns, fuzzt_ns,HRTIMER_MODE_REL , trsp); }EXPORT_SYMBOL_GPL (torture_hrtimeout_us);
@@ -123,7 +124,7 @@ int torture_hrtimeout_ms(u32 baset_ms, u32 fuzzt_us, struct torture_random_state fuzzt_ns = (u32 )~0U ; else fuzzt_ns = fuzzt_us *NSEC_PER_USEC ; -return torture_hrtimeout_ns (baset_ns, fuzzt_ns, trsp); +return torture_hrtimeout_ns (baset_ns, fuzzt_ns,HRTIMER_MODE_REL , trsp); }EXPORT_SYMBOL_GPL (torture_hrtimeout_ms);
@@ -136,7 +137,7 @@ int torture_hrtimeout_jiffies(u32 baset_j, struct torture_random_state *trsp) {ktime_t baset_ns =jiffies_to_nsecs (baset_j); -return torture_hrtimeout_ns (baset_ns,jiffies_to_nsecs (1 ), trsp); +return torture_hrtimeout_ns (baset_ns,jiffies_to_nsecs (1 ),HRTIMER_MODE_REL , trsp); }EXPORT_SYMBOL_GPL (torture_hrtimeout_jiffies);
@@ -153,7 +154,7 @@ int torture_hrtimeout_s(u32 baset_s, u32 fuzzt_ms, struct torture_random_state * fuzzt_ns = (u32 )~0U ; else fuzzt_ns = fuzzt_ms *NSEC_PER_MSEC ; -return torture_hrtimeout_ns (baset_ns, fuzzt_ns, trsp); +return torture_hrtimeout_ns (baset_ns, fuzzt_ns,HRTIMER_MODE_REL , trsp); }EXPORT_SYMBOL_GPL (torture_hrtimeout_s);
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 407/530 rcutorture: Fix stuttering races and other issues
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joel Fernandes (Google) <[email protected]>
[ Upstream commit cca42bd8eb1b54a4c9bbf48c79d120e66619a3e4 ]
The stuttering code isn't functioning as expected. Ideally, it should pause the torture threads for a designated period before resuming. Yet, it fails to halt the test for the correct duration. Additionally, a race condition exists, potentially causing the stuttering code to pause for an extended period if the 'spt' variable is non-zero due to the stutter orchestration thread's inadequate CPU time.
Moreover, over-stuttering can hinder RCU's progress on TREE07 kernels. This happens as the stuttering code may run within a softirq due to RCU callbacks. Consequently, ksoftirqd keeps a CPU busy for several seconds, thus obstructing RCU's progress. This situation triggers a warning message in the logs:
[ 2169.481783] rcu_torture_writer: rtort_pipe_count: 9
This warning suggests that an RCU torture object, although invisible to RCU readers, couldn't make it past the pipe array and be freed -- a strong indication that there weren't enough grace periods during the stutter interval.
To address these issues, this patch sets the "stutter end" time to an absolute point in the future set by the main stutter thread. This is then used for waiting in stutter_wait(). While the stutter thread still defines this absolute time, the waiters' waiting logic doesn't rely on the stutter thread receiving sufficient CPU time to halt the stuttering as the halting is now self-controlled.
--- kernel/torture.c | 45 ++++++++++++--------------------------------- 1 file changed, 12 insertions(+), 33 deletions(-)
kernel/torture.c +12 -33
@@ -721,7 +721,7 @@ static void torture_shutdown_cleanup(void)* suddenly applied to or removed from the system. */ static struct task_struct *stutter_task; -static int stutter_pause_test; +static ktime_t stutter_till_abs_time;static int stutter;static int stutter_gap;
@@ -731,30 +731,16 @@ static int stutter_gap;*/ bool stutter_wait (const char *title) { -unsigned int i =0 ;bool ret = false; -int spt; +ktime_t till_ns;cond_resched_tasks_rcu_qs (); - spt =READ_ONCE (stutter_pause_test); -for (; spt; spt =READ_ONCE (stutter_pause_test)) { -if (!ret && !rt_task (current)) { -sched_set_normal (current,MAX_NICE ); - ret = true; - } -if (spt ==1 ) { -torture_hrtimeout_jiffies (1 ,NULL ); - }else if (spt ==2 ) { -while (READ_ONCE (stutter_pause_test)) { -if (!(i++ &0xffff )) -torture_hrtimeout_us (10 ,0 ,NULL ); -cond_resched (); - } - }else { -torture_hrtimeout_jiffies (round_jiffies_relative (HZ ),NULL ); - } -torture_shutdown_absorb (title); + till_ns =READ_ONCE (stutter_till_abs_time); +if (till_ns &&ktime_before (ktime_get (), till_ns)) { +torture_hrtimeout_ns (till_ns,0 ,HRTIMER_MODE_ABS ,NULL ); + ret = true; } +torture_shutdown_absorb (title);return ret; }EXPORT_SYMBOL_GPL (stutter_wait);
@@ -765,23 +751,16 @@ EXPORT_SYMBOL_GPL(stutter_wait);*/ static int torture_stutter (void *arg) { -DEFINE_TORTURE_RANDOM (rand); -int wtime; +ktime_t till_ns;VERBOSE_TOROUT_STRING ("torture_stutter task started" ); do { if (!torture_must_stop() && stutter > 1) { - wtime = stutter; - if (stutter > 2) { - WRITE_ONCE(stutter_pause_test, 1); - wtime = stutter - 3; - torture_hrtimeout_jiffies(wtime, &rand); - wtime = 2; - } - WRITE_ONCE(stutter_pause_test, 2); - torture_hrtimeout_jiffies(wtime, NULL); + till_ns = ktime_add_ns(ktime_get(), + jiffies_to_nsecs(stutter)); + WRITE_ONCE(stutter_till_abs_time, till_ns); + torture_hrtimeout_jiffies(stutter - 1, NULL); } - WRITE_ONCE(stutter_pause_test, 0); if (!torture_must_stop()) torture_hrtimeout_jiffies(stutter_gap, NULL); torture_shutdown_absorb("torture_stutter");
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 408/530 selftests/resctrl: Remove bw_report and bm_type from main()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ilpo Järvinen <[email protected]>
[ Upstream commit 47e36f16c7846bf3627ff68525e02555c53dc99e ]
bw_report is always set to "reads" and bm_type is set to "fill_buf" but is never used.
Set bw_report directly to "reads" in MBA/MBM test and remove bm_type.
Stable-dep-of: 3aff51464455 ("selftests/resctrl: Extend signal handler coverage to unmount on receiving signal")
--- tools/testing/selftests/resctrl/mba_test.c | 4 ++-- tools/testing/selftests/resctrl/mbm_test.c | 4 ++-- tools/testing/selftests/resctrl/resctrl.h | 4 ++-- .../testing/selftests/resctrl/resctrl_tests.c | 18 +++++++----------- 4 files changed, 13 insertions(+), 17 deletions(-)
tools/testing/selftests/resctrl/mba_test.c +2 -2
@@ -141,7 +141,7 @@ void mba_test_cleanup(void)remove (RESULT_FILE_NAME ); } -int mba_schemata_change (int cpu_no,char *bw_report,char **benchmark_cmd) +int mba_schemata_change (int cpu_no,char **benchmark_cmd) {struct resctrl_val_param param = { .resctrl_val =MBA_STR ,
@@ -149,7 +149,7 @@ int mba_schemata_change(int cpu_no, char *bw_report, char **benchmark_cmd) .mongrp = "m1", .cpu_no = cpu_no, .filename = RESULT_FILE_NAME, - .bw_report = bw_report, + .bw_report = "reads", .setup = mba_setup };int ret;
tools/testing/selftests/resctrl/mbm_test.c +2 -2
@@ -109,7 +109,7 @@ void mbm_test_cleanup(void)remove (RESULT_FILE_NAME ); } -int mbm_bw_change (size_t span,int cpu_no,char *bw_report,char **benchmark_cmd) +int mbm_bw_change (size_t span,int cpu_no,char **benchmark_cmd) {struct resctrl_val_param param = { .resctrl_val =MBM_STR ,
@@ -118,7 +118,7 @@ int mbm_bw_change(size_t span, int cpu_no, char *bw_report, char **benchmark_cmd .span = span, .cpu_no = cpu_no, .filename = RESULT_FILE_NAME, - .bw_report = bw_report, + .bw_report = "reads", .setup = mbm_setup };int ret;
tools/testing/selftests/resctrl/resctrl.h +2 -2
@@ -93,10 +93,10 @@ int perf_event_open(struct perf_event_attr *hw_event, pid_t pid, int cpu, int group_fd, unsigned long flags);int run_fill_buf (size_t span,int memflush,int op,bool once);int resctrl_val (char **benchmark_cmd,struct resctrl_val_param *param); -int mbm_bw_change (size_t span,int cpu_no,char *bw_report,char **benchmark_cmd); +int mbm_bw_change (size_t span,int cpu_no,char **benchmark_cmd);void tests_cleanup (void );void mbm_test_cleanup (void ); -int mba_schemata_change (int cpu_no,char *bw_report,char **benchmark_cmd); +int mba_schemata_change (int cpu_no,char **benchmark_cmd);void mba_test_cleanup (void );int get_cbm_mask (char *cache_type,char *cbm_mask);int get_cache_size (int cpu_no,char *cache_type,unsigned long *cache_size);
tools/testing/selftests/resctrl/resctrl_tests.c +7 -11
@@ -70,8 +70,7 @@ void tests_cleanup(void)cat_test_cleanup (); } -static void run_mbm_test (char **benchmark_cmd,size_t span, -int cpu_no,char *bw_report) +static void run_mbm_test (char **benchmark_cmd,size_t span,int cpu_no) {int res;
@@ -90,7 +89,7 @@ static void run_mbm_test(char **benchmark_cmd, size_t span, goto umount; } - res =mbm_bw_change (span, cpu_no, bw_report, benchmark_cmd); + res =mbm_bw_change (span, cpu_no, benchmark_cmd);ksft_test_result (!res,"MBM: bw change\n" );if ((get_vendor () ==ARCH_INTEL ) && res)ksft_print_msg ("Intel MBM may be inaccurate when Sub-NUMA Clustering is enabled. Check BIOS configuration.\n" );
@@ -99,7 +98,7 @@ static void run_mbm_test(char **benchmark_cmd, size_t span,umount_resctrlfs (); } -static void run_mba_test (char **benchmark_cmd,int cpu_no,char *bw_report) +static void run_mba_test (char **benchmark_cmd,int cpu_no) {int res;
@@ -118,7 +117,7 @@ static void run_mba_test(char **benchmark_cmd, int cpu_no, char *bw_report) goto umount; } - res =mba_schemata_change (cpu_no, bw_report, benchmark_cmd); + res =mba_schemata_change (cpu_no, benchmark_cmd);ksft_test_result (!res,"MBA: schemata change\n" ); umount:
@@ -179,9 +178,9 @@ static void run_cat_test(int cpu_no, int no_of_bits)int main (int argc,char **argv) {bool has_ben = false, mbm_test = true, mba_test = true, cmt_test = true; -char *benchmark_cmd[BENCHMARK_ARGS ], bw_report[64 ], bm_type[64 ];char benchmark_cmd_area[BENCHMARK_ARGS ][BENCHMARK_ARG_SIZE ];int c, cpu_no =1 , argc_new = argc, i, no_of_bits =0 ; +char *benchmark_cmd[BENCHMARK_ARGS ];int ben_ind, ben_count, tests =0 ;size_t span =250 *MB ;bool cat_test = true;
@@ -284,9 +283,6 @@ int main(int argc, char **argv) benchmark_cmd[5 ] =NULL ; } -sprintf (bw_report,"reads" ); -sprintf (bm_type,"fill_buf" ); -if (!check_resctrlfs_support ())return ksft_exit_skip ("resctrl FS does not exist. Enable X86_CPU_RESCTRL config option.\n" );
@@ -298,10 +294,10 @@ int main(int argc, char **argv)ksft_set_plan (tests ? :4 );if (mbm_test) -run_mbm_test (benchmark_cmd, span, cpu_no, bw_report); +run_mbm_test (benchmark_cmd, span, cpu_no);if (mba_test) -run_mba_test (benchmark_cmd, cpu_no, bw_report); +run_mba_test (benchmark_cmd, cpu_no);if (cmt_test)run_cmt_test (benchmark_cmd, cpu_no);
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 409/530 selftests/resctrl: Simplify span lifetime
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ilpo Järvinen <[email protected]>
[ Upstream commit b1a901e078c4ee4a6fe13021c4577ef5f3155251 ]
struct resctrl_val_param contains span member. resctrl_val(), however, never uses it because the value of span is embedded into the default benchmark command and parsed from it by run_benchmark().
Remove span from resctrl_val_param. Provide DEFAULT_SPAN for the code that needs it. CMT and CAT tests communicate span that is different from the DEFAULT_SPAN between their internal functions which is converted into passing it directly as a parameter.
Stable-dep-of: 3aff51464455 ("selftests/resctrl: Extend signal handler coverage to unmount on receiving signal")
--- tools/testing/selftests/resctrl/cache.c | 5 +++-- tools/testing/selftests/resctrl/cat_test.c | 13 +++++++------ tools/testing/selftests/resctrl/cmt_test.c | 11 ++++++----- tools/testing/selftests/resctrl/mbm_test.c | 5 ++--- tools/testing/selftests/resctrl/resctrl.h | 8 ++++---- tools/testing/selftests/resctrl/resctrl_tests.c | 9 ++++----- 6 files changed, 26 insertions(+), 25 deletions(-)
tools/testing/selftests/resctrl/cache.c +3 -2
@@ -205,10 +205,11 @@ int measure_cache_vals(struct resctrl_val_param *param, int bm_pid)* cache_val: execute benchmark and measure LLC occupancy resctrl * and perf cache miss for the benchmark * @param: parameters passed to cache_val() +* @span: buffer size for the benchmark * * Return: 0 on success. non-zero on failure. */ -int cat_val (struct resctrl_val_param *param) +int cat_val (struct resctrl_val_param *param,size_t span) {int memflush =1 , operation =0 , ret =0 ;char *resctrl_val = param->resctrl_val;
@@ -245,7 +246,7 @@ int cat_val(struct resctrl_val_param *param)if (ret)break ; -if (run_fill_buf (param->span, memflush, operation, true)) { +if (run_fill_buf (span, memflush, operation, true)) {fprintf (stderr,"Error-running fill buffer\n" ); ret =-1 ; goto pe_close;
tools/testing/selftests/resctrl/cat_test.c +7 -6
@@ -41,7 +41,7 @@ static int cat_setup(struct resctrl_val_param *p)return ret; } -static int check_results (struct resctrl_val_param *param) +static int check_results (struct resctrl_val_param *param,size_t span) {char *token_array[8 ], temp[512 ];unsigned long sum_llc_perf_miss =0 ;
@@ -76,7 +76,7 @@ static int check_results(struct resctrl_val_param *param)fclose (fp); no_of_bits =count_bits (param->mask); -return show_cache_info (sum_llc_perf_miss, no_of_bits, param->span /64 , +return show_cache_info (sum_llc_perf_miss, no_of_bits, span /64 ,MAX_DIFF ,MAX_DIFF_PERCENT , runs -1 ,get_vendor () ==ARCH_INTEL , false); }
@@ -96,6 +96,7 @@ int cat_perf_miss_val(int cpu_no, int n, char *cache_type)char cbm_mask[256 ];int count_of_bits;char pipe_message; +size_t span;/* Get default cbm mask for L3/L2 cache */ ret =get_cbm_mask (cache_type, cbm_mask);
@@ -140,7 +141,7 @@ int cat_perf_miss_val(int cpu_no, int n, char *cache_type)/* Set param values for parent thread which will be allocated bitmask * with (max_bits - n) bits */ - param.span = cache_size * (count_of_bits - n) / count_of_bits; + span = cache_size * (count_of_bits - n) / count_of_bits;strcpy (param.ctrlgrp,"c2" );strcpy (param.mongrp,"m2" );strcpy (param.filename,RESULT_FILE_NAME2 );
@@ -162,7 +163,7 @@ int cat_perf_miss_val(int cpu_no, int n, char *cache_type) param.mask = l_mask_1;strcpy (param.ctrlgrp,"c1" );strcpy (param.mongrp,"m1" ); - param.span = cache_size * n / count_of_bits; + span = cache_size * n / count_of_bits;strcpy (param.filename,RESULT_FILE_NAME1 ); param.num_of_runs =0 ; param.cpu_no = sibling_cpu_no;
@@ -176,9 +177,9 @@ int cat_perf_miss_val(int cpu_no, int n, char *cache_type)remove (param.filename); - ret =cat_val (¶m); + ret =cat_val (¶m, span);if (ret ==0 ) - ret =check_results (¶m); + ret =check_results (¶m, span);if (bm_pid ==0 ) {/* Tell parent that child is ready */
tools/testing/selftests/resctrl/cmt_test.c +6 -5
@@ -27,7 +27,7 @@ static int cmt_setup(struct resctrl_val_param *p)return 0 ; } -static int check_results (struct resctrl_val_param *param,int no_of_bits) +static int check_results (struct resctrl_val_param *param,size_t span,int no_of_bits) {char *token_array[8 ], temp[512 ];unsigned long sum_llc_occu_resc =0 ;
@@ -58,7 +58,7 @@ static int check_results(struct resctrl_val_param *param, int no_of_bits) }fclose (fp); -return show_cache_info (sum_llc_occu_resc, no_of_bits, param->span, +return show_cache_info (sum_llc_occu_resc, no_of_bits, span,MAX_DIFF ,MAX_DIFF_PERCENT , runs -1 , true, true); }
@@ -74,6 +74,7 @@ int cmt_resctrl_val(int cpu_no, int n, char **benchmark_cmd)unsigned long long_mask;char cbm_mask[256 ];int count_of_bits; +size_t span;int ret; ret =get_cbm_mask ("L3" , cbm_mask);
@@ -102,13 +103,13 @@ int cmt_resctrl_val(int cpu_no, int n, char **benchmark_cmd) .cpu_no = cpu_no, .filename = RESULT_FILE_NAME, .mask = ~(long_mask << n) & long_mask, - .span = cache_size * n / count_of_bits, .num_of_runs = 0, .setup = cmt_setup, }; + span = cache_size * n / count_of_bits;if (strcmp (benchmark_cmd[0 ],"fill_buf" ) ==0 ) -sprintf (benchmark_cmd[1 ],"%zu" , param.span); +sprintf (benchmark_cmd[1 ],"%zu" , span);remove (RESULT_FILE_NAME );
@@ -116,7 +117,7 @@ int cmt_resctrl_val(int cpu_no, int n, char **benchmark_cmd)if (ret) goto out; - ret =check_results (¶m, n); + ret =check_results (¶m, span, n); out:cmt_test_cleanup ();
tools/testing/selftests/resctrl/mbm_test.c +2 -3
@@ -109,13 +109,12 @@ void mbm_test_cleanup(void)remove (RESULT_FILE_NAME ); } -int mbm_bw_change (size_t span,int cpu_no,char **benchmark_cmd) +int mbm_bw_change (int cpu_no,char **benchmark_cmd) {struct resctrl_val_param param = { .resctrl_val =MBM_STR , .ctrlgrp ="c1" , .mongrp ="m1" , - .span = span, .cpu_no = cpu_no, .filename =RESULT_FILE_NAME , .bw_report ="reads" ,
@@ -129,7 +128,7 @@ int mbm_bw_change(size_t span, int cpu_no, char **benchmark_cmd)if (ret) goto out; - ret =check_results (span); + ret =check_results (DEFAULT_SPAN ); out:mbm_test_cleanup ();
tools/testing/selftests/resctrl/resctrl.h +4 -4
@@ -33,6 +33,8 @@#define END_OF_TESTS 1 +#define DEFAULT_SPAN (250 * MB) +#define PARENT_EXIT (err_msg) \ do { \ perror(err_msg); \
@@ -47,7 +49,6 @@* @ctrlgrp: Name of the control monitor group (con_mon grp) * @mongrp: Name of the monitor group (mon grp) * @cpu_no: CPU number to which the benchmark would be binded -* @span: Memory bytes accessed in each benchmark iteration * @filename: Name of file to which the o/p should be written * @bw_report: Bandwidth report type (reads vs writes) * @setup: Call back function to setup test environment
@@ -57,7 +58,6 @@ struct resctrl_val_param {char ctrlgrp[64 ];char mongrp[64 ];int cpu_no; -size_t span;char filename[64 ];char *bw_report;unsigned long mask;
@@ -93,7 +93,7 @@ int perf_event_open(struct perf_event_attr *hw_event, pid_t pid, int cpu, int group_fd, unsigned long flags);int run_fill_buf (size_t span,int memflush,int op,bool once);int resctrl_val (char **benchmark_cmd,struct resctrl_val_param *param); -int mbm_bw_change (size_t span,int cpu_no,char **benchmark_cmd); +int mbm_bw_change (int cpu_no,char **benchmark_cmd);void tests_cleanup (void );void mbm_test_cleanup (void );int mba_schemata_change (int cpu_no,char **benchmark_cmd);
@@ -103,7 +103,7 @@ int get_cache_size(int cpu_no, char *cache_type, unsigned long *cache_size);void ctrlc_handler (int signum,siginfo_t *info,void *ptr);int signal_handler_register (void );void signal_handler_unregister (void ); -int cat_val (struct resctrl_val_param *param); +int cat_val (struct resctrl_val_param *param,size_t span);void cat_test_cleanup (void );int cat_perf_miss_val (int cpu_no,int no_of_bits,char *cache_type);int cmt_resctrl_val (int cpu_no,int n,char **benchmark_cmd);
tools/testing/selftests/resctrl/resctrl_tests.c +4 -5
@@ -70,7 +70,7 @@ void tests_cleanup(void)cat_test_cleanup (); } -static void run_mbm_test (char **benchmark_cmd,size_t span,int cpu_no) +static void run_mbm_test (char **benchmark_cmd,int cpu_no) {int res;
@@ -89,7 +89,7 @@ static void run_mbm_test(char **benchmark_cmd, size_t span, int cpu_no) goto umount; } - res =mbm_bw_change (span, cpu_no, benchmark_cmd); + res =mbm_bw_change (cpu_no, benchmark_cmd);ksft_test_result (!res,"MBM: bw change\n" );if ((get_vendor () ==ARCH_INTEL ) && res)ksft_print_msg ("Intel MBM may be inaccurate when Sub-NUMA Clustering is enabled. Check BIOS configuration.\n" );
@@ -182,7 +182,6 @@ int main(int argc, char **argv)int c, cpu_no =1 , argc_new = argc, i, no_of_bits =0 ;char *benchmark_cmd[BENCHMARK_ARGS ];int ben_ind, ben_count, tests =0 ; -size_t span =250 *MB ;bool cat_test = true;for (i =0 ; i < argc; i++) {
@@ -276,7 +275,7 @@ int main(int argc, char **argv) benchmark_cmd[i] = benchmark_cmd_area[i];strcpy (benchmark_cmd[0 ],"fill_buf" ); -sprintf (benchmark_cmd[1 ],"%zu" , span); +sprintf (benchmark_cmd[1 ],"%u" ,DEFAULT_SPAN );strcpy (benchmark_cmd[2 ],"1" );strcpy (benchmark_cmd[3 ],"0" );strcpy (benchmark_cmd[4 ],"false" );
@@ -294,7 +293,7 @@ int main(int argc, char **argv)ksft_set_plan (tests ? :4 );if (mbm_test) -run_mbm_test (benchmark_cmd, span, cpu_no); +run_mbm_test (benchmark_cmd, cpu_no);if (mba_test)run_mba_test (benchmark_cmd, cpu_no);
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 410/530 selftests/resctrl: Make benchmark command const and build it with pointers
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ilpo Järvinen <[email protected]>
[ Upstream commit e33cb5702a9f287d829b0e9e6abe57f6a4aba6d2 ]
Benchmark command is used in multiple tests so it should not be mutated by the tests but CMT test alters span argument. Due to the order of tests (CMT test runs last), mutating the span argument in CMT test does not trigger any real problems currently.
Mark benchmark_cmd strings as const and setup the benchmark command using pointers. Because the benchmark command becomes const, the input arguments can be used directly. Besides being simpler, using the input arguments directly also removes the internal size restriction.
CMT test has to create a copy of the benchmark command before altering the benchmark command.
Stable-dep-of: 3aff51464455 ("selftests/resctrl: Extend signal handler coverage to unmount on receiving signal")
--- tools/testing/selftests/resctrl/cmt_test.c | 25 +++++++++--- tools/testing/selftests/resctrl/mba_test.c | 2 +- tools/testing/selftests/resctrl/mbm_test.c | 2 +- tools/testing/selftests/resctrl/resctrl.h | 10 +++-- .../testing/selftests/resctrl/resctrl_tests.c | 39 ++++++++----------- tools/testing/selftests/resctrl/resctrl_val.c | 10 ++++- 6 files changed, 53 insertions(+), 35 deletions(-)
tools/testing/selftests/resctrl/cmt_test.c +20 -5
@@ -68,14 +68,17 @@ void cmt_test_cleanup(void)remove (RESULT_FILE_NAME ); } -int cmt_resctrl_val (int cpu_no,int n,char **benchmark_cmd) +int cmt_resctrl_val (int cpu_no,int n,const char *const *benchmark_cmd) { +const char *const *cmd = benchmark_cmd; +const char *new_cmd[BENCHMARK_ARGS ];unsigned long cache_size =0 ;unsigned long long_mask; +char *span_str =NULL ;char cbm_mask[256 ];int count_of_bits;size_t span; -int ret; +int ret, i; ret =get_cbm_mask ("L3" , cbm_mask);if (ret)
@@ -108,12 +111,23 @@ int cmt_resctrl_val(int cpu_no, int n, char **benchmark_cmd) }; span = cache_size * n / count_of_bits; -if (strcmp (benchmark_cmd[0 ],"fill_buf" ) ==0 ) -sprintf (benchmark_cmd[1 ],"%zu" , span); + +if (strcmp (cmd[0 ],"fill_buf" ) ==0 ) { +/* Duplicate the command to be able to replace span in it */ +for (i =0 ; benchmark_cmd[i]; i++) + new_cmd[i] = benchmark_cmd[i]; + new_cmd[i] =NULL ; + + ret =asprintf (&span_str,"%zu" , span); +if (ret <0 ) +return -1 ; + new_cmd[1 ] = span_str; + cmd = new_cmd; + }remove (RESULT_FILE_NAME ); - ret =resctrl_val (benchmark_cmd, ¶m); + ret =resctrl_val (cmd, ¶m);if (ret) goto out;
@@ -121,6 +135,7 @@ int cmt_resctrl_val(int cpu_no, int n, char **benchmark_cmd) out:cmt_test_cleanup (); +free (span_str);return ret; }
tools/testing/selftests/resctrl/mba_test.c +1 -1
@@ -141,7 +141,7 @@ void mba_test_cleanup(void)remove (RESULT_FILE_NAME ); } -int mba_schemata_change (int cpu_no,char **benchmark_cmd) +int mba_schemata_change (int cpu_no,const char *const *benchmark_cmd) {struct resctrl_val_param param = { .resctrl_val =MBA_STR ,
tools/testing/selftests/resctrl/mbm_test.c +1 -1
@@ -109,7 +109,7 @@ void mbm_test_cleanup(void)remove (RESULT_FILE_NAME ); } -int mbm_bw_change (int cpu_no,char **benchmark_cmd) +int mbm_bw_change (int cpu_no,const char *const *benchmark_cmd) {struct resctrl_val_param param = { .resctrl_val =MBM_STR ,
tools/testing/selftests/resctrl/resctrl.h +6 -4
@@ -33,6 +33,8 @@#define END_OF_TESTS 1 +#define BENCHMARK_ARGS 64 +#define DEFAULT_SPAN (250 * MB)#define PARENT_EXIT (err_msg) \
@@ -92,11 +94,11 @@ int write_bm_pid_to_resctrl(pid_t bm_pid, char *ctrlgrp, char *mongrp,int perf_event_open (struct perf_event_attr *hw_event,pid_t pid,int cpu,int group_fd,unsigned long flags);int run_fill_buf (size_t span,int memflush,int op,bool once); -int resctrl_val (char **benchmark_cmd,struct resctrl_val_param *param); -int mbm_bw_change (int cpu_no,char **benchmark_cmd); +int resctrl_val (const char *const *benchmark_cmd,struct resctrl_val_param *param); +int mbm_bw_change (int cpu_no,const char *const *benchmark_cmd);void tests_cleanup (void );void mbm_test_cleanup (void ); -int mba_schemata_change (int cpu_no,char **benchmark_cmd); +int mba_schemata_change (int cpu_no,const char *const *benchmark_cmd);void mba_test_cleanup (void );int get_cbm_mask (char *cache_type,char *cbm_mask);int get_cache_size (int cpu_no,char *cache_type,unsigned long *cache_size);
@@ -106,7 +108,7 @@ void signal_handler_unregister(void);int cat_val (struct resctrl_val_param *param,size_t span);void cat_test_cleanup (void );int cat_perf_miss_val (int cpu_no,int no_of_bits,char *cache_type); -int cmt_resctrl_val (int cpu_no,int n,char **benchmark_cmd); +int cmt_resctrl_val (int cpu_no,int n,const char *const *benchmark_cmd);unsigned int count_bits (unsigned long n);void cmt_test_cleanup (void );int get_core_sibling (int cpu_no);
tools/testing/selftests/resctrl/resctrl_tests.c +17 -22
@@ -10,9 +10,6 @@*/ #include "resctrl.h" -#define BENCHMARK_ARGS 64 -#define BENCHMARK_ARG_SIZE 64 -static int detect_vendor (void ) {FILE *inf =fopen ("/proc/cpuinfo" ,"r" );
@@ -70,7 +67,7 @@ void tests_cleanup(void)cat_test_cleanup (); } -static void run_mbm_test (char **benchmark_cmd,int cpu_no) +static void run_mbm_test (const char *const *benchmark_cmd,int cpu_no) {int res;
@@ -98,7 +95,7 @@ static void run_mbm_test(char **benchmark_cmd, int cpu_no)umount_resctrlfs (); } -static void run_mba_test (char **benchmark_cmd,int cpu_no) +static void run_mba_test (const char *const *benchmark_cmd,int cpu_no) {int res;
@@ -124,7 +121,7 @@ static void run_mba_test(char **benchmark_cmd, int cpu_no)umount_resctrlfs (); } -static void run_cmt_test (char **benchmark_cmd,int cpu_no) +static void run_cmt_test (const char *const *benchmark_cmd,int cpu_no) {int res;
@@ -178,11 +175,12 @@ static void run_cat_test(int cpu_no, int no_of_bits)int main (int argc,char **argv) {bool has_ben = false, mbm_test = true, mba_test = true, cmt_test = true; -char benchmark_cmd_area[BENCHMARK_ARGS ][BENCHMARK_ARG_SIZE ];int c, cpu_no =1 , argc_new = argc, i, no_of_bits =0 ; -char *benchmark_cmd[BENCHMARK_ARGS ]; +const char *benchmark_cmd[BENCHMARK_ARGS ];int ben_ind, ben_count, tests =0 ; +char *span_str =NULL ;bool cat_test = true; +int ret;for (i =0 ; i < argc; i++) {if (strcmp (argv[i],"-b" ) ==0 ) {
@@ -262,23 +260,19 @@ int main(int argc, char **argv)ksft_exit_fail_msg ("Too long benchmark command.\n" );/* Extract benchmark command from command line. */ -for (i = ben_ind; i < argc; i++) { - benchmark_cmd[i - ben_ind] = benchmark_cmd_area[i]; -if (strlen (argv[i]) >=BENCHMARK_ARG_SIZE ) -ksft_exit_fail_msg ("Too long benchmark command argument.\n" ); -sprintf (benchmark_cmd[i - ben_ind],"%s" , argv[i]); - } +for (i =0 ; i < argc - ben_ind; i++) + benchmark_cmd[i] = argv[i + ben_ind]; benchmark_cmd[ben_count] =NULL ; }else {/* If no benchmark is given by "-b" argument, use fill_buf. */ -for (i =0 ; i <5 ; i++) - benchmark_cmd[i] = benchmark_cmd_area[i]; - -strcpy (benchmark_cmd[0 ],"fill_buf" ); -sprintf (benchmark_cmd[1 ],"%u" ,DEFAULT_SPAN ); -strcpy (benchmark_cmd[2 ],"1" ); -strcpy (benchmark_cmd[3 ],"0" ); -strcpy (benchmark_cmd[4 ],"false" ); + benchmark_cmd[0 ] ="fill_buf" ; + ret =asprintf (&span_str,"%u" ,DEFAULT_SPAN ); +if (ret <0 ) +ksft_exit_fail_msg ("Out of memory!\n" ); + benchmark_cmd[1 ] = span_str; + benchmark_cmd[2 ] ="1" ; + benchmark_cmd[3 ] ="0" ; + benchmark_cmd[4 ] ="false" ; benchmark_cmd[5 ] =NULL ; }
@@ -304,5 +298,6 @@ int main(int argc, char **argv)if (cat_test)run_cat_test (cpu_no, no_of_bits); +free (span_str);ksft_finished (); }
tools/testing/selftests/resctrl/resctrl_val.c +8 -2
@@ -629,7 +629,7 @@ measure_vals(struct resctrl_val_param *param, unsigned long *bw_resc_start)* * Return: 0 on success. non-zero on failure. */ -int resctrl_val (char **benchmark_cmd,struct resctrl_val_param *param) +int resctrl_val (const char *const *benchmark_cmd,struct resctrl_val_param *param) {char *resctrl_val = param->resctrl_val;unsigned long bw_resc_start =0 ;
@@ -710,7 +710,13 @@ int resctrl_val(char **benchmark_cmd, struct resctrl_val_param *param)if (ret) goto out; - value.sival_ptr = benchmark_cmd; +/* +* The cast removes constness but nothing mutates benchmark_cmd within +* the context of this process. At the receiving process, it becomes +* argv, which is mutable, on exec() but that's after fork() so it +* doesn't matter for the process running the tests. +*/ + value.sival_ptr = (void *)benchmark_cmd;/* Taskset benchmark to specified cpu */ ret =taskset_benchmark (bm_pid, param->cpu_no);
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 411/530 selftests/resctrl: Extend signal handler coverage to unmount on receiving signal
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ilpo Järvinen <[email protected]>
[ Upstream commit 3aff5146445582454c35900f3c0c972987cdd595 ]
Unmounting resctrl FS has been moved into the per test functions in resctrl_tests.c by commit caddc0fbe495 ("selftests/resctrl: Move resctrl FS mount/umount to higher level"). In case a signal (SIGINT, SIGTERM, or SIGHUP) is received, the running selftest is aborted by ctrlc_handler() which then unmounts resctrl fs before exiting. The current section between signal_handler_register() and signal_handler_unregister(), however, does not cover the entire duration when resctrl FS is mounted.
Move signal_handler_register() and signal_handler_unregister() calls from per test files into resctrl_tests.c to properly unmount resctrl fs. In order to not add signal_handler_register()/unregister() n times, create helpers test_prepare() and test_cleanup().
Do not call ksft_exit_fail_msg() in test_prepare() but only in the per test function to keep the control flow cleaner without adding calls to exit() deep into the call chain.
Adjust child process kill() call in ctrlc_handler() to only be invoked if the child was already forked.
--- tools/testing/selftests/resctrl/cat_test.c | 8 --- .../testing/selftests/resctrl/resctrl_tests.c | 69 ++++++++++++------- tools/testing/selftests/resctrl/resctrl_val.c | 22 +++--- 3 files changed, 55 insertions(+), 44 deletions(-)
tools/testing/selftests/resctrl/cat_test.c +0 -8
@@ -167,12 +167,6 @@ int cat_perf_miss_val(int cpu_no, int n, char *cache_type)strcpy (param.filename,RESULT_FILE_NAME1 ); param.num_of_runs =0 ; param.cpu_no = sibling_cpu_no; - }else { - ret =signal_handler_register (); -if (ret) { -kill (bm_pid,SIGKILL ); - goto out; - } }remove (param.filename);
@@ -209,10 +203,8 @@ int cat_perf_miss_val(int cpu_no, int n, char *cache_type) }close (pipefd[0 ]);kill (bm_pid,SIGKILL ); -signal_handler_unregister (); } -out:cat_test_cleanup ();return ret;
tools/testing/selftests/resctrl/resctrl_tests.c +45 -24
144 lines not on this page · raw message
tools/testing/selftests/resctrl/resctrl_val.c +10 -12
@@ -468,7 +468,9 @@ pid_t bm_pid, ppid;void ctrlc_handler (int signum,siginfo_t *info,void *ptr) { -kill (bm_pid,SIGKILL ); +/* Only kill child after bm_pid is set after fork() */ +if (bm_pid) +kill (bm_pid,SIGKILL );umount_resctrlfs ();tests_cleanup ();ksft_print_msg ("Ending\n\n" );
@@ -485,6 +487,8 @@ int signal_handler_register(void)struct sigaction sigact = {};int ret =0 ; + bm_pid =0 ; + sigact.sa_sigaction = ctrlc_handler;sigemptyset (&sigact.sa_mask); sigact.sa_flags =SA_SIGINFO ;
@@ -706,10 +710,6 @@ int resctrl_val(const char * const *benchmark_cmd, struct resctrl_val_param *parksft_print_msg ("Benchmark PID: %d\n" , bm_pid); - ret =signal_handler_register (); -if (ret) - goto out; -/* * The cast removes constness but nothing mutates benchmark_cmd within * the context of this process. At the receiving process, it becomes
@@ -721,19 +721,19 @@ int resctrl_val(const char * const *benchmark_cmd, struct resctrl_val_param *par/* Taskset benchmark to specified cpu */ ret =taskset_benchmark (bm_pid, param->cpu_no);if (ret) - goto unregister; + goto out;/* Write benchmark to specified control&monitoring grp in resctrl FS */ ret =write_bm_pid_to_resctrl (bm_pid, param->ctrlgrp, param->mongrp, resctrl_val);if (ret) - goto unregister; + goto out;if (!strncmp (resctrl_val,MBM_STR ,sizeof (MBM_STR )) || !strncmp (resctrl_val,MBA_STR ,sizeof (MBA_STR ))) { ret =initialize_mem_bw_imc ();if (ret) - goto unregister; + goto out;initialize_mem_bw_resctrl (param->ctrlgrp, param->mongrp, param->cpu_no, resctrl_val);
@@ -748,7 +748,7 @@ int resctrl_val(const char * const *benchmark_cmd, struct resctrl_val_param *par sizeof(pipe_message)) {perror ("# failed reading message from child process" );close (pipefd[0 ]); - goto unregister; + goto out; } }close (pipefd[0 ]);
@@ -757,7 +757,7 @@ int resctrl_val(const char * const *benchmark_cmd, struct resctrl_val_param *parif (sigqueue (bm_pid,SIGUSR1 , value) ==-1 ) {perror ("# sigqueue SIGUSR1 to child" ); ret = errno; - goto unregister; + goto out; }/* Give benchmark enough time to fully run */
@@ -786,8 +786,6 @@ int resctrl_val(const char * const *benchmark_cmd, struct resctrl_val_param *par } } -unregister: -signal_handler_unregister (); out:kill (bm_pid,SIGKILL );
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 412/530 parisc: Prevent booting 64-bit kernels on PA1.x machines
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Helge Deller <[email protected]>
commit a406b8b424fa01f244c1aab02ba186258448c36b upstream.
Bail out early with error message when trying to boot a 64-bit kernel on 32-bit machines. This fixes the previous commit to include the check for true 64-bit kernels as well.
--- arch/parisc/kernel/head.S | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
arch/parisc/kernel/head.S +2 -3
@@ -70,9 +70,8 @@ $bss_loop: stw,ma %arg2,4(%r1) stw,ma %arg3,4(%r1) -#if !defined(CONFIG_64BIT) && defined(CONFIG_PA20) - /* This 32-bit kernel was compiled for PA2.0 CPUs. Check current CPU - * and halt kernel if we detect a PA1.x CPU. */ +#if defined(CONFIG_PA20) + /* check for 64-bit capable CPU as required by current kernel */ ldi 32,%r10 mtctl %r10,%cr11 .level 2.0
Greg Kroah-Hartman
maintainerPATCH 413/530 parisc/pgtable: Do not drop upper 5 address bits of physical address
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Helge Deller <[email protected]>
commit 166b0110d1ee53290bd11618df6e3991c117495a upstream.
When calculating the pfn for the iitlbt/idtlbt instruction, do not drop the upper 5 address bits. This doesn't seem to have an effect on physical hardware which uses less physical address bits, but in qemu the missing bits are visible.
--- arch/parisc/kernel/entry.S | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
arch/parisc/kernel/entry.S +3 -4
@@ -475,13 +475,13 @@ * to a CPU TLB 4k PFN (4k => 12 bits to shift) */ #define PAGE_ADD_SHIFT (PAGE_SHIFT-12) #define PAGE_ADD_HUGE_SHIFT (REAL_HPAGE_SHIFT-12) + #define PFN_START_BIT (63-ASM_PFN_PTE_SHIFT+(63-58)-PAGE_ADD_SHIFT) /* Drop prot bits and convert to page addr for iitlbt and idtlbt */ .macro convert_for_tlb_insert20 pte,tmp #ifdef CONFIG_HUGETLB_PAGE copy \pte,\tmp - extrd,u \tmp,(63-ASM_PFN_PTE_SHIFT)+(63-58)+PAGE_ADD_SHIFT,\ - 64-PAGE_SHIFT-PAGE_ADD_SHIFT,\pte + extrd,u \tmp,PFN_START_BIT,PFN_START_BIT+1,\pte depdi _PAGE_SIZE_ENCODING_DEFAULT,63,\ (63-58)+PAGE_ADD_SHIFT,\pte
@@ -489,8 +489,7 @@ depdi _HUGE_PAGE_SIZE_ENCODING_DEFAULT,63,\ (63-58)+PAGE_ADD_HUGE_SHIFT,\pte #else /* Huge pages disabled */ - extrd,u \pte,(63-ASM_PFN_PTE_SHIFT)+(63-58)+PAGE_ADD_SHIFT,\ - 64-PAGE_SHIFT-PAGE_ADD_SHIFT,\pte + extrd,u \pte,PFN_START_BIT,PFN_START_BIT+1,\pte depdi _PAGE_SIZE_ENCODING_DEFAULT,63,\ (63-58)+PAGE_ADD_SHIFT,\pte #endif
Greg Kroah-Hartman
maintainerPATCH 414/530 parisc/power: Fix power soft-off when running on qemu
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Helge Deller <[email protected]>
commit 6ad6e15a9c46b8f0932cd99724f26f3db4db1cdf upstream.
Firmware returns the physical address of the power switch, so need to use gsc_writel() instead of direct memory access.
--- drivers/parisc/power.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/parisc/power.c +1 -1
@@ -201,7 +201,7 @@ static struct notifier_block parisc_panistatic int qemu_power_off (struct sys_off_data *data) {/* this turns the system off via SeaBIOS */ - *(int *)data->cb_data =0 ; +gsc_writel (0 , (unsigned long ) data->cb_data);pdc_soft_power_button (1 );return NOTIFY_DONE ; }
Greg Kroah-Hartman
maintainerPATCH 415/530 parisc: fix mmap_base calculation when stack grows upwards
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Helge Deller <[email protected]>
commit 5f74f820f6fc844b95f9e5e406e0a07d97510420 upstream.
Matoro reported various userspace crashes on the parisc platform with kernel 6.6 and bisected it to commit 3033cd430768 ("parisc: Use generic mmap top-down layout and brk randomization").
That commit switched parisc to use the common infrastructure to calculate mmap_base, but missed that the mmap_base() function takes care for architectures where the stack grows downwards only.
Fix the mmap_base() calculation to include the stack-grows-upwards case and thus fix the userspace crashes on parisc.
--- arch/parisc/Kconfig | 6 +++--- arch/parisc/include/asm/elf.h | 10 +--------- arch/parisc/include/asm/processor.h | 2 ++ arch/parisc/kernel/sys_parisc.c | 2 +- mm/util.c | 10 ++++++++++ 5 files changed, 17 insertions(+), 13 deletions(-)
arch/parisc/Kconfig +3 -3
@@ -138,11 +138,11 @@ config ARCH_MMAP_RND_COMPAT_BITS_MIN default 8 config ARCH_MMAP_RND_BITS_MAX - default 24 if 64BIT - default 17 + default 18 if 64BIT + default 13 config ARCH_MMAP_RND_COMPAT_BITS_MAX - default 17 + default 13 # unless you want to implement ACPI on PA-RISC ... ;-) config PM
arch/parisc/include/asm/elf.h +1 -9
@@ -349,15 +349,7 @@ struct pt_regs; /* forward declaration..#define ELF_HWCAP 0 -/* Masks for stack and mmap randomization */ -#define BRK_RND_MASK (is_32bit_task() ? 0x07ffUL : 0x3ffffUL) -#define MMAP_RND_MASK (is_32bit_task() ? 0x1fffUL : 0x3ffffUL) -#define STACK_RND_MASK MMAP_RND_MASK - -struct mm_struct ; -extern unsigned long arch_randomize_brk (struct mm_struct *); -#define arch_randomize_brk arch_randomize_brk - +#define STACK_RND_MASK 0x7ff/* 8MB of VA */ #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1struct linux_binprm ;
arch/parisc/include/asm/processor.h +2 -0
@@ -47,6 +47,8 @@#ifndef __ASSEMBLY__ +struct rlimit ; +unsigned long mmap_upper_limit (struct rlimit *rlim_stack);unsigned long calc_max_stack_size (unsigned long stack_max);/*
arch/parisc/kernel/sys_parisc.c +1 -1
@@ -77,7 +77,7 @@ unsigned long calc_max_stack_size(unsign* indicating that "current" should be used instead of a passed-in * value from the exec bprm as done with arch_pick_mmap_layout(). */ -static unsigned long mmap_upper_limit (struct rlimit *rlim_stack) +unsigned long mmap_upper_limit (struct rlimit *rlim_stack) {unsigned long stack_base;
mm/util.c +10 -0
@@ -414,6 +414,15 @@ static int mmap_is_legacy(struct rlimitstatic unsigned long mmap_base (unsigned long rnd,struct rlimit *rlim_stack) { +#ifdef CONFIG_STACK_GROWSUP +/* +* For an upwards growing stack the calculation is much simpler. +* Memory for the maximum stack size is reserved at the top of the +* task. mmap_base starts directly below the stack and grows +* downwards. +*/ +return PAGE_ALIGN_DOWN (mmap_upper_limit (rlim_stack) - rnd); +#else unsigned long gap = rlim_stack->rlim_cur;unsigned long pad = stack_guard_gap;
@@ -431,6 +440,7 @@ static unsigned long mmap_base(unsigned gap =MAX_GAP ;return PAGE_ALIGN (STACK_TOP - gap - rnd); +#endif }void arch_pick_mmap_layout (struct mm_struct *mm,struct rlimit *rlim_stack)
Greg Kroah-Hartman
maintainerPATCH 416/530 xhci: Enable RPM on controllers that support low-power states
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Basavaraj Natikar <[email protected]>
commit a5d6264b638efeca35eff72177fd28d149e0764b upstream.
Use the low-power states of the underlying platform to enable runtime PM. If the platform doesn't support runtime D3, then enabling default RPM will result in the controller malfunctioning, as in the case of hotplug devices not being detected because of a failed interrupt generation.
--- drivers/usb/host/xhci-pci.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/usb/host/xhci-pci.c +3 -1
@@ -695,7 +695,9 @@ static int xhci_pci_probe(struct pci_dev/* USB-2 and USB-3 roothubs initialized, allow runtime pm suspend */ pm_runtime_put_noidle (&dev->dev); -if (xhci->quirks &XHCI_DEFAULT_PM_RUNTIME_ALLOW ) +if (pci_choose_state (dev,PMSG_SUSPEND ) ==PCI_D0 ) +pm_runtime_forbid (&dev->dev); +else if (xhci->quirks &XHCI_DEFAULT_PM_RUNTIME_ALLOW )pm_runtime_allow (&dev->dev);dma_set_max_seg_size (&dev->dev,UINT_MAX );
Greg Kroah-Hartman
maintainerPATCH 417/530 smb3: fix creating FIFOs when mounting with "sfu" mount option
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steve French <[email protected]>
commit 72bc63f5e23a38b65ff2a201bdc11401d4223fa9 upstream.
Fixes some xfstests including generic/564 and generic/157
The "sfu" mount option can be useful for creating special files (character and block devices in particular) but could not create FIFOs. It did recognize existing empty files with the "system" attribute flag as FIFOs but this is too general, so to support creating FIFOs more safely use a new tag (but the same length as those for char and block devices ie "IntxLNK" and "IntxBLK") "LnxFIFO" to indicate that the file should be treated as a
FIFO (when mounted with the "sfu"). For some additional context note that
"sfu" followed the way that "Services for Unix" on Windows handled these special files (at least for character and block devices and symlinks), which is different than newer Windows which can handle special files as reparse points (which isn't an option to many servers).
--- fs/smb/client/cifspdu.h | 2 +- fs/smb/client/inode.c | 4 ++++ fs/smb/client/smb2ops.c | 8 +++++++- 3 files changed, 12 insertions(+), 2 deletions(-)
fs/smb/client/cifspdu.h +1 -1
@@ -2570,7 +2570,7 @@ typedef struct {struct win_dev { -unsigned char type[8 ];/* IntxCHR or IntxBLK */ +unsigned char type[8 ];/* IntxCHR or IntxBLK or LnxFIFO*/ __le64 major;__le64 minor; } __attribute__((packed));
fs/smb/client/inode.c +4 -0
@@ -592,6 +592,10 @@ cifs_sfu_type(struct cifs_fattr *fattr,cifs_dbg (FYI ,"Symlink\n" ); fattr->cf_mode |=S_IFLNK ; fattr->cf_dtype =DT_LNK ; + }else if (memcmp ("LnxFIFO" , pbuf,8 ) ==0 ) { +cifs_dbg (FYI ,"FIFO\n" ); + fattr->cf_mode |=S_IFIFO ; + fattr->cf_dtype =DT_FIFO ; }else { fattr->cf_mode |=S_IFREG ;/* file? */ fattr->cf_dtype =DT_REG ;
fs/smb/client/smb2ops.c +7 -1
@@ -5087,7 +5087,7 @@ smb2_make_node(unsigned int xid, struct* over SMB2/SMB3 and Samba will do this with SMB3.1.1 POSIX Extensions */ -if (!S_ISCHR (mode) && !S_ISBLK (mode)) +if (!S_ISCHR (mode) && !S_ISBLK (mode) && !S_ISFIFO (mode))return rc;cifs_dbg (FYI ,"sfu compat create special file\n" );
@@ -5135,6 +5135,12 @@ smb2_make_node(unsigned int xid, struct pdev->minor =cpu_to_le64 (MINOR (dev)); rc = tcon->ses->server->ops->sync_write (xid, &fid, &io_parms, &bytes_written, iov,1 ); + }else if (S_ISFIFO (mode)) { +memcpy (pdev->type,"LnxFIFO" ,8 ); + pdev->major =0 ; + pdev->minor =0 ; + rc = tcon->ses->server->ops->sync_write (xid, &fid, &io_parms, + &bytes_written, iov,1 ); } tcon->ses->server->ops->close (xid, tcon, &fid);d_drop (dentry);
Greg Kroah-Hartman
maintainerPATCH 418/530 smb3: fix touch -h of symlink
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steve French <[email protected]>
commit 475efd9808a3094944a56240b2711349e433fb66 upstream.
For example:
touch -h -t 02011200 testfile
where testfile is a symlink would not change the timestamp, but
touch -t 02011200 testfiledoes work to change the timestamp of the target
--- fs/smb/client/cifsfs.c | 1 + 1 file changed, 1 insertion(+)
fs/smb/client/cifsfs.c +1 -0
@@ -1191,6 +1191,7 @@ const char *cifs_get_link(struct dentryconst struct inode_operations cifs_symlink_inode_ops = { .get_link = cifs_get_link, + .setattr = cifs_setattr, .permission = cifs_permission, .listxattr = cifs_listxattr, };
Greg Kroah-Hartman
maintainerPATCH 419/530 smb3: allow dumping session and tcon id to improve stats analysis and debugging
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steve French <[email protected]>
commit de4eceab578ead12a71e5b5588a57e142bbe8ceb upstream.
When multiple mounts are to the same share from the same client it was not possible to determine which section of /proc/fs/cifs/Stats (and DebugData) correspond to that mount. In some recent examples this turned out to be a significant problem when trying to analyze performance data - since there are many cases where unless we know the tree id and session id we can't figure out which stats (e.g. number of SMB3.1.1 requests by type, the total time they take, which is slowest, how many fail etc.) apply to which mount. The only existing loosely related ioctl CIFS_IOC_GET_MNT_INFO does not return the information needed to uniquely identify which tcon is which mount although it does return various flags and device info.
Add a cifs.ko ioctl CIFS_IOC_GET_TCON_INFO (0x800ccf0c) to return tid, session id, tree connect count.
--- fs/smb/client/cifs_ioctl.h | 6 ++++++ fs/smb/client/ioctl.c | 25 +++++++++++++++++++++++++ 2 files changed, 31 insertions(+)
fs/smb/client/cifs_ioctl.h +6 -0
@@ -26,6 +26,11 @@ struct smb_mnt_fs_info {__u64 cifs_posix_caps; } __packed; +struct smb_mnt_tcon_info { +__u32 tid; +__u64 session_id; +} __packed; +struct smb_snapshot_array {__u32 number_of_snapshots;__u32 number_of_snapshots_returned;
@@ -108,6 +113,7 @@ struct smb3_notify_info {#define CIFS_IOC_NOTIFY _IOW(CIFS_IOCTL_MAGIC, 9, struct smb3_notify)#define CIFS_DUMP_FULL_KEY _IOWR(CIFS_IOCTL_MAGIC, 10, struct smb3_full_key_debug_info)#define CIFS_IOC_NOTIFY_INFO _IOWR(CIFS_IOCTL_MAGIC, 11, struct smb3_notify_info) +#define CIFS_IOC_GET_TCON_INFO _IOR(CIFS_IOCTL_MAGIC, 12, struct smb_mnt_tcon_info)#define CIFS_IOC_SHUTDOWN _IOR('X', 125, __u32)/*
fs/smb/client/ioctl.c +25 -0
@@ -117,6 +117,20 @@ out_drop_write:return rc; } +static long smb_mnt_get_tcon_info (struct cifs_tcon *tcon,void __user *arg) +{ +int rc =0 ; +struct smb_mnt_tcon_info tcon_inf; + + tcon_inf.tid = tcon->tid; + tcon_inf.session_id = tcon->ses->Suid; + +if (copy_to_user (arg, &tcon_inf,sizeof (struct smb_mnt_tcon_info ))) + rc = -EFAULT ; + +return rc; +} +static long smb_mnt_get_fsinfo (unsigned int xid,struct cifs_tcon *tcon,void __user *arg) {
@@ -414,6 +428,17 @@ long cifs_ioctl(struct file *filep, unsi tcon =tlink_tcon (pSMBFile->tlink); rc =smb_mnt_get_fsinfo (xid, tcon, (void __user *)arg);break ; +case CIFS_IOC_GET_TCON_INFO : + cifs_sb =CIFS_SB (inode->i_sb); + tlink =cifs_sb_tlink (cifs_sb); +if (IS_ERR (tlink)) { + rc =PTR_ERR (tlink); +break ; + } + tcon =tlink_tcon (tlink); + rc =smb_mnt_get_tcon_info (tcon, (void __user *)arg); +cifs_put_tlink (tlink); +break ;case CIFS_ENUMERATE_SNAPSHOTS :if (pSMBFile ==NULL )break ;
Greg Kroah-Hartman
maintainerPATCH 420/530 smb3: fix caching of ctime on setxattr
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steve French <[email protected]>
commit 5923d6686a100c2b4cabd4c2ca9d5a12579c7614 upstream.
Fixes xfstest generic/728 which had been failing due to incorrect ctime after setxattr and removexattr
Update ctime on successful set of xattr
--- fs/smb/client/xattr.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
fs/smb/client/xattr.c +4 -1
@@ -150,10 +150,13 @@ static int cifs_xattr_set(const struct xif (cifs_sb->mnt_cifs_flags &CIFS_MOUNT_NO_XATTR ) goto out; -if (pTcon->ses->server->ops->set_EA) +if (pTcon->ses->server->ops->set_EA) { rc = pTcon->ses->server->ops->set_EA (xid, pTcon, full_path, name, value, (__u16 )size, cifs_sb->local_nls, cifs_sb); +if (rc ==0 ) +inode_set_ctime_current (inode); + }break ;case XATTR_CIFS_ACL :
Greg Kroah-Hartman
maintainerPATCH 421/530 smb: client: fix use-after-free bug in cifs_debug_data_proc_show()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paulo Alcantara <[email protected]>
commit d328c09ee9f15ee5a26431f5aad7c9239fa85e62 upstream.
Skip SMB sessions that are being teared down
(e.g. @ses->ses_status == SES_EXITING) in cifs_debug_data_proc_show() to avoid use-after-free in @ses.
This fixes the following GPF when reading from /proc/fs/cifs/DebugData while mounting and umounting
[ 816.251274] general protection fault, probably for non-canonical address 0x6b6b6b6b6b6b6d81: 0000 [#1] PREEMPT SMP NOPTI ... [ 816.260138] Call Trace: [ 816.260329] <TASK> [ 816.260499] ? die_addr+0x36/0x90 [ 816.260762] ? exc_general_protection+0x1b3/0x410 [ 816.261126] ? asm_exc_general_protection+0x26/0x30 [ 816.261502] ? cifs_debug_tcon+0xbd/0x240 [cifs] [ 816.261878] ? cifs_debug_tcon+0xab/0x240 [cifs] [ 816.262249] cifs_debug_data_proc_show+0x516/0xdb0 [cifs] [ 816.262689] ? seq_read_iter+0x379/0x470 [ 816.262995] seq_read_iter+0x118/0x470 [ 816.263291] proc_reg_read_iter+0x53/0x90 [ 816.263596] ? srso_alias_return_thunk+0x5/0x7f [ 816.263945] vfs_read+0x201/0x350 [ 816.264211] ksys_read+0x75/0x100 [ 816.264472] do_syscall_64+0x3f/0x90 [ 816.264750] entry_SYSCALL_64_after_hwframe+0x6e/0xd8 [ 816.265135] RIP: 0033:0x7fd5e669d381
--- fs/smb/client/cifs_debug.c | 6 ++++++ 1 file changed, 6 insertions(+)
fs/smb/client/cifs_debug.c +6 -0
@@ -452,6 +452,11 @@ skip_rdma:seq_printf (m,"\n\n\tSessions: " ); i =0 ;list_for_each_entry (ses, &server->smb_ses_list, smb_ses_list) { +spin_lock (&ses->ses_lock); +if (ses->ses_status ==SES_EXITING ) { +spin_unlock (&ses->ses_lock); +continue ; + } i++; if ((ses->serverDomain == NULL) || (ses->serverOS == NULL) ||
@@ -472,6 +477,7 @@ skip_rdma: ses->ses_count, ses->serverOS, ses->serverNOS, ses->capabilities, ses->ses_status); } +spin_unlock (&ses->ses_lock);seq_printf (m,"\n\tSecurity type: %s " ,get_security_type_str (server->ops->select_sectype (server, ses->sectype)));
Greg Kroah-Hartman
maintainerPATCH 422/530 smb: client: fix use-after-free in smb2_query_info_compound()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paulo Alcantara <[email protected]>
commit 5c86919455c1edec99ebd3338ad213b59271a71b upstream.
The following UAF was triggered when running fstests generic/072 with KASAN enabled against Windows Server 2022 and mount options 'multichannel,max_channels=2,vers=3.1.1,mfsymlinks,noperm'
BUG: KASAN: slab-use-after-free in smb2_query_info_compound+0x423/0x6d0 [cifs] Read of size 8 at addr ffff888014941048 by task xfs_io/27534 CPU: 0 PID: 27534 Comm: xfs_io Not tainted 6.6.0-rc7 #1 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.16.2-3-gd478f380-rebuilt.opensuse.org 04/01/2014 Call Trace: dump_stack_lvl+0x4a/0x80 print_report+0xcf/0x650 ? srso_alias_return_thunk+0x5/0x7f ? srso_alias_return_thunk+0x5/0x7f ? __phys_addr+0x46/0x90 kasan_report+0xda/0x110 ? smb2_query_info_compound+0x423/0x6d0 [cifs] ? smb2_query_info_compound+0x423/0x6d0 [cifs] smb2_query_info_compound+0x423/0x6d0 [cifs] ? __pfx_smb2_query_info_compound+0x10/0x10 [cifs] ? srso_alias_return_thunk+0x5/0x7f ? __stack_depot_save+0x39/0x480 ? kasan_save_stack+0x33/0x60 ? kasan_set_track+0x25/0x30 ? ____kasan_slab_free+0x126/0x170 smb2_queryfs+0xc2/0x2c0 [cifs] ? __pfx_smb2_queryfs+0x10/0x10 [cifs] ? __pfx___lock_acquire+0x10/0x10 smb311_queryfs+0x210/0x220 [cifs] ? __pfx_smb311_queryfs+0x10/0x10 [cifs] ? srso_alias_return_thunk+0x5/0x7f ? __lock_acquire+0x480/0x26c0 ? lock_release+0x1ed/0x640 ? srso_alias_return_thunk+0x5/0x7f ? do_raw_spin_unlock+0x9b/0x100 cifs_statfs+0x18c/0x4b0 [cifs] statfs_by_dentry+0x9b/0xf0 fd_statfs+0x4e/0xb0 __do_sys_fstatfs+0x7f/0xe0 ? __pfx___do_sys_fstatfs+0x10/0x10 ? srso_alias_return_thunk+0x5/0x7f ? lockdep_hardirqs_on_prepare+0x136/0x200 ? srso_alias_return_thunk+0x5/0x7f do_syscall_64+0x3f/0x90 entry_SYSCALL_64_after_hwframe+0x6e/0xd8 Allocated by task 27534: kasan_save_stack+0x33/0x60 kasan_set_track+0x25/0x30 __kasan_kmalloc+0x8f/0xa0 open_cached_dir+0x71b/0x1240 [cifs] smb2_query_info_compound+0x5c3/0x6d0 [cifs] smb2_queryfs+0xc2/0x2c0 [cifs] smb311_queryfs+0x210/0x220 [cifs] cifs_statfs+0x18c/0x4b0 [cifs] statfs_by_dentry+0x9b/0xf0 fd_statfs+0x4e/0xb0 __do_sys_fstatfs+0x7f/0xe0 do_syscall_64+0x3f/0x90 entry_SYSCALL_64_after_hwframe+0x6e/0xd8 Freed by task 27534: kasan_save_stack+0x33/0x60 kasan_set_track+0x25/0x30 kasan_save_free_info+0x2b/0x50 ____kasan_slab_free+0x126/0x170 slab_free_freelist_hook+0xd0/0x1e0 __kmem_cache_free+0x9d/0x1b0 open_cached_dir+0xff5/0x1240 [cifs] smb2_query_info_compound+0x5c3/0x6d0 [cifs] smb2_queryfs+0xc2/0x2c0 [cifs]
This is a race between open_cached_dir() and cached_dir_lease_break() where the cache entry for the open directory handle receives a lease break while creating it. And before returning from open_cached_dir(), we put the last reference of the new @cfid because of !@cfid->has_lease.
Besides the UAF, while running xfstests a lot of missed lease breaks have been noticed in tests that run several concurrent statfs(2) calls on those cached fids
CIFS: VFS: \\w22-root1.gandalf.test No task to wake, unknown frame...
CIFS: VFS: \\w22-root1.gandalf.test Cmd: 18 Err: 0x0 Flags: 0x1...
CIFS: VFS: \\w22-root1.gandalf.test smb buf 00000000715bfe83 len 108
CIFS: VFS: Dump pending requests:
CIFS: VFS: \\w22-root1.gandalf.test No task to wake, unknown frame...
CIFS: VFS: \\w22-root1.gandalf.test Cmd: 18 Err: 0x0 Flags: 0x1...
CIFS: VFS: \\w22-root1.gandalf.test smb buf 000000005aa7316e len 108
...
To fix both, in open_cached_dir() ensure that @cfid->has_lease is set right before sending out compounded request so that any potential lease break will be get processed by demultiplex thread while we're still caching @cfid. And, if open failed for some reason, re-check @cfid->has_lease to decide whether or not put lease reference.
--- fs/smb/client/cached_dir.c | 84 ++++++++++++++++++++++++++------------------- 1 file changed, 49 insertions(+), 35 deletions(-)
fs/smb/client/cached_dir.c +49 -35
@@ -32,7 +32,7 @@ static struct cached_fid *find_or_create* fully cached or it may be in the process of * being deleted due to a lease break. */ -if (!cfid->has_lease) { +if (!cfid->time || !cfid->has_lease) {spin_unlock (&cfids->cfid_list_lock);return NULL ; }
@@ -193,10 +193,20 @@ int open_cached_dir(unsigned int xid, st npath =path_no_prefix (cifs_sb, path);if (IS_ERR (npath)) { rc =PTR_ERR (npath); -kfree (utf16_path); -return rc; + goto out; } +if (!npath[0 ]) { + dentry =dget (cifs_sb->root); + }else { + dentry =path_to_dentry (cifs_sb, npath); +if (IS_ERR (dentry)) { + rc = -ENOENT ; + goto out; + } + } + cfid->dentry = dentry; +/* * We do not hold the lock for the open because in case * SMB2_open needs to reconnect.
@@ -249,6 +259,15 @@ int open_cached_dir(unsigned int xid, stsmb2_set_related (&rqst[1 ]); +/* +* Set @cfid->has_lease to true before sending out compounded request so +* its lease reference can be put in cached_dir_lease_break() due to a +* potential lease break right after the request is sent or while @cfid +* is still being cached. Concurrent processes won't be to use it yet +* due to @cfid->time being zero. +*/ + cfid->has_lease = true; + rc =compound_send_recv (xid, ses, server, flags,2 , rqst, resp_buftype, rsp_iov);
@@ -263,6 +282,8 @@ int open_cached_dir(unsigned int xid, st cfid->tcon = tcon; cfid->is_open = true; +spin_lock (&cfids->cfid_list_lock); + o_rsp = (struct smb2_create_rsp *)rsp_iov[0 ].iov_base; oparms.fid->persistent_fid = o_rsp->PersistentFileId; oparms.fid->volatile_fid = o_rsp->VolatileFileId;
@@ -270,18 +291,25 @@ int open_cached_dir(unsigned int xid, st oparms.fid->mid =le64_to_cpu (o_rsp->hdr.MessageId);#endif /* CIFS_DEBUG2 */ -if (o_rsp->OplockLevel !=SMB2_OPLOCK_LEVEL_LEASE ) + rc = -EINVAL ; +if (o_rsp->OplockLevel !=SMB2_OPLOCK_LEVEL_LEASE ) { +spin_unlock (&cfids->cfid_list_lock); goto oshr_free; + }smb2_parse_contexts (server, o_rsp, &oparms.fid->epoch, oparms.fid->lease_key, &oplock,NULL ,NULL ); -if (!(oplock &SMB2_LEASE_READ_CACHING_HE )) +if (!(oplock &SMB2_LEASE_READ_CACHING_HE )) { +spin_unlock (&cfids->cfid_list_lock); goto oshr_free; + } qi_rsp = (struct smb2_query_info_rsp *)rsp_iov[1 ].iov_base; -if (le32_to_cpu (qi_rsp->OutputBufferLength) <sizeof (struct smb2_file_all_info )) +if (le32_to_cpu (qi_rsp->OutputBufferLength) <sizeof (struct smb2_file_all_info )) { +spin_unlock (&cfids->cfid_list_lock); goto oshr_free; + } if (!smb2_validate_and_copy_iov( le16_to_cpu(qi_rsp->OutputBufferOffset), sizeof(struct smb2_file_all_info),
@@ -289,37 +317,24 @@ int open_cached_dir(unsigned int xid, st (char *)&cfid->file_all_info)) cfid->file_all_info_is_valid = true; -if (!npath[0 ]) - dentry =dget (cifs_sb->root); -else { - dentry =path_to_dentry (cifs_sb, npath); -if (IS_ERR (dentry)) { - rc = -ENOENT ; - goto oshr_free; - } - } -spin_lock (&cfids->cfid_list_lock); - cfid->dentry = dentry; cfid->time = jiffies; - cfid->has_lease = true;spin_unlock (&cfids->cfid_list_lock); +/* At this point the directory handle is fully cached */ + rc =0 ; oshr_free: -kfree (utf16_path);SMB2_open_free (&rqst[0 ]);SMB2_query_info_free (&rqst[1 ]);free_rsp_buf (resp_buftype[0 ], rsp_iov[0 ].iov_base);free_rsp_buf (resp_buftype[1 ], rsp_iov[1 ].iov_base); -spin_lock (&cfids->cfid_list_lock); -if (!cfid->has_lease) { -if (rc) { -if (cfid->on_list) { -list_del (&cfid->entry); - cfid->on_list = false; - cfids->num_entries--; - } - rc = -ENOENT ; - }else { +if (rc) { +spin_lock (&cfids->cfid_list_lock); +if (cfid->on_list) { +list_del (&cfid->entry); + cfid->on_list = false; + cfids->num_entries--; + } +if (cfid->has_lease) {/* * We are guaranteed to have two references at this * point. One for the caller and one for a potential
@@ -327,25 +342,24 @@ oshr_free:* will be closed when the caller closes the cached * handle. */ + cfid->has_lease = false;spin_unlock (&cfids->cfid_list_lock);kref_put (&cfid->refcount, smb2_close_cached_fid); goto out; } +spin_unlock (&cfids->cfid_list_lock); } -spin_unlock (&cfids->cfid_list_lock); +out:if (rc) {if (cfid->is_open)SMB2_close (0 , cfid->tcon, cfid->fid.persistent_fid, cfid->fid.volatile_fid);free_cached_dir (cfid); - cfid =NULL ; - } -out: -if (rc ==0 ) { + }else { *ret_cfid = cfid;atomic_inc (&tcon->num_remote_opens); } - +kfree (utf16_path);return rc; }
Greg Kroah-Hartman
maintainerPATCH 423/530 smb: client: fix potential deadlock when releasing mids
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paulo Alcantara <[email protected]>
commit e6322fd177c6885a21dd4609dc5e5c973d1a2eb7 upstream.
All release_mid() callers seem to hold a reference of @mid so there is no need to call kref_put(&mid->refcount, __release_mid) under @server->mid_lock spinlock. If they don't, then an use-after-free bug would have occurred anyways.
By getting rid of such spinlock also fixes a potential deadlock as shown below
CPU 0 CPU 1
------------------------------------------------------------------cifs_demultiplex_thread() cifs_debug_data_proc_show()
release_mid()
spin_lock(&server->mid_lock);
spin_lock(&cifs_tcp_ses_lock)
spin_lock(&server->mid_lock) __release_mid()
smb2_find_smb_tcon()
spin_lock(&cifs_tcp_ses_lock) *deadlock*
--- fs/smb/client/cifsproto.h | 7 ++++++- fs/smb/client/smb2misc.c | 2 +- fs/smb/client/transport.c | 11 +---------- 3 files changed, 8 insertions(+), 12 deletions(-)
fs/smb/client/cifsproto.h +6 -1
@@ -81,7 +81,7 @@ extern char *cifs_build_path_to_root(strextern char *build_wildcard_path_from_dentry (struct dentry *direntry);char *cifs_build_devname (char *nodename,const char *prepath);extern void delete_mid (struct mid_q_entry *mid); -extern void release_mid (struct mid_q_entry *mid); +void __release_mid (struct kref *refcount);extern void cifs_wake_up_task (struct mid_q_entry *mid);extern int cifs_handle_standard (struct TCP_Server_Info *server,struct mid_q_entry *mid);
@@ -740,4 +740,9 @@ static inline bool dfs_src_pathname_equa return true; } +static inline void release_mid (struct mid_q_entry *mid) +{ +kref_put (&mid->refcount, __release_mid); +} +#endif /* _CIFSPROTO_H */
fs/smb/client/smb2misc.c +1 -1
@@ -787,7 +787,7 @@ __smb2_handle_cancelled_cmd(struct cifs_ {struct close_cancelled_open *cancelled; - cancelled =kzalloc (sizeof (*cancelled),GFP_ATOMIC ); + cancelled =kzalloc (sizeof (*cancelled),GFP_KERNEL );if (!cancelled)return -ENOMEM ;
fs/smb/client/transport.c +1 -10
@@ -76,7 +76,7 @@ alloc_mid(const struct smb_hdr *smb_buffreturn temp; } -static void __release_mid (struct kref *refcount) +void __release_mid (struct kref *refcount) {struct mid_q_entry *midEntry = container_of(refcount, struct mid_q_entry, refcount);
@@ -156,15 +156,6 @@ static void __release_mid(struct kref *rmempool_free (midEntry, cifs_mid_poolp); } -void release_mid (struct mid_q_entry *mid) -{ -struct TCP_Server_Info *server = mid->server; - -spin_lock (&server->mid_lock); -kref_put (&mid->refcount, __release_mid); -spin_unlock (&server->mid_lock); -} -void delete_mid (struct mid_q_entry *mid) {
Greg Kroah-Hartman
maintainerPATCH 424/530 smb: client: fix mount when dns_resolver key is not available
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paulo Alcantara <[email protected]>
commit 5e2fd17f434d2fed78efb123e2fc6711e4f598f1 upstream.
There was a wrong assumption that with CONFIG_CIFS_DFS_UPCALL=y there would always be a dns_resolver key set up so we could unconditionally upcall to resolve UNC hostname rather than using the value provided by mount(2).
Only require it when performing automount of junctions within a DFS share so users that don't have dns_resolver key still can mount their regular shares with server hostname resolved by mount.cifs(8).
--- fs/smb/client/dfs.c | 18 +++++++++++++----- fs/smb/client/fs_context.h | 1 + fs/smb/client/namespace.c | 17 +++++++++++++++-- 3 files changed, 29 insertions(+), 7 deletions(-)
fs/smb/client/dfs.c +13 -5
@@ -263,15 +263,23 @@ out:return rc; } -/* Resolve UNC hostname in @ctx->source and set ip addr in @ctx->dstaddr */ +/* +* If @ctx->dfs_automount, then update @ctx->dstaddr earlier with the DFS root +* server from where we'll start following any referrals. Otherwise rely on the +* value provided by mount(2) as the user might not have dns_resolver key set up +* and therefore failing to upcall to resolve UNC hostname under @ctx->source. +*/ static int update_fs_context_dstaddr (struct smb3_fs_context *ctx) {struct sockaddr *addr = (struct sockaddr *)&ctx->dstaddr; -int rc; +int rc =0 ; - rc =dns_resolve_server_name_to_ip (ctx->source, addr,NULL ); -if (!rc) -cifs_set_port (addr, ctx->port); +if (!ctx->nodfs && ctx->dfs_automount) { + rc =dns_resolve_server_name_to_ip (ctx->source, addr,NULL ); +if (!rc) +cifs_set_port (addr, ctx->port); + ctx->dfs_automount = false; + }return rc; }
fs/smb/client/fs_context.h +1 -0
@@ -268,6 +268,7 @@ struct smb3_fs_context { bool witness:1; /* use witness protocol */char *leaf_fullpath;struct cifs_ses *dfs_root_ses; + bool dfs_automount:1; /* set for dfs automount only */ };extern const struct fs_parameter_spec smb3_fs_parameters[];
fs/smb/client/namespace.c +15 -2
@@ -117,6 +117,18 @@ cifs_build_devname(char *nodename, constreturn dev; } +static bool is_dfs_mount (struct dentry *dentry) +{ +struct cifs_sb_info *cifs_sb =CIFS_SB (dentry->d_sb); +struct cifs_tcon *tcon =cifs_sb_master_tcon (cifs_sb); +bool ret; + +spin_lock (&tcon->tc_lock); + ret = !!tcon->origin_fullpath; +spin_unlock (&tcon->tc_lock); +return ret; +} +/* Return full path out of a dentry set for automount */ static char *automount_fullpath (struct dentry *dentry,void *page) {
@@ -212,8 +224,9 @@ static struct vfsmount *cifs_do_automoun ctx->source =NULL ; goto out; } -cifs_dbg (FYI ,"%s: ctx: source=%s UNC=%s prepath=%s\n" , - __func__, ctx->source, ctx->UNC, ctx->prepath); + ctx->dfs_automount =is_dfs_mount (mntpt); +cifs_dbg (FYI ,"%s: ctx: source=%s UNC=%s prepath=%s dfs_automount=%d\n" , + __func__, ctx->source, ctx->UNC, ctx->prepath, ctx->dfs_automount); mnt =fc_mount (fc); out:
Greg Kroah-Hartman
maintainerPATCH 425/530 cifs: reconnect helper should set reconnect for the right channel
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shyam Prasad N <[email protected]>
commit c3326a61cdbf3ce1273d9198b6cbf90965d7e029 upstream.
We introduced a helper function to be used by non-cifsd threads to mark the connection for reconnect. For multichannel, when only a particular channel needs to be reconnected, this had a bug.
This change fixes that by marking that particular channel for reconnect.
--- fs/smb/client/connect.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
fs/smb/client/connect.c +5 -4
@@ -156,13 +156,14 @@ cifs_signal_cifsd_for_reconnect(struct T/* If server is a channel, select the primary channel */ pserver =SERVER_IS_CHAN (server) ? server->primary_server : server; -spin_lock (&pserver->srv_lock); +/* if we need to signal just this channel */ if (!all_channels) { - pserver->tcpStatus = CifsNeedReconnect; -spin_unlock (&pserver->srv_lock); +spin_lock (&server->srv_lock); +if (server->tcpStatus != CifsExiting) + server->tcpStatus = CifsNeedReconnect; +spin_unlock (&server->srv_lock);return ; } -spin_unlock (&pserver->srv_lock);spin_lock (&cifs_tcp_ses_lock);list_for_each_entry (ses, &pserver->smb_ses_list, smb_ses_list) {
Greg Kroah-Hartman
maintainerPATCH 426/530 cifs: force interface update before a fresh session setup
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shyam Prasad N <[email protected]>
commit d9a6d78096056a3cb5c5f07a730ab92f2f9ac4e6 upstream.
During a session reconnect, it is possible that the server moved to another physical server (happens in case of Azure files). So at this time, force a query of server interfaces again (in case of multichannel session), such that the secondary channels connect to the right IP addresses (possibly updated now).
--- fs/smb/client/connect.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
fs/smb/client/connect.c +5 -1
@@ -3850,8 +3850,12 @@ cifs_setup_session(const unsigned int xi is_binding = !CIFS_ALL_CHANS_NEED_RECONNECT (ses);spin_unlock (&ses->chan_lock); -if (!is_binding) +if (!is_binding) { ses->ses_status =SES_IN_SETUP ; + +/* force iface_list refresh */ + ses->iface_last_update =0 ; + }spin_unlock (&ses->ses_lock);/* update ses ip_addr only for primary chan */
Greg Kroah-Hartman
maintainerPATCH 427/530 cifs: do not reset chan_max if multichannel is not supported at mount
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shyam Prasad N <[email protected]>
commit 6e5e64c9477d58e73cb1a0e83eacad1f8df247cf upstream.
If the mount command has specified multichannel as a mount option, but multichannel is found to be unsupported by the server at the time of mount, we set chan_max to 1. Which means that the user needs to remount the share if the server starts supporting multichannel.
This change removes this reset. What it means is that if the user specified multichannel or max_channels during mount, and at this time, multichannel is not supported, but the server starts supporting it at a later point, the client will be capable of scaling out the number of channels.
--- fs/smb/client/sess.c | 1 - 1 file changed, 1 deletion(-)
fs/smb/client/sess.c +0 -1
@@ -186,7 +186,6 @@ int cifs_try_adding_channels(struct cifs }if (!(server->capabilities &SMB2_GLOBAL_CAP_MULTI_CHANNEL )) { - ses->chan_max =1 ;spin_unlock (&ses->chan_lock);cifs_server_dbg (VFS ,"no multichannel support\n" );return 0 ;
Greg Kroah-Hartman
maintainerPATCH 428/530 cifs: do not pass cifs_sb when trying to add channels
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shyam Prasad N <[email protected]>
commit 9599d59eb8fc0c0fd9480c4f22901533d08965ee upstream.
The only reason why cifs_sb gets passed today to cifs_try_adding_channels is to pass the local_nls field for the new channels and binding session. However, the ses struct already has local_nls field that is setup during the first cifs_setup_session. So there is no need to pass cifs_sb.
This change removes cifs_sb from the arg list for this and the functions that it calls and uses ses->local_nls instead.
--- fs/smb/client/cifsproto.h | 2 +- fs/smb/client/connect.c | 2 +- fs/smb/client/sess.c | 12 ++++++------ 3 files changed, 8 insertions(+), 8 deletions(-)
fs/smb/client/cifsproto.h +1 -1
@@ -610,7 +610,7 @@ void cifs_free_hash(struct shash_desc **struct cifs_chan *cifs_ses_find_chan (struct cifs_ses *ses,struct TCP_Server_Info *server); -int cifs_try_adding_channels (struct cifs_sb_info *cifs_sb,struct cifs_ses *ses); +int cifs_try_adding_channels (struct cifs_ses *ses);bool is_server_using_iface (struct TCP_Server_Info *server,struct cifs_server_iface *iface);bool is_ses_using_iface (struct cifs_ses *ses,struct cifs_server_iface *iface);
fs/smb/client/connect.c +1 -1
@@ -3561,7 +3561,7 @@ int cifs_mount(struct cifs_sb_info *cifs ctx->prepath =NULL ; out: -cifs_try_adding_channels (cifs_sb, mnt_ctx.ses); +cifs_try_adding_channels (mnt_ctx.ses); rc =mount_setup_tlink (cifs_sb, mnt_ctx.ses, mnt_ctx.tcon);if (rc) goto error;
fs/smb/client/sess.c +6 -6
@@ -24,7 +24,7 @@#include "fs_context.h" static int -cifs_ses_add_channel (struct cifs_sb_info *cifs_sb,struct cifs_ses *ses, +cifs_ses_add_channel (struct cifs_ses *ses,struct cifs_server_iface *iface);bool
@@ -157,7 +157,7 @@ cifs_chan_is_iface_active(struct cifs_se }/* returns number of channels added */ -int cifs_try_adding_channels (struct cifs_sb_info *cifs_sb,struct cifs_ses *ses) +int cifs_try_adding_channels (struct cifs_ses *ses) {struct TCP_Server_Info *server = ses->server;int old_chan_count, new_chan_count;
@@ -230,7 +230,7 @@ int cifs_try_adding_channels(struct cifskref_get (&iface->refcount);spin_unlock (&ses->iface_lock); - rc =cifs_ses_add_channel (cifs_sb, ses, iface); + rc =cifs_ses_add_channel (ses, iface);spin_lock (&ses->iface_lock);if (rc) {
@@ -354,7 +354,7 @@ cifs_ses_find_chan(struct cifs_ses *ses, }static int -cifs_ses_add_channel (struct cifs_sb_info *cifs_sb,struct cifs_ses *ses, +cifs_ses_add_channel (struct cifs_ses *ses,struct cifs_server_iface *iface) {struct TCP_Server_Info *chan_server;
@@ -433,7 +433,7 @@ cifs_ses_add_channel(struct cifs_sb_info* This will be used for encoding/decoding user/domain/pw * during sess setup auth. */ - ctx->local_nls = cifs_sb->local_nls; + ctx->local_nls = ses->local_nls;/* Use RDMA if possible */ ctx->rdma = iface->rdma_capable;
@@ -479,7 +479,7 @@ cifs_ses_add_channel(struct cifs_sb_info rc =cifs_negotiate_protocol (xid, ses, chan->server);if (!rc) - rc =cifs_setup_session (xid, ses, chan->server, cifs_sb->local_nls); + rc =cifs_setup_session (xid, ses, chan->server, ses->local_nls);mutex_unlock (&ses->session_mutex);
Greg Kroah-Hartman
maintainerPATCH 429/530 cifs: Fix encryption of cleared, but unset rq_iter data buffers
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Howells <[email protected]>
commit 37de5a80e932f828c34abeaae63170d73930dca3 upstream.
Each smb_rqst struct contains two things: an array of kvecs (rq_iov) that contains the protocol data for an RPC op and an iterator (rq_iter) that contains the data payload of an RPC op. When an smb_rqst is allocated rq_iter is it always cleared, but we don't set it up unless we're going to use it.
The functions that determines the size of the ciphertext buffer that will be needed to encrypt a request, cifs_get_num_sgs(), assumes that rq_iter is always initialised - and employs user_backed_iter() to check that the iterator isn't user-backed. This used to incidentally work, because ->user_backed was set to false because the iterator has never been initialised, but with commit f1b4cb650b9a0eeba206d8f069fcdc532bfbcd74[1] which changes user_backed_iter() to determine this based on the iterator type insted, a warning is now emitted:
WARNING: CPU: 7 PID: 4584 at fs/smb/client/cifsglob.h:2165 smb2_get_aead_req+0x3fc/0x420 [cifs]
...
RIP: 0010:smb2_get_aead_req+0x3fc/0x420 [cifs]
...
crypt_message+0x33e/0x550 [cifs]
smb3_init_transform_rq+0x27d/0x3f0 [cifs]
smb_send_rqst+0xc7/0x160 [cifs]
compound_send_recv+0x3ca/0x9f0 [cifs]
cifs_send_recv+0x25/0x30 [cifs]
SMB2_tcon+0x38a/0x820 [cifs]
cifs_get_smb_ses+0x69c/0xee0 [cifs]
cifs_mount_get_session+0x76/0x1d0 [cifs]
dfs_mount_share+0x74/0x9d0 [cifs]
cifs_mount+0x6e/0x2e0 [cifs]
cifs_smb3_do_mount+0x143/0x300 [cifs]
smb3_get_tree+0x15e/0x290 [cifs]
vfs_get_tree+0x2d/0xe0
do_new_mount+0x124/0x340
__se_sys_mount+0x143/0x1a0The problem is that rq_iter was never set, so the type is 0 (ie. ITER_UBUF) which causes user_backed_iter() to return true. The code doesn't malfunction because it checks the size of the iterator - which is 0.
Fix cifs_get_num_sgs() to ignore rq_iter if its count is 0, thereby bypassing the warnings.
It might be better to explicitly initialise rq_iter to a zero-length ITER_BVEC, say, as it can always be reinitialised later.
--- fs/smb/client/cifsglob.h | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
fs/smb/client/cifsglob.h +9 -3
@@ -2143,6 +2143,7 @@ static inline int cifs_get_num_sgs(constunsigned int len, skip;unsigned int nents =0 ;unsigned long addr; +size_t data_size;int i, j;/*
@@ -2158,17 +2159,21 @@ static inline int cifs_get_num_sgs(const* rqst[1+].rq_iov[0+] data to be encrypted/decrypted */ for (i =0 ; i < num_rqst; i++) { + data_size =iov_iter_count (&rqst[i].rq_iter); +/* We really don't want a mixture of pinned and unpinned pages * in the sglist. It's hard to keep track of which is what. * Instead, we convert to a BVEC-type iterator higher up. */ -if (WARN_ON_ONCE (user_backed_iter (&rqst[i].rq_iter))) +if (data_size && +WARN_ON_ONCE (user_backed_iter (&rqst[i].rq_iter)))return -EIO ;/* We also don't want to have any extra refs or pins to clean * up in the sglist. */ -if (WARN_ON_ONCE (iov_iter_extract_will_pin (&rqst[i].rq_iter))) +if (data_size && +WARN_ON_ONCE (iov_iter_extract_will_pin (&rqst[i].rq_iter)))return -EIO ;for (j =0 ; j < rqst[i].rq_nvec; j++) {
@@ -2184,7 +2189,8 @@ static inline int cifs_get_num_sgs(const } skip =0 ; } - nents +=iov_iter_npages (&rqst[i].rq_iter,INT_MAX ); +if (data_size) + nents +=iov_iter_npages (&rqst[i].rq_iter,INT_MAX ); } nents +=DIV_ROUND_UP (offset_in_page (sig) +SMB2_SIGNATURE_SIZE ,PAGE_SIZE );return nents;
Greg Kroah-Hartman
maintainerPATCH 430/530 xfs: recovery should not clear di_flushiter unconditionally
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dave Chinner <[email protected]>
commit 7930d9e103700cde15833638855b750715c12091 upstream.
Because on v3 inodes, di_flushiter doesn't exist. It overlaps with zero padding in the inode, except when NREXT64=1 configurations are in use and the zero padding is no longer padding but holds the 64 bit extent counter.
This manifests obviously on big endian platforms (e.g. s390) because the log dinode is in host order and the overlap is the LSBs of the extent count field. It is not noticed on little endian machines because the overlap is at the MSB end of the extent count field and we need to get more than 2^^48 extents in the inode before it manifests. i.e. the heat death of the universe will occur before we see the problem in little endian machines.
This is a zero-day issue for NREXT64=1 configuraitons on big endian machines. Fix it by only clearing di_flushiter on v2 inodes during recovery.
--- fs/xfs/xfs_inode_item_recover.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-)
fs/xfs/xfs_inode_item_recover.c +17 -15
@@ -369,24 +369,26 @@ xlog_recover_inode_commit_pass2(* superblock flag to determine whether we need to look at di_flushiter * to skip replay when the on disk inode is newer than the log one */ -if (!xfs_has_v3inodes (mp) && - ldip->di_flushiter <be16_to_cpu (dip->di_flushiter)) { -/* -* Deal with the wrap case, DI_MAX_FLUSH is less -* than smaller numbers -*/ -if (be16_to_cpu (dip->di_flushiter) ==DI_MAX_FLUSH && - ldip->di_flushiter < (DI_MAX_FLUSH >>1 )) { -/* do nothing */ - }else { -trace_xfs_log_recover_inode_skip (log, in_f); - error =0 ; - goto out_release; +if (!xfs_has_v3inodes (mp)) { +if (ldip->di_flushiter <be16_to_cpu (dip->di_flushiter)) { +/* +* Deal with the wrap case, DI_MAX_FLUSH is less +* than smaller numbers +*/ +if (be16_to_cpu (dip->di_flushiter) ==DI_MAX_FLUSH && + ldip->di_flushiter < (DI_MAX_FLUSH >>1 )) { +/* do nothing */ + }else { +trace_xfs_log_recover_inode_skip (log, in_f); + error =0 ; + goto out_release; + } } + +/* Take the opportunity to reset the flush iteration count */ + ldip->di_flushiter =0 ; } -/* Take the opportunity to reset the flush iteration count */ - ldip->di_flushiter =0 ;if (unlikely (S_ISREG (ldip->di_mode))) { if ((ldip->di_format != XFS_DINODE_FMT_EXTENTS) &&
Greg Kroah-Hartman
maintainerPATCH 431/530 btrfs: zoned: wait for data BG to be finished on direct IO allocation
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Naohiro Aota <[email protected]>
commit 776a838f1fa95670c1c1cf7109a898090b473fa3 upstream.
Running the fio command below on a ZNS device results in "Resource temporarily unavailable" error.
$ sudo fio --name=w --directory=/mnt --filesize=1GB --bs=16MB --numjobs=16 \
--rw=write --ioengine=libaio --iodepth=128 --direct=1 fio: io_u error on file /mnt/w.2.0: Resource temporarily unavailable: write offset=117440512, buflen=16777216
fio: io_u error on file /mnt/w.2.0: Resource temporarily unavailable: write offset=134217728, buflen=16777216
...
This happens because -EAGAIN error returned from btrfs_reserve_extent() called from btrfs_new_extent_direct() is spilling over to the userland.
btrfs_reserve_extent() returns -EAGAIN when there is no active zone available. Then, the caller should wait for some other on-going IO to finish a zone and retry the allocation.
This logic is already implemented for buffered write in cow_file_range(), but it is missing for the direct IO counterpart. Implement the same logic for it.
--- fs/btrfs/inode.c | 7 +++++++ 1 file changed, 7 insertions(+)
fs/btrfs/inode.c +7 -0
@@ -6974,8 +6974,15 @@ static struct extent_map *btrfs_new_exteint ret; alloc_hint =get_extent_allocation_hint (inode, start, len); +again: ret =btrfs_reserve_extent (root, len, len, fs_info->sectorsize,0 , alloc_hint, &ins,1 ,1 ); +if (ret == -EAGAIN ) { +ASSERT (btrfs_is_zoned (fs_info)); +wait_on_bit_io (&inode->root->fs_info->flags,BTRFS_FS_NEED_ZONE_FINISH , +TASK_UNINTERRUPTIBLE ); + goto again; + }if (ret)return ERR_PTR (ret);
Greg Kroah-Hartman
maintainerPATCH 432/530 ALSA: info: Fix potential deadlock at disconnection
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
commit c7a60651953359f98dbf24b43e1bf561e1573ed4 upstream.
As reported recently, ALSA core info helper may cause a deadlock at the forced device disconnection during the procfs operation.
The proc_remove() (that is called from the snd_card_disconnect() helper) has a synchronization of the pending procfs accesses via wait_for_completion(). Meanwhile, ALSA procfs helper takes the global mutex_lock(&info_mutex) at both the proc_open callback and snd_card_info_disconnect() helper. Since the proc_open can't finish due to the mutex lock, wait_for_completion() never returns, either, hence it deadlocks.
TASK#1 TASK#2 proc_reg_open() takes use_pde() snd_info_text_entry_open() snd_card_disconnect() snd_info_card_disconnect() takes mutex_lock(&info_mutex) proc_remove() wait_for_completion(unused_pde) ... waiting task#1 closes mutex_lock(&info_mutex) => DEADLOCK
This patch is a workaround for avoiding the deadlock scenario above.
The basic strategy is to move proc_remove() call outside the mutex lock. proc_remove() can work gracefully without extra locking, and it can delete the tree recursively alone. So, we call proc_remove() at snd_info_card_disconnection() at first, then delete the rest resources recursively within the info_mutex lock.
After the change, the function snd_info_disconnect() doesn't do disconnection by itself any longer, but it merely clears the procfs pointer. So rename the function to snd_info_clear_entries() for avoiding confusion.
The similar change is applied to snd_info_free_entry(), too. Since the proc_remove() is called only conditionally with the non-NULL entry->p, it's skipped after the snd_info_clear_entries() call.
--- sound/core/info.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-)
sound/core/info.c +13 -8
@@ -56,7 +56,7 @@ struct snd_info_private_data { };static int snd_info_version_init (void ); -static void snd_info_disconnect (struct snd_info_entry *entry); +static void snd_info_clear_entries (struct snd_info_entry *entry);/*
@@ -569,11 +569,16 @@ void snd_info_card_disconnect(struct snd {if (!card)return ; -mutex_lock (&info_mutex); +proc_remove (card->proc_root_link); - card->proc_root_link =NULL ;if (card->proc_root) -snd_info_disconnect (card->proc_root); +proc_remove (card->proc_root->p); + +mutex_lock (&info_mutex); +if (card->proc_root) +snd_info_clear_entries (card->proc_root); + card->proc_root_link =NULL ; + card->proc_root =NULL ;mutex_unlock (&info_mutex); }
@@ -745,15 +750,14 @@ struct snd_info_entry *snd_info_create_c }EXPORT_SYMBOL (snd_info_create_card_entry); -static void snd_info_disconnect (struct snd_info_entry *entry) +static void snd_info_clear_entries (struct snd_info_entry *entry) {struct snd_info_entry *p;if (!entry->p)return ;list_for_each_entry (p, &entry->children, list) -snd_info_disconnect (p); -proc_remove (entry->p); +snd_info_clear_entries (p); entry->p =NULL ; }
@@ -770,8 +774,9 @@ void snd_info_free_entry(struct snd_infoif (!entry)return ;if (entry->p) { +proc_remove (entry->p);mutex_lock (&info_mutex); -snd_info_disconnect (entry); +snd_info_clear_entries (entry);mutex_unlock (&info_mutex); }
Greg Kroah-Hartman
maintainerPATCH 433/530 ALSA: hda/realtek: Enable Mute LED on HP 255 G8
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eymen Yigit <[email protected]>
commit 8384c0baf223e1c3bc7b1c711d80a4c6106d210e upstream.
This HP Notebook uses ALC236 codec with COEF 0x07 idx 1 controlling the mute LED. Enable already existing quirk for this device.
--- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+)
sound/pci/hda/patch_realtek.c +1 -0
@@ -9746,6 +9746,7 @@ static const struct snd_pci_quirk alc269SND_PCI_QUIRK (0x103c ,0x8898 ,"HP EliteBook 845 G8 Notebook PC" ,ALC285_FIXUP_HP_LIMIT_INT_MIC_BOOST ),SND_PCI_QUIRK (0x103c ,0x88d0 ,"HP Pavilion 15-eh1xxx (mainboard 88D0)" ,ALC287_FIXUP_HP_GPIO_LED ),SND_PCI_QUIRK (0x103c ,0x8902 ,"HP OMEN 16" ,ALC285_FIXUP_HP_MUTE_LED ), +SND_PCI_QUIRK (0x103c ,0x890e ,"HP 255 G8 Notebook PC" ,ALC236_FIXUP_HP_MUTE_LED_COEFBIT2 ),SND_PCI_QUIRK (0x103c ,0x8919 ,"HP Pavilion Aero Laptop 13-be0xxx" ,ALC287_FIXUP_HP_GPIO_LED ),SND_PCI_QUIRK (0x103c ,0x896d ,"HP ZBook Firefly 16 G9" ,ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED ), SND_PCI_QUIRK(0x103c, 0x896e, "HP EliteBook x360 830 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
Greg Kroah-Hartman
maintainerPATCH 434/530 ALSA: hda/realtek - Add Dell ALC295 to pin fall back table
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kailang Yang <[email protected]>
commit 4b21a669ca21ed8f24ef4530b2918be5730114de upstream.
Add ALC295 to pin fall back table.
Remove 5 pin quirks for Dell ALC295.
ALC295 was only support MIC2 for external MIC function. ALC295 assigned model "ALC269_FIXUP_DELL1_MIC_NO_PRESENCE" for pin fall back table.
It was assigned wrong model. So, let's remove it.
--- sound/pci/hda/patch_realtek.c | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-)
sound/pci/hda/patch_realtek.c +3 -16
@@ -10735,22 +10735,6 @@ static const struct snd_hda_pin_quirk al {0x12, 0x90a60130}, {0x17, 0x90170110}, {0x21, 0x03211020}), -SND_HDA_PIN_QUIRK (0x10ec0295 ,0x1028 ,"Dell" ,ALC269_FIXUP_DELL4_MIC_NO_PRESENCE , - {0x14, 0x90170110}, - {0x21, 0x04211020}), -SND_HDA_PIN_QUIRK (0x10ec0295 ,0x1028 ,"Dell" ,ALC269_FIXUP_DELL4_MIC_NO_PRESENCE , - {0x14, 0x90170110}, - {0x21, 0x04211030}), -SND_HDA_PIN_QUIRK (0x10ec0295 ,0x1028 ,"Dell" ,ALC269_FIXUP_DELL1_MIC_NO_PRESENCE , -ALC295_STANDARD_PINS , - {0x17, 0x21014020}, - {0x18, 0x21a19030}), -SND_HDA_PIN_QUIRK (0x10ec0295 ,0x1028 ,"Dell" ,ALC269_FIXUP_DELL1_MIC_NO_PRESENCE , -ALC295_STANDARD_PINS , - {0x17, 0x21014040}, - {0x18, 0x21a19050}), -SND_HDA_PIN_QUIRK (0x10ec0295 ,0x1028 ,"Dell" ,ALC269_FIXUP_DELL1_MIC_NO_PRESENCE , -ALC295_STANDARD_PINS ),SND_HDA_PIN_QUIRK (0x10ec0298 ,0x1028 ,"Dell" ,ALC298_FIXUP_DELL1_MIC_NO_PRESENCE ,ALC298_STANDARD_PINS , {0x17, 0x90170110}),
@@ -10794,6 +10778,9 @@ static const struct snd_hda_pin_quirk alSND_HDA_PIN_QUIRK (0x10ec0289 ,0x1028 ,"Dell" ,ALC269_FIXUP_DELL4_MIC_NO_PRESENCE , {0x19, 0x40000000}, {0x1b, 0x40000000}), +SND_HDA_PIN_QUIRK (0x10ec0295 ,0x1028 ,"Dell" ,ALC269_FIXUP_DELL4_MIC_NO_PRESENCE , + {0x19, 0x40000000}, + {0x1b, 0x40000000}),SND_HDA_PIN_QUIRK (0x10ec0256 ,0x1028 ,"Dell" ,ALC255_FIXUP_DELL1_MIC_NO_PRESENCE , {0x19, 0x40000000}, {0x1a, 0x40000000}),
Greg Kroah-Hartman
maintainerPATCH 435/530 ALSA: hda/realtek - Enable internal speaker of ASUS K6500ZC
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chandradeep Dey <[email protected]>
commit 713f040cd22285fcc506f40a0d259566e6758c3c upstream.
Apply the already existing quirk chain ALC294_FIXUP_ASUS_SPK to enable the internal speaker of ASUS K6500ZC.
--- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+)
sound/pci/hda/patch_realtek.c +1 -0
@@ -9821,6 +9821,7 @@ static const struct snd_pci_quirk alc269SND_PCI_QUIRK (0x1043 ,0x10a1 ,"ASUS UX391UA" ,ALC294_FIXUP_ASUS_SPK ),SND_PCI_QUIRK (0x1043 ,0x10c0 ,"ASUS X540SA" ,ALC256_FIXUP_ASUS_MIC ),SND_PCI_QUIRK (0x1043 ,0x10d0 ,"ASUS X540LA/X540LJ" ,ALC255_FIXUP_ASUS_MIC_NO_PRESENCE ), +SND_PCI_QUIRK (0x1043 ,0x10d3 ,"ASUS K6500ZC" ,ALC294_FIXUP_ASUS_SPK ),SND_PCI_QUIRK (0x1043 ,0x115d ,"Asus 1015E" ,ALC269_FIXUP_LIMIT_INT_MIC_BOOST ),SND_PCI_QUIRK (0x1043 ,0x11c0 ,"ASUS X556UR" ,ALC255_FIXUP_ASUS_MIC_NO_PRESENCE ), SND_PCI_QUIRK(0x1043, 0x125e, "ASUS Q524UQK", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
Greg Kroah-Hartman
maintainerPATCH 436/530 ALSA: hda/realtek: Enable Mute LED on HP 255 G10
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matus Malych <[email protected]>
commit b944aa9d86d5f782bfe5e51336434c960304839c upstream.
HP 255 G10 has a mute LED that can be made to work using quirk ALC236_FIXUP_HP_MUTE_LED_COEFBIT2.
Enable already existing quirk - at correct line to keep order
--- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+)
sound/pci/hda/patch_realtek.c +1 -0
@@ -9782,6 +9782,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 ,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 ), SND_PCI_QUIRK(0x103c, 0x8b44, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
Greg Kroah-Hartman
maintainerPATCH 437/530 ALSA: hda/realtek: Add quirks for HP Laptops
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stefan Binding <[email protected]>
commit 5d639b60971f003d3a9b2b31f8ec73b0718b5d57 upstream.
These HP laptops use Realtek HDA codec combined with 2 or 4 CS35L41 Amplifiers using SPI with Internal Boost.
--- sound/pci/hda/patch_realtek.c | 3 +++ 1 file changed, 3 insertions(+)
sound/pci/hda/patch_realtek.c +3 -0
@@ -9816,6 +9816,9 @@ static const struct snd_pci_quirk alc269SND_PCI_QUIRK (0x103c ,0x8c70 ,"HP EliteBook 835 G11" ,ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED ),SND_PCI_QUIRK (0x103c ,0x8c71 ,"HP EliteBook 845 G11" ,ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED ),SND_PCI_QUIRK (0x103c ,0x8c72 ,"HP EliteBook 865 G11" ,ALC287_FIXUP_CS35L41_I2C_2_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 ),SND_PCI_QUIRK (0x1043 ,0x103e ,"ASUS X540SA" ,ALC256_FIXUP_ASUS_MIC ),SND_PCI_QUIRK (0x1043 ,0x103f ,"ASUS TX300" ,ALC282_FIXUP_ASUS_TX300 ), SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Greg Kroah-Hartman
maintainerPATCH 438/530 Revert ncsi: Propagate carrier gain/loss events to the NCSI controller
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johnathan Mantey <[email protected]>
commit 9e2e7efbbbff69d8340abb56d375dd79d1f5770f upstream.
This reverts commit 3780bb29311eccb7a1c9641032a112eed237f7e3.
The cited commit introduced unwanted behavior.
The intent for the commit was to be able to detect carrier loss/gain for just the NIC connected to the BMC. The unwanted effect is a carrier loss for auxiliary paths also causes the BMC to lose carrier. The BMC never regains carrier despite the secondary NIC regaining a link.
This change, when merged, needs to be backported to stable kernels. 5.4-stable, 5.10-stable, 5.15-stable, 6.1-stable, 6.5-stable
--- net/ncsi/ncsi-aen.c | 5 ----- 1 file changed, 5 deletions(-)
net/ncsi/ncsi-aen.c +0 -5
@@ -89,11 +89,6 @@ static int ncsi_aen_handler_lsc(struct nif ((had_link == has_link) || chained)return 0 ; -if (had_link) -netif_carrier_off (ndp->ndev.dev); -else -netif_carrier_on (ndp->ndev.dev); -if (!ndp->multi_package && !nc->package->multi_channel) {if (had_link) { ndp->flags |=NCSI_DEV_RESHUFFLE ;
Greg Kroah-Hartman
maintainerPATCH 439/530 Revert "i2c: pxa: move to generic GPIO recovery"
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Robert Marko <[email protected]>
commit 7b211c7671212cad0b83603c674838c7e824d845 upstream.
This reverts commit 0b01392c18b9993a584f36ace1d61118772ad0ca.
Conversion of PXA to generic I2C recovery, makes the I2C bus completely lock up if recovery pinctrl is present in the DT and I2C recovery is enabled.
So, until the generic I2C recovery can also work with PXA lets revert to have working I2C and I2C recovery again.
--- drivers/i2c/busses/i2c-pxa.c | 76 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 68 insertions(+), 8 deletions(-)
drivers/i2c/busses/i2c-pxa.c +68 -8
@@ -264,6 +264,9 @@ struct pxa_i2c {u32 hs_mask;struct i2c_bus_recovery_info recovery; +struct pinctrl *pinctrl; +struct pinctrl_state *pinctrl_default; +struct pinctrl_state *pinctrl_recovery; };#define _IBMR (i2c) ((i2c)->reg_ibmr)
@@ -1300,12 +1303,13 @@ static void i2c_pxa_prepare_recovery(str*/ gpiod_set_value (i2c->recovery.scl_gpiod, ibmr &IBMR_SCLS );gpiod_set_value (i2c->recovery.sda_gpiod, ibmr &IBMR_SDAS ); + +WARN_ON (pinctrl_select_state (i2c->pinctrl, i2c->pinctrl_recovery)); }static void i2c_pxa_unprepare_recovery (struct i2c_adapter *adap) {struct pxa_i2c *i2c = adap->algo_data; -struct i2c_bus_recovery_info *bri = adap->bus_recovery_info;u32 isr;/*
@@ -1319,7 +1323,7 @@ static void i2c_pxa_unprepare_recovery(si2c_pxa_do_reset (i2c); } -WARN_ON (pinctrl_select_state (bri->pinctrl, bri->pins_default)); +WARN_ON (pinctrl_select_state (i2c->pinctrl, i2c->pinctrl_default));dev_dbg (&i2c->adap.dev,"recovery: IBMR 0x%08x ISR 0x%08x\n" ,readl (_IBMR (i2c)),readl (_ISR (i2c)));
@@ -1341,20 +1345,76 @@ static int i2c_pxa_init_recovery(structif (IS_ENABLED (CONFIG_I2C_PXA_SLAVE ))return 0 ; - bri->pinctrl =devm_pinctrl_get (dev); -if (PTR_ERR (bri->pinctrl) == -ENODEV ) { - bri->pinctrl =NULL ; + i2c->pinctrl =devm_pinctrl_get (dev); +if (PTR_ERR (i2c->pinctrl) == -ENODEV ) + i2c->pinctrl =NULL ; +if (IS_ERR (i2c->pinctrl)) +return PTR_ERR (i2c->pinctrl); + +if (!i2c->pinctrl) +return 0 ; + + i2c->pinctrl_default =pinctrl_lookup_state (i2c->pinctrl, +PINCTRL_STATE_DEFAULT ); + i2c->pinctrl_recovery =pinctrl_lookup_state (i2c->pinctrl,"recovery" ); + +if (IS_ERR (i2c->pinctrl_default) ||IS_ERR (i2c->pinctrl_recovery)) { +dev_info (dev,"missing pinmux recovery information: %ld %ld\n" , +PTR_ERR (i2c->pinctrl_default), +PTR_ERR (i2c->pinctrl_recovery)); +return 0 ; + } + +/* +* Claiming GPIOs can influence the pinmux state, and may glitch the +* I2C bus. Do this carefully. +*/ + bri->scl_gpiod =devm_gpiod_get (dev,"scl" ,GPIOD_OUT_HIGH_OPEN_DRAIN ); +if (bri->scl_gpiod ==ERR_PTR (-EPROBE_DEFER )) +return -EPROBE_DEFER ; +if (IS_ERR (bri->scl_gpiod)) { +dev_info (dev,"missing scl gpio recovery information: %pe\n" , + bri->scl_gpiod); +return 0 ; + } + +/* +* We have SCL. Pull SCL low and wait a bit so that SDA glitches +* have no effect. +*/ +gpiod_direction_output (bri->scl_gpiod,0 ); +udelay (10 ); + bri->sda_gpiod =devm_gpiod_get (dev,"sda" ,GPIOD_OUT_HIGH_OPEN_DRAIN ); + +/* Wait a bit in case of a SDA glitch, and then release SCL. */ +udelay (10 ); +gpiod_direction_output (bri->scl_gpiod,1 ); + +if (bri->sda_gpiod ==ERR_PTR (-EPROBE_DEFER )) +return -EPROBE_DEFER ; + +if (IS_ERR (bri->sda_gpiod)) { +dev_info (dev,"missing sda gpio recovery information: %pe\n" , + bri->sda_gpiod);return 0 ; } -if (IS_ERR (bri->pinctrl)) -return PTR_ERR (bri->pinctrl); bri->prepare_recovery = i2c_pxa_prepare_recovery; bri->unprepare_recovery = i2c_pxa_unprepare_recovery; + bri->recover_bus = i2c_generic_scl_recovery; i2c->adap.bus_recovery_info = bri; -return 0 ; +/* +* Claiming GPIOs can change the pinmux state, which confuses the +* pinctrl since pinctrl's idea of the current setting is unaffected +* by the pinmux change caused by claiming the GPIO. Work around that +* by switching pinctrl to the GPIO state here. We do it this way to +* avoid glitching the I2C bus. +*/ +pinctrl_select_state (i2c->pinctrl, i2c->pinctrl_recovery); + +return pinctrl_select_state (i2c->pinctrl, i2c->pinctrl_default); }static int i2c_pxa_probe (struct platform_device *dev)
Greg Kroah-Hartman
maintainerPATCH 440/530 lsm: fix default return value for vm_enough_memory
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ondrej Mosnacek <[email protected]>
commit 866d648059d5faf53f1cd960b43fe8365ad93ea7 upstream.
1 is the return value that implements a "no-op" hook, not 0.
--- include/linux/lsm_hook_defs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/lsm_hook_defs.h +1 -1
@@ -48,7 +48,7 @@ LSM_HOOK(int, 0, quota_on, struct dentry LSM_HOOK(int, 0, syslog, int type) LSM_HOOK(int, 0, settime, const struct timespec64 *ts, const struct timezone *tz) -LSM_HOOK(int, 0, vm_enough_memory, struct mm_struct *mm, long pages) +LSM_HOOK(int, 1, vm_enough_memory, struct mm_struct *mm, long pages) LSM_HOOK(int, 0, bprm_creds_for_exec, struct linux_binprm *bprm) LSM_HOOK(int, 0, bprm_creds_from_file, struct linux_binprm *bprm, struct file *file) LSM_HOOK(int, 0, bprm_check_security, struct linux_binprm *bprm)
Greg Kroah-Hartman
maintainerPATCH 441/530 lsm: fix default return value for inode_getsecctx
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ondrej Mosnacek <[email protected]>
commit b36995b8609a5a8fe5cf259a1ee768fcaed919f8 upstream.
-EOPNOTSUPP is the return value that implements a "no-op" hook, not 0.
Without this fix having only the BPF LSM enabled (with no programs attached) can cause uninitialized variable reads in nfsd4_encode_fattr(), because the BPF hook returns 0 without touching the 'ctxlen' variable and the corresponding 'contextlen' variable in nfsd4_encode_fattr() remains uninitialized, yet being treated as valid based on the 0 return value.
--- include/linux/lsm_hook_defs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/lsm_hook_defs.h +1 -1
@@ -273,7 +273,7 @@ LSM_HOOK(void, LSM_RET_VOID, release_sec LSM_HOOK(void, LSM_RET_VOID, inode_invalidate_secctx, struct inode *inode) LSM_HOOK(int, 0, inode_notifysecctx, struct inode *inode, void *ctx, u32 ctxlen) LSM_HOOK(int, 0, inode_setsecctx, struct dentry *dentry, void *ctx, u32 ctxlen) -LSM_HOOK(int, 0, inode_getsecctx, struct inode *inode, void **ctx, +LSM_HOOK(int, -EOPNOTSUPP, inode_getsecctx, struct inode *inode, void **ctx, u32 *ctxlen)#if defined(CONFIG_SECURITY ) && defined(CONFIG_WATCH_QUEUE )
Greg Kroah-Hartman
maintainerPATCH 442/530 sbsa_gwdt: Calculate timeout with 64-bit math
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darren Hart <[email protected]>
commit 5d6aa89bba5bd6af2580f872b57f438dab883738 upstream.
Commit abd3ac7902fb ("watchdog: sbsa: Support architecture version 1") introduced new timer math for watchdog revision 1 with the 48 bit offset register.
The gwdt->clk and timeout are u32, but the argument being calculated is u64. Without a cast, the compiler performs u32 operations, truncating intermediate steps, resulting in incorrect values.
A watchdog revision 1 implementation with a gwdt->clk of 1GHz and a timeout of 600s writes 3647256576 to the one shot watchdog instead of 300000000000, resulting in the watchdog firing in 3.6s instead of 600s.
Force u64 math by casting the first argument (gwdt->clk) as a u64. Make the order of operations explicit with parenthesis.
--- drivers/watchdog/sbsa_gwdt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/watchdog/sbsa_gwdt.c +2 -2
@@ -152,14 +152,14 @@ static int sbsa_gwdt_set_timeout(struct timeout = clamp_t(unsigned int, timeout, 1, wdd->max_hw_heartbeat_ms / 1000);if (action) -sbsa_gwdt_reg_write (gwdt->clk * timeout, gwdt); +sbsa_gwdt_reg_write ((u64 )gwdt->clk * timeout, gwdt);else /* * In the single stage mode, The first signal (WS0) is ignored, * the timeout is (WOR * 2), so the WOR should be configured * to half value of timeout. */ -sbsa_gwdt_reg_write (gwdt->clk /2 * timeout, gwdt); +sbsa_gwdt_reg_write (((u64 )gwdt->clk /2 ) * timeout, gwdt);return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 443/530 i2c: designware: Disable TX_EMPTY irq while waiting for block length byte
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tam Nguyen <[email protected]>
commit e8183fa10c25c7b3c20670bf2b430ddcc1ee03c0 upstream.
During SMBus block data read process, we have seen high interrupt rate because of TX_EMPTY irq status while waiting for block length byte (the first data byte after the address phase). The interrupt handler does not do anything because the internal state is kept as STATUS_WRITE_IN_PROGRESS. Hence, we should disable TX_EMPTY IRQ until I2C DesignWare receives first data byte from I2C device, then re-enable it to resume SMBus transaction.
It takes 0.789 ms for host to receive data length from slave. Without the patch, i2c_dw_isr() is called 99 times by TX_EMPTY interrupt. And it is none after applying the patch.
--- drivers/i2c/busses/i2c-designware-master.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-)
drivers/i2c/busses/i2c-designware-master.c +16 -3
@@ -519,10 +519,16 @@ i2c_dw_xfer_msg(struct dw_i2c_dev *dev)/* * Because we don't know the buffer length in the -* I2C_FUNC_SMBUS_BLOCK_DATA case, we can't stop -* the transaction here. +* I2C_FUNC_SMBUS_BLOCK_DATA case, we can't stop the +* transaction here. Also disable the TX_EMPTY IRQ +* while waiting for the data length byte to avoid the +* bogus interrupts flood. */ -if (buf_len >0 || flags &I2C_M_RECV_LEN ) { +if (flags &I2C_M_RECV_LEN ) { + dev->status |=STATUS_WRITE_IN_PROGRESS ; + intr_mask &= ~DW_IC_INTR_TX_EMPTY ; +break ; + }else if (buf_len >0 ) {/* more bytes to be written */ dev->status |=STATUS_WRITE_IN_PROGRESS ;break ;
@@ -558,6 +564,13 @@ i2c_dw_recv_len(struct dw_i2c_dev *dev, msgs[dev->msg_read_idx].len = len; msgs[dev->msg_read_idx].flags &= ~I2C_M_RECV_LEN ; +/* +* Received buffer length, re-enable TX_EMPTY interrupt +* to resume the SMBUS transaction. +*/ +regmap_update_bits (dev->map,DW_IC_INTR_MASK ,DW_IC_INTR_TX_EMPTY , +DW_IC_INTR_TX_EMPTY ); +return len; }
Greg Kroah-Hartman
maintainerPATCH 444/530 s390/ap: fix AP bus crash on early config change callback invocation
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Harald Freudenberger <[email protected]>
commit e14aec23025eeb1f2159ba34dbc1458467c4c347 upstream.
Fix kernel crash in AP bus code caused by very early invocation of the config change callback function via SCLP.
After a fresh IML of the machine the crypto cards are still offline and will get switched online only with activation of any LPAR which has the card in it's configuration. A crypto card coming online is reported to the LPAR via SCLP and the AP bus offers a callback function to get this kind of information. However, it may happen that the callback is invoked before the AP bus init function is complete. As the callback triggers a synchronous AP bus scan, the scan may already run but some internal states are not initialized by the AP bus init function resulting in a crash like this:
[ 11.635859] Unable to handle kernel pointer dereference in virtual kernel address space [ 11.635861] Failing address: 0000000000000000 TEID: 0000000000000887 [ 11.635862] Fault in home space mode while using kernel ASCE. [ 11.635864] AS:00000000894c4007 R3:00000001fece8007 S:00000001fece7800 P:000000000000013d [ 11.635879] Oops: 0004 ilc:1 [#1] SMP [ 11.635882] Modules linked in: [ 11.635884] CPU: 5 PID: 42 Comm: kworker/5:0 Not tainted 6.6.0-rc3-00003-g4dbf7cdc6b42 #12 [ 11.635886] Hardware name: IBM 3931 A01 751 (LPAR) [ 11.635887] Workqueue: events_long ap_scan_bus [ 11.635891] Krnl PSW : 0704c00180000000 0000000000000000 (0x0) [ 11.635895] R:0 T:1 IO:1 EX:1 Key:0 M:1 W:0 P:0 AS:3 CC:0 PM:0 RI:0 EA:3 [ 11.635897] Krnl GPRS: 0000000001000a00 0000000000000000 0000000000000006 0000000089591940 [ 11.635899] 0000000080000000 0000000000000a00 0000000000000000 0000000000000000 [ 11.635901] 0000000081870c00 0000000089591000 000000008834e4e2 0000000002625a00 [ 11.635903] 0000000081734200 0000038000913c18 000000008834c6d6 0000038000913ac8 [ 11.635906] Krnl Code:>0000000000000000: 0000 illegal [ 11.635906] 0000000000000002: 0000 illegal [ 11.635906] 0000000000000004: 0000 illegal [ 11.635906] 0000000000000006: 0000 illegal [ 11.635906] 0000000000000008: 0000 illegal [ 11.635906] 000000000000000a: 0000 illegal [ 11.635906] 000000000000000c: 0000 illegal [ 11.635906] 000000000000000e: 0000 illegal [ 11.635915] Call Trace: [ 11.635916] [<0000000000000000>] 0x0 [ 11.635918] [<000000008834e4e2>] ap_queue_init_state+0x82/0xb8 [ 11.635921] [<000000008834ba1c>] ap_scan_domains+0x6fc/0x740 [ 11.635923] [<000000008834c092>] ap_scan_adapter+0x632/0x8b0 [ 11.635925] [<000000008834c3e4>] ap_scan_bus+0xd4/0x288 [ 11.635927] [<00000000879a33ba>] process_one_work+0x19a/0x410 [ 11.635930] Discipline DIAG cannot be used without z/VM [ 11.635930] [<00000000879a3a2c>] worker_thread+0x3fc/0x560 [ 11.635933] [<00000000879aea60>] kthread+0x120/0x128 [ 11.635936] [<000000008792afa4>] __ret_from_fork+0x3c/0x58 [ 11.635938] [<00000000885ebe62>] ret_from_fork+0xa/0x30 [ 11.635942] Last Breaking-Event-Address: [ 11.635942] [<000000008834c6d4>] ap_wait+0xcc/0x148
This patch improves the ap_bus_force_rescan() function which is invoked by the config change callback by checking if a first initial AP bus scan has been done. If not, the force rescan request is simple ignored. Anyhow it does not make sense to trigger AP bus re-scans even before the very first bus scan is complete.
--- drivers/s390/crypto/ap_bus.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/s390/crypto/ap_bus.c +4 -0
@@ -1022,6 +1022,10 @@ EXPORT_SYMBOL(ap_driver_unregister);void ap_bus_force_rescan (void ) { +/* Only trigger AP bus scans after the initial scan is done */ +if (atomic64_read (&ap_scan_bus_count) <=0 ) +return ; +/* processing a asynchronous bus rescan */ del_timer (&ap_config_timer);queue_work (system_long_wq, &ap_scan_work);
Greg Kroah-Hartman
maintainerPATCH 445/530 net: ethtool: Fix documentation of ethtool_sprintf()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrew Lunn <[email protected]>
commit f55d8e60f10909dbc5524e261041e1d28d7d20d8 upstream.
This function takes a pointer to a pointer, unlike sprintf() which is passed a plain pointer. Fix up the documentation to make this clear.
--- include/linux/ethtool.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
include/linux/ethtool.h +2 -2
@@ -1045,10 +1045,10 @@ static inline int ethtool_mm_frag_size_m/** * ethtool_sprintf - Write formatted string to ethtool string data -* @data: Pointer to start of string to update +* @data: Pointer to a pointer to the start of string to update * @fmt: Format of string to write * -* Write formatted string to data. Update data to point at start of +* Write formatted string to *data. Update *data to point at start of * next string. */ extern __printf(2, 3) void ethtool_sprintf(u8 **data, const char *fmt, ...);
Greg Kroah-Hartman
maintainerPATCH 446/530 net: dsa: lan9303: consequently nested-lock physical MDIO
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Sverdlin <[email protected]>
commit 5a22fbcc10f3f7d94c5d88afbbffa240a3677057 upstream.
When LAN9303 is MDIO-connected two callchains exist into mdio->bus->write():
1. switch ports 1&2 ("physical" PHYs):
virtual (switch-internal) MDIO bus (lan9303_switch_ops->phy_{read|write})->
lan9303_mdio_phy_{read|write} -> mdiobus_{read|write}_nested
2. LAN9303 virtual PHY:
virtual MDIO bus (lan9303_phy_{read|write}) ->
lan9303_virt_phy_reg_{read|write} -> regmap -> lan9303_mdio_{read|write}
If the latter functions just take mutex_lock(&sw_dev->device->bus->mdio_lock) it triggers a LOCKDEP false-positive splat. It's false-positive because the first mdio_lock in the second callchain above belongs to virtual MDIO bus, the second mdio_lock belongs to physical MDIO bus.
Consequent annotation in lan9303_mdio_{read|write} as nested lock (similar to lan9303_mdio_phy_{read|write}, it's the same physical MDIO bus) prevents the following splat:
WARNING: possible circular locking dependency detected
5.15.71 #1 Not tainted
------------------------------------------------------
kworker/u4:3/609 is trying to acquire lock:ffff000011531c68 (lan9303_mdio:131:(&lan9303_mdio_regmap_config)->lock){+.+.}-{3:3}, at: regmap_lock_mutex but task is already holding lock:ffff0000114c44d8 (&bus->mdio_lock){+.+.}-{3:3}, at: mdiobus_read
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #1 (&bus->mdio_lock){+.+.}-{3:3}:
lock_acquire
__mutex_lock
mutex_lock_nested
lan9303_mdio_read
_regmap_read
regmap_read
lan9303_probe
lan9303_mdio_probe
mdio_probe
really_probe
__driver_probe_device
driver_probe_device
__device_attach_driver
bus_for_each_drv
__device_attach
device_initial_probe
bus_probe_device
deferred_probe_work_func
process_one_work
worker_thread
kthread
ret_from_fork
-> #0 (lan9303_mdio:131:(&lan9303_mdio_regmap_config)->lock){+.+.}-{3:3}:
__lock_acquire
lock_acquire.part.0
lock_acquire
__mutex_lock
mutex_lock_nested
regmap_lock_mutex
regmap_read
lan9303_phy_read
dsa_slave_phy_read
__mdiobus_read
mdiobus_read
get_phy_device
mdiobus_scan
__mdiobus_register
dsa_register_switch
lan9303_probe
lan9303_mdio_probe
mdio_probe
really_probe
__driver_probe_device
driver_probe_device
__device_attach_driver
bus_for_each_drv
__device_attach
device_initial_probe
bus_probe_device
deferred_probe_work_func
process_one_work
worker_thread
kthread
ret_from_fork
other info that might help us debug this:
Possible unsafe locking scenario:
CPU0 CPU1
---- ----
lock(&bus->mdio_lock);
lock(lan9303_mdio:131:(&lan9303_mdio_regmap_config)->lock);
lock(&bus->mdio_lock);
lock(lan9303_mdio:131:(&lan9303_mdio_regmap_config)->lock);
*** DEADLOCK ***
5 locks held by kworker/u4:3/609:
#0: ffff000002842938 ((wq_completion)events_unbound){+.+.}-{0:0}, at: process_one_work
#1: ffff80000bacbd60 (deferred_probe_work){+.+.}-{0:0}, at: process_one_work
#2: ffff000007645178 (&dev->mutex){....}-{3:3}, at: __device_attach
#3: ffff8000096e6e78 (dsa2_mutex){+.+.}-{3:3}, at: dsa_register_switch
#4: ffff0000114c44d8 (&bus->mdio_lock){+.+.}-{3:3}, at: mdiobus_read
stack backtrace:
CPU: 1 PID: 609 Comm: kworker/u4:3 Not tainted 5.15.71 #1
Workqueue: events_unbound deferred_probe_work_func
Call trace:
dump_backtrace
show_stack
dump_stack_lvl
dump_stack
print_circular_bug
check_noncircular
__lock_acquire
lock_acquire.part.0
lock_acquire
__mutex_lock
mutex_lock_nested
regmap_lock_mutex
regmap_read
lan9303_phy_read
dsa_slave_phy_read
__mdiobus_read
mdiobus_read
get_phy_device
mdiobus_scan
__mdiobus_register
dsa_register_switch
lan9303_probe
lan9303_mdio_probe...
--- drivers/net/dsa/lan9303_mdio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/dsa/lan9303_mdio.c +2 -2
@@ -32,7 +32,7 @@ static int lan9303_mdio_write(void *ctx,struct lan9303_mdio *sw_dev = (struct lan9303_mdio *)ctx; reg <<=2 ;/* reg num to offset */ -mutex_lock (&sw_dev->device->bus->mdio_lock); +mutex_lock_nested (&sw_dev->device->bus->mdio_lock,MDIO_MUTEX_NESTED );lan9303_mdio_real_write (sw_dev->device, reg, val &0xffff );lan9303_mdio_real_write (sw_dev->device, reg +2 , (val >>16 ) &0xffff );mutex_unlock (&sw_dev->device->bus->mdio_lock);
@@ -50,7 +50,7 @@ static int lan9303_mdio_read(void *ctx,struct lan9303_mdio *sw_dev = (struct lan9303_mdio *)ctx; reg <<=2 ;/* reg num to offset */ -mutex_lock (&sw_dev->device->bus->mdio_lock); +mutex_lock_nested (&sw_dev->device->bus->mdio_lock,MDIO_MUTEX_NESTED ); *val =lan9303_mdio_real_read (sw_dev->device, reg); *val |= (lan9303_mdio_real_read (sw_dev->device, reg +2 ) <<16 );mutex_unlock (&sw_dev->device->bus->mdio_lock);