From b3b4b3bcd6f483a0bb22be843f05d73278581136 Mon Sep 17 00:00:00 2001 From: Yabin Cui Date: Tue, 1 Dec 2020 14:05:50 -0800 Subject: [PATCH 01/12] msm: kgsl: introduce CONFIG_CORESIGHT_ADRENO. We want to build coresight drivers as builtin drivers. But adreno-coresight.c in msm_adreno.ko calls coresight functions. To avoid exporting new symbols in vmlinux and breaking the ABI, this patch separates adreno-coresight.c into CONFIG_CORESIGHT_ADRENO. CONFIG_CORESIGHT_ADRENO is only enabled when both coresight and adreno are builtin drivers. Bug: 167414982 Bug: 170753932 Signed-off-by: Yabin Cui Change-Id: I7488293445ade738ba03cc457320e0d74f910886 --- drivers/gpu/msm/Kconfig | 4 ++++ drivers/gpu/msm/Makefile | 2 +- drivers/gpu/msm/adreno.h | 17 +++++++++++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/msm/Kconfig b/drivers/gpu/msm/Kconfig index b0e45d5ff58c..e4a03a2e80fa 100644 --- a/drivers/gpu/msm/Kconfig +++ b/drivers/gpu/msm/Kconfig @@ -26,3 +26,7 @@ config QCOM_ADRENO_DEFAULT_GOVERNOR config QCOM_KGSL_IOMMU bool default y if QCOM_KGSL && (MSM_IOMMU || ARM_SMMU) + +config CORESIGHT_ADRENO + bool + default y if QCOM_KGSL=y && CORESIGHT=y diff --git a/drivers/gpu/msm/Makefile b/drivers/gpu/msm/Makefile index 126bafb1ec18..98d2f4baa47c 100644 --- a/drivers/gpu/msm/Makefile +++ b/drivers/gpu/msm/Makefile @@ -31,7 +31,6 @@ msm_adreno-y += \ adreno_drawctxt.o \ adreno_dispatch.o \ adreno_snapshot.o \ - adreno_coresight.o \ adreno_trace.o \ adreno_a3xx.o \ adreno_a5xx.o \ @@ -51,6 +50,7 @@ msm_adreno-y += \ msm_adreno-$(CONFIG_QCOM_KGSL_IOMMU) += adreno_iommu.o msm_adreno-$(CONFIG_DEBUG_FS) += adreno_debugfs.o adreno_profile.o msm_adreno-$(CONFIG_COMPAT) += adreno_compat.o +msm_adreno-$(CONFIG_CORESIGHT_ADRENO) += adreno_coresight.o msm_kgsl_core-objs = $(msm_kgsl_core-y) msm_adreno-objs = $(msm_adreno-y) diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h index 906ba577b0d2..58f805f3e506 100644 --- a/drivers/gpu/msm/adreno.h +++ b/drivers/gpu/msm/adreno.h @@ -806,6 +806,7 @@ struct adreno_coresight_attr { struct adreno_coresight_register *reg; }; +#if IS_ENABLED(CONFIG_CORESIGHT_ADRENO) ssize_t adreno_coresight_show_register(struct device *device, struct device_attribute *attr, char *buf); @@ -818,6 +819,12 @@ ssize_t adreno_coresight_store_register(struct device *dev, adreno_coresight_show_register, \ adreno_coresight_store_register), \ (_reg), } +#else +#define ADRENO_CORESIGHT_ATTR(_attrname, _reg) \ + struct adreno_coresight_attr coresight_attr_##_attrname = { \ + __ATTR_NULL, \ + (_reg), } +#endif /* CONFIG_CORESIGHT_ADRENO */ /** * struct adreno_coresight - GPU specific coresight definition @@ -1089,12 +1096,22 @@ void adreno_fault_skipcmd_detached(struct adreno_device *adreno_dev, struct adreno_context *drawctxt, struct kgsl_drawobj *drawobj); +#if IS_ENABLED(CONFIG_CORESIGHT_ADRENO) int adreno_coresight_init(struct adreno_device *adreno_dev); void adreno_coresight_start(struct adreno_device *adreno_dev); void adreno_coresight_stop(struct adreno_device *adreno_dev); void adreno_coresight_remove(struct adreno_device *adreno_dev); +#else +static inline int adreno_coresight_init(struct adreno_device *adreno_dev) +{ + return -ENODEV; +} +static inline void adreno_coresight_start(struct adreno_device *adreno_dev) { } +static inline void adreno_coresight_stop(struct adreno_device *adreno_dev) { } +static inline void adreno_coresight_remove(struct adreno_device *adreno_dev) { } +#endif /* CONFIG_CORESIGHT_ADRENO */ bool adreno_hw_isidle(struct adreno_device *adreno_dev); From 1dfa39a8de954cac771762065bee238cc66486b5 Mon Sep 17 00:00:00 2001 From: Faiz Nabi Kuchay Date: Tue, 7 Jun 2022 12:47:35 +0530 Subject: [PATCH 02/12] BACKPORT: audio-kernel: Disable clock voting logs trace_printk is recommended for debugging purpose as it requires temporary memory to handle strings. If used anywhere within the kernel, memory will be allocated to it. Hence removed it to avoid any unnecessary memory allocation. Change-Id: If7b0cada91c97b21987f91e0ff7b7a15ce2145e2 Signed-off-by: Faiz Nabi Kuchay Signed-off-by: Hridaya Prajapati --- techpack/audio/asoc/codecs/audio-ext-clk-up.c | 12 ++--- .../audio/asoc/codecs/bolero/bolero-cdc.c | 13 +----- .../audio/asoc/codecs/bolero/bolero-clk-rsc.c | 10 +--- techpack/audio/asoc/codecs/bolero/rx-macro.c | 9 +--- techpack/audio/asoc/codecs/bolero/tx-macro.c | 19 +------- techpack/audio/asoc/codecs/bolero/va-macro.c | 1 - techpack/audio/asoc/codecs/bolero/wsa-macro.c | 9 +--- techpack/audio/asoc/msm-dai-q6-v2.c | 1 - techpack/audio/dsp/digital-cdc-rsc-mgr.c | 5 +- techpack/audio/dsp/q6afe.c | 30 ------------ techpack/audio/soc/pinctrl-lpi.c | 6 --- techpack/audio/soc/swr-mstr-ctrl.c | 46 ------------------- 12 files changed, 13 insertions(+), 148 deletions(-) diff --git a/techpack/audio/asoc/codecs/audio-ext-clk-up.c b/techpack/audio/asoc/codecs/audio-ext-clk-up.c index 3da8c1928a00..14e116fd4cad 100644 --- a/techpack/audio/asoc/codecs/audio-ext-clk-up.c +++ b/techpack/audio/asoc/codecs/audio-ext-clk-up.c @@ -76,8 +76,6 @@ static int audio_ext_clk_prepare(struct clk_hw *hw) if ((clk_priv->clk_src >= AUDIO_EXT_CLK_LPASS) && (clk_priv->clk_src < AUDIO_EXT_CLK_LPASS_MAX)) { clk_priv->clk_cfg.enable = 1; - trace_printk("%s: vote for %d clock\n", - __func__, clk_priv->clk_src); ret = afe_set_lpass_clk_cfg(IDX_RSVD_3, &clk_priv->clk_cfg); if (ret < 0) { pr_err_ratelimited("%s afe_set_digital_codec_core_clock failed\n", @@ -120,8 +118,6 @@ static void audio_ext_clk_unprepare(struct clk_hw *hw) if ((clk_priv->clk_src >= AUDIO_EXT_CLK_LPASS) && (clk_priv->clk_src < AUDIO_EXT_CLK_LPASS_MAX)) { clk_priv->clk_cfg.enable = 0; - trace_printk("%s: unvote for %d clock\n", - __func__, clk_priv->clk_src); ret = afe_set_lpass_clk_cfg(IDX_RSVD_3, &clk_priv->clk_cfg); if (ret < 0) pr_err_ratelimited("%s: afe_set_lpass_clk_cfg failed, ret = %d\n", @@ -156,7 +152,7 @@ static int lpass_hw_vote_prepare(struct clk_hw *hw) int ret; if (clk_priv->clk_src == AUDIO_EXT_CLK_LPASS_CORE_HW_VOTE) { - trace_printk("%s: vote for %d clock\n", + pr_debug("%s: vote for %d clock\n", __func__, clk_priv->clk_src); ret = afe_vote_lpass_core_hw(AFE_LPASS_CORE_HW_MACRO_BLOCK, "LPASS_HW_MACRO", @@ -169,7 +165,7 @@ static int lpass_hw_vote_prepare(struct clk_hw *hw) } if (clk_priv->clk_src == AUDIO_EXT_CLK_LPASS_AUDIO_HW_VOTE) { - trace_printk("%s: vote for %d clock\n", + pr_debug("%s: vote for %d clock\n", __func__, clk_priv->clk_src); ret = afe_vote_lpass_core_hw(AFE_LPASS_CORE_HW_DCODEC_BLOCK, "LPASS_HW_DCODEC", @@ -190,7 +186,7 @@ static void lpass_hw_vote_unprepare(struct clk_hw *hw) int ret = 0; if (clk_priv->clk_src == AUDIO_EXT_CLK_LPASS_CORE_HW_VOTE) { - trace_printk("%s: unvote for %d clock\n", + pr_debug("%s: unvote for %d clock\n", __func__, clk_priv->clk_src); ret = afe_unvote_lpass_core_hw( AFE_LPASS_CORE_HW_MACRO_BLOCK, @@ -202,7 +198,7 @@ static void lpass_hw_vote_unprepare(struct clk_hw *hw) } if (clk_priv->clk_src == AUDIO_EXT_CLK_LPASS_AUDIO_HW_VOTE) { - trace_printk("%s: unvote for %d clock\n", + pr_debug("%s: unvote for %d clock\n", __func__, clk_priv->clk_src); ret = afe_unvote_lpass_core_hw( AFE_LPASS_CORE_HW_DCODEC_BLOCK, diff --git a/techpack/audio/asoc/codecs/bolero/bolero-cdc.c b/techpack/audio/asoc/codecs/bolero/bolero-cdc.c index e80a82390a81..5f8d32788b22 100644 --- a/techpack/audio/asoc/codecs/bolero/bolero-cdc.c +++ b/techpack/audio/asoc/codecs/bolero/bolero-cdc.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -879,7 +880,7 @@ static int bolero_ssr_enable(struct device *dev, void *data) priv->component, BOLERO_MACRO_EVT_CLK_RESET, 0x0); } - trace_printk("%s: clk count reset\n", __func__); + pr_debug("%s: clk count reset\n", __func__); if (priv->rsc_clk_cb) priv->rsc_clk_cb(priv->clk_dev, BOLERO_MACRO_EVT_SSR_GFMUX_UP); @@ -902,7 +903,6 @@ static int bolero_ssr_enable(struct device *dev, void *data) /* Add a 100usec sleep to ensure last register write is done */ usleep_range(100,110); bolero_clk_rsc_enable_all_clocks(priv->clk_dev, false); - trace_printk("%s: regcache_sync done\n", __func__); /* call ssr event for supported macros */ for (macro_idx = START_MACRO; macro_idx < MAX_MACRO; macro_idx++) { if (!priv->macro_params[macro_idx].event_handler) @@ -911,7 +911,6 @@ static int bolero_ssr_enable(struct device *dev, void *data) priv->component, BOLERO_MACRO_EVT_SSR_UP, 0x0); } - trace_printk("%s: SSR up events processed by all macros\n", __func__); bolero_cdc_notifier_call(priv, BOLERO_WCD_EVT_SSR_UP); return 0; } @@ -1441,8 +1440,6 @@ int bolero_runtime_resume(struct device *dev) } } priv->core_hw_vote_count++; - trace_printk("%s: hw vote count %d\n", - __func__, priv->core_hw_vote_count); audio_vote: if (priv->lpass_audio_hw_vote == NULL) { @@ -1459,8 +1456,6 @@ audio_vote: } } priv->core_audio_vote_count++; - trace_printk("%s: audio vote count %d\n", - __func__, priv->core_audio_vote_count); done: mutex_unlock(&priv->vote_lock); @@ -1484,8 +1479,6 @@ int bolero_runtime_suspend(struct device *dev) dev_dbg(dev, "%s: Invalid lpass core hw node\n", __func__); } - trace_printk("%s: hw vote count %d\n", - __func__, priv->core_hw_vote_count); if (priv->lpass_audio_hw_vote != NULL) { if (--priv->core_audio_vote_count == 0) @@ -1497,8 +1490,6 @@ int bolero_runtime_suspend(struct device *dev) dev_dbg(dev, "%s: Invalid lpass audio hw node\n", __func__); } - trace_printk("%s: audio vote count %d\n", - __func__, priv->core_audio_vote_count); mutex_unlock(&priv->vote_lock); return 0; diff --git a/techpack/audio/asoc/codecs/bolero/bolero-clk-rsc.c b/techpack/audio/asoc/codecs/bolero/bolero-clk-rsc.c index 9cc9b1ca86b9..5b1bc0c7e1b7 100644 --- a/techpack/audio/asoc/codecs/bolero/bolero-clk-rsc.c +++ b/techpack/audio/asoc/codecs/bolero/bolero-clk-rsc.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -135,7 +136,6 @@ int bolero_rsc_clk_reset(struct device *dev, int clk_id) dev_dbg(priv->dev, "%s: clock reset after ssr, count %d\n", __func__, count); - trace_printk("%s: clock reset after ssr, count %d\n", __func__, count); while (count--) { clk_prepare_enable(priv->clk[clk_id]); clk_prepare_enable(priv->clk[clk_id + NPL_CLK_OFFSET]); @@ -290,8 +290,6 @@ static int bolero_clk_rsc_mux1_clk_request(struct bolero_clk_rsc *priv, if (priv->dev_up_gfmux) { iowrite32(0x1, clk_muxsel); muxsel = ioread32(clk_muxsel); - trace_printk("%s: muxsel value after enable: %d\n", - __func__, muxsel); } bolero_clk_rsc_mux0_clk_request(priv, default_clk_id, @@ -323,8 +321,6 @@ static int bolero_clk_rsc_mux1_clk_request(struct bolero_clk_rsc *priv, if (priv->dev_up_gfmux) { iowrite32(0x0, clk_muxsel); muxsel = ioread32(clk_muxsel); - trace_printk("%s: muxsel value after disable: %d\n", - __func__, muxsel); } } } @@ -547,7 +543,6 @@ int bolero_clk_rsc_request_clock(struct device *dev, if (!priv->dev_up && enable) { dev_err_ratelimited(priv->dev, "%s: SSR is in progress..\n", __func__); - trace_printk("%s: SSR is in progress..\n", __func__); ret = -EINVAL; goto err; } @@ -577,9 +572,6 @@ int bolero_clk_rsc_request_clock(struct device *dev, dev_dbg(priv->dev, "%s: clk_cnt: %d for requested clk: %d, enable: %d\n", __func__, priv->clk_cnt[clk_id_req], clk_id_req, enable); - trace_printk("%s: clk_cnt: %d for requested clk: %d, enable: %d\n", - __func__, priv->clk_cnt[clk_id_req], clk_id_req, - enable); mutex_unlock(&priv->rsc_clk_lock); diff --git a/techpack/audio/asoc/codecs/bolero/rx-macro.c b/techpack/audio/asoc/codecs/bolero/rx-macro.c index 063a1b6f402d..5f096a255334 100644 --- a/techpack/audio/asoc/codecs/bolero/rx-macro.c +++ b/techpack/audio/asoc/codecs/bolero/rx-macro.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -1296,7 +1297,7 @@ static int rx_macro_mclk_enable(struct rx_macro_priv *rx_priv, } } exit: - trace_printk("%s: mclk_enable = %u, dapm = %d clk_users= %d\n", + dev_dbg(rx_priv->dev, "%s: mclk_enable = %u, dapm = %d clk_users= %d\n", __func__, mclk_enable, dapm, rx_priv->rx_mclk_users); mutex_unlock(&rx_priv->mclk_lock); return ret; @@ -1383,7 +1384,6 @@ static int rx_macro_event_handler(struct snd_soc_component *component, rx_macro_wcd_clsh_imped_config(component, data, false); break; case BOLERO_MACRO_EVT_SSR_DOWN: - trace_printk("%s, enter SSR down\n", __func__); rx_priv->dev_up = false; if (rx_priv->swr_ctrl_data) { swrm_wcd_notify( @@ -1418,7 +1418,6 @@ static int rx_macro_event_handler(struct snd_soc_component *component, rx_macro_core_vote(rx_priv, false); break; case BOLERO_MACRO_EVT_SSR_UP: - trace_printk("%s, enter SSR up\n", __func__); rx_priv->dev_up = true; /* reset swr after ssr/pdr */ rx_priv->reset_swr = true; @@ -3715,8 +3714,6 @@ static int rx_swrm_clock(void *handle, bool enable) mutex_lock(&rx_priv->swr_clk_lock); - trace_printk("%s: swrm clock %s\n", - __func__, (enable ? "enable" : "disable")); dev_dbg(rx_priv->dev, "%s: swrm clock %s\n", __func__, (enable ? "enable" : "disable")); if (enable) { @@ -3783,8 +3780,6 @@ static int rx_swrm_clock(void *handle, bool enable) } } } - trace_printk("%s: swrm clock users %d\n", - __func__, rx_priv->swr_clk_users); dev_dbg(rx_priv->dev, "%s: swrm clock users %d\n", __func__, rx_priv->swr_clk_users); exit: diff --git a/techpack/audio/asoc/codecs/bolero/tx-macro.c b/techpack/audio/asoc/codecs/bolero/tx-macro.c index bd04e85b507f..b6c15749d666 100644 --- a/techpack/audio/asoc/codecs/bolero/tx-macro.c +++ b/techpack/audio/asoc/codecs/bolero/tx-macro.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -374,7 +375,6 @@ static int tx_macro_event_handler(struct snd_soc_component *component, switch (event) { case BOLERO_MACRO_EVT_SSR_DOWN: - trace_printk("%s, enter SSR down\n", __func__); if (tx_priv->swr_ctrl_data) { swrm_wcd_notify( tx_priv->swr_ctrl_data[0].tx_swr_pdev, @@ -391,7 +391,6 @@ static int tx_macro_event_handler(struct snd_soc_component *component, } break; case BOLERO_MACRO_EVT_SSR_UP: - trace_printk("%s, enter SSR up\n", __func__); /* reset swr after ssr/pdr */ tx_priv->reset_swr = true; if (tx_priv->swr_ctrl_data) @@ -2461,9 +2460,6 @@ static int tx_macro_tx_va_mclk_enable(struct tx_macro_priv *tx_priv, { int ret = 0, clk_tx_ret = 0; - trace_printk("%s: clock type %s, enable: %s tx_mclk_users: %d\n", - __func__, (clk_type ? "VA_MCLK" : "TX_MCLK"), - (enable ? "enable" : "disable"), tx_priv->tx_mclk_users); dev_dbg(tx_priv->dev, "%s: clock type %s, enable: %s tx_mclk_users: %d\n", __func__, (clk_type ? "VA_MCLK" : "TX_MCLK"), @@ -2471,7 +2467,6 @@ static int tx_macro_tx_va_mclk_enable(struct tx_macro_priv *tx_priv, if (enable) { if (tx_priv->swr_clk_users == 0) { - trace_printk("%s: tx swr clk users 0\n", __func__); ret = msm_cdc_pinctrl_select_active_state( tx_priv->tx_swr_gpio_p); if (ret < 0) { @@ -2489,7 +2484,6 @@ static int tx_macro_tx_va_mclk_enable(struct tx_macro_priv *tx_priv, TX_CORE_CLK, true); if (clk_type == TX_MCLK) { - trace_printk("%s: requesting TX_MCLK\n", __func__); ret = tx_macro_mclk_enable(tx_priv, 1); if (ret < 0) { if (tx_priv->swr_clk_users == 0) @@ -2502,7 +2496,6 @@ static int tx_macro_tx_va_mclk_enable(struct tx_macro_priv *tx_priv, } } if (clk_type == VA_MCLK) { - trace_printk("%s: requesting VA_MCLK\n", __func__); ret = bolero_clk_rsc_request_clock(tx_priv->dev, TX_CORE_CLK, VA_CORE_CLK, @@ -2534,8 +2527,6 @@ static int tx_macro_tx_va_mclk_enable(struct tx_macro_priv *tx_priv, if (tx_priv->swr_clk_users == 0) { dev_dbg(tx_priv->dev, "%s: reset_swr: %d\n", __func__, tx_priv->reset_swr); - trace_printk("%s: reset_swr: %d\n", - __func__, tx_priv->reset_swr); if (tx_priv->reset_swr) regmap_update_bits(regmap, BOLERO_CDC_TX_CLK_RST_CTRL_SWR_CONTROL, @@ -2631,7 +2622,6 @@ done: TX_CORE_CLK, false); exit: - trace_printk("%s: exit\n", __func__); return ret; } @@ -2711,10 +2701,6 @@ static int tx_macro_swrm_clock(void *handle, bool enable) } mutex_lock(&tx_priv->swr_clk_lock); - trace_printk("%s: swrm clock %s tx_swr_clk_cnt: %d va_swr_clk_cnt: %d\n", - __func__, - (enable ? "enable" : "disable"), - tx_priv->tx_swr_clk_cnt, tx_priv->va_swr_clk_cnt); dev_dbg(tx_priv->dev, "%s: swrm clock %s tx_swr_clk_cnt: %d va_swr_clk_cnt: %d\n", __func__, (enable ? "enable" : "disable"), @@ -2777,9 +2763,6 @@ static int tx_macro_swrm_clock(void *handle, bool enable) } } - trace_printk("%s: swrm clock users %d tx_clk_sts_cnt: %d va_clk_sts_cnt: %d\n", - __func__, tx_priv->swr_clk_users, tx_priv->tx_clk_status, - tx_priv->va_clk_status); dev_dbg(tx_priv->dev, "%s: swrm clock users %d tx_clk_sts_cnt: %d va_clk_sts_cnt: %d\n", __func__, tx_priv->swr_clk_users, tx_priv->tx_clk_status, diff --git a/techpack/audio/asoc/codecs/bolero/va-macro.c b/techpack/audio/asoc/codecs/bolero/va-macro.c index 2b989b1f2792..20cadd0442ef 100644 --- a/techpack/audio/asoc/codecs/bolero/va-macro.c +++ b/techpack/audio/asoc/codecs/bolero/va-macro.c @@ -314,7 +314,6 @@ static int va_macro_event_handler(struct snd_soc_component *component, VA_CORE_CLK, false); break; case BOLERO_MACRO_EVT_SSR_UP: - trace_printk("%s, enter SSR up\n", __func__); /* reset swr after ssr/pdr */ va_priv->reset_swr = true; if (va_priv->swr_ctrl_data) diff --git a/techpack/audio/asoc/codecs/bolero/wsa-macro.c b/techpack/audio/asoc/codecs/bolero/wsa-macro.c index 4e06d12bea90..e0c4ff416147 100644 --- a/techpack/audio/asoc/codecs/bolero/wsa-macro.c +++ b/techpack/audio/asoc/codecs/bolero/wsa-macro.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -1007,7 +1008,6 @@ static int wsa_macro_event_handler(struct snd_soc_component *component, switch (event) { case BOLERO_MACRO_EVT_SSR_DOWN: - trace_printk("%s, enter SSR down\n", __func__); if (wsa_priv->swr_ctrl_data) { swrm_wcd_notify( wsa_priv->swr_ctrl_data[0].wsa_swr_pdev, @@ -1038,7 +1038,6 @@ static int wsa_macro_event_handler(struct snd_soc_component *component, WSA_CORE_CLK, false); break; case BOLERO_MACRO_EVT_SSR_UP: - trace_printk("%s, enter SSR up\n", __func__); /* reset swr after ssr/pdr */ wsa_priv->reset_swr = true; if (wsa_priv->swr_ctrl_data) @@ -2862,9 +2861,6 @@ static int wsa_swrm_clock(void *handle, bool enable) mutex_lock(&wsa_priv->swr_clk_lock); - trace_printk("%s: %s swrm clock %s\n", - dev_name(wsa_priv->dev), __func__, - (enable ? "enable" : "disable")); dev_dbg(wsa_priv->dev, "%s: swrm clock %s\n", __func__, (enable ? "enable" : "disable")); if (enable) { @@ -2930,9 +2926,6 @@ static int wsa_swrm_clock(void *handle, bool enable) } } } - trace_printk("%s: %s swrm clock users: %d\n", - dev_name(wsa_priv->dev), __func__, - wsa_priv->swr_clk_users); dev_dbg(wsa_priv->dev, "%s: swrm clock users %d\n", __func__, wsa_priv->swr_clk_users); exit: diff --git a/techpack/audio/asoc/msm-dai-q6-v2.c b/techpack/audio/asoc/msm-dai-q6-v2.c index 1effeceeabaf..ab1a357bcdd2 100644 --- a/techpack/audio/asoc/msm-dai-q6-v2.c +++ b/techpack/audio/asoc/msm-dai-q6-v2.c @@ -1287,7 +1287,6 @@ static int msm_dai_q6_island_mode_put(struct snd_kcontrol *kcontrol, u16 port_id = (u16)kcontrol->private_value; pr_debug("%s: island mode = %d\n", __func__, value); - trace_printk("%s: island mode = %d\n", __func__, value); afe_set_island_mode_cfg(port_id, value); return 0; diff --git a/techpack/audio/dsp/digital-cdc-rsc-mgr.c b/techpack/audio/dsp/digital-cdc-rsc-mgr.c index be5d5cad79d7..b4cb22f75cb9 100644 --- a/techpack/audio/dsp/digital-cdc-rsc-mgr.c +++ b/techpack/audio/dsp/digital-cdc-rsc-mgr.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -33,7 +34,6 @@ int digital_cdc_rsc_mgr_hw_vote_enable(struct clk* vote_handle) mutex_unlock(&hw_vote_lock); pr_debug("%s: return %d\n", __func__, ret); - trace_printk("%s: return %d\n", __func__, ret); return ret; } EXPORT_SYMBOL(digital_cdc_rsc_mgr_hw_vote_enable); @@ -55,7 +55,7 @@ void digital_cdc_rsc_mgr_hw_vote_disable(struct clk* vote_handle) mutex_lock(&hw_vote_lock); clk_disable_unprepare(vote_handle); mutex_unlock(&hw_vote_lock); - trace_printk("%s\n", __func__); + pr_debug("%s\n", __func__); } EXPORT_SYMBOL(digital_cdc_rsc_mgr_hw_vote_disable); @@ -79,7 +79,6 @@ void digital_cdc_rsc_mgr_hw_vote_reset(struct clk* vote_handle) count++; } pr_debug("%s: Vote count after SSR: %d\n", __func__, count); - trace_printk("%s: Vote count after SSR: %d\n", __func__, count); while (count--) clk_prepare_enable(vote_handle); diff --git a/techpack/audio/dsp/q6afe.c b/techpack/audio/dsp/q6afe.c index 0fdeaae0e905..490f1708d372 100644 --- a/techpack/audio/dsp/q6afe.c +++ b/techpack/audio/dsp/q6afe.c @@ -1543,8 +1543,6 @@ static int afe_apr_send_pkt(void *data, wait_queue_head_t *wait) pr_err_ratelimited("%s: request timedout\n", __func__); ret = -ETIMEDOUT; - trace_printk("%s: wait for ADSP response timed out\n", - __func__); } else if (atomic_read(&this_afe.status) > 0) { pr_err("%s: DSP returned error[%s]\n", __func__, adsp_err_get_err_str(atomic_read( @@ -3335,8 +3333,6 @@ int afe_send_port_island_mode(u16 port_id) } pr_debug("%s: AFE set island mode 0x%x enable for port 0x%x ret %d\n", __func__, island_mode, port_id, ret); - trace_printk("%s: AFE set island mode 0x%x enable for port 0x%x ret %d\n", - __func__, island_mode, port_id, ret); return ret; } EXPORT_SYMBOL(afe_send_port_island_mode); @@ -4659,8 +4655,6 @@ void afe_set_island_mode_cfg(u16 port_id, u32 enable_flag) port_index = afe_get_port_index(port_id); this_afe.island_mode[port_index] = enable_flag; - trace_printk("%s: set island mode cfg 0x%x for port 0x%x\n", - __func__, this_afe.island_mode[port_index], port_id); } EXPORT_SYMBOL(afe_set_island_mode_cfg); @@ -8852,15 +8846,6 @@ int afe_set_lpass_clock(u16 port_id, struct afe_clk_cfg *cfg) cfg->clk_root, cfg->clk_set_mode, cfg->reserved, q6audio_get_port_id(port_id)); - trace_printk("%s: Minor version =0x%x clk val1 = %d\n" - "clk val2 = %d, clk src = 0x%x\n" - "clk root = 0x%x clk mode = 0x%x resrv = 0x%x\n" - "port id = 0x%x\n", - __func__, cfg->i2s_cfg_minor_version, - cfg->clk_val1, cfg->clk_val2, cfg->clk_src, - cfg->clk_root, cfg->clk_set_mode, - cfg->reserved, q6audio_get_port_id(port_id)); - ret = q6afe_pack_and_set_param_in_band(port_id, q6audio_get_port_index(port_id), param_hdr, (u8 *) &clk_cfg); @@ -9195,20 +9180,11 @@ int afe_set_lpass_clk_cfg(int index, struct afe_clk_set *cfg) cfg->clk_id, cfg->clk_freq_in_hz, cfg->clk_attri, cfg->clk_root, cfg->enable); - trace_printk("%s: Minor version =0x%x clk id = %d\n" - "clk freq (Hz) = %d, clk attri = 0x%x\n" - "clk root = 0x%x clk enable = 0x%x\n", - __func__, cfg->clk_set_minor_version, - cfg->clk_id, cfg->clk_freq_in_hz, cfg->clk_attri, - cfg->clk_root, cfg->enable); - ret = q6afe_svc_pack_and_set_param_in_band(index, param_hdr, (u8 *) cfg); if (ret < 0) { pr_err_ratelimited("%s: AFE clk cfg failed with ret %d\n", __func__, ret); - trace_printk("%s: AFE clk cfg failed with ret %d\n", - __func__, ret); } mutex_unlock(&this_afe.afe_clk_lock); return ret; @@ -11282,8 +11258,6 @@ int afe_vote_lpass_core_hw(uint32_t hw_block_id, char *client_name, pr_debug("%s: lpass core hw vote opcode[0x%x] hw id[0x%x]\n", __func__, cmd_ptr->hdr.opcode, cmd_ptr->hw_block_id); - trace_printk("%s: lpass core hw vote opcode[0x%x] hw id[0x%x]\n", - __func__, cmd_ptr->hdr.opcode, cmd_ptr->hw_block_id); *client_handle = 0; ret = afe_apr_send_clk_pkt((uint32_t *)cmd_ptr, @@ -11323,7 +11297,6 @@ int afe_unvote_lpass_core_hw(uint32_t hw_block_id, uint32_t client_handle) if (!this_afe.lpass_hw_core_client_hdl[hw_block_id]) { pr_debug("%s: SSR in progress, return\n", __func__); - trace_printk("%s: SSR in progress, return\n", __func__); goto done; } @@ -11343,9 +11316,6 @@ int afe_unvote_lpass_core_hw(uint32_t hw_block_id, uint32_t client_handle) pr_debug("%s: lpass core hw unvote opcode[0x%x] hw id[0x%x]\n", __func__, cmd_ptr->hdr.opcode, cmd_ptr->hw_block_id); - trace_printk("%s: lpass core hw unvote opcode[0x%x] hw id[0x%x]\n", - __func__, cmd_ptr->hdr.opcode, cmd_ptr->hw_block_id); - if (cmd_ptr->client_handle <= 0) { pr_err("%s: invalid client handle\n", __func__); ret = -EINVAL; diff --git a/techpack/audio/soc/pinctrl-lpi.c b/techpack/audio/soc/pinctrl-lpi.c index ec075e828bc1..4b0a1143c004 100644 --- a/techpack/audio/soc/pinctrl-lpi.c +++ b/techpack/audio/soc/pinctrl-lpi.c @@ -516,7 +516,6 @@ int lpi_pinctrl_suspend(struct device *dev) { int ret = 0; - trace_printk("%s: system suspend\n", __func__); dev_dbg(dev, "%s: system suspend\n", __func__); if ((!pm_runtime_enabled(dev) || !pm_runtime_suspended(dev))) { @@ -553,7 +552,6 @@ static struct notifier_block service_nb = { static void lpi_pinctrl_ssr_disable(struct device *dev, void *data) { - trace_printk("%s: enter\n", __func__); lpi_dev_up = false; lpi_pinctrl_suspend(dev); } @@ -878,7 +876,6 @@ int lpi_pinctrl_runtime_resume(struct device *dev) int ret = 0; struct clk *hw_vote = state->lpass_core_hw_vote; - trace_printk("%s: enter\n", __func__); if (state->lpass_core_hw_vote == NULL) { dev_dbg(dev, "%s: Invalid core hw node\n", __func__); if (state->lpass_audio_hw_vote == NULL) { @@ -904,7 +901,6 @@ int lpi_pinctrl_runtime_resume(struct device *dev) exit: mutex_unlock(&state->core_hw_vote_lock); - trace_printk("%s: exit\n", __func__); return 0; } @@ -913,7 +909,6 @@ int lpi_pinctrl_runtime_suspend(struct device *dev) struct lpi_gpio_state *state = dev_get_drvdata(dev); struct clk *hw_vote = state->lpass_core_hw_vote; - trace_printk("%s: enter\n", __func__); if (state->lpass_core_hw_vote == NULL) { dev_dbg(dev, "%s: Invalid core hw node\n", __func__); if (state->lpass_audio_hw_vote == NULL) { @@ -929,7 +924,6 @@ int lpi_pinctrl_runtime_suspend(struct device *dev) state->core_hw_vote_status = false; } mutex_unlock(&state->core_hw_vote_lock); - trace_printk("%s: exit\n", __func__); return 0; } diff --git a/techpack/audio/soc/swr-mstr-ctrl.c b/techpack/audio/soc/swr-mstr-ctrl.c index f8659d9e1b21..7e60a297796e 100644 --- a/techpack/audio/soc/swr-mstr-ctrl.c +++ b/techpack/audio/soc/swr-mstr-ctrl.c @@ -381,8 +381,6 @@ static int swrm_request_hw_vote(struct swr_mstr_ctrl *swrm, if (!swrm->dev_up) { dev_dbg(swrm->dev, "%s: device is down or SSR state\n", __func__); - trace_printk("%s: device is down or SSR state\n", - __func__); mutex_unlock(&swrm->devlock); return -ENODEV; } @@ -413,8 +411,6 @@ static int swrm_request_hw_vote(struct swr_mstr_ctrl *swrm, if (!swrm->dev_up) { dev_dbg(swrm->dev, "%s: device is down or SSR state\n", __func__); - trace_printk("%s: device is down or SSR state\n", - __func__); mutex_unlock(&swrm->devlock); return -ENODEV; } @@ -443,8 +439,6 @@ static int swrm_request_hw_vote(struct swr_mstr_ctrl *swrm, mutex_unlock(&swrm->devlock); dev_dbg(swrm->dev, "%s: hw_clk_en: %d audio_core_clk_en: %d\n", __func__, swrm->hw_core_clk_en, swrm->aud_core_clk_en); - trace_printk("%s: hw_clk_en: %d audio_core_clk_en: %d\n", - __func__, swrm->hw_core_clk_en, swrm->aud_core_clk_en); return ret; } @@ -510,8 +504,6 @@ static int swrm_clk_request(struct swr_mstr_ctrl *swrm, bool enable) } swrm->clk_ref_count++; if (swrm->clk_ref_count == 1) { - trace_printk("%s: clock enable count %d", - __func__, swrm->clk_ref_count); ret = swrm->clk(swrm->handle, true); if (ret) { dev_err_ratelimited(swrm->dev, @@ -521,8 +513,6 @@ static int swrm_clk_request(struct swr_mstr_ctrl *swrm, bool enable) } } } else if (--swrm->clk_ref_count == 0) { - trace_printk("%s: clock disable count %d", - __func__, swrm->clk_ref_count); swrm->clk(swrm->handle, false); complete(&swrm->clk_off_complete); } @@ -1835,7 +1825,6 @@ static irqreturn_t swr_mstr_interrupt(int irq, void *dev) struct swr_device *swr_dev; struct swr_master *mstr = &swrm->master; - trace_printk("%s enter\n", __func__); if (unlikely(swrm_lock_sleep(swrm) == false)) { dev_err(swrm->dev, "%s Failed to hold suspend\n", __func__); return IRQ_NONE; @@ -1853,7 +1842,6 @@ static irqreturn_t swr_mstr_interrupt(int irq, void *dev) intr_sts = swr_master_read(swrm, SWRM_INTERRUPT_STATUS); intr_sts_masked = intr_sts & swrm->intr_mask; - trace_printk("%s: status: 0x%x \n", __func__, intr_sts_masked); handle_irq: for (i = 0; i < SWRM_INTERRUPT_MAX; i++) { value = intr_sts_masked & (1 << i); @@ -1998,7 +1986,6 @@ handle_irq: mutex_unlock(&swrm->reslock); exit: swrm_unlock_sleep(swrm); - trace_printk("%s exit\n", __func__); return ret; } @@ -2013,7 +2000,6 @@ static irqreturn_t swr_mstr_interrupt_v2(int irq, void *dev) struct swr_device *swr_dev; struct swr_master *mstr = &swrm->master; - trace_printk("%s enter\n", __func__); if (unlikely(swrm_lock_sleep(swrm) == false)) { dev_err(swrm->dev, "%s Failed to hold suspend\n", __func__); return IRQ_NONE; @@ -2040,7 +2026,6 @@ static irqreturn_t swr_mstr_interrupt_v2(int irq, void *dev) intr_sts_masked = intr_sts & swrm->intr_mask; dev_dbg(swrm->dev, "%s: status: 0x%x \n", __func__, intr_sts_masked); - trace_printk("%s: status: 0x%x \n", __func__, intr_sts_masked); handle_irq: for (i = 0; i < SWRM_INTERRUPT_MAX; i++) { value = intr_sts_masked & (1 << i); @@ -2245,7 +2230,6 @@ err_audio_hw_vote: exit: mutex_unlock(&swrm->reslock); swrm_unlock_sleep(swrm); - trace_printk("%s exit\n", __func__); return ret; } @@ -2259,7 +2243,6 @@ static irqreturn_t swrm_wakeup_interrupt(int irq, void *dev) return IRQ_NONE; } - trace_printk("%s enter\n", __func__); mutex_lock(&swrm->devlock); if (!swrm->dev_up) { if (swrm->wake_irq > 0) { @@ -2298,7 +2281,6 @@ static irqreturn_t swrm_wakeup_interrupt(int irq, void *dev) pm_runtime_put_autosuspend(swrm->dev); swrm_unlock_sleep(swrm); exit: - trace_printk("%s exit\n", __func__); return ret; } @@ -2313,7 +2295,6 @@ static void swrm_wakeup_work(struct work_struct *work) return; } - trace_printk("%s enter\n", __func__); mutex_lock(&swrm->devlock); if (!swrm->dev_up) { mutex_unlock(&swrm->devlock); @@ -2329,7 +2310,6 @@ static void swrm_wakeup_work(struct work_struct *work) pm_runtime_put_autosuspend(swrm->dev); swrm_unlock_sleep(swrm); exit: - trace_printk("%s exit\n", __func__); pm_relax(swrm->dev); } @@ -3041,8 +3021,6 @@ static int swrm_runtime_resume(struct device *dev) dev_dbg(dev, "%s: pm_runtime: resume, state:%d\n", __func__, swrm->state); - trace_printk("%s: pm_runtime: resume, state:%d\n", - __func__, swrm->state); mutex_lock(&swrm->reslock); if (swrm_request_hw_vote(swrm, LPASS_HW_CORE, true)) { @@ -3093,9 +3071,6 @@ static int swrm_runtime_resume(struct device *dev) dev_dbg(dev, "%s slave device up not implemented\n", __func__); - trace_printk( - "%s slave device up not implemented\n", - __func__); ret = 0; } else if (ret) { dev_err(dev, @@ -3153,8 +3128,6 @@ exit: swrm->req_clk_switch = false; mutex_unlock(&swrm->reslock); - trace_printk("%s: pm_runtime: resume done, state:%d\n", - __func__, swrm->state); return ret; } @@ -3170,8 +3143,6 @@ static int swrm_runtime_suspend(struct device *dev) int current_state = 0; struct irq_data *irq_data = NULL; - trace_printk("%s: pm_runtime: suspend state: %d\n", - __func__, swrm->state); dev_dbg(dev, "%s: pm_runtime: suspend state: %d\n", __func__, swrm->state); if (swrm->state == SWR_MSTR_SSR_RESET) { @@ -3200,7 +3171,6 @@ static int swrm_runtime_suspend(struct device *dev) if ((current_state != SWR_MSTR_SSR) && swrm_is_port_en(&swrm->master)) { dev_dbg(dev, "%s ports are enabled\n", __func__); - trace_printk("%s ports are enabled\n", __func__); ret = -EBUSY; goto exit; } @@ -3234,22 +3204,14 @@ static int swrm_runtime_suspend(struct device *dev) dev_dbg_ratelimited(dev, "%s slave device down not implemented\n", __func__); - trace_printk( - "%s slave device down not implemented\n", - __func__); ret = 0; } else if (ret) { dev_err(dev, "%s: failed to shutdown swr dev %d\n", __func__, swr_dev->dev_num); - trace_printk( - "%s: failed to shutdown swr dev %d\n", - __func__, swr_dev->dev_num); goto exit; } } - trace_printk("%s: clk stop mode not supported or SSR exit\n", - __func__); } else { /* Mask bus clash interrupt */ swrm->intr_mask &= ~((u32)0x08); @@ -3297,8 +3259,6 @@ exit: if (!hw_core_err) swrm_request_hw_vote(swrm, LPASS_HW_CORE, false); mutex_unlock(&swrm->reslock); - trace_printk("%s: pm_runtime: suspend done state: %d\n", - __func__, swrm->state); return ret; } #endif /* CONFIG_PM */ @@ -3310,7 +3270,6 @@ static int swrm_device_suspend(struct device *dev) int ret = 0; dev_dbg(dev, "%s: swrm state: %d\n", __func__, swrm->state); - trace_printk("%s: swrm state: %d\n", __func__, swrm->state); if (!pm_runtime_enabled(dev) || !pm_runtime_suspended(dev)) { ret = swrm_runtime_suspend(dev); if (!ret) { @@ -3329,7 +3288,6 @@ static int swrm_device_down(struct device *dev) struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev); dev_dbg(dev, "%s: swrm state: %d\n", __func__, swrm->state); - trace_printk("%s: swrm state: %d\n", __func__, swrm->state); mutex_lock(&swrm->force_down_lock); swrm->state = SWR_MSTR_SSR; @@ -3507,7 +3465,6 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data) } break; case SWR_DEVICE_SSR_DOWN: - trace_printk("%s: swr device down called\n", __func__); mutex_lock(&swrm->mlock); if (swrm->state == SWR_MSTR_DOWN) dev_dbg(swrm->dev, "%s:SWR master is already Down:%d\n", @@ -3526,7 +3483,6 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data) break; case SWR_DEVICE_SSR_UP: /* wait for clk voting to be zero */ - trace_printk("%s: swr device up called\n", __func__); reinit_completion(&swrm->clk_off_complete); if (swrm->clk_ref_count && !wait_for_completion_timeout(&swrm->clk_off_complete, @@ -3552,7 +3508,6 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data) break; case SWR_DEVICE_DOWN: dev_dbg(swrm->dev, "%s: swr master down called\n", __func__); - trace_printk("%s: swr master down called\n", __func__); mutex_lock(&swrm->mlock); if (swrm->state == SWR_MSTR_DOWN) dev_dbg(swrm->dev, "%s:SWR master is already Down:%d\n", @@ -3563,7 +3518,6 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data) break; case SWR_DEVICE_UP: dev_dbg(swrm->dev, "%s: swr master up called\n", __func__); - trace_printk("%s: swr master up called\n", __func__); mutex_lock(&swrm->devlock); if (!swrm->dev_up) { dev_dbg(swrm->dev, "SSR not complete yet\n"); From 327fcc87ed7eb90387deb3e0817fece30a9a6744 Mon Sep 17 00:00:00 2001 From: Alan Maguire Date: Mon, 13 Jul 2020 12:52:33 +0100 Subject: [PATCH 03/12] bpf: Use dedicated bpf_trace_printk event instead of trace_printk() The bpf helper bpf_trace_printk() uses trace_printk() under the hood. This leads to an alarming warning message originating from trace buffer allocation which occurs the first time a program using bpf_trace_printk() is loaded. We can instead create a trace event for bpf_trace_printk() and enable it in-kernel when/if we encounter a program using the bpf_trace_printk() helper. With this approach, trace_printk() is not used directly and no warning message appears. This work was started by Steven (see Link) and finished by Alan; added Steven's Signed-off-by with his permission. Change-Id: Ie1e4cf1dce934e62613440b5081cb757cdbe982c Signed-off-by: Steven Rostedt (VMware) Signed-off-by: Alan Maguire Signed-off-by: Alexei Starovoitov Acked-by: Andrii Nakryiko Link: https://lore.kernel.org/r/20200628194334.6238b933@oasis.local.home Link: https://lore.kernel.org/bpf/1594641154-18897-2-git-send-email-alan.maguire@oracle.com --- kernel/trace/Makefile | 2 ++ kernel/trace/bpf_trace.c | 42 +++++++++++++++++++++++++++++++++++----- kernel/trace/bpf_trace.h | 34 ++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 5 deletions(-) create mode 100644 kernel/trace/bpf_trace.h diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile index f5226374d79c..211476dbed44 100644 --- a/kernel/trace/Makefile +++ b/kernel/trace/Makefile @@ -28,6 +28,8 @@ ifdef CONFIG_GCOV_PROFILE_FTRACE GCOV_PROFILE := y endif +CFLAGS_bpf_trace.o := -I$(src) + CFLAGS_trace_benchmark.o := -I$(src) CFLAGS_trace_events_filter.o := -I$(src) diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c index 6317249a434f..2c4f414bf0b8 100644 --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c @@ -11,12 +11,16 @@ #include #include #include +#include #include #include #include "trace_probe.h" #include "trace.h" +#define CREATE_TRACE_POINTS +#include "bpf_trace.h" + u64 bpf_get_stackid(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5); u64 bpf_get_stack(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5); @@ -156,6 +160,30 @@ static const struct bpf_func_proto *bpf_get_probe_write_proto(void) return &bpf_probe_write_user_proto; } +static DEFINE_RAW_SPINLOCK(trace_printk_lock); + +#define BPF_TRACE_PRINTK_SIZE 1024 + +static inline __printf(1, 0) int bpf_do_trace_printk(const char *fmt, ...) +{ + static char buf[BPF_TRACE_PRINTK_SIZE]; + unsigned long flags; + va_list ap; + int ret; + + raw_spin_lock_irqsave(&trace_printk_lock, flags); + va_start(ap, fmt); + ret = vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + /* vsnprintf() will not append null for zero-length strings */ + if (ret == 0) + buf[0] = '\0'; + trace_bpf_trace_printk(buf); + raw_spin_unlock_irqrestore(&trace_printk_lock, flags); + + return ret; +} + /* * Only limited trace_printk() conversion specifiers allowed: * %d %i %u %x %ld %li %lu %lx %lld %lli %llu %llx %p %s @@ -246,8 +274,7 @@ BPF_CALL_5(bpf_trace_printk, char *, fmt, u32, fmt_size, u64, arg1, */ #define __BPF_TP_EMIT() __BPF_ARG3_TP() #define __BPF_TP(...) \ - __trace_printk(0 /* Fake ip */, \ - fmt, ##__VA_ARGS__) + bpf_do_trace_printk(fmt, ##__VA_ARGS__) #define __BPF_ARG1_TP(...) \ ((mod[0] == 2 || (mod[0] == 1 && __BITS_PER_LONG == 64)) \ @@ -284,10 +311,15 @@ static const struct bpf_func_proto bpf_trace_printk_proto = { const struct bpf_func_proto *bpf_get_trace_printk_proto(void) { /* - * this program might be calling bpf_trace_printk, - * so allocate per-cpu printk buffers + * This program might be calling bpf_trace_printk, + * so enable the associated bpf_trace/bpf_trace_printk event. + * Repeat this each time as it is possible a user has + * disabled bpf_trace_printk events. By loading a program + * calling bpf_trace_printk() however the user has expressed + * the intent to see such events. */ - trace_printk_init_buffers(); + if (trace_set_clr_event("bpf_trace", "bpf_trace_printk", 1)) + pr_warn_ratelimited("could not enable bpf_trace_printk events"); return &bpf_trace_printk_proto; } diff --git a/kernel/trace/bpf_trace.h b/kernel/trace/bpf_trace.h new file mode 100644 index 000000000000..9acbc11ac7bb --- /dev/null +++ b/kernel/trace/bpf_trace.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM bpf_trace + +#if !defined(_TRACE_BPF_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) + +#define _TRACE_BPF_TRACE_H + +#include + +TRACE_EVENT(bpf_trace_printk, + + TP_PROTO(const char *bpf_string), + + TP_ARGS(bpf_string), + + TP_STRUCT__entry( + __string(bpf_string, bpf_string) + ), + + TP_fast_assign( + __assign_str(bpf_string, bpf_string); + ), + + TP_printk("%s", __get_str(bpf_string)) +); + +#endif /* _TRACE_BPF_TRACE_H */ + +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH . +#define TRACE_INCLUDE_FILE bpf_trace + +#include From f973db0464b34af2fe01ecc72512ad1166538ac0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barnab=C3=A1s=20Cz=C3=A9m=C3=A1n?= Date: Thu, 24 Oct 2024 22:44:08 +0800 Subject: [PATCH 04/12] clk/qcom/clk-alpha-pll: Fix pll post div mask when width is not set MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Many qcom clock drivers do not have .width set. In that case value of (p)->width - 1 will be negative which breaks clock tree. Fix this by checking if width is zero, and pass 3 to GENMASK if that's the case. Fixes: 1c35411 ("clk: qcom: support for 2 bit PLL post divider") Change-Id: I8e4fa923b1183a14c7893f08597a8289f8c3e3b8 Signed-off-by: Barnabás Czémán Reviewed-by: Dmitry Baryshkov Reviewed-by: Christopher Obbard Tested-by: Christopher Obbard Link: https://lore.kernel.org/r/20241006-fix-postdiv-mask-v3-1-160354980433@mainlining.org Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/clk-alpha-pll.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c index 978b891b2dd6..148e88301c84 100644 --- a/drivers/clk/qcom/clk-alpha-pll.c +++ b/drivers/clk/qcom/clk-alpha-pll.c @@ -44,7 +44,7 @@ #define PLL_USER_CTL(p) ((p)->offset + (p)->regs[PLL_OFF_USER_CTL]) #define PLL_POST_DIV_SHIFT 8 -#define PLL_POST_DIV_MASK(p) GENMASK((p)->width - 1, 0) +#define PLL_POST_DIV_MASK(p) GENMASK((p)->width ? (p)->width - 1 : 3, 0) #define PLL_ALPHA_EN BIT(24) #define PLL_ALPHA_MODE BIT(25) #define PLL_VCO_SHIFT 20 From 90e35adc2c73d6efc7f4cefe254e1a281518a5ad Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Fri, 23 Nov 2018 23:18:03 +0100 Subject: [PATCH 05/12] bpf: add __weak hook for allocating executable memory By default, BPF uses module_alloc() to allocate executable memory, but this is not necessary on all arches and potentially undesirable on some of them. So break out the module_alloc() and module_memfree() calls into __weak functions to allow them to be overridden in arch code. Signed-off-by: Ard Biesheuvel Signed-off-by: Daniel Borkmann Signed-off-by: Danny Lin Change-Id: I582794881942bc0b766515861f2232354860536b --- kernel/bpf/core.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c index 14f453a768e6..87d8cd8d3d8b 100644 --- a/kernel/bpf/core.c +++ b/kernel/bpf/core.c @@ -627,6 +627,16 @@ static void bpf_jit_uncharge_modmem(u32 pages) atomic_long_sub(pages, &bpf_jit_current); } +void *__weak bpf_jit_alloc_exec(unsigned long size) +{ + return module_alloc(size); +} + +void __weak bpf_jit_free_exec(void *addr) +{ + module_memfree(addr); +} + #if IS_ENABLED(CONFIG_BPF_JIT) && IS_ENABLED(CONFIG_CFI_CLANG) bool __weak arch_bpf_jit_check_func(const struct bpf_prog *prog) { @@ -652,7 +662,7 @@ bpf_jit_binary_alloc(unsigned int proglen, u8 **image_ptr, if (bpf_jit_charge_modmem(pages)) return NULL; - hdr = module_alloc(size); + hdr = bpf_jit_alloc_exec(size); if (!hdr) { bpf_jit_uncharge_modmem(pages); return NULL; @@ -677,7 +687,7 @@ void bpf_jit_binary_free(struct bpf_binary_header *hdr) { u32 pages = hdr->pages; - module_memfree(hdr); + bpf_jit_free_exec(hdr); bpf_jit_uncharge_modmem(pages); } From 030d374eb947bb568417170bec8be656fcd96d3e Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Fri, 23 Nov 2018 23:18:04 +0100 Subject: [PATCH 06/12] arm64/bpf: don't allocate BPF JIT programs in module memory The arm64 module region is a 128 MB region that is kept close to the core kernel, in order to ensure that relative branches are always in range. So using the same region for programs that do not have this restriction is wasteful, and preferably avoided. Now that the core BPF JIT code permits the alloc/free routines to be overridden, implement them by vmalloc()/vfree() calls from a dedicated 128 MB region set aside for BPF programs. This ensures that BPF programs are still in branching range of each other, which is something the JIT currently depends upon (and is not guaranteed when using module_alloc() on KASLR kernels like we do currently). It also ensures that placement of BPF programs does not correlate with the placement of the core kernel or modules, making it less likely that leaking the former will reveal the latter. This also solves an issue under KASAN, where shadow memory is needlessly allocated for all BPF programs (which don't require KASAN shadow pages since they are not KASAN instrumented) Signed-off-by: Ard Biesheuvel Acked-by: Will Deacon Signed-off-by: Daniel Borkmann Signed-off-by: Danny Lin Change-Id: Id3a066651f282249e8825b7bcdf9a78e84c1f878 --- arch/arm64/include/asm/memory.h | 5 ++++- arch/arm64/net/bpf_jit_comp.c | 13 +++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h index 3128c8cf98c1..f9e8eb7086f8 100644 --- a/arch/arm64/include/asm/memory.h +++ b/arch/arm64/include/asm/memory.h @@ -62,8 +62,11 @@ #define PAGE_OFFSET (UL(0xffffffffffffffff) - \ (UL(1) << (VA_BITS - 1)) + 1) #define KIMAGE_VADDR (MODULES_END) +#define BPF_JIT_REGION_START (VA_START + KASAN_SHADOW_SIZE) +#define BPF_JIT_REGION_SIZE (SZ_128M) +#define BPF_JIT_REGION_END (BPF_JIT_REGION_START + BPF_JIT_REGION_SIZE) #define MODULES_END (MODULES_VADDR + MODULES_VSIZE) -#define MODULES_VADDR (VA_START + KASAN_SHADOW_SIZE) +#define MODULES_VADDR (BPF_JIT_REGION_END) #define MODULES_VSIZE (SZ_128M) #define VMEMMAP_START (PAGE_OFFSET - VMEMMAP_SIZE) #define PCI_IO_END (VMEMMAP_START - SZ_2M) diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c index fe622cb354a9..9ca7d0978c52 100644 --- a/arch/arm64/net/bpf_jit_comp.c +++ b/arch/arm64/net/bpf_jit_comp.c @@ -964,6 +964,19 @@ out: return prog; } +void *bpf_jit_alloc_exec(unsigned long size) +{ + return __vmalloc_node_range(size, PAGE_SIZE, BPF_JIT_REGION_START, + BPF_JIT_REGION_END, GFP_KERNEL, + PAGE_KERNEL_EXEC, 0, NUMA_NO_NODE, + __builtin_return_address(0)); +} + +void bpf_jit_free_exec(void *addr) +{ + return vfree(addr); +} + #ifdef CONFIG_CFI_CLANG bool arch_bpf_jit_check_func(const struct bpf_prog *prog) { From 8e9cd82b7863b1c42a2a54d983dde795b4a7b286 Mon Sep 17 00:00:00 2001 From: Diab Neiroukh Date: Thu, 14 Jan 2021 20:32:38 +0000 Subject: [PATCH 07/12] arm64: bpf: Don't use module memory for the BPF JIT CFI check. Signed-off-by: Diab Neiroukh Change-Id: Ibe2716d57a4cb3bab3fa9d89191f7bbe9e0adc1c --- arch/arm64/net/bpf_jit_comp.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c index 9ca7d0978c52..71f460eb867e 100644 --- a/arch/arm64/net/bpf_jit_comp.c +++ b/arch/arm64/net/bpf_jit_comp.c @@ -984,17 +984,10 @@ bool arch_bpf_jit_check_func(const struct bpf_prog *prog) /* * bpf_func must be correctly aligned and within the correct region. - * module_alloc places JIT code in the module region, unless - * ARM64_MODULE_PLTS is enabled, in which case we might end up using - * the vmalloc region too. */ if (unlikely(!IS_ALIGNED(func, sizeof(u32)))) return false; - if (IS_ENABLED(CONFIG_ARM64_MODULE_PLTS) && - is_vmalloc_addr(prog->bpf_func)) - return true; - - return (func >= MODULES_VADDR && func < MODULES_END); + return (func >= BPF_JIT_REGION_START && func < BPF_JIT_REGION_END); } #endif From cee0aa0c3178d8d0d4d7d20040c10fa1d752aee3 Mon Sep 17 00:00:00 2001 From: Sami Tolvanen Date: Tue, 11 Aug 2020 11:31:11 -0700 Subject: [PATCH 08/12] ANDROID: arm64: add __va_function With CFI, the compiler replaces function references with pointers to the CFI jump table. This breaks passing these addresses to code running at EL2, where the jump tables are not valid. Add a __va_function macro similarly to the earlier __pa_function to take address of the actual function in inline assembly and use that in kvm_ksym_ref instead. Bug: 163385976 Change-Id: I097b99409995512c00786300e7d18fe42c720a1b (cherry picked from commit 2f4d6c9fd77c88ad0500aad4bf1f64aaf2654c49) Signed-off-by: Sami Tolvanen --- arch/arm64/include/asm/kvm_asm.h | 4 ++-- arch/arm64/include/asm/memory.h | 8 +++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h index e3c0dba5bdde..4be3ce91994e 100644 --- a/arch/arm64/include/asm/kvm_asm.h +++ b/arch/arm64/include/asm/kvm_asm.h @@ -40,9 +40,9 @@ /* Translate a kernel address of @sym into its equivalent linear mapping */ #define kvm_ksym_ref(sym) \ ({ \ - void *val = &sym; \ + void *val = __va_function(sym); \ if (!is_kernel_in_hyp_mode()) \ - val = lm_alias(&sym); \ + val = lm_alias(val); \ val; \ }) diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h index f9e8eb7086f8..daec82346800 100644 --- a/arch/arm64/include/asm/memory.h +++ b/arch/arm64/include/asm/memory.h @@ -326,13 +326,15 @@ static inline void *phys_to_virt(phys_addr_t x) * virtual address. Therefore, use inline assembly to ensure we are * always taking the address of the actual function. */ -#define __pa_function(x) ({ \ - unsigned long addr; \ +#define __va_function(x) ({ \ + void *addr; \ asm("adrp %0, " __stringify(x) "\n\t" \ "add %0, %0, :lo12:" __stringify(x) : "=r" (addr)); \ - __pa_symbol(addr); \ + addr; \ }) +#define __pa_function(x) __pa_symbol(__va_function(x)) + /* * virt_to_page(k) convert a _valid_ virtual address to struct page * * virt_addr_valid(k) indicates whether a virtual address is valid From 9bafb37470d34ece89c1ba7ad4b7a170736dad6f Mon Sep 17 00:00:00 2001 From: Ben Dai Date: Wed, 31 Mar 2021 09:29:17 +0800 Subject: [PATCH 09/12] ANDROID: arm64: Fix the address of ftrace_call compiled with CFI_CLANG When CONFIG_CFI_CLANG and CONFIG_DYNAMIC_FTRACE are enabled, LLVM will generate a jump function named ftrace_call.cfi_jt for ftrace_call, which makes "&ftrace_call" in ftrace_update_ftrace_func() actually the address of ftrace_call.cfi_jt. As a result, the tracer can't be really enabled through runtime modification. Use __va_function() to get the actual address of ftrace_call to fix the issue. Bug: 184105181 Signed-off-by: Ben Dai Change-Id: Ic9272cd4ab447b3b145d8e397e5c9010c49f7a12 --- arch/arm64/kernel/ftrace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/kernel/ftrace.c b/arch/arm64/kernel/ftrace.c index 4254d7808def..95120aea9c76 100644 --- a/arch/arm64/kernel/ftrace.c +++ b/arch/arm64/kernel/ftrace.c @@ -58,7 +58,7 @@ int ftrace_update_ftrace_func(ftrace_func_t func) unsigned long pc; u32 new; - pc = (unsigned long)&ftrace_call; + pc = (unsigned long)__va_function(ftrace_call); new = aarch64_insn_gen_branch_imm(pc, (unsigned long)func, AARCH64_INSN_BRANCH_LINK); From b891b375910c2f4bc13820fc526589c10125f5f6 Mon Sep 17 00:00:00 2001 From: "rogercl.yang" Date: Wed, 23 Sep 2020 11:32:32 +0800 Subject: [PATCH 10/12] ANDROID: adding __nocfi to cpuidle_enter_state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Background: When CPU is going to idle state, it would inform RCU that current CPU is entering idle through rcu_idle_enter(), and RCU will ignore read-side critical sections of this CPU. However, there is CFI check mechanism inside idle flow and calls rcu_read_lock(), so "rcu_read_lock() used illegally while idle" in rcu_read_lock() will be triggered because rcu_idle_enter() was already called before. Beside, the pointer of rcu_dereference() might be invalid due to the RCU read-side critical sections will be ignoring in this going idle CPU, it might cause problems like: access the wrong data/address, kernel exception... Based on above description: We will add __nocfi to cpuidle_enter_state to avoid “rcu_read_lock() used illegally while idle!” and avoid the usage of invalid pointer of rcu_dereference() in this situation. Bug: 169017431 Change-Id: I8bbe25704e18cfde351a8f4277dd4b44b07421f5 Signed-off-by: rogercl.yang Signed-off-by: Chun-Hung Wu --- drivers/cpuidle/cpuidle.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index 3b71fe130337..573605ead9f9 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c @@ -199,7 +199,7 @@ int cpuidle_enter_s2idle(struct cpuidle_driver *drv, struct cpuidle_device *dev) * @drv: cpuidle driver for this cpu * @index: index into the states table in @drv of the state to enter */ -int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv, +int __nocfi cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { int entered_state; From fa0cd620e374de71235105eba2261a5b3a49a5ab Mon Sep 17 00:00:00 2001 From: Alexander Winkowski Date: Sat, 29 Mar 2025 14:50:48 +0000 Subject: [PATCH 11/12] ANDROID: Update CFI patchset from android11-5.4 Change-Id: Iff956ce7c2b89d3a442b0b81deba0da323f5d18b Signed-off-by: Alexander Winkowski --- arch/arm64/kernel/cpu-reset.h | 2 +- arch/arm64/net/bpf_jit_comp.c | 10 ++--- include/linux/cfi.h | 10 ++++- include/linux/compiler-clang.h | 2 +- kernel/cfi.c | 79 +++++++++++++++++++--------------- kernel/kallsyms.c | 47 ++++++++++---------- kernel/module.c | 4 +- 7 files changed, 83 insertions(+), 71 deletions(-) diff --git a/arch/arm64/kernel/cpu-reset.h b/arch/arm64/kernel/cpu-reset.h index f300e7577688..85fa1d180f85 100644 --- a/arch/arm64/kernel/cpu-reset.h +++ b/arch/arm64/kernel/cpu-reset.h @@ -16,7 +16,7 @@ void __cpu_soft_restart(unsigned long el2_switch, unsigned long entry, unsigned long arg0, unsigned long arg1, unsigned long arg2); -static inline void __noreturn cpu_soft_restart(unsigned long entry, +static inline void __noreturn __nocfi cpu_soft_restart(unsigned long entry, unsigned long arg0, unsigned long arg1, unsigned long arg2) diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c index 71f460eb867e..c955edef232a 100644 --- a/arch/arm64/net/bpf_jit_comp.c +++ b/arch/arm64/net/bpf_jit_comp.c @@ -982,12 +982,8 @@ bool arch_bpf_jit_check_func(const struct bpf_prog *prog) { const uintptr_t func = (const uintptr_t)prog->bpf_func; - /* - * bpf_func must be correctly aligned and within the correct region. - */ - if (unlikely(!IS_ALIGNED(func, sizeof(u32)))) - return false; - - return (func >= BPF_JIT_REGION_START && func < BPF_JIT_REGION_END); + /* bpf_func must be correctly aligned and within the BPF JIT region */ + return (func >= BPF_JIT_REGION_START && func < BPF_JIT_REGION_END && + IS_ALIGNED(func, sizeof(u32))); } #endif diff --git a/include/linux/cfi.h b/include/linux/cfi.h index e27033d5dd53..6ef37b35faaa 100644 --- a/include/linux/cfi.h +++ b/include/linux/cfi.h @@ -1,3 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Clang Control Flow Integrity (CFI) support. + * + * Copyright (C) 2019 Google LLC + */ #ifndef _LINUX_CFI_H #define _LINUX_CFI_H @@ -6,13 +12,13 @@ #ifdef CONFIG_CFI_CLANG #ifdef CONFIG_MODULES -typedef void (*cfi_check_fn)(uint64_t, void *, void *); +typedef void (*cfi_check_fn)(uint64_t id, void *ptr, void *diag); /* Compiler-generated function in each module, and the kernel */ #define CFI_CHECK_FN __cfi_check #define CFI_CHECK_FN_NAME __stringify(CFI_CHECK_FN) -extern void CFI_CHECK_FN(uint64_t, void *, void *); +extern void CFI_CHECK_FN(uint64_t id, void *ptr, void *diag); #ifdef CONFIG_CFI_CLANG_SHADOW extern void cfi_module_add(struct module *mod, unsigned long min_addr, diff --git a/include/linux/compiler-clang.h b/include/linux/compiler-clang.h index a89045d3c403..08866a9ad037 100644 --- a/include/linux/compiler-clang.h +++ b/include/linux/compiler-clang.h @@ -49,7 +49,7 @@ __attribute__((__assume_aligned__(a, ## __VA_ARGS__))) #ifdef CONFIG_CFI_CLANG -#define __nocfi __attribute__((no_sanitize("cfi"))) +#define __nocfi __attribute__((__no_sanitize__("cfi"))) #endif #ifdef CONFIG_LTO_CLANG diff --git a/kernel/cfi.c b/kernel/cfi.c index 5092eaa403c7..31419747b86d 100644 --- a/kernel/cfi.c +++ b/kernel/cfi.c @@ -1,16 +1,17 @@ +// SPDX-License-Identifier: GPL-2.0 /* - * CFI (Control Flow Integrity) error and slowpath handling + * Clang Control Flow Integrity (CFI) error and slowpath handling. * - * Copyright (C) 2017 Google, Inc. + * Copyright (C) 2019 Google LLC */ #include +#include #include +#include #include #include #include -#include -#include #include #include @@ -25,12 +26,10 @@ static inline void handle_cfi_failure(void *ptr) { -#ifdef CONFIG_CFI_PERMISSIVE - WARN_RATELIMIT(1, "CFI failure (target: %pF):\n", ptr); -#else - pr_err("CFI failure (target: %pF):\n", ptr); - BUG(); -#endif + if (IS_ENABLED(CONFIG_CFI_PERMISSIVE)) + WARN_RATELIMIT(1, "CFI failure (target: %pS):\n", ptr); + else + panic("CFI failure (target: %pS)\n", ptr); } #ifdef CONFIG_MODULES @@ -44,7 +43,7 @@ struct shadow_range { unsigned long max_page; }; -#define SHADOW_ORDER 1 +#define SHADOW_ORDER 2 #define SHADOW_PAGES (1 << SHADOW_ORDER) #define SHADOW_SIZE \ ((SHADOW_PAGES * PAGE_SIZE - sizeof(struct shadow_range)) / sizeof(u16)) @@ -57,8 +56,8 @@ struct cfi_shadow { u16 shadow[SHADOW_SIZE]; }; -static DEFINE_SPINLOCK(shadow_update_lock); -static struct cfi_shadow __rcu *cfi_shadow __read_mostly = NULL; +static DEFINE_MUTEX(shadow_update_lock); +static struct cfi_shadow __rcu *cfi_shadow __read_mostly; static inline int ptr_to_shadow(const struct cfi_shadow *s, unsigned long ptr) { @@ -79,7 +78,8 @@ static inline int ptr_to_shadow(const struct cfi_shadow *s, unsigned long ptr) static inline unsigned long shadow_to_ptr(const struct cfi_shadow *s, int index) { - BUG_ON(index < 0 || index >= SHADOW_SIZE); + if (unlikely(index < 0 || index >= SHADOW_SIZE)) + return 0; if (unlikely(s->shadow[index] == SHADOW_INVALID)) return 0; @@ -90,7 +90,8 @@ static inline unsigned long shadow_to_ptr(const struct cfi_shadow *s, static inline unsigned long shadow_to_page(const struct cfi_shadow *s, int index) { - BUG_ON(index < 0 || index >= SHADOW_SIZE); + if (unlikely(index < 0 || index >= SHADOW_SIZE)) + return 0; return (s->r.min_page + index) << PAGE_SHIFT; } @@ -138,7 +139,8 @@ static void add_module_to_shadow(struct cfi_shadow *s, struct module *mod) unsigned long check = (unsigned long)mod->cfi_check; int check_index = ptr_to_shadow(s, check); - BUG_ON((check & PAGE_MASK) != check); /* Must be page aligned */ + if (unlikely((check & PAGE_MASK) != check)) + return; /* Must be page aligned */ if (check_index < 0) return; /* Module not addressable with shadow */ @@ -151,9 +153,10 @@ static void add_module_to_shadow(struct cfi_shadow *s, struct module *mod) /* For each page, store the check function index in the shadow */ for (ptr = min_page_addr; ptr <= max_page_addr; ptr += PAGE_SIZE) { int index = ptr_to_shadow(s, ptr); + if (index >= 0) { - /* Assume a page only contains code for one module */ - BUG_ON(s->shadow[index] != SHADOW_INVALID); + /* Each page must only contain one module */ + WARN_ON(s->shadow[index] != SHADOW_INVALID); s->shadow[index] = (u16)check_index; } } @@ -172,6 +175,7 @@ static void remove_module_from_shadow(struct cfi_shadow *s, struct module *mod) for (ptr = min_page_addr; ptr <= max_page_addr; ptr += PAGE_SIZE) { int index = ptr_to_shadow(s, ptr); + if (index >= 0) s->shadow[index] = SHADOW_INVALID; } @@ -186,14 +190,12 @@ static void update_shadow(struct module *mod, unsigned long min_addr, struct cfi_shadow *next = (struct cfi_shadow *) __get_free_pages(GFP_KERNEL, SHADOW_ORDER); - BUG_ON(!next); - next->r.mod_min_addr = min_addr; next->r.mod_max_addr = max_addr; next->r.min_page = min_addr >> PAGE_SHIFT; next->r.max_page = max_addr >> PAGE_SHIFT; - spin_lock(&shadow_update_lock); + mutex_lock(&shadow_update_lock); prev = rcu_dereference_protected(cfi_shadow, 1); prepare_next_shadow(prev, next); @@ -201,7 +203,7 @@ static void update_shadow(struct module *mod, unsigned long min_addr, set_memory_ro((unsigned long)next, SHADOW_PAGES); rcu_assign_pointer(cfi_shadow, next); - spin_unlock(&shadow_update_lock); + mutex_unlock(&shadow_update_lock); synchronize_rcu(); if (prev) { @@ -245,33 +247,36 @@ static inline cfi_check_fn ptr_to_check_fn(const struct cfi_shadow __rcu *s, static inline cfi_check_fn find_module_cfi_check(void *ptr) { + cfi_check_fn f = CFI_CHECK_FN; struct module *mod; preempt_disable(); mod = __module_address((unsigned long)ptr); + if (mod) + f = mod->cfi_check; preempt_enable(); - if (mod) - return mod->cfi_check; - - return CFI_CHECK_FN; + return f; } static inline cfi_check_fn find_cfi_check(void *ptr) { -#ifdef CONFIG_CFI_CLANG_SHADOW + bool rcu; cfi_check_fn f; - if (!rcu_access_pointer(cfi_shadow)) - return CFI_CHECK_FN; /* No loaded modules */ + rcu = rcu_is_watching(); + if (!rcu) + rcu_nmi_enter(); +#ifdef CONFIG_CFI_CLANG_SHADOW /* Look up the __cfi_check function to use */ - rcu_read_lock(); - f = ptr_to_check_fn(rcu_dereference(cfi_shadow), (unsigned long)ptr); - rcu_read_unlock(); + rcu_read_lock_sched(); + f = ptr_to_check_fn(rcu_dereference_sched(cfi_shadow), + (unsigned long)ptr); + rcu_read_unlock_sched(); if (f) - return f; + goto out; /* * Fall back to find_module_cfi_check, which works also for a larger @@ -279,7 +284,13 @@ static inline cfi_check_fn find_cfi_check(void *ptr) */ #endif /* CONFIG_CFI_CLANG_SHADOW */ - return find_module_cfi_check(ptr); + f = find_module_cfi_check(ptr); + +out: + if (!rcu) + rcu_nmi_exit(); + + return f; } void cfi_slowpath_handler(uint64_t id, void *ptr, void *diag) diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c index b8ec1dbd1be5..dfbdb3f344d0 100644 --- a/kernel/kallsyms.c +++ b/kernel/kallsyms.c @@ -158,6 +158,26 @@ static unsigned long kallsyms_sym_address(int idx) return kallsyms_relative_base - 1 - kallsyms_offsets[idx]; } +#if defined(CONFIG_CFI_CLANG) && defined(CONFIG_THINLTO) +/* + * LLVM appends a hash to static function names when ThinLTO and CFI are + * both enabled, which causes confusion and potentially breaks user space + * tools, so we will strip the postfix from expanded symbol names. + */ +static inline char *cleanup_symbol_name(char *s) +{ + char *res = NULL; + + res = strrchr(s, '$'); + if (res) + *res = '\0'; + + return res; +} +#else +static inline char *cleanup_symbol_name(char *s) { return NULL; } +#endif + /* Lookup the address for this symbol. Returns 0 if not found. */ unsigned long kallsyms_lookup_name(const char *name) { @@ -170,6 +190,9 @@ unsigned long kallsyms_lookup_name(const char *name) if (strcmp(namebuf, name) == 0) return kallsyms_sym_address(i); + + if (cleanup_symbol_name(namebuf) && strcmp(namebuf, name) == 0) + return kallsyms_sym_address(i); } return module_kallsyms_lookup_name(name); } @@ -268,30 +291,6 @@ int kallsyms_lookup_size_offset(unsigned long addr, unsigned long *symbolsize, !!__bpf_address_lookup(addr, symbolsize, offset, namebuf); } -#ifdef CONFIG_CFI_CLANG -/* - * LLVM appends .cfi to function names when CONFIG_CFI_CLANG is enabled, - * which causes confusion and potentially breaks user space tools, so we - * will strip the postfix from expanded symbol names. - */ -static inline void cleanup_symbol_name(char *s) -{ - char *res; - -#ifdef CONFIG_THINLTO - /* Filter out hashes from static functions */ - res = strrchr(s, '$'); - if (res) - *res = '\0'; -#endif - res = strrchr(s, '.'); - if (res && !strcmp(res, ".cfi")) - *res = '\0'; -} -#else -static inline void cleanup_symbol_name(char *s) {} -#endif - /* * Lookup an address * - modname is set to NULL if it's in the kernel. diff --git a/kernel/module.c b/kernel/module.c index b8c25c751586..88ff3060bdb6 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -4235,10 +4235,10 @@ int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *, static void cfi_init(struct module *mod) { #ifdef CONFIG_CFI_CLANG - preempt_disable(); + rcu_read_lock_sched(); mod->cfi_check = (cfi_check_fn)mod_find_symname(mod, CFI_CHECK_FN_NAME); - preempt_enable(); + rcu_read_unlock_sched(); cfi_module_add(mod, module_addr_min, module_addr_max); #endif } From 9124f74b062ee73758f220b4f156082262bea53c Mon Sep 17 00:00:00 2001 From: Alexander Winkowski Date: Sat, 29 Mar 2025 19:07:31 +0000 Subject: [PATCH 12/12] Revert "ANDROID: modpost: add an exception for CFI stubs" This reverts commit e525d2cfbe652f4e287a7f84ce397d4f751d3aed. Reason for revert: not present in android11-5.4 Change-Id: If175677a9002962baf605e632c74435f659e0420 Signed-off-by: Alexander Winkowski --- scripts/mod/modpost.c | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 7ec4480e9ca8..f4b9fdd67381 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -945,7 +945,6 @@ static const char *const head_sections[] = { ".head.text*", NULL }; static const char *const linker_symbols[] = { "__init_begin", "_sinittext", "_einittext", NULL }; static const char *const optim_symbols[] = { "*.constprop.*", NULL }; -static const char *const cfi_symbols[] = { "*.cfi", NULL }; enum mismatch { TEXT_TO_ANY_INIT, @@ -1176,16 +1175,6 @@ static const struct sectioncheck *section_mismatch( * names to work. (One situation where gcc can autogenerate ELF * local symbols is when "-fsection-anchors" is used.) * - * Pattern 7: - * With CONFIG_CFI_CLANG, clang appends .cfi to all indirectly called - * functions and creates a function stub with the original name. This - * stub is always placed in .text, even if the actual function with the - * .cfi postfix is in .init.text or .exit.text. - * This pattern is identified by - * tosec = init or exit section - * fromsec = text section - * tosym = *.cfi - * **/ static int secref_whitelist(const struct sectioncheck *mismatch, const char *fromsec, const char *fromsym, @@ -1228,12 +1217,6 @@ static int secref_whitelist(const struct sectioncheck *mismatch, if (strstarts(fromsym, ".L")) return 0; - /* Check for pattern 7 */ - if (match(fromsec, text_sections) && - match(tosec, init_exit_sections) && - match(tosym, cfi_symbols)) - return 0; - return 1; }