* [PATCH 03/13] ASoC: ti: Use snd_soc_substream_to_rtd() for accessing private_data
From: Krzysztof Kozlowski @ 2024-04-30 14:02 UTC (permalink / raw)
To: Srinivas Kandagatla, Banajit Goswami, Liam Girdwood, Mark Brown,
Jaroslav Kysela, Takashi Iwai, Thierry Reding, Jonathan Hunter,
Peter Ujfalusi, Jarkko Nikula, Daniel Mack, Haojian Zhuang,
Robert Jarzmik, Shengjiu Wang, Xiubo Li, Fabio Estevam,
Nicolin Chen, Shawn Guo, Sascha Hauer, Pengutronix Kernel Team,
Matthias Brugger, AngeloGioacchino Del Regno, Jerome Brunet,
Neil Armstrong, Kevin Hilman, Martin Blumenstingl,
Sylwester Nawrocki, Ban Tao, Chen-Yu Tsai, Jernej Skrabec,
Samuel Holland
Cc: alsa-devel, linux-sound, linux-kernel, linux-tegra, linux-omap,
linux-arm-kernel, linuxppc-dev, imx, linux-mediatek,
linux-amlogic, linux-sunxi, Krzysztof Kozlowski
In-Reply-To: <20240430-asoc-snd-substream-clean-v1-0-6f8a8902b479@linaro.org>
Do not open-code snd_soc_substream_to_rtd().
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
---
sound/soc/ti/omap-hdmi.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/ti/omap-hdmi.c b/sound/soc/ti/omap-hdmi.c
index 4513b527ab97..639bc83f4263 100644
--- a/sound/soc/ti/omap-hdmi.c
+++ b/sound/soc/ti/omap-hdmi.c
@@ -40,7 +40,7 @@ struct hdmi_audio_data {
static
struct hdmi_audio_data *card_drvdata_substream(struct snd_pcm_substream *ss)
{
- struct snd_soc_pcm_runtime *rtd = ss->private_data;
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(ss);
return snd_soc_card_get_drvdata(rtd->card);
}
--
2.43.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 02/13] ASoC: tegra: Use snd_soc_substream_to_rtd() for accessing private_data
From: Krzysztof Kozlowski @ 2024-04-30 14:02 UTC (permalink / raw)
To: Srinivas Kandagatla, Banajit Goswami, Liam Girdwood, Mark Brown,
Jaroslav Kysela, Takashi Iwai, Thierry Reding, Jonathan Hunter,
Peter Ujfalusi, Jarkko Nikula, Daniel Mack, Haojian Zhuang,
Robert Jarzmik, Shengjiu Wang, Xiubo Li, Fabio Estevam,
Nicolin Chen, Shawn Guo, Sascha Hauer, Pengutronix Kernel Team,
Matthias Brugger, AngeloGioacchino Del Regno, Jerome Brunet,
Neil Armstrong, Kevin Hilman, Martin Blumenstingl,
Sylwester Nawrocki, Ban Tao, Chen-Yu Tsai, Jernej Skrabec,
Samuel Holland
Cc: alsa-devel, linux-sound, linux-kernel, linux-tegra, linux-omap,
linux-arm-kernel, linuxppc-dev, imx, linux-mediatek,
linux-amlogic, linux-sunxi, Krzysztof Kozlowski
In-Reply-To: <20240430-asoc-snd-substream-clean-v1-0-6f8a8902b479@linaro.org>
Do not open-code snd_soc_substream_to_rtd().
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
---
sound/soc/tegra/tegra_asoc_machine.c | 2 +-
sound/soc/tegra/tegra_pcm.c | 6 +++---
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/sound/soc/tegra/tegra_asoc_machine.c b/sound/soc/tegra/tegra_asoc_machine.c
index 192e9692bdf2..775ce433fdbf 100644
--- a/sound/soc/tegra/tegra_asoc_machine.c
+++ b/sound/soc/tegra/tegra_asoc_machine.c
@@ -290,7 +290,7 @@ static unsigned int tegra_machine_mclk_rate_6mhz(unsigned int srate)
static int tegra_machine_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
struct snd_soc_card *card = rtd->card;
struct tegra_machine *machine = snd_soc_card_get_drvdata(card);
diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c
index 42acb56543db..4bdbcd2635ef 100644
--- a/sound/soc/tegra/tegra_pcm.c
+++ b/sound/soc/tegra/tegra_pcm.c
@@ -76,7 +76,7 @@ EXPORT_SYMBOL_GPL(tegra_pcm_platform_unregister);
int tegra_pcm_open(struct snd_soc_component *component,
struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_dmaengine_dai_dma_data *dmap;
struct dma_chan *chan;
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
@@ -127,7 +127,7 @@ EXPORT_SYMBOL_GPL(tegra_pcm_open);
int tegra_pcm_close(struct snd_soc_component *component,
struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
if (rtd->dai_link->no_pcm)
return 0;
@@ -142,7 +142,7 @@ int tegra_pcm_hw_params(struct snd_soc_component *component,
struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_dmaengine_dai_dma_data *dmap;
struct dma_slave_config slave_config;
struct dma_chan *chan;
--
2.43.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 01/13] ASoC: qcom: Use snd_soc_substream_to_rtd() for accessing private_data
From: Krzysztof Kozlowski @ 2024-04-30 14:02 UTC (permalink / raw)
To: Srinivas Kandagatla, Banajit Goswami, Liam Girdwood, Mark Brown,
Jaroslav Kysela, Takashi Iwai, Thierry Reding, Jonathan Hunter,
Peter Ujfalusi, Jarkko Nikula, Daniel Mack, Haojian Zhuang,
Robert Jarzmik, Shengjiu Wang, Xiubo Li, Fabio Estevam,
Nicolin Chen, Shawn Guo, Sascha Hauer, Pengutronix Kernel Team,
Matthias Brugger, AngeloGioacchino Del Regno, Jerome Brunet,
Neil Armstrong, Kevin Hilman, Martin Blumenstingl,
Sylwester Nawrocki, Ban Tao, Chen-Yu Tsai, Jernej Skrabec,
Samuel Holland
Cc: alsa-devel, linux-sound, linux-kernel, linux-tegra, linux-omap,
linux-arm-kernel, linuxppc-dev, imx, linux-mediatek,
linux-amlogic, linux-sunxi, Krzysztof Kozlowski
In-Reply-To: <20240430-asoc-snd-substream-clean-v1-0-6f8a8902b479@linaro.org>
Do not open-code snd_soc_substream_to_rtd().
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
---
sound/soc/qcom/apq8016_sbc.c | 4 ++--
sound/soc/qcom/qdsp6/q6apm-dai.c | 2 +-
sound/soc/qcom/sc7180.c | 10 +++++-----
sound/soc/qcom/sc7280.c | 12 ++++++------
sound/soc/qcom/sc8280xp.c | 8 ++++----
sound/soc/qcom/sdw.c | 8 ++++----
sound/soc/qcom/sm8250.c | 10 +++++-----
sound/soc/qcom/x1e80100.c | 8 ++++----
8 files changed, 31 insertions(+), 31 deletions(-)
diff --git a/sound/soc/qcom/apq8016_sbc.c b/sound/soc/qcom/apq8016_sbc.c
index 4834a56eaa88..3023cf180a75 100644
--- a/sound/soc/qcom/apq8016_sbc.c
+++ b/sound/soc/qcom/apq8016_sbc.c
@@ -192,7 +192,7 @@ static int msm8916_qdsp6_dai_init(struct snd_soc_pcm_runtime *rtd)
static int msm8916_qdsp6_startup(struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_card *card = rtd->card;
struct apq8016_sbc_data *data = snd_soc_card_get_drvdata(card);
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
@@ -213,7 +213,7 @@ static int msm8916_qdsp6_startup(struct snd_pcm_substream *substream)
static void msm8916_qdsp6_shutdown(struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_card *card = rtd->card;
struct apq8016_sbc_data *data = snd_soc_card_get_drvdata(card);
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
diff --git a/sound/soc/qcom/qdsp6/q6apm-dai.c b/sound/soc/qcom/qdsp6/q6apm-dai.c
index df19fc3376b7..db2f82e00a49 100644
--- a/sound/soc/qcom/qdsp6/q6apm-dai.c
+++ b/sound/soc/qcom/qdsp6/q6apm-dai.c
@@ -329,7 +329,7 @@ static int q6apm_dai_open(struct snd_soc_component *component,
struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_soc_pcm_runtime *soc_prtd = substream->private_data;
+ struct snd_soc_pcm_runtime *soc_prtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(soc_prtd, 0);
struct device *dev = component->dev;
struct q6apm_dai_data *pdata;
diff --git a/sound/soc/qcom/sc7180.c b/sound/soc/qcom/sc7180.c
index 029780d6fe6d..bc030ce29680 100644
--- a/sound/soc/qcom/sc7180.c
+++ b/sound/soc/qcom/sc7180.c
@@ -200,7 +200,7 @@ static int sc7180_startup_realtek_codec(struct snd_soc_pcm_runtime *rtd)
static int sc7180_snd_startup(struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_card *card = rtd->card;
struct sc7180_snd_data *data = snd_soc_card_get_drvdata(card);
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
@@ -234,7 +234,7 @@ static int sc7180_snd_startup(struct snd_pcm_substream *substream)
static int sc7180_qdsp_snd_startup(struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_card *card = rtd->card;
struct sc7180_snd_data *data = snd_soc_card_get_drvdata(card);
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
@@ -307,7 +307,7 @@ static int dmic_set(struct snd_kcontrol *kcontrol,
static void sc7180_snd_shutdown(struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_card *card = rtd->card;
struct sc7180_snd_data *data = snd_soc_card_get_drvdata(card);
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
@@ -334,7 +334,7 @@ static void sc7180_snd_shutdown(struct snd_pcm_substream *substream)
static void sc7180_qdsp_snd_shutdown(struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_card *card = rtd->card;
struct sc7180_snd_data *data = snd_soc_card_get_drvdata(card);
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
@@ -389,7 +389,7 @@ static int sc7180_adau7002_init(struct snd_soc_pcm_runtime *rtd)
static int sc7180_adau7002_snd_startup(struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
struct snd_pcm_runtime *runtime = substream->runtime;
diff --git a/sound/soc/qcom/sc7280.c b/sound/soc/qcom/sc7280.c
index d36f029b7888..207ac5da4dd4 100644
--- a/sound/soc/qcom/sc7280.c
+++ b/sound/soc/qcom/sc7280.c
@@ -205,7 +205,7 @@ static int sc7280_snd_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_dai *codec_dai;
const struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
struct sc7280_snd_data *pdata = snd_soc_card_get_drvdata(rtd->card);
@@ -237,7 +237,7 @@ static int sc7280_snd_hw_params(struct snd_pcm_substream *substream,
static int sc7280_snd_swr_prepare(struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
const struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
struct sc7280_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id];
@@ -268,7 +268,7 @@ static int sc7280_snd_swr_prepare(struct snd_pcm_substream *substream)
static int sc7280_snd_prepare(struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
const struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
switch (cpu_dai->id) {
@@ -287,7 +287,7 @@ static int sc7280_snd_prepare(struct snd_pcm_substream *substream)
static int sc7280_snd_hw_free(struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct sc7280_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
const struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id];
@@ -312,7 +312,7 @@ static int sc7280_snd_hw_free(struct snd_pcm_substream *substream)
static void sc7280_snd_shutdown(struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_card *card = rtd->card;
struct sc7280_snd_data *data = snd_soc_card_get_drvdata(card);
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
@@ -339,7 +339,7 @@ static int sc7280_snd_startup(struct snd_pcm_substream *substream)
{
unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS;
unsigned int codec_dai_fmt = SND_SOC_DAIFMT_CBS_CFS;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
int ret = 0;
diff --git a/sound/soc/qcom/sc8280xp.c b/sound/soc/qcom/sc8280xp.c
index 878bd50ad4a7..06fd47c4178f 100644
--- a/sound/soc/qcom/sc8280xp.c
+++ b/sound/soc/qcom/sc8280xp.c
@@ -50,7 +50,7 @@ static int sc8280xp_snd_init(struct snd_soc_pcm_runtime *rtd)
static void sc8280xp_snd_shutdown(struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
struct sc8280xp_snd_data *pdata = snd_soc_card_get_drvdata(rtd->card);
struct sdw_stream_runtime *sruntime = pdata->sruntime[cpu_dai->id];
@@ -89,7 +89,7 @@ static int sc8280xp_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
static int sc8280xp_snd_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
struct sc8280xp_snd_data *pdata = snd_soc_card_get_drvdata(rtd->card);
@@ -98,7 +98,7 @@ static int sc8280xp_snd_hw_params(struct snd_pcm_substream *substream,
static int sc8280xp_snd_prepare(struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
struct sc8280xp_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id];
@@ -109,7 +109,7 @@ static int sc8280xp_snd_prepare(struct snd_pcm_substream *substream)
static int sc8280xp_snd_hw_free(struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct sc8280xp_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id];
diff --git a/sound/soc/qcom/sdw.c b/sound/soc/qcom/sdw.c
index 7f5089bbe022..eaa8bb016e50 100644
--- a/sound/soc/qcom/sdw.c
+++ b/sound/soc/qcom/sdw.c
@@ -21,7 +21,7 @@
*/
int qcom_snd_sdw_startup(struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
struct sdw_stream_runtime *sruntime;
struct snd_soc_dai *codec_dai;
@@ -54,7 +54,7 @@ int qcom_snd_sdw_prepare(struct snd_pcm_substream *substream,
struct sdw_stream_runtime *sruntime,
bool *stream_prepared)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
int ret;
@@ -105,7 +105,7 @@ int qcom_snd_sdw_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct sdw_stream_runtime **psruntime)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_dai *codec_dai;
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
struct sdw_stream_runtime *sruntime;
@@ -135,7 +135,7 @@ EXPORT_SYMBOL_GPL(qcom_snd_sdw_hw_params);
int qcom_snd_sdw_hw_free(struct snd_pcm_substream *substream,
struct sdw_stream_runtime *sruntime, bool *stream_prepared)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
switch (cpu_dai->id) {
diff --git a/sound/soc/qcom/sm8250.c b/sound/soc/qcom/sm8250.c
index d70df72c0160..a15dafb99b33 100644
--- a/sound/soc/qcom/sm8250.c
+++ b/sound/soc/qcom/sm8250.c
@@ -50,7 +50,7 @@ static int sm8250_snd_startup(struct snd_pcm_substream *substream)
{
unsigned int fmt = SND_SOC_DAIFMT_BP_FP;
unsigned int codec_dai_fmt = SND_SOC_DAIFMT_BC_FC;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
@@ -72,7 +72,7 @@ static int sm8250_snd_startup(struct snd_pcm_substream *substream)
static void sm2450_snd_shutdown(struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
struct sm8250_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id];
@@ -84,7 +84,7 @@ static void sm2450_snd_shutdown(struct snd_pcm_substream *substream)
static int sm8250_snd_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
struct sm8250_snd_data *pdata = snd_soc_card_get_drvdata(rtd->card);
@@ -93,7 +93,7 @@ static int sm8250_snd_hw_params(struct snd_pcm_substream *substream,
static int sm8250_snd_prepare(struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
struct sm8250_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id];
@@ -104,7 +104,7 @@ static int sm8250_snd_prepare(struct snd_pcm_substream *substream)
static int sm8250_snd_hw_free(struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct sm8250_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id];
diff --git a/sound/soc/qcom/x1e80100.c b/sound/soc/qcom/x1e80100.c
index c3c8bf7ffb5b..0e0773a85809 100644
--- a/sound/soc/qcom/x1e80100.c
+++ b/sound/soc/qcom/x1e80100.c
@@ -31,7 +31,7 @@ static int x1e80100_snd_init(struct snd_soc_pcm_runtime *rtd)
static void x1e80100_snd_shutdown(struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
struct x1e80100_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id];
@@ -67,7 +67,7 @@ static int x1e80100_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
static int x1e80100_snd_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
struct x1e80100_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
@@ -76,7 +76,7 @@ static int x1e80100_snd_hw_params(struct snd_pcm_substream *substream,
static int x1e80100_snd_prepare(struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
struct x1e80100_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id];
@@ -87,7 +87,7 @@ static int x1e80100_snd_prepare(struct snd_pcm_substream *substream)
static int x1e80100_snd_hw_free(struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct x1e80100_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id];
--
2.43.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 00/13] ASoC: Use snd_soc_substream_to_rtd() for accessing private_data
From: Krzysztof Kozlowski @ 2024-04-30 14:02 UTC (permalink / raw)
To: Srinivas Kandagatla, Banajit Goswami, Liam Girdwood, Mark Brown,
Jaroslav Kysela, Takashi Iwai, Thierry Reding, Jonathan Hunter,
Peter Ujfalusi, Jarkko Nikula, Daniel Mack, Haojian Zhuang,
Robert Jarzmik, Shengjiu Wang, Xiubo Li, Fabio Estevam,
Nicolin Chen, Shawn Guo, Sascha Hauer, Pengutronix Kernel Team,
Matthias Brugger, AngeloGioacchino Del Regno, Jerome Brunet,
Neil Armstrong, Kevin Hilman, Martin Blumenstingl,
Sylwester Nawrocki, Ban Tao, Chen-Yu Tsai, Jernej Skrabec,
Samuel Holland
Cc: alsa-devel, linux-sound, linux-kernel, linux-tegra, linux-omap,
linux-arm-kernel, linuxppc-dev, imx, linux-mediatek,
linux-amlogic, linux-sunxi, Krzysztof Kozlowski
Hi,
Do not open-code snd_soc_substream_to_rtd() when accessing
snd_pcm_substream->private_data. This makes code more consistent with
rest of ASoC and allows in the future to move the field to any other
place or add additional checks in snd_soc_substream_to_rtd().
Best regards,
Krzysztof
---
Krzysztof Kozlowski (13):
ASoC: qcom: Use snd_soc_substream_to_rtd() for accessing private_data
ASoC: tegra: Use snd_soc_substream_to_rtd() for accessing private_data
ASoC: ti: Use snd_soc_substream_to_rtd() for accessing private_data
ASoC: arm: Use snd_soc_substream_to_rtd() for accessing private_data
ASoC: amd: Use snd_soc_substream_to_rtd() for accessing private_data
ASoC: fsl: Use snd_soc_substream_to_rtd() for accessing private_data
ASoC: img: Use snd_soc_substream_to_rtd() for accessing private_data
ASoC: kirkwood: Use snd_soc_substream_to_rtd() for accessing private_data
ASoC: loongson: Use snd_soc_substream_to_rtd() for accessing private_data
ASoC: mediatek: Use snd_soc_substream_to_rtd() for accessing private_data
ASoC: meson: Use snd_soc_substream_to_rtd() for accessing private_data
ASoC: samsung: Use snd_soc_substream_to_rtd() for accessing private_data
ASoC: sunxi: Use snd_soc_substream_to_rtd() for accessing private_data
sound/arm/pxa2xx-pcm-lib.c | 4 ++--
sound/soc/amd/acp/acp-mach-common.c | 2 +-
sound/soc/amd/acp3x-rt5682-max9836.c | 2 +-
sound/soc/amd/ps/ps-sdw-dma.c | 2 +-
sound/soc/fsl/fsl-asoc-card.c | 2 +-
sound/soc/fsl/imx-card.c | 6 +++---
sound/soc/fsl/imx-hdmi.c | 2 +-
sound/soc/fsl/imx-pcm-rpmsg.c | 6 +++---
sound/soc/img/img-i2s-in.c | 2 +-
sound/soc/img/img-i2s-out.c | 2 +-
sound/soc/kirkwood/kirkwood-dma.c | 2 +-
sound/soc/loongson/loongson_card.c | 2 +-
sound/soc/loongson/loongson_dma.c | 2 +-
sound/soc/mediatek/mt7986/mt7986-afe-pcm.c | 4 ++--
sound/soc/mediatek/mt8186/mt8186-afe-pcm.c | 14 +++++++-------
sound/soc/mediatek/mt8186/mt8186-mt6366.c | 2 +-
sound/soc/mediatek/mt8188/mt8188-afe-pcm.c | 8 ++++----
sound/soc/mediatek/mt8188/mt8188-mt6359.c | 6 +++---
sound/soc/mediatek/mt8195/mt8195-afe-pcm.c | 10 +++++-----
sound/soc/mediatek/mt8195/mt8195-mt6359.c | 4 ++--
sound/soc/meson/aiu-fifo.c | 2 +-
sound/soc/meson/axg-fifo.c | 2 +-
sound/soc/qcom/apq8016_sbc.c | 4 ++--
sound/soc/qcom/qdsp6/q6apm-dai.c | 2 +-
sound/soc/qcom/sc7180.c | 10 +++++-----
sound/soc/qcom/sc7280.c | 12 ++++++------
sound/soc/qcom/sc8280xp.c | 8 ++++----
sound/soc/qcom/sdw.c | 8 ++++----
sound/soc/qcom/sm8250.c | 10 +++++-----
sound/soc/qcom/x1e80100.c | 8 ++++----
sound/soc/samsung/midas_wm1811.c | 2 +-
sound/soc/sunxi/sun50i-dmic.c | 2 +-
sound/soc/tegra/tegra_asoc_machine.c | 2 +-
sound/soc/tegra/tegra_pcm.c | 6 +++---
sound/soc/ti/omap-hdmi.c | 2 +-
35 files changed, 82 insertions(+), 82 deletions(-)
---
base-commit: 82415cf72c7e224be7a6496f3a53c0b365c2fe9d
change-id: 20240430-asoc-snd-substream-clean-924b717d8f54
Best regards,
--
Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v2 1/3] arm64/mm: Refactor PMD_PRESENT_INVALID and PTE_PROT_NONE bits
From: Ryan Roberts @ 2024-04-30 14:02 UTC (permalink / raw)
To: Will Deacon
Cc: Catalin Marinas, Joey Gouly, Ard Biesheuvel, Mark Rutland,
Anshuman Khandual, David Hildenbrand, Peter Xu, Mike Rapoport,
Shivansh Vij, linux-arm-kernel, linux-kernel
In-Reply-To: <20240430133037.GA13848@willie-the-truck>
On 30/04/2024 14:30, Will Deacon wrote:
> Hey Ryan,
>
> Just a couple of comments on this:
>
> On Mon, Apr 29, 2024 at 03:02:05PM +0100, Ryan Roberts wrote:
>> diff --git a/arch/arm64/include/asm/pgtable-prot.h b/arch/arm64/include/asm/pgtable-prot.h
>> index dd9ee67d1d87..de62e6881154 100644
>> --- a/arch/arm64/include/asm/pgtable-prot.h
>> +++ b/arch/arm64/include/asm/pgtable-prot.h
>> @@ -18,14 +18,7 @@
>> #define PTE_DIRTY (_AT(pteval_t, 1) << 55)
>> #define PTE_SPECIAL (_AT(pteval_t, 1) << 56)
>> #define PTE_DEVMAP (_AT(pteval_t, 1) << 57)
>> -#define PTE_PROT_NONE (_AT(pteval_t, 1) << 58) /* only when !PTE_VALID */
>> -
>> -/*
>> - * This bit indicates that the entry is present i.e. pmd_page()
>> - * still points to a valid huge page in memory even if the pmd
>> - * has been invalidated.
>> - */
>> -#define PMD_PRESENT_INVALID (_AT(pteval_t, 1) << 59) /* only when !PMD_SECT_VALID */
>> +#define PTE_INVALID (_AT(pteval_t, 1) << 59) /* only when !PTE_VALID */
>
> So this now overlaps with AttrIndx[3] if FEAT_AIE is implemented. Although
> this shouldn't matter on the face of things because it's only used for
> invalid entries, we originally moved the PROT_NONE bit from 2 to 57 back
> in 3676f9ef5481 ("arm64: Move PTE_PROT_NONE higher up") because it was
> possible to change the memory type for PROT_NONE mappings via some
> drivers.
I'm not sure I follow your argument.
1. We don't support FEAT_AIE (currently) so AttrIndx[3] is always going to be 0
for valid ptes. Drivers are only calling our helpers (e.g.
pgprot_writecombine(), right?) and those only know how to set AttrIndx[2:0].
2. PMD_PRESENT_INVALID was already occupying bit 59. So wouldn't the same shape
of concern apply there too for PMDs that have been invalidated, where the driver
then comes along and changes the memory type? (Perhaps because
PMD_PRESENT_INVALID is only set while the PTL is held this can't happen).
3. I had this same vague concern about confusion due to overlapping bit 59,
which is why in the next patch, I'm moving it to the NS bit.
Experience tells me that when I'm arguing confidently with someone who is much
more expert than me, then I'm using wrong... so what have I missed? :)
>
> Moving the field to the NS bit (as you do later in the series) resolves
> this, but the architecture currently says that the NS bit is RES0. How
> can we guarantee that it won't be repurposed by hardware in future?
Well it remains free for use in valid entries of course. So I guess you are
asking how to guarantee we won't also need to be able to modify it on the fly
for PROT_NONE entries? I don't have a definite answer, but I've been working on
the assumption that the architecture introducing a feature that is only needed
in states where NS is not needed is unlikely (so using that bit for the feature
is also unlikely). And then needing to manipulate that feature dyanically for
PROT_NONE mappings is even less likely.
If all else fails we could move it to nG (bit 11) to free up bit 5. But that
requires a bit more fiddling with the swap pte format.
>
>> #define _PROT_DEFAULT (PTE_TYPE_PAGE | PTE_AF | PTE_SHARED)
>> #define _PROT_SECT_DEFAULT (PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S)
>> @@ -103,7 +96,7 @@ static inline bool __pure lpa2_is_enabled(void)
>> __val; \
>> })
>>
>> -#define PAGE_NONE __pgprot(((_PAGE_DEFAULT) & ~PTE_VALID) | PTE_PROT_NONE | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_UXN)
>> +#define PAGE_NONE __pgprot(((_PAGE_DEFAULT) & ~PTE_VALID) | PTE_INVALID | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_UXN)
>> /* shared+writable pages are clean by default, hence PTE_RDONLY|PTE_WRITE */
>> #define PAGE_SHARED __pgprot(_PAGE_SHARED)
>> #define PAGE_SHARED_EXEC __pgprot(_PAGE_SHARED_EXEC)
>> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
>> index afdd56d26ad7..8dd4637d6b56 100644
>> --- a/arch/arm64/include/asm/pgtable.h
>> +++ b/arch/arm64/include/asm/pgtable.h
>> @@ -105,7 +105,7 @@ static inline pteval_t __phys_to_pte_val(phys_addr_t phys)
>> /*
>> * The following only work if pte_present(). Undefined behaviour otherwise.
>> */
>> -#define pte_present(pte) (!!(pte_val(pte) & (PTE_VALID | PTE_PROT_NONE)))
>> +#define pte_present(pte) (pte_valid(pte) || pte_invalid(pte))
>> #define pte_young(pte) (!!(pte_val(pte) & PTE_AF))
>> #define pte_special(pte) (!!(pte_val(pte) & PTE_SPECIAL))
>> #define pte_write(pte) (!!(pte_val(pte) & PTE_WRITE))
>> @@ -132,6 +132,7 @@ static inline pteval_t __phys_to_pte_val(phys_addr_t phys)
>> #define pte_dirty(pte) (pte_sw_dirty(pte) || pte_hw_dirty(pte))
>>
>> #define pte_valid(pte) (!!(pte_val(pte) & PTE_VALID))
>> +#define pte_invalid(pte) ((pte_val(pte) & (PTE_VALID | PTE_INVALID)) == PTE_INVALID)
>> /*
>> * Execute-only user mappings do not have the PTE_USER bit set. All valid
>> * kernel mappings have the PTE_UXN bit set.
>> @@ -261,6 +262,13 @@ static inline pte_t pte_mkpresent(pte_t pte)
>> return set_pte_bit(pte, __pgprot(PTE_VALID));
>> }
>>
>> +static inline pte_t pte_mkinvalid(pte_t pte)
>> +{
>> + pte = set_pte_bit(pte, __pgprot(PTE_INVALID));
>> + pte = clear_pte_bit(pte, __pgprot(PTE_VALID));
>> + return pte;
>> +}
>> +
>> static inline pmd_t pmd_mkcont(pmd_t pmd)
>> {
>> return __pmd(pmd_val(pmd) | PMD_SECT_CONT);
>> @@ -469,7 +477,7 @@ static inline pte_t pte_swp_clear_exclusive(pte_t pte)
>> */
>> static inline int pte_protnone(pte_t pte)
>> {
>> - return (pte_val(pte) & (PTE_VALID | PTE_PROT_NONE)) == PTE_PROT_NONE;
>> + return pte_invalid(pte) && !pte_user(pte) && !pte_user_exec(pte);
>> }
>
> Why do we need to check pte_user_*() here? Isn't PROT_NONE the only case
> in which a pte will have PTE_INVALID set?
I guess for *ptes* this is technically correct. But I was trying to make the
format generic and reusable for *pmds* too. (pmd_protnone() wraps
pte_protnone()). For pmds, PTE_INVALID also represents invalid-but-present PMDs
(i.e. pmds on which pmd_mkinvalid() has been called).
The intention is that PTE_INVALID indicates "present but not valid in HW". And
(!pte_user(pte) && !pte_user_exec(pte)) indicates the PROT_NONE permission.
>
> Will
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 08/17] net: lan966x: remove debugfs directory in probe() error path
From: Andrew Lunn @ 2024-04-30 14:01 UTC (permalink / raw)
To: Herve Codina
Cc: Thomas Gleixner, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Lee Jones, Arnd Bergmann, Horatiu Vultur, UNGLinuxDriver,
Heiner Kallweit, Russell King, Saravana Kannan, Bjorn Helgaas,
Philipp Zabel, Lars Povlsen, Steen Hegelund, Daniel Machon,
Alexandre Belloni, linux-kernel, devicetree, netdev, linux-pci,
linux-arm-kernel, Allan Nielsen, Luca Ceresoli, Thomas Petazzoni,
stable
In-Reply-To: <20240430083730.134918-9-herve.codina@bootlin.com>
On Tue, Apr 30, 2024 at 10:37:17AM +0200, Herve Codina wrote:
> A debugfs directory entry is create early during probe(). This entry is
> not removed on error path leading to some "already present" issues in
> case of EPROBE_DEFER.
>
> Create this entry later in the probe() code to avoid the need to change
> many 'return' in 'goto' and add the removal in the already present error
> path.
>
> Fixes: 942814840127 ("net: lan966x: Add VCAP debugFS support")
> Cc: <stable@vger.kernel.org>
> Signed-off-by: Herve Codina <herve.codina@bootlin.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Andrew
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [soc:soc/arm] BUILD SUCCESS e29d430169d7dba605fc14c7039ad46ffd4cadde
From: kernel test robot @ 2024-04-30 13:58 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: linux-arm-kernel, arm
tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git soc/arm
branch HEAD: e29d430169d7dba605fc14c7039ad46ffd4cadde Merge tag 'imx-soc-6.10' of git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux into soc/arm
elapsed time: 1000m
configs tested: 118
configs skipped: 120
The following configs have been built successfully.
More configs may be tested in the coming days.
tested configs:
alpha allnoconfig gcc
alpha allyesconfig gcc
alpha defconfig gcc
arc allmodconfig gcc
arc allnoconfig gcc
arc allyesconfig gcc
arc defconfig gcc
arc randconfig-001-20240430 gcc
arc randconfig-002-20240430 gcc
arm allmodconfig gcc
arm allnoconfig clang
arm allyesconfig gcc
arm defconfig clang
arm neponset_defconfig gcc
arm64 allnoconfig gcc
arm64 defconfig gcc
arm64 randconfig-002-20240430 gcc
arm64 randconfig-004-20240430 gcc
csky allmodconfig gcc
csky allnoconfig gcc
csky allyesconfig gcc
csky defconfig gcc
csky randconfig-001-20240430 gcc
csky randconfig-002-20240430 gcc
i386 allmodconfig gcc
i386 allnoconfig gcc
i386 allyesconfig gcc
i386 buildonly-randconfig-001-20240430 gcc
i386 buildonly-randconfig-003-20240430 gcc
i386 buildonly-randconfig-006-20240430 gcc
i386 randconfig-002-20240430 gcc
i386 randconfig-003-20240430 gcc
i386 randconfig-004-20240430 gcc
i386 randconfig-005-20240430 gcc
i386 randconfig-006-20240430 gcc
i386 randconfig-011-20240430 gcc
i386 randconfig-014-20240430 gcc
i386 randconfig-015-20240430 gcc
i386 randconfig-016-20240430 gcc
loongarch allmodconfig gcc
loongarch allnoconfig gcc
loongarch allyesconfig gcc
loongarch defconfig gcc
loongarch randconfig-001-20240430 gcc
loongarch randconfig-002-20240430 gcc
m68k allmodconfig gcc
m68k allnoconfig gcc
m68k allyesconfig gcc
m68k defconfig gcc
microblaze allmodconfig gcc
microblaze allnoconfig gcc
microblaze allyesconfig gcc
microblaze defconfig gcc
mips allmodconfig gcc
mips allnoconfig gcc
mips allyesconfig gcc
nios2 allmodconfig gcc
nios2 allnoconfig gcc
nios2 allyesconfig gcc
nios2 defconfig gcc
nios2 randconfig-001-20240430 gcc
nios2 randconfig-002-20240430 gcc
openrisc allmodconfig gcc
openrisc allnoconfig gcc
openrisc allyesconfig gcc
openrisc defconfig gcc
parisc allmodconfig gcc
parisc allnoconfig gcc
parisc allyesconfig gcc
parisc defconfig gcc
parisc randconfig-001-20240430 gcc
parisc randconfig-002-20240430 gcc
parisc64 defconfig gcc
powerpc allmodconfig gcc
powerpc allnoconfig gcc
powerpc ppa8548_defconfig gcc
powerpc ppc64e_defconfig gcc
powerpc randconfig-001-20240430 gcc
powerpc randconfig-002-20240430 gcc
powerpc tqm5200_defconfig gcc
riscv allnoconfig gcc
riscv randconfig-001-20240430 gcc
s390 allyesconfig gcc
s390 randconfig-001-20240430 gcc
s390 randconfig-002-20240430 gcc
sh allmodconfig gcc
sh allnoconfig gcc
sh allyesconfig gcc
sh defconfig gcc
sh randconfig-001-20240430 gcc
sh randconfig-002-20240430 gcc
sh se7722_defconfig gcc
sh se7780_defconfig gcc
sh sh03_defconfig gcc
sparc allmodconfig gcc
sparc allnoconfig gcc
sparc allyesconfig gcc
sparc defconfig gcc
sparc64 allmodconfig gcc
sparc64 allyesconfig gcc
sparc64 defconfig gcc
sparc64 randconfig-001-20240430 gcc
sparc64 randconfig-002-20240430 gcc
um allyesconfig gcc
um i386_defconfig gcc
x86_64 buildonly-randconfig-001-20240430 gcc
x86_64 defconfig gcc
x86_64 randconfig-003-20240430 gcc
x86_64 randconfig-004-20240430 gcc
x86_64 randconfig-005-20240430 gcc
x86_64 randconfig-013-20240430 gcc
x86_64 randconfig-075-20240430 gcc
x86_64 rhel-8.3-bpf gcc
x86_64 rhel-8.3 gcc
xtensa allnoconfig gcc
xtensa allyesconfig gcc
xtensa randconfig-001-20240430 gcc
xtensa randconfig-002-20240430 gcc
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 08/17] net: lan966x: remove debugfs directory in probe() error path
From: Andrew Lunn @ 2024-04-30 13:57 UTC (permalink / raw)
To: Herve Codina
Cc: Thomas Gleixner, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Lee Jones, Arnd Bergmann, Horatiu Vultur, UNGLinuxDriver,
Heiner Kallweit, Russell King, Saravana Kannan, Bjorn Helgaas,
Philipp Zabel, Lars Povlsen, Steen Hegelund, Daniel Machon,
Alexandre Belloni, linux-kernel, devicetree, netdev, linux-pci,
linux-arm-kernel, Allan Nielsen, Luca Ceresoli, Thomas Petazzoni,
stable
In-Reply-To: <20240430083730.134918-9-herve.codina@bootlin.com>
On Tue, Apr 30, 2024 at 10:37:17AM +0200, Herve Codina wrote:
> A debugfs directory entry is create early during probe(). This entry is
> not removed on error path leading to some "already present" issues in
> case of EPROBE_DEFER.
>
> Create this entry later in the probe() code to avoid the need to change
> many 'return' in 'goto' and add the removal in the already present error
> path.
>
> Fixes: 942814840127 ("net: lan966x: Add VCAP debugFS support")
> Cc: <stable@vger.kernel.org>
> Signed-off-by: Herve Codina <herve.codina@bootlin.com>
I know you plan to split this patchset up and submit via different
subsystems. When you do, please post this for net, not net-next, since
it is a fix.
Andrew
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 2/3] iommu/of: Support ats-supported device-tree property
From: Robin Murphy @ 2024-04-30 13:57 UTC (permalink / raw)
To: Jean-Philippe Brucker, will, lpieralisi, kw, robh, bhelgaas,
krzk+dt, conor+dt, liviu.dudau, sudeep.holla, joro
Cc: nicolinc, ketanp, linux-pci, linux-arm-kernel, iommu, devicetree
In-Reply-To: <20240429113938.192706-4-jean-philippe@linaro.org>
On 29/04/2024 12:39 pm, Jean-Philippe Brucker wrote:
> Device-tree declares whether a PCI root-complex supports ATS by setting
> the "ats-supported" property. Copy this flag into device fwspec to let
> IOMMU drivers quickly check if they can enable ATS for a device.
I don't think this functionally conflicts with what I've got going on in
this area at the moment, and although the way it fits around the other
error handling seems a bit obtuse and clunky IMO, apparently that's the
fault of the existing ACPI implementation, so for now,
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
> Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
> Tested-by: Ketan Patil <ketanp@nvidia.com>
> ---
> drivers/iommu/of_iommu.c | 9 +++++++++
> 1 file changed, 9 insertions(+)
>
> diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
> index 3afe0b48a48db..082b94c2b3291 100644
> --- a/drivers/iommu/of_iommu.c
> +++ b/drivers/iommu/of_iommu.c
> @@ -105,6 +105,14 @@ static int of_iommu_configure_device(struct device_node *master_np,
> of_iommu_configure_dev(master_np, dev);
> }
>
> +static void of_pci_check_device_ats(struct device *dev, struct device_node *np)
> +{
> + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
> +
> + if (fwspec && of_property_read_bool(np, "ats-supported"))
> + fwspec->flags |= IOMMU_FWSPEC_PCI_RC_ATS;
> +}
> +
> /*
> * Returns:
> * 0 on success, an iommu was configured
> @@ -147,6 +155,7 @@ int of_iommu_configure(struct device *dev, struct device_node *master_np,
> pci_request_acs();
> err = pci_for_each_dma_alias(to_pci_dev(dev),
> of_pci_iommu_init, &info);
> + of_pci_check_device_ats(dev, master_np);
> } else {
> err = of_iommu_configure_device(master_np, dev, id);
> }
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 06/17] dt-bindings: net: mscc-miim: Add resets property
From: Andrew Lunn @ 2024-04-30 13:55 UTC (permalink / raw)
To: Herve Codina
Cc: Thomas Gleixner, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Lee Jones, Arnd Bergmann, Horatiu Vultur, UNGLinuxDriver,
Heiner Kallweit, Russell King, Saravana Kannan, Bjorn Helgaas,
Philipp Zabel, Lars Povlsen, Steen Hegelund, Daniel Machon,
Alexandre Belloni, linux-kernel, devicetree, netdev, linux-pci,
linux-arm-kernel, Allan Nielsen, Luca Ceresoli, Thomas Petazzoni
In-Reply-To: <20240430083730.134918-7-herve.codina@bootlin.com>
On Tue, Apr 30, 2024 at 10:37:15AM +0200, Herve Codina wrote:
> Add the (optional) resets property.
> The mscc-miim device is impacted by the switch reset especially when the
> mscc-miim device is used as part of the LAN966x PCI device.
>
> Signed-off-by: Herve Codina <herve.codina@bootlin.com>
> ---
> Documentation/devicetree/bindings/net/mscc,miim.yaml | 8 ++++++++
> 1 file changed, 8 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/net/mscc,miim.yaml b/Documentation/devicetree/bindings/net/mscc,miim.yaml
> index 5b292e7c9e46..a8c92cec85a6 100644
> --- a/Documentation/devicetree/bindings/net/mscc,miim.yaml
> +++ b/Documentation/devicetree/bindings/net/mscc,miim.yaml
> @@ -38,6 +38,14 @@ properties:
>
> clock-frequency: true
>
> + resets:
> + items:
> + - description: Reset controller used for switch core reset (soft reset)
A follow up to the comment on the next patch. I think it should be
made clear in the patch and the binding, the aim is to reset the MDIO
bus master, not the switch. It just happens that the MDIO bus master
is within the domain of the switch core, and so the switch core reset
also resets the MDIO bus master.
Architecturally, this is important. I would not expect the MDIO driver
to be resetting the switch, the switch driver should be doing
that. But we have seen some odd Qualcomm patches where the MDIO driver
has been doing things outside the scope of MDIO, playing with resets
and clocks which are not directly related to the MDIO bus master. I
want to avoid any confusion here, especially when Qualcomm tries
again, and maybe points at this code.
Andrew
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v2] arm64/mm: pmd_mkinvalid() must handle swap pmds
From: Will Deacon @ 2024-04-30 13:55 UTC (permalink / raw)
To: Ryan Roberts
Cc: Catalin Marinas, Mark Rutland, Anshuman Khandual, Andrew Morton,
Zi Yan, Aneesh Kumar K.V, linux-arm-kernel, linux-mm,
linux-kernel, stable
In-Reply-To: <20240430133138.732088-1-ryan.roberts@arm.com>
On Tue, Apr 30, 2024 at 02:31:38PM +0100, Ryan Roberts wrote:
> __split_huge_pmd_locked() can be called for a present THP, devmap or
> (non-present) migration entry. It calls pmdp_invalidate()
> unconditionally on the pmdp and only determines if it is present or not
> based on the returned old pmd.
>
> But arm64's pmd_mkinvalid(), called by pmdp_invalidate(),
> unconditionally sets the PMD_PRESENT_INVALID flag, which causes future
> pmd_present() calls to return true - even for a swap pmd. Therefore any
> lockless pgtable walker could see the migration entry pmd in this state
> and start interpretting the fields (e.g. pmd_pfn()) as if it were
> present, leading to BadThings (TM). GUP-fast appears to be one such
> lockless pgtable walker.
>
> While the obvious fix is for core-mm to avoid such calls for non-present
> pmds (pmdp_invalidate() will also issue TLBI which is not necessary for
> this case either), all other arches that implement pmd_mkinvalid() do it
> in such a way that it is robust to being called with a non-present pmd.
> So it is simpler and safer to make arm64 robust too. This approach means
> we can even add tests to debug_vm_pgtable.c to validate the required
> behaviour.
>
> This is a theoretical bug found during code review. I don't have any
> test case to trigger it in practice.
>
> Cc: stable@vger.kernel.org
> Fixes: 53fa117bb33c ("arm64/mm: Enable THP migration")
> Signed-off-by: Ryan Roberts <ryan.roberts@arm.com>
> ---
>
> Hi all,
>
> v1 of this fix [1] took the approach of fixing core-mm to never call
> pmdp_invalidate() on a non-present pmd. But Zi Yan highlighted that only arm64
> suffers this problem; all other arches are robust. So his suggestion was to
> instead make arm64 robust in the same way and add tests to validate it. Despite
> my stated reservations in the context of the v1 discussion, having thought on it
> for a bit, I now agree with Zi Yan. Hence this post.
>
> Andrew has v1 in mm-unstable at the moment, so probably the best thing to do is
> remove it from there and have this go in through the arm64 tree? Assuming there
> is agreement that this approach is right one.
>
> This applies on top of v6.9-rc5. Passes all the mm selftests on arm64.
>
> [1] https://lore.kernel.org/linux-mm/20240425170704.3379492-1-ryan.roberts@arm.com/
>
> Thanks,
> Ryan
>
>
> arch/arm64/include/asm/pgtable.h | 12 +++++--
> mm/debug_vm_pgtable.c | 61 ++++++++++++++++++++++++++++++++
> 2 files changed, 71 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> index afdd56d26ad7..7d580271a46d 100644
> --- a/arch/arm64/include/asm/pgtable.h
> +++ b/arch/arm64/include/asm/pgtable.h
> @@ -511,8 +511,16 @@ static inline int pmd_trans_huge(pmd_t pmd)
>
> static inline pmd_t pmd_mkinvalid(pmd_t pmd)
> {
> - pmd = set_pmd_bit(pmd, __pgprot(PMD_PRESENT_INVALID));
> - pmd = clear_pmd_bit(pmd, __pgprot(PMD_SECT_VALID));
> + /*
> + * If not valid then either we are already present-invalid or we are
> + * not-present (i.e. none or swap entry). We must not convert
> + * not-present to present-invalid. Unbelievably, the core-mm may call
> + * pmd_mkinvalid() for a swap entry and all other arches can handle it.
> + */
> + if (pmd_valid(pmd)) {
> + pmd = set_pmd_bit(pmd, __pgprot(PMD_PRESENT_INVALID));
> + pmd = clear_pmd_bit(pmd, __pgprot(PMD_SECT_VALID));
> + }
>
> return pmd;
> }
Acked-by: Will Deacon <will@kernel.org>
But it might be worth splitting the tests from the fix to make backporting
easier.
Catalin -- I assume you'll pick this up, but please shout if you want me
to take it instead.
Will
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v6 1/6] iommu/arm-smmu-v3: Pass in cmdq pointer to arm_smmu_cmdq_issue_cmdlist()
From: Jason Gunthorpe @ 2024-04-30 13:54 UTC (permalink / raw)
To: Nicolin Chen
Cc: will, robin.murphy, joro, thierry.reding, vdumpa, jonathanh,
linux-kernel, iommu, linux-arm-kernel, linux-tegra
In-Reply-To: <0acb55059f7212abdf4277a81e2f033127072bc9.1714451595.git.nicolinc@nvidia.com>
On Mon, Apr 29, 2024 at 09:43:44PM -0700, Nicolin Chen wrote:
> The driver currently calls arm_smmu_get_cmdq() helper in different places,
> although they are all called from the arm_smmu_cmdq_issue_cmdlist().
>
> Allow to pass in the cmdq pointer, instead of calling arm_smmu_get_cmdq()
> every time.
>
> This will also help CMDQV extension in NVIDIA Tegra241 SoC, as its driver
> will maintain its own cmdq pointers, then need to redirect arm_smmu->cmdq
> to one of its vcmdqs upon seeing a supported command.
>
> Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
> ---
> drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 15 ++++++++-------
> 1 file changed, 8 insertions(+), 7 deletions(-)
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Jason
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 07/17] net: mdio: mscc-miim: Handle the switch reset
From: Andrew Lunn @ 2024-04-30 13:46 UTC (permalink / raw)
To: Herve Codina
Cc: Thomas Gleixner, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Lee Jones, Arnd Bergmann, Horatiu Vultur, UNGLinuxDriver,
Heiner Kallweit, Russell King, Saravana Kannan, Bjorn Helgaas,
Philipp Zabel, Lars Povlsen, Steen Hegelund, Daniel Machon,
Alexandre Belloni, linux-kernel, devicetree, netdev, linux-pci,
linux-arm-kernel, Allan Nielsen, Luca Ceresoli, Thomas Petazzoni
In-Reply-To: <20240430083730.134918-8-herve.codina@bootlin.com>
On Tue, Apr 30, 2024 at 10:37:16AM +0200, Herve Codina wrote:
> The mscc-miim device can be impacted by the switch reset, at least when
> this device is part of the LAN966x PCI device.
Just to be sure i understand this correctly. The MDIO bus master can
be reset using the "switch" reset. So you are adding code to ensure
the "switch" reset is out of reset state, so the MDIO bus master
works.
Given that this is a new property, maybe give it a better name to
indicate it resets both the switch and the MDIO bus master?
Andrew
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH] ARM: Use conditionals for CFI branches
From: Ard Biesheuvel @ 2024-04-30 13:45 UTC (permalink / raw)
To: Linus Walleij
Cc: Russell King, Sami Tolvanen, Kees Cook, Nathan Chancellor,
Nick Desaulniers, Arnd Bergmann, linux-arm-kernel, llvm
In-Reply-To: <CACRpkdYq5SON_ANbEHgvzBuTQd8zkY1M5dEATgzqz1j7W58pdw@mail.gmail.com>
On Tue, 30 Apr 2024 at 13:45, Linus Walleij <linus.walleij@linaro.org> wrote:
>
> On Tue, Apr 30, 2024 at 11:19 AM Ard Biesheuvel <ardb@kernel.org> wrote:
>
>
> > These functions are only called indirectly if MULTI_CACHE is enabled,
> > right? If so, this could be
> >
> > #if defined(CONFIG_CFI_CLANG) && defined(MULTI_CACHE)
>
> Hm Sami may know better here, but with !MULTI_CACHE the
> functions are indeed called directly, but does that mean the
> compiler will not emit some magic bytes in front of these
> symbols then?
>
Ah yes, of course. So that wouldn't work.
So the alternative might be
#if defined(CONFIG_CFI_CLANG) && defined(MULTI_CACHE)
SYM_TYPED_FUNC_START(v4_flush_kern_dcache_area)
b v4_dma_flush_range
SYM_FUNC_END(v4_flush_kern_dcache_area)
#else
SYM_FUNC_ALIAS(v4_flush_kern_dcache_area, v4_dma_flush_range)
#endif
Of course, unless anyone has an interest in building these older
platforms with Clang and CFI, it doesn't really make a difference, so
perhaps we should just go with your version.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH v3 4/4] iommu/arm-smmu-v3: Enable HTTU for stage1 with io-pgtable mapping
From: Shameer Kolothum @ 2024-04-30 13:43 UTC (permalink / raw)
To: iommu, linux-arm-kernel
Cc: robin.murphy, will, joro, jgg, ryan.roberts, kevin.tian, nicolinc,
mshavit, eric.auger, joao.m.martins, jiangkunkun, zhukeqian1,
linuxarm
In-Reply-To: <20240430134308.1604-1-shameerali.kolothum.thodi@huawei.com>
From: Kunkun Jiang <jiangkunkun@huawei.com>
If io-pgtable quirk flag indicates support for hardware update of
dirty state, enable HA/HD bits in the SMMU CD and also set the DBM
bit in the page descriptor.
Now report the dirty page tracking capability of SMMUv3 and
select IOMMUFD_DRIVER for ARM_SMMU_V3 if IOMMUFD is enabled.
Co-developed-by: Keqian Zhu <zhukeqian1@huawei.com>
Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
Signed-off-by: Kunkun Jiang <jiangkunkun@huawei.com>
Signed-off-by: Joao Martins <joao.m.martins@oracle.com>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Reviewed-by: Ryan Roberts <ryan.roberts@arm.com>
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
---
drivers/iommu/Kconfig | 1 +
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 15 +++++++++++++++
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 3 +++
drivers/iommu/io-pgtable-arm.c | 5 ++++-
4 files changed, 23 insertions(+), 1 deletion(-)
diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index f872aeccd820..912cffc9f001 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -390,6 +390,7 @@ config ARM_SMMU_V3
select IOMMU_API
select IOMMU_IO_PGTABLE_LPAE
select GENERIC_MSI_IRQ
+ select IOMMUFD_DRIVER if IOMMUFD
help
Support for implementations of the ARM System MMU architecture
version 3 providing translation support to a PCIe root complex.
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index ad18436c5f7f..e3143be3cfc6 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -1333,6 +1333,12 @@ void arm_smmu_make_s1_cd(struct arm_smmu_cd *target,
CTXDESC_CD_0_ASET |
FIELD_PREP(CTXDESC_CD_0_ASID, smmu_domain->asid)
);
+
+ /* To enable dirty flag update, set both Access flag and dirty state update */
+ if (pgtbl_cfg->quirks & IO_PGTABLE_QUIRK_ARM_HD)
+ target->data[0] |= cpu_to_le64(CTXDESC_CD_0_TCR_HA |
+ CTXDESC_CD_0_TCR_HD);
+
target->data[1] = cpu_to_le64(pgtbl_cfg->arm_lpae_s1_cfg.ttbr &
CTXDESC_CD_1_TTB0_MASK);
target->data[3] = cpu_to_le64(pgtbl_cfg->arm_lpae_s1_cfg.mair);
@@ -2264,6 +2270,13 @@ static const struct iommu_flush_ops arm_smmu_flush_ops = {
.tlb_add_page = arm_smmu_tlb_inv_page_nosync,
};
+static bool arm_smmu_dbm_capable(struct arm_smmu_device *smmu)
+{
+ u32 features = (ARM_SMMU_FEAT_HD | ARM_SMMU_FEAT_COHERENCY);
+
+ return (smmu->features & features) == features;
+}
+
/* IOMMU API */
static bool arm_smmu_capable(struct device *dev, enum iommu_cap cap)
{
@@ -2276,6 +2289,8 @@ static bool arm_smmu_capable(struct device *dev, enum iommu_cap cap)
case IOMMU_CAP_NOEXEC:
case IOMMU_CAP_DEFERRED_FLUSH:
return true;
+ case IOMMU_CAP_DIRTY_TRACKING:
+ return arm_smmu_dbm_capable(master->smmu);
default:
return false;
}
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
index fd60052a9ec6..f684676d0bb5 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -312,6 +312,9 @@ struct arm_smmu_cd {
#define CTXDESC_CD_0_TCR_IPS GENMASK_ULL(34, 32)
#define CTXDESC_CD_0_TCR_TBI0 (1ULL << 38)
+#define CTXDESC_CD_0_TCR_HA (1UL << 43)
+#define CTXDESC_CD_0_TCR_HD (1UL << 42)
+
#define CTXDESC_CD_0_AA64 (1UL << 41)
#define CTXDESC_CD_0_S (1UL << 44)
#define CTXDESC_CD_0_R (1UL << 45)
diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
index da6cc52859ba..20ac0e833c7b 100644
--- a/drivers/iommu/io-pgtable-arm.c
+++ b/drivers/iommu/io-pgtable-arm.c
@@ -433,6 +433,8 @@ static arm_lpae_iopte arm_lpae_prot_to_pte(struct arm_lpae_io_pgtable *data,
pte = ARM_LPAE_PTE_nG;
if (!(prot & IOMMU_WRITE) && (prot & IOMMU_READ))
pte |= ARM_LPAE_PTE_AP_RDONLY;
+ else if (data->iop.cfg.quirks & IO_PGTABLE_QUIRK_ARM_HD)
+ pte |= ARM_LPAE_PTE_AP_WRITABLE_CLEAN;
if (!(prot & IOMMU_PRIV))
pte |= ARM_LPAE_PTE_AP_UNPRIV;
} else {
@@ -923,7 +925,8 @@ arm_64_lpae_alloc_pgtable_s1(struct io_pgtable_cfg *cfg, void *cookie)
if (cfg->quirks & ~(IO_PGTABLE_QUIRK_ARM_NS |
IO_PGTABLE_QUIRK_ARM_TTBR1 |
- IO_PGTABLE_QUIRK_ARM_OUTER_WBWA))
+ IO_PGTABLE_QUIRK_ARM_OUTER_WBWA |
+ IO_PGTABLE_QUIRK_ARM_HD))
return NULL;
data = arm_lpae_alloc_pgtable(cfg);
--
2.34.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v3 3/4] iommu/arm-smmu-v3: Add support for dirty tracking in domain alloc
From: Shameer Kolothum @ 2024-04-30 13:43 UTC (permalink / raw)
To: iommu, linux-arm-kernel
Cc: robin.murphy, will, joro, jgg, ryan.roberts, kevin.tian, nicolinc,
mshavit, eric.auger, joao.m.martins, jiangkunkun, zhukeqian1,
linuxarm
In-Reply-To: <20240430134308.1604-1-shameerali.kolothum.thodi@huawei.com>
From: Joao Martins <joao.m.martins@oracle.com>
This provides all the infrastructure to enable dirty tracking if the
hardware has the capability and domain alloc request for it.
Please note, we still report no support for IOMMU_CAP_DIRTY_TRACKING
as it will finally be enabled in a subsequent patch.
Signed-off-by: Joao Martins <joao.m.martins@oracle.com>
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
---
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 82 +++++++++++++++------
include/linux/io-pgtable.h | 4 +
2 files changed, 63 insertions(+), 23 deletions(-)
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index bed0183ba809..ad18436c5f7f 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -38,6 +38,7 @@ MODULE_PARM_DESC(disable_msipolling,
"Disable MSI-based polling for CMD_SYNC completion.");
static struct iommu_ops arm_smmu_ops;
+static struct iommu_dirty_ops arm_smmu_dirty_ops;
enum arm_smmu_msi_index {
EVTQ_MSI_INDEX,
@@ -80,7 +81,8 @@ static struct arm_smmu_option_prop arm_smmu_options[] = {
};
static int arm_smmu_domain_finalise(struct arm_smmu_domain *smmu_domain,
- struct arm_smmu_device *smmu);
+ struct arm_smmu_device *smmu,
+ u32 flags);
static int arm_smmu_alloc_cd_tables(struct arm_smmu_master *master);
static void arm_smmu_tlb_inv_all_s2(struct arm_smmu_domain *smmu_domain);
@@ -2335,7 +2337,7 @@ static struct iommu_domain *arm_smmu_domain_alloc_paging(struct device *dev)
struct arm_smmu_master *master = dev_iommu_priv_get(dev);
int ret;
- ret = arm_smmu_domain_finalise(smmu_domain, master->smmu);
+ ret = arm_smmu_domain_finalise(smmu_domain, master->smmu, 0);
if (ret) {
kfree(smmu_domain);
return ERR_PTR(ret);
@@ -2408,13 +2410,14 @@ static void arm_smmu_domain_free_paging(struct iommu_domain *domain)
}
static int arm_smmu_domain_finalise(struct arm_smmu_domain *smmu_domain,
- struct arm_smmu_device *smmu)
+ struct arm_smmu_device *smmu,
+ u32 flags)
{
int ret;
- unsigned long ias, oas;
enum io_pgtable_fmt fmt;
struct io_pgtable_cfg pgtbl_cfg;
struct io_pgtable_ops *pgtbl_ops;
+ bool enable_dirty = flags & IOMMU_HWPT_ALLOC_DIRTY_TRACKING;
/* Restrict the stage to what we can actually support */
if (!(smmu->features & ARM_SMMU_FEAT_TRANS_S1))
@@ -2422,31 +2425,32 @@ static int arm_smmu_domain_finalise(struct arm_smmu_domain *smmu_domain,
if (!(smmu->features & ARM_SMMU_FEAT_TRANS_S2))
smmu_domain->stage = ARM_SMMU_DOMAIN_S1;
+ pgtbl_cfg = (struct io_pgtable_cfg) {
+ .pgsize_bitmap = smmu->pgsize_bitmap,
+ .coherent_walk = smmu->features & ARM_SMMU_FEAT_COHERENCY,
+ .tlb = &arm_smmu_flush_ops,
+ .iommu_dev = smmu->dev,
+ };
+
switch (smmu_domain->stage) {
case ARM_SMMU_DOMAIN_S1:
- ias = (smmu->features & ARM_SMMU_FEAT_VAX) ? 52 : 48;
- ias = min_t(unsigned long, ias, VA_BITS);
- oas = smmu->ias;
+ unsigned long ias = (smmu->features &
+ ARM_SMMU_FEAT_VAX) ? 52 : 48;
+ pgtbl_cfg.ias = min_t(unsigned long, ias, VA_BITS);
+ pgtbl_cfg.oas = smmu->ias;
+ if (enable_dirty)
+ pgtbl_cfg.quirks |= IO_PGTABLE_QUIRK_ARM_HD;
fmt = ARM_64_LPAE_S1;
break;
case ARM_SMMU_DOMAIN_S2:
- ias = smmu->ias;
- oas = smmu->oas;
+ pgtbl_cfg.ias = smmu->ias;
+ pgtbl_cfg.oas = smmu->oas;
fmt = ARM_64_LPAE_S2;
break;
default:
return -EINVAL;
}
- pgtbl_cfg = (struct io_pgtable_cfg) {
- .pgsize_bitmap = smmu->pgsize_bitmap,
- .ias = ias,
- .oas = oas,
- .coherent_walk = smmu->features & ARM_SMMU_FEAT_COHERENCY,
- .tlb = &arm_smmu_flush_ops,
- .iommu_dev = smmu->dev,
- };
-
pgtbl_ops = alloc_io_pgtable_ops(fmt, &pgtbl_cfg, smmu_domain);
if (!pgtbl_ops)
return -ENOMEM;
@@ -2454,7 +2458,8 @@ static int arm_smmu_domain_finalise(struct arm_smmu_domain *smmu_domain,
smmu_domain->domain.pgsize_bitmap = pgtbl_cfg.pgsize_bitmap;
smmu_domain->domain.geometry.aperture_end = (1UL << pgtbl_cfg.ias) - 1;
smmu_domain->domain.geometry.force_aperture = true;
-
+ if (enable_dirty && smmu_domain->stage == ARM_SMMU_DOMAIN_S1)
+ smmu_domain->domain.dirty_ops = &arm_smmu_dirty_ops;
ret = arm_smmu_domain_alloc_id(smmu, smmu_domain);
if (ret < 0) {
free_io_pgtable_ops(pgtbl_ops);
@@ -2777,7 +2782,7 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
mutex_lock(&smmu_domain->init_mutex);
if (!smmu_domain->smmu) {
- ret = arm_smmu_domain_finalise(smmu_domain, smmu);
+ ret = arm_smmu_domain_finalise(smmu_domain, smmu, 0);
} else if (smmu_domain->smmu != smmu)
ret = -EINVAL;
@@ -2842,7 +2847,7 @@ static int arm_smmu_s1_set_dev_pasid(struct iommu_domain *domain,
mutex_lock(&smmu_domain->init_mutex);
if (!smmu_domain->smmu)
- ret = arm_smmu_domain_finalise(smmu_domain, smmu);
+ ret = arm_smmu_domain_finalise(smmu_domain, smmu, 0);
else if (smmu_domain->smmu != smmu)
ret = -EINVAL;
mutex_unlock(&smmu_domain->init_mutex);
@@ -3175,7 +3180,8 @@ arm_smmu_domain_alloc_user(struct device *dev, u32 flags,
const struct iommu_user_data *user_data)
{
struct arm_smmu_master *master = dev_iommu_priv_get(dev);
- const u32 PAGING_FLAGS = IOMMU_HWPT_ALLOC_NEST_PARENT;
+ const u32 PAGING_FLAGS = IOMMU_HWPT_ALLOC_NEST_PARENT |
+ IOMMU_HWPT_ALLOC_DIRTY_TRACKING;
struct arm_smmu_domain *smmu_domain;
int ret;
@@ -3188,6 +3194,10 @@ arm_smmu_domain_alloc_user(struct device *dev, u32 flags,
if (user_data)
return ERR_PTR(-EINVAL);
+ if ((flags & IOMMU_HWPT_ALLOC_DIRTY_TRACKING) &&
+ !device_iommu_capable(dev, IOMMU_CAP_DIRTY_TRACKING))
+ return ERR_PTR(-EOPNOTSUPP);
+
smmu_domain = arm_smmu_domain_alloc();
if (!smmu_domain)
return ERR_PTR(-ENOMEM);
@@ -3203,7 +3213,7 @@ arm_smmu_domain_alloc_user(struct device *dev, u32 flags,
smmu_domain->domain.type = IOMMU_DOMAIN_UNMANAGED;
smmu_domain->domain.ops = arm_smmu_ops.default_domain_ops;
- ret = arm_smmu_domain_finalise(smmu_domain, master->smmu);
+ ret = arm_smmu_domain_finalise(smmu_domain, master->smmu, flags);
if (ret)
goto err_free;
return &smmu_domain->domain;
@@ -3479,6 +3489,27 @@ static void arm_smmu_release_device(struct device *dev)
kfree(master);
}
+static int arm_smmu_read_and_clear_dirty(struct iommu_domain *domain,
+ unsigned long iova, size_t size,
+ unsigned long flags,
+ struct iommu_dirty_bitmap *dirty)
+{
+ struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
+ struct io_pgtable_ops *ops = smmu_domain->pgtbl_ops;
+
+ return ops->read_and_clear_dirty(ops, iova, size, flags, dirty);
+}
+
+static int arm_smmu_set_dirty_tracking(struct iommu_domain *domain,
+ bool enabled)
+{
+ /*
+ * Always enabled and the dirty bitmap is cleared prior to
+ * set_dirty_tracking().
+ */
+ return 0;
+}
+
static struct iommu_group *arm_smmu_device_group(struct device *dev)
{
struct iommu_group *group;
@@ -3622,6 +3653,11 @@ static struct iommu_ops arm_smmu_ops = {
}
};
+static struct iommu_dirty_ops arm_smmu_dirty_ops = {
+ .read_and_clear_dirty = arm_smmu_read_and_clear_dirty,
+ .set_dirty_tracking = arm_smmu_set_dirty_tracking,
+};
+
/* Probing and initialisation functions */
static int arm_smmu_init_one_queue(struct arm_smmu_device *smmu,
struct arm_smmu_queue *q,
diff --git a/include/linux/io-pgtable.h b/include/linux/io-pgtable.h
index 86cf1f7ae389..8e75f944f07a 100644
--- a/include/linux/io-pgtable.h
+++ b/include/linux/io-pgtable.h
@@ -85,6 +85,8 @@ struct io_pgtable_cfg {
*
* IO_PGTABLE_QUIRK_ARM_OUTER_WBWA: Override the outer-cacheability
* attributes set in the TCR for a non-coherent page-table walker.
+ *
+ * IO_PGTABLE_QUIRK_ARM_HD: Enables dirty tracking in stage 1 pagetable.
*/
#define IO_PGTABLE_QUIRK_ARM_NS BIT(0)
#define IO_PGTABLE_QUIRK_NO_PERMS BIT(1)
@@ -92,6 +94,8 @@ struct io_pgtable_cfg {
#define IO_PGTABLE_QUIRK_ARM_MTK_TTBR_EXT BIT(4)
#define IO_PGTABLE_QUIRK_ARM_TTBR1 BIT(5)
#define IO_PGTABLE_QUIRK_ARM_OUTER_WBWA BIT(6)
+ #define IO_PGTABLE_QUIRK_ARM_HD BIT(7)
+
unsigned long quirks;
unsigned long pgsize_bitmap;
unsigned int ias;
--
2.34.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v3 2/4] iommu/io-pgtable-arm: Add read_and_clear_dirty() support
From: Shameer Kolothum @ 2024-04-30 13:43 UTC (permalink / raw)
To: iommu, linux-arm-kernel
Cc: robin.murphy, will, joro, jgg, ryan.roberts, kevin.tian, nicolinc,
mshavit, eric.auger, joao.m.martins, jiangkunkun, zhukeqian1,
linuxarm
In-Reply-To: <20240430134308.1604-1-shameerali.kolothum.thodi@huawei.com>
.read_and_clear_dirty() IOMMU domain op takes care of reading the dirty
bits (i.e. PTE has DBM set and AP[2] clear) and marshalling into a
bitmap of a given page size.
While reading the dirty bits we also set the PTE AP[2] bit to mark it
as writable-clean depending on read_and_clear_dirty() flags.
PTE states with respect to DBM bit:
DBM bit AP[2]("RDONLY" bit)
1. writable_clean 1 1
2. writable_dirty 1 0
3. read-only 0 1
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
---
drivers/iommu/io-pgtable-arm.c | 105 ++++++++++++++++++++++++++++++++-
1 file changed, 103 insertions(+), 2 deletions(-)
diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
index f7828a7aad41..da6cc52859ba 100644
--- a/drivers/iommu/io-pgtable-arm.c
+++ b/drivers/iommu/io-pgtable-arm.c
@@ -75,6 +75,7 @@
#define ARM_LPAE_PTE_NSTABLE (((arm_lpae_iopte)1) << 63)
#define ARM_LPAE_PTE_XN (((arm_lpae_iopte)3) << 53)
+#define ARM_LPAE_PTE_DBM (((arm_lpae_iopte)1) << 51)
#define ARM_LPAE_PTE_AF (((arm_lpae_iopte)1) << 10)
#define ARM_LPAE_PTE_SH_NS (((arm_lpae_iopte)0) << 8)
#define ARM_LPAE_PTE_SH_OS (((arm_lpae_iopte)2) << 8)
@@ -84,7 +85,7 @@
#define ARM_LPAE_PTE_ATTR_LO_MASK (((arm_lpae_iopte)0x3ff) << 2)
/* Ignore the contiguous bit for block splitting */
-#define ARM_LPAE_PTE_ATTR_HI_MASK (((arm_lpae_iopte)6) << 52)
+#define ARM_LPAE_PTE_ATTR_HI_MASK (ARM_LPAE_PTE_XN | ARM_LPAE_PTE_DBM)
#define ARM_LPAE_PTE_ATTR_MASK (ARM_LPAE_PTE_ATTR_LO_MASK | \
ARM_LPAE_PTE_ATTR_HI_MASK)
/* Software bit for solving coherency races */
@@ -92,7 +93,11 @@
/* Stage-1 PTE */
#define ARM_LPAE_PTE_AP_UNPRIV (((arm_lpae_iopte)1) << 6)
-#define ARM_LPAE_PTE_AP_RDONLY (((arm_lpae_iopte)2) << 6)
+#define ARM_LPAE_PTE_AP_RDONLY_BIT 7
+#define ARM_LPAE_PTE_AP_RDONLY (((arm_lpae_iopte)1) << \
+ ARM_LPAE_PTE_AP_RDONLY_BIT)
+#define ARM_LPAE_PTE_AP_WRITABLE_CLEAN (ARM_LPAE_PTE_AP_RDONLY | \
+ ARM_LPAE_PTE_DBM)
#define ARM_LPAE_PTE_ATTRINDX_SHIFT 2
#define ARM_LPAE_PTE_nG (((arm_lpae_iopte)1) << 11)
@@ -138,6 +143,9 @@
#define iopte_prot(pte) ((pte) & ARM_LPAE_PTE_ATTR_MASK)
+#define iopte_hw_dirty(pte) (((pte) & ARM_LPAE_PTE_AP_WRITABLE_CLEAN) == \
+ ARM_LPAE_PTE_DBM)
+
struct arm_lpae_io_pgtable {
struct io_pgtable iop;
@@ -729,6 +737,98 @@ static phys_addr_t arm_lpae_iova_to_phys(struct io_pgtable_ops *ops,
return iopte_to_paddr(pte, data) | iova;
}
+struct io_pgtable_walk_data {
+ struct iommu_dirty_bitmap *dirty;
+ unsigned long flags;
+ u64 addr;
+ const u64 end;
+};
+
+static int __arm_lpae_iopte_walk_dirty(struct arm_lpae_io_pgtable *data,
+ struct io_pgtable_walk_data *walk_data,
+ arm_lpae_iopte *ptep,
+ int lvl);
+
+static int io_pgtable_visit_dirty(struct arm_lpae_io_pgtable *data,
+ struct io_pgtable_walk_data *walk_data,
+ arm_lpae_iopte *ptep, int lvl)
+{
+ struct io_pgtable *iop = &data->iop;
+ arm_lpae_iopte pte = READ_ONCE(*ptep);
+
+ if (WARN_ON(!pte))
+ return -EINVAL;
+
+ if (iopte_leaf(pte, lvl, iop->fmt)) {
+ size_t size = ARM_LPAE_BLOCK_SIZE(lvl, data);
+
+ if (iopte_hw_dirty(pte)) {
+ iommu_dirty_bitmap_record(walk_data->dirty,
+ walk_data->addr, size);
+ if (!(walk_data->flags & IOMMU_DIRTY_NO_CLEAR))
+ set_bit(ARM_LPAE_PTE_AP_RDONLY_BIT,
+ (unsigned long *)ptep);
+ }
+ walk_data->addr += size;
+ return 0;
+ }
+
+ ptep = iopte_deref(pte, data);
+ return __arm_lpae_iopte_walk_dirty(data, walk_data, ptep, lvl + 1);
+}
+
+static int __arm_lpae_iopte_walk_dirty(struct arm_lpae_io_pgtable *data,
+ struct io_pgtable_walk_data *walk_data,
+ arm_lpae_iopte *ptep,
+ int lvl)
+{
+ u32 idx;
+ int max_entries, ret;
+
+ if (WARN_ON(lvl == ARM_LPAE_MAX_LEVELS))
+ return -EINVAL;
+
+ if (lvl == data->start_level)
+ max_entries = ARM_LPAE_PGD_SIZE(data) / sizeof(arm_lpae_iopte);
+ else
+ max_entries = ARM_LPAE_PTES_PER_TABLE(data);
+
+ for (idx = ARM_LPAE_LVL_IDX(walk_data->addr, lvl, data);
+ (idx < max_entries) && (walk_data->addr < walk_data->end); ++idx) {
+ ret = io_pgtable_visit_dirty(data, walk_data, ptep + idx, lvl);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int arm_lpae_read_and_clear_dirty(struct io_pgtable_ops *ops,
+ unsigned long iova, size_t size,
+ unsigned long flags,
+ struct iommu_dirty_bitmap *dirty)
+{
+ struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops);
+ struct io_pgtable_cfg *cfg = &data->iop.cfg;
+ struct io_pgtable_walk_data walk_data = {
+ .dirty = dirty,
+ .flags = flags,
+ .addr = iova,
+ .end = iova + size,
+ };
+ arm_lpae_iopte *ptep = data->pgd;
+ int lvl = data->start_level;
+
+ if (WARN_ON(!size))
+ return -EINVAL;
+ if (WARN_ON((iova + size - 1) & ~(BIT(cfg->ias) - 1)))
+ return -EINVAL;
+ if (data->iop.fmt != ARM_64_LPAE_S1)
+ return -EINVAL;
+
+ return __arm_lpae_iopte_walk_dirty(data, &walk_data, ptep, lvl);
+}
+
static void arm_lpae_restrict_pgsizes(struct io_pgtable_cfg *cfg)
{
unsigned long granule, page_sizes;
@@ -807,6 +907,7 @@ arm_lpae_alloc_pgtable(struct io_pgtable_cfg *cfg)
.map_pages = arm_lpae_map_pages,
.unmap_pages = arm_lpae_unmap_pages,
.iova_to_phys = arm_lpae_iova_to_phys,
+ .read_and_clear_dirty = arm_lpae_read_and_clear_dirty,
};
return data;
--
2.34.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v3 1/4] iommu/arm-smmu-v3: Add feature detection for HTTU
From: Shameer Kolothum @ 2024-04-30 13:43 UTC (permalink / raw)
To: iommu, linux-arm-kernel
Cc: robin.murphy, will, joro, jgg, ryan.roberts, kevin.tian, nicolinc,
mshavit, eric.auger, joao.m.martins, jiangkunkun, zhukeqian1,
linuxarm
In-Reply-To: <20240430134308.1604-1-shameerali.kolothum.thodi@huawei.com>
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
If the SMMU supports it and the kernel was built with HTTU support,
Probe support for Hardware Translation Table Update (HTTU) which is
essentially to enable hardware update of access and dirty flags.
Probe and set the smmu::features for Hardware Dirty and Hardware Access
bits. This is in preparation, to enable it on the context descriptors of
stage 1 format.
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
Signed-off-by: Joao Martins <joao.m.martins@oracle.com>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Reviewed-by: Ryan Roberts <ryan.roberts@arm.com>
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
---
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 32 +++++++++++++++++++++
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 5 ++++
2 files changed, 37 insertions(+)
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 5250e1d89fb8..bed0183ba809 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -4197,6 +4197,28 @@ static void arm_smmu_device_iidr_probe(struct arm_smmu_device *smmu)
}
}
+static void arm_smmu_get_httu(struct arm_smmu_device *smmu, u32 reg)
+{
+ u32 fw_features = smmu->features & (ARM_SMMU_FEAT_HA | ARM_SMMU_FEAT_HD);
+ u32 features = 0;
+
+ switch (FIELD_GET(IDR0_HTTU, reg)) {
+ case IDR0_HTTU_ACCESS_DIRTY:
+ features |= ARM_SMMU_FEAT_HD;
+ fallthrough;
+ case IDR0_HTTU_ACCESS:
+ features |= ARM_SMMU_FEAT_HA;
+ }
+
+ if (smmu->dev->of_node)
+ smmu->features |= features;
+ else if (features != fw_features)
+ /* ACPI IORT sets the HTTU bits */
+ dev_warn(smmu->dev,
+ "IDR0.HTTU overridden by FW configuration (0x%x)\n",
+ fw_features);
+}
+
static int arm_smmu_device_hw_probe(struct arm_smmu_device *smmu)
{
u32 reg;
@@ -4257,6 +4279,8 @@ static int arm_smmu_device_hw_probe(struct arm_smmu_device *smmu)
smmu->features |= ARM_SMMU_FEAT_E2H;
}
+ arm_smmu_get_httu(smmu, reg);
+
/*
* The coherency feature as set by FW is used in preference to the ID
* register, but warn on mismatch.
@@ -4452,6 +4476,14 @@ static int arm_smmu_device_acpi_probe(struct platform_device *pdev,
if (iort_smmu->flags & ACPI_IORT_SMMU_V3_COHACC_OVERRIDE)
smmu->features |= ARM_SMMU_FEAT_COHERENCY;
+ switch (FIELD_GET(ACPI_IORT_SMMU_V3_HTTU_OVERRIDE, iort_smmu->flags)) {
+ case IDR0_HTTU_ACCESS_DIRTY:
+ smmu->features |= ARM_SMMU_FEAT_HD;
+ fallthrough;
+ case IDR0_HTTU_ACCESS:
+ smmu->features |= ARM_SMMU_FEAT_HA;
+ }
+
return 0;
}
#else
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
index d888441c5ec1..fd60052a9ec6 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -33,6 +33,9 @@
#define IDR0_ASID16 (1 << 12)
#define IDR0_ATS (1 << 10)
#define IDR0_HYP (1 << 9)
+#define IDR0_HTTU GENMASK(7, 6)
+#define IDR0_HTTU_ACCESS 1
+#define IDR0_HTTU_ACCESS_DIRTY 2
#define IDR0_COHACC (1 << 4)
#define IDR0_TTF GENMASK(3, 2)
#define IDR0_TTF_AARCH64 2
@@ -665,6 +668,8 @@ struct arm_smmu_device {
#define ARM_SMMU_FEAT_E2H (1 << 18)
#define ARM_SMMU_FEAT_NESTING (1 << 19)
#define ARM_SMMU_FEAT_ATTR_TYPES_OVR (1 << 20)
+#define ARM_SMMU_FEAT_HA (1 << 21)
+#define ARM_SMMU_FEAT_HD (1 << 22)
u32 features;
#define ARM_SMMU_OPT_SKIP_PREFETCH (1 << 0)
--
2.34.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v3 0/4] iommu/smmuv3: Add IOMMUFD dirty tracking support for SMMUv3
From: Shameer Kolothum @ 2024-04-30 13:43 UTC (permalink / raw)
To: iommu, linux-arm-kernel
Cc: robin.murphy, will, joro, jgg, ryan.roberts, kevin.tian, nicolinc,
mshavit, eric.auger, joao.m.martins, jiangkunkun, zhukeqian1,
linuxarm
Hi
v2 --> v3
-Rebased on top of the latest of Jason's refactor series git[3].
-Addressed comments from Ryan and Jason(patch 2 & 3, Thanks!)
-Added R-by tags to 1 & 4.
Please take a look and let me know your feedback.
Thanks,
Shameer
---
This is revisiting the earlier attempts [1, 2] to use SMMUv3 HTTU feature
for dirty page tracking. The Intel/AMD support is already mainline.
Basic sanity tests are done using an emulation setup and on a test
hardware setup. Block page split/merge(BBML) is not part of this
series. I am planning to send it separately.
v1 --> v2:
https://lore.kernel.org/linux-iommu/20231128094940.1344-1-shameerali.kolothum.thodi@huawei.com/
Addressed review comments from Jason and Joao(Thanks)
-Moved dirty_ops setting to domain finalise(patch #3)
-Only enable DBM for stage 1 if domain_alloc_user() requests it.
-Changed IO page table walker(patch #2) and tested with 4KB/16KB/64KB
with l1/l2/l3 traversal.(The earlier one had a bug where it fails to
walk L3 level).
-Rearranged patches a bit to improve bi-sectability.
-Rebased on top of Jason's v5 of SMMUv3 new API series git.
1. https://lore.kernel.org/lkml/20210413085457.25400-1-zhukeqian1@huawei.com/
2. https://lore.kernel.org/linux-iommu/20230518204650.14541-1-joao.m.martins@oracle.com/
3. https://github.com/jgunthorpe/linux/commits/smmuv3_newapi
Jean-Philippe Brucker (1):
iommu/arm-smmu-v3: Add feature detection for HTTU
Joao Martins (1):
iommu/arm-smmu-v3: Add support for dirty tracking in domain alloc
Kunkun Jiang (1):
iommu/arm-smmu-v3: Enable HTTU for stage1 with io-pgtable mapping
Shameer Kolothum (1):
iommu/io-pgtable-arm: Add read_and_clear_dirty() support
drivers/iommu/Kconfig | 1 +
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 129 ++++++++++++++++----
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 8 ++
drivers/iommu/io-pgtable-arm.c | 110 ++++++++++++++++-
include/linux/io-pgtable.h | 4 +
5 files changed, 226 insertions(+), 26 deletions(-)
--
2.34.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v8 04/16] ACPI: processor: Move checks and availability of acpi_processor earlier
From: Jonathan Cameron @ 2024-04-30 13:42 UTC (permalink / raw)
To: Gavin Shan, linuxarm
Cc: Thomas Gleixner, Peter Zijlstra, linux-pm, loongarch, linux-acpi,
linux-arch, linux-kernel, linux-arm-kernel, kvmarm, x86,
Russell King, Rafael J . Wysocki, Miguel Luis, James Morse,
Salil Mehta, Jean-Philippe Brucker, Catalin Marinas, Will Deacon,
Marc Zyngier, Hanjun Guo, Ingo Molnar, Borislav Petkov,
Dave Hansen, justin.he, jianyong.wu, Lorenzo Pieralisi,
Sudeep Holla
In-Reply-To: <20240430111341.00003dba@huawei.com>
On Tue, 30 Apr 2024 11:13:41 +0100
Jonathan Cameron <Jonathan.Cameron@huawei.com> wrote:
> On Tue, 30 Apr 2024 10:28:38 +0100
> Jonathan Cameron <Jonathan.Cameron@Huawei.com> wrote:
>
> > On Tue, 30 Apr 2024 14:17:24 +1000
> > Gavin Shan <gshan@redhat.com> wrote:
> >
> > > On 4/26/24 23:51, Jonathan Cameron wrote:
> > > > Make the per_cpu(processors, cpu) entries available earlier so that
> > > > they are available in arch_register_cpu() as ARM64 will need access
> > > > to the acpi_handle to distinguish between acpi_processor_add()
> > > > and earlier registration attempts (which will fail as _STA cannot
> > > > be checked).
> > > >
> > > > Reorder the remove flow to clear this per_cpu() after
> > > > arch_unregister_cpu() has completed, allowing it to be used in
> > > > there as well.
> > > >
> > > > Note that on x86 for the CPU hotplug case, the pr->id prior to
> > > > acpi_map_cpu() may be invalid. Thus the per_cpu() structures
> > > > must be initialized after that call or after checking the ID
> > > > is valid (not hotplug path).
> > > >
> > > > Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
> > > >
> > > > ---
> > > > v8: On buggy bios detection when setting per_cpu structures
> > > > do not carry on.
> > > > Fix up the clearing of per cpu structures to remove unwanted
> > > > side effects and ensure an error code isn't use to reference them.
> > > > ---
> > > > drivers/acpi/acpi_processor.c | 79 +++++++++++++++++++++--------------
> > > > 1 file changed, 48 insertions(+), 31 deletions(-)
> > > >
> > > > diff --git a/drivers/acpi/acpi_processor.c b/drivers/acpi/acpi_processor.c
> > > > index ba0a6f0ac841..3b180e21f325 100644
> > > > --- a/drivers/acpi/acpi_processor.c
> > > > +++ b/drivers/acpi/acpi_processor.c
> > > > @@ -183,8 +183,38 @@ static void __init acpi_pcc_cpufreq_init(void) {}
> > > > #endif /* CONFIG_X86 */
> > > >
> > > > /* Initialization */
> > > > +static DEFINE_PER_CPU(void *, processor_device_array);
> > > > +
> > > > +static bool acpi_processor_set_per_cpu(struct acpi_processor *pr,
> > > > + struct acpi_device *device)
> > > > +{
> > > > + BUG_ON(pr->id >= nr_cpu_ids);
> > >
> > > One blank line after BUG_ON() if we need to follow original implementation.
> >
> > Sure unintentional - I'll put that back.
> >
> > >
> > > > + /*
> > > > + * Buggy BIOS check.
> > > > + * ACPI id of processors can be reported wrongly by the BIOS.
> > > > + * Don't trust it blindly
> > > > + */
> > > > + if (per_cpu(processor_device_array, pr->id) != NULL &&
> > > > + per_cpu(processor_device_array, pr->id) != device) {
> > > > + dev_warn(&device->dev,
> > > > + "BIOS reported wrong ACPI id %d for the processor\n",
> > > > + pr->id);
> > > > + /* Give up, but do not abort the namespace scan. */
> > >
> > > It depends on how the return value is handled by the caller if the namespace
> > > is continued to be scanned. The caller can be acpi_processor_hotadd_init()
> > > and acpi_processor_get_info() after this patch is applied. So I think this
> > > specific comment need to be moved to the caller.
> >
> > Good point. This gets messy and was an unintended change.
> >
> > Previously the options were:
> > 1) acpi_processor_get_info() failed for other reasons - this code was never called.
> > 2) acpi_processor_get_info() succeeded without acpi_processor_hotadd_init (non hotplug)
> > this code then ran and would paper over the problem doing a bunch of cleanup under err.
> > 3) acpi_processor_get_info() succeeded with acpi_processor_hotadd_init called.
> > This code then ran and would paper over the problem doing a bunch of cleanup under err.
> >
> > We should maintain that or argue cleanly against it.
> >
> > This isn't helped the the fact I have no idea which cases we care about for that bios
> > bug handling. Do any of those bios's ever do hotplug? Guess we have to try and maintain
> > whatever protection this was offering.
> >
> > Also, the original code leaks data in some paths and I have limited idea
> > of whether it is intentional or not. So to tidy the issue up that you've identified
> > I'll need to try and make that code consistent first.
> >
> > I suspect the only way to do that is going to be to duplicate the allocations we
> > 'want' to leak to deal with the bios bug detection.
> >
> > For example acpi_processor_get_info() failing leaks pr and pr->throttling.shared_cpu_map
> > before this series. After this series we need pr to leak because it's used for the detection
> > via processor_device_array.
> >
> > I'll work through this but it's going to be tricky to tell if we get right.
> > Step 1 will be closing the existing leaks and then we will have something
> > consistent to build on.
> >
> I 'think' that fixing the original leaks makes this all much more straight forward.
> That return 0 for acpi_processor_get_info() never made sense as far as I can tell.
> The pr isn't used after this point.
>
> What about something along lines of.
>
> diff --git a/drivers/acpi/acpi_processor.c b/drivers/acpi/acpi_processor.c
> index 161c95c9d60a..97cff4492304 100644
> --- a/drivers/acpi/acpi_processor.c
> +++ b/drivers/acpi/acpi_processor.c
> @@ -392,8 +392,10 @@ static int acpi_processor_add(struct acpi_device *device,
> device->driver_data = pr;
>
> result = acpi_processor_get_info(device);
> - if (result) /* Processor is not physically present or unavailable */
> - return 0;
> + if (result) { /* Processor is not physically present or unavailable */
> + result = 0;
> + goto err_free_throttling_mask;
FWIW this is wrong, should be goto err_clear_driver_data
(you can see it set just at the top of this block and that never fails!)
The err_free_throttling_mask label should be unused and hence won't exist in v9.
> + }
>
> BUG_ON(pr->id >= nr_cpu_ids);
>
> @@ -408,7 +410,7 @@ static int acpi_processor_add(struct acpi_device *device,
> "BIOS reported wrong ACPI id %d for the processor\n",
> pr->id);
> /* Give up, but do not abort the namespace scan. */
> - goto err;
> + goto err_clear_driver_data;
> }
> /*
> * processor_device_array is not cleared on errors to allow buggy BIOS
> @@ -420,12 +422,12 @@ static int acpi_processor_add(struct acpi_device *device,
> dev = get_cpu_device(pr->id);
> if (!dev) {
> result = -ENODEV;
> - goto err;
> + goto err_clear_per_cpu;
> }
>
> result = acpi_bind_one(dev, device);
> if (result)
> - goto err;
> + goto err_clear_per_cpu;
>
> pr->dev = dev;
>
> @@ -436,10 +438,12 @@ static int acpi_processor_add(struct acpi_device *device,
> dev_err(dev, "Processor driver could not be attached\n");
> acpi_unbind_one(dev);
>
> - err:
> - free_cpumask_var(pr->throttling.shared_cpu_map);
> - device->driver_data = NULL;
> + err_clear_per_cpu:
> per_cpu(processors, pr->id) = NULL;
> + err_clear_driver_data:
> + device->driver_data = NULL;
> + err_free_throttling_mask:
> + free_cpumask_var(pr->throttling.shared_cpu_map);
> err_free_pr:
> kfree(pr);
> return result;
>
> Then the diff on this patch is simply:
>
> diff --git a/drivers/acpi/acpi_processor.c b/drivers/acpi/acpi_processor.c
> index 3c49eae1e943..3b75f5aeb7ab 100644
> --- a/drivers/acpi/acpi_processor.c
> +++ b/drivers/acpi/acpi_processor.c
> @@ -200,7 +200,6 @@ static bool acpi_processor_set_per_cpu(struct acpi_processor *pr,
> dev_warn(&device->dev,
> "BIOS reported wrong ACPI id %d for the processor\n",
> pr->id);
> - /* Give up, but do not abort the namespace scan. */
> return false;
> }
> /*
> @@ -230,13 +229,14 @@ static int acpi_processor_hotadd_init(struct acpi_processor *pr,
> goto out;
>
> if (!acpi_processor_set_per_cpu(pr, device)) {
> + ret = -EINVAL;
> acpi_unmap_cpu(pr->id);
> goto out;
> }
>
> ret = arch_register_cpu(pr->id);
> if (ret) {
> - /* Leave the processor device array in place to detect buggy bios */
> +x /* Leave the processor device array in place to detect buggy bios */
> per_cpu(processors, pr->id) = NULL;
> acpi_unmap_cpu(pr->id);
> goto out;
> @@ -262,7 +262,7 @@ static inline int acpi_processor_hotadd_init(struct acpi_processor *pr,
> }
> #endif /* CONFIG_ACPI_HOTPLUG_CPU */
>
> -static int acpi_processor_get_info(struct acpi_device *device)
> +static int acpi_processor_get_info(struct acpi_device *device, bool bios_bug)
> {
> union acpi_object object = { 0 };
> struct acpi_buffer buffer = { sizeof(union acpi_object), &object };
> @@ -361,7 +361,7 @@ static int acpi_processor_get_info(struct acpi_device *device)
> return ret;
> } else {
> if (!acpi_processor_set_per_cpu(pr, device))
> - return 0;
> + return -EINVAL;
> }
>
> /*
> > >
> > > Besides, it seems acpi_processor_set_per_cpu() isn't properly called and
> > > memory leakage can happen. More details are given below.
> > >
> > > > + return false;
> > > > + }
> > > > + /*
> > > > + * processor_device_array is not cleared on errors to allow buggy BIOS
> > > > + * checks.
> > > > + */
> > > > + per_cpu(processor_device_array, pr->id) = device;
> > > > + per_cpu(processors, pr->id) = pr;
> > > > +
> > > > + return true;
> > > > +}
> > > > +
> > > > #ifdef CONFIG_ACPI_HOTPLUG_CPU
> > > > -static int acpi_processor_hotadd_init(struct acpi_processor *pr)
> > > > +static int acpi_processor_hotadd_init(struct acpi_processor *pr,
> > > > + struct acpi_device *device)
> > > > {
> > > > int ret;
> > > >
> > > > @@ -198,8 +228,15 @@ static int acpi_processor_hotadd_init(struct acpi_processor *pr)
> > > > if (ret)
> > > > goto out;
> > > >
> > > > + if (!acpi_processor_set_per_cpu(pr, device)) {
> > > > + acpi_unmap_cpu(pr->id);
> > > > + goto out;
> > > > + }
> > > > +
> > >
> > > With the 'goto out', zero is returned from acpi_processor_hotadd_init() to acpi_processor_get_info().
>
> Indeed a bug :(
>
> > > The zero return value is carried from acpi_map_cpu() in acpi_processor_hotadd_init(). If I'm correct,
> > > we need return errno from acpi_processor_get_info() to acpi_processor_add() so that cleanup can be
> > > done. For example, the cleanup corresponding to the 'err' tag can be done in acpi_processor_add().
> > > Otherwise, we will have memory leakage.
>
> The confusion here was that previously acpi_processor_add() was missing error cleanup for
> acpi_processor_get_info(). With that in place I think it's all much simpler.
>
> Thanks for your eagle eyes!
>
> Jonathan
>
>
> > >
> > > > ret = arch_register_cpu(pr->id);
> > > > if (ret) {
> > > > + /* Leave the processor device array in place to detect buggy bios */
> > > > + per_cpu(processors, pr->id) = NULL;
> > > > acpi_unmap_cpu(pr->id);
> > > > goto out;
> > > > }
> > > > @@ -217,7 +254,8 @@ static int acpi_processor_hotadd_init(struct acpi_processor *pr)
> > > > return ret;
> > > > }
> > > > #else
> > > > -static inline int acpi_processor_hotadd_init(struct acpi_processor *pr)
> > > > +static inline int acpi_processor_hotadd_init(struct acpi_processor *pr,
> > > > + struct acpi_device *device)
> > > > {
> > > > return -ENODEV;
> > > > }
> > > > @@ -316,10 +354,13 @@ static int acpi_processor_get_info(struct acpi_device *device)
> > > > * because cpuid <-> apicid mapping is persistent now.
> > > > */
> > > > if (invalid_logical_cpuid(pr->id) || !cpu_present(pr->id)) {
> > > > - int ret = acpi_processor_hotadd_init(pr);
> > > > + int ret = acpi_processor_hotadd_init(pr, device);
> > > >
> > > > if (ret)
> > > > return ret;
> > > > + } else {
> > > > + if (!acpi_processor_set_per_cpu(pr, device))
> > > > + return 0;
> > > > }
> > > >
> > >
> > > For non-hotplug case, we still need pass the error to acpi_processor_add() so that
> > > cleanup corresponding 'err' tag can be done. Otherwise, we will have memory leakage.
> > >
> > > > /*
> > > > @@ -365,8 +406,6 @@ static int acpi_processor_get_info(struct acpi_device *device)
> > > > * (cpu_data(cpu)) values, like CPU feature flags, family, model, etc.
> > > > * Such things have to be put in and set up by the processor driver's .probe().
> > > > */
> > > > -static DEFINE_PER_CPU(void *, processor_device_array);
> > > > -
> > > > static int acpi_processor_add(struct acpi_device *device,
> > > > const struct acpi_device_id *id)
> > > > {
> > > > @@ -395,28 +434,6 @@ static int acpi_processor_add(struct acpi_device *device,
> > > > if (result) /* Processor is not physically present or unavailable */
> > > > return 0;
> > > >
> > > > - BUG_ON(pr->id >= nr_cpu_ids);
> > > > -
> > > > - /*
> > > > - * Buggy BIOS check.
> > > > - * ACPI id of processors can be reported wrongly by the BIOS.
> > > > - * Don't trust it blindly
> > > > - */
> > > > - if (per_cpu(processor_device_array, pr->id) != NULL &&
> > > > - per_cpu(processor_device_array, pr->id) != device) {
> > > > - dev_warn(&device->dev,
> > > > - "BIOS reported wrong ACPI id %d for the processor\n",
> > > > - pr->id);
> > > > - /* Give up, but do not abort the namespace scan. */
> > > > - goto err;
> > > > - }
> > > > - /*
> > > > - * processor_device_array is not cleared on errors to allow buggy BIOS
> > > > - * checks.
> > > > - */
> > > > - per_cpu(processor_device_array, pr->id) = device;
> > > > - per_cpu(processors, pr->id) = pr;
> > > > -
> > > > dev = get_cpu_device(pr->id);
> > > > if (!dev) {
> > > > result = -ENODEV;
> > > > @@ -469,10 +486,6 @@ static void acpi_processor_remove(struct acpi_device *device)
> > > > device_release_driver(pr->dev);
> > > > acpi_unbind_one(pr->dev);
> > > >
> > > > - /* Clean up. */
> > > > - per_cpu(processor_device_array, pr->id) = NULL;
> > > > - per_cpu(processors, pr->id) = NULL;
> > > > -
> > > > cpu_maps_update_begin();
> > > > cpus_write_lock();
> > > >
> > > > @@ -480,6 +493,10 @@ static void acpi_processor_remove(struct acpi_device *device)
> > > > arch_unregister_cpu(pr->id);
> > > > acpi_unmap_cpu(pr->id);
> > > >
> > > > + /* Clean up. */
> > > > + per_cpu(processor_device_array, pr->id) = NULL;
> > > > + per_cpu(processors, pr->id) = NULL;
> > > > +
> > > > cpus_write_unlock();
> > > > cpu_maps_update_done();
> > > >
> > >
> > > Thanks,
> > > Gavin
> > >
> >
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 00/17] Add support for the LAN966x PCI device using a DT overlay
From: Andrew Lunn @ 2024-04-30 13:40 UTC (permalink / raw)
To: Herve Codina
Cc: Thomas Gleixner, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Lee Jones, Arnd Bergmann, Horatiu Vultur, UNGLinuxDriver,
Heiner Kallweit, Russell King, Saravana Kannan, Bjorn Helgaas,
Philipp Zabel, Lars Povlsen, Steen Hegelund, Daniel Machon,
Alexandre Belloni, linux-kernel, devicetree, netdev, linux-pci,
linux-arm-kernel, Allan Nielsen, Luca Ceresoli, Thomas Petazzoni
In-Reply-To: <20240430083730.134918-1-herve.codina@bootlin.com>
On Tue, Apr 30, 2024 at 10:37:09AM +0200, Herve Codina wrote:
> Hi,
>
> This series adds support for the LAN966x chip when used as a PCI
> device.
> This patch series for now adds a Device Tree overlay that describes an
> initial subset of the devices available over PCI in the LAN996x, and
> follow-up patch series will add support for more once this initial
> support has landed.
What host systems have you tested with? Are they all native DT, or
have you tested on an ACPI system? I'm just wondering how well DT
overlay works if i were to plug a LAN966x device into something like
an x86 ComExpress board?
Andrew
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH net-next] net: phy: Don't conditionally compile the phy_link_topology creation
From: Maxime Chevallier @ 2024-04-30 13:36 UTC (permalink / raw)
To: Heiner Kallweit
Cc: davem, netdev, linux-kernel, thomas.petazzoni, Andrew Lunn,
Jakub Kicinski, Eric Dumazet, Paolo Abeni, Russell King,
linux-arm-kernel, Christophe Leroy, Herve Codina,
Florian Fainelli, Vladimir Oltean, Köry Maincent,
Jesse Brandeburg, Marek Behún, Piergiorgio Beruto,
Oleksij Rempel, Nicolò Veronese, Simon Horman, mwojtas,
Nathan Chancellor, Antoine Tenart
In-Reply-To: <20240430135734.503f51a2@device-28.home>
On Tue, 30 Apr 2024 13:57:34 +0200
Maxime Chevallier <maxime.chevallier@bootlin.com> wrote:
> Hello Heiner,
>
> On Tue, 30 Apr 2024 10:17:31 +0200
> Heiner Kallweit <hkallweit1@gmail.com> wrote:
>
> > On 29.04.2024 15:10, Maxime Chevallier wrote:
> > > The core of the phy_link_topology isn't directly tied to phylib, and at
> > > the moment it's initialized, phylib might not be loaded yet. Move the
> > > initialization of the topology to the phy_link_topology_core header,
> > > which contains the bare minimum so that we can initialize it at netdev
> > > creation.
> > >
> >
> > The change fixes the issue for me, but according to my personal taste
> > the code isn't intuitive and still error-prone. Also there's no good
> > reason to inline a function like phy_link_topo_create() and make it
> > publicly available. Do you expect it to be ever used outside net core?
> > In general it may make sense to add a config symbol for the topology
> > extension, there seem to be very few, specialized use cases for it.
>
> I think I'm missing the point here then. Do you mean adding a Kconfig
> option to explicitely turn phy_link_topology on ? or build it as a
> dedicated kernel module ?
>
> Or do you see something such as "if phylib is M or Y, then build the
> topology stuff and make sure it's allocated when a netdev gets created
> ?"
I've prototyped something that's cleaner and should fit what you
described, which is to have a Kconfig option for phy_topology and
have it autoselected by CONFIG_SFP (for now, the only case where we can
have multiple PHYs on the link). When phy mux support is added (I'll
followup with that once the topology is settled), we can also make is
select the phy_topology config option. I'll send that patch when I'll
have properly tested it, especially with all the different bits
(phylib, sfp, drivers) being tested as modules or builtin.
Thanks for the tips,
Maxime
>
> Thanks,
>
> Maxime
>
> >
> > > Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
> > > Closes: https://lore.kernel.org/netdev/2e11b89d-100f-49e7-9c9a-834cc0b82f97@gmail.com/
> > > Closes: https://lore.kernel.org/netdev/20240409201553.GA4124869@dev-arch.thelio-3990X/
> > > ---
> > > drivers/net/phy/phy_link_topology.c | 23 --------------------
> > > include/linux/phy_link_topology.h | 5 -----
> > > include/linux/phy_link_topology_core.h | 30 +++++++++++++++++---------
> > > 3 files changed, 20 insertions(+), 38 deletions(-)
> > >
> > > diff --git a/drivers/net/phy/phy_link_topology.c b/drivers/net/phy/phy_link_topology.c
> > > index 985941c5c558..960aedd73308 100644
> > > --- a/drivers/net/phy/phy_link_topology.c
> > > +++ b/drivers/net/phy/phy_link_topology.c
> > > @@ -12,29 +12,6 @@
> > > #include <linux/rtnetlink.h>
> > > #include <linux/xarray.h>
> > >
> > > -struct phy_link_topology *phy_link_topo_create(struct net_device *dev)
> > > -{
> > > - struct phy_link_topology *topo;
> > > -
> > > - topo = kzalloc(sizeof(*topo), GFP_KERNEL);
> > > - if (!topo)
> > > - return ERR_PTR(-ENOMEM);
> > > -
> > > - xa_init_flags(&topo->phys, XA_FLAGS_ALLOC1);
> > > - topo->next_phy_index = 1;
> > > -
> > > - return topo;
> > > -}
> > > -
> > > -void phy_link_topo_destroy(struct phy_link_topology *topo)
> > > -{
> > > - if (!topo)
> > > - return;
> > > -
> > > - xa_destroy(&topo->phys);
> > > - kfree(topo);
> > > -}
> > > -
> > > int phy_link_topo_add_phy(struct phy_link_topology *topo,
> > > struct phy_device *phy,
> > > enum phy_upstream upt, void *upstream)
> > > diff --git a/include/linux/phy_link_topology.h b/include/linux/phy_link_topology.h
> > > index 6b79feb607e7..ad72d7881257 100644
> > > --- a/include/linux/phy_link_topology.h
> > > +++ b/include/linux/phy_link_topology.h
> > > @@ -32,11 +32,6 @@ struct phy_device_node {
> > > struct phy_device *phy;
> > > };
> > >
> > > -struct phy_link_topology {
> > > - struct xarray phys;
> > > - u32 next_phy_index;
> > > -};
> > > -
> > > static inline struct phy_device *
> > > phy_link_topo_get_phy(struct phy_link_topology *topo, u32 phyindex)
> > > {
> > > diff --git a/include/linux/phy_link_topology_core.h b/include/linux/phy_link_topology_core.h
> > > index 0a6479055745..0116ec49cd1b 100644
> > > --- a/include/linux/phy_link_topology_core.h
> > > +++ b/include/linux/phy_link_topology_core.h
> > > @@ -2,24 +2,34 @@
> > > #ifndef __PHY_LINK_TOPOLOGY_CORE_H
> > > #define __PHY_LINK_TOPOLOGY_CORE_H
> > >
> > > -struct phy_link_topology;
> > > +#include <linux/xarray.h>
> > >
> > > -#if IS_REACHABLE(CONFIG_PHYLIB)
> > > -
> > > -struct phy_link_topology *phy_link_topo_create(struct net_device *dev);
> > > -void phy_link_topo_destroy(struct phy_link_topology *topo);
> > > -
> > > -#else
> > > +struct phy_link_topology {
> > > + struct xarray phys;
> > > + u32 next_phy_index;
> > > +};
> > >
> > > static inline struct phy_link_topology *phy_link_topo_create(struct net_device *dev)
> > > {
> > > - return NULL;
> > > + struct phy_link_topology *topo;
> > > +
> > > + topo = kzalloc(sizeof(*topo), GFP_KERNEL);
> > > + if (!topo)
> > > + return ERR_PTR(-ENOMEM);
> > > +
> > > + xa_init_flags(&topo->phys, XA_FLAGS_ALLOC1);
> > > + topo->next_phy_index = 1;
> > > +
> > > + return topo;
> > > }
> > >
> > > static inline void phy_link_topo_destroy(struct phy_link_topology *topo)
> > > {
> > > -}
> > > + if (!topo)
> > > + return;
> > >
> > > -#endif
> > > + xa_destroy(&topo->phys);
> > > + kfree(topo);
> > > +}
> > >
> > > #endif /* __PHY_LINK_TOPOLOGY_CORE_H */
> >
>
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v2 1/3] arm64/mm: Refactor PMD_PRESENT_INVALID and PTE_PROT_NONE bits
From: Ryan Roberts @ 2024-04-30 13:34 UTC (permalink / raw)
To: Catalin Marinas
Cc: Will Deacon, Joey Gouly, Ard Biesheuvel, Mark Rutland,
Anshuman Khandual, David Hildenbrand, Peter Xu, Mike Rapoport,
Shivansh Vij, linux-arm-kernel, linux-kernel
In-Reply-To: <ZjDyCg2LkFEXRS6k@arm.com>
On 30/04/2024 14:28, Catalin Marinas wrote:
> On Tue, Apr 30, 2024 at 12:35:49PM +0100, Ryan Roberts wrote:
>> There is still one problem I need to resolve; During this work I discovered that
>> core-mm can call pmd_mkinvalid() for swap pmds. On arm64 this will turn the swap
>> pmd into a present pmd, and BadThings can happen in GUP-fast (and any other
>> lockless SW table walkers). My original fix modified core-mm to only call
>> pmd_mkinvalid() for present pmds. But discussion over there has shown that arm64
>> is the only arch that cannot handle this. So I've been convinced that it's
>> probably more robust to make arm64 handle it gracefully and add tests to
>> debug_vm_pgtable.c to check for this. Patch incoming shortly, but it will cause
>> a conflict with this series. So I'll send a v2 of this once that fix is accepted.
>
> Sounds fine. I can queue the arm64 pmd_mkinvalid() fix for 6.9 and you
> can base this series on top. But I have a preference for this patchset
> to sit in -next for a bit anyway, so it might be 6.11 material.
Yeah that works for me. I just sent the pmd_mkinvalid() fix.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH] perf cs-etm: Improve version detection and error reporting
From: James Clark @ 2024-04-30 13:32 UTC (permalink / raw)
To: linux-perf-users, coresight
Cc: James Clark, Suzuki K Poulose, Mike Leach, John Garry,
Will Deacon, Leo Yan, Peter Zijlstra, Ingo Molnar,
Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland,
Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
Liang, Kan, linux-arm-kernel, linux-kernel
When the config validation functions are warning about ETMv3, they do it
based on "not ETMv4". If the drivers aren't all loaded or the hardware
doesn't support Coresight it will appear as "not ETMv4" and then Perf
will print the error message "... not supported in ETMv3 ..." which is
wrong and confusing.
cs_etm_is_etmv4() is also misnamed because it also returns true for
ETE because ETE has a superset of the ETMv4 metadata files. Although
this was always done in the correct order so it wasn't a bug.
Improve all this by making a single get version function which also
handles not present as a separate case. Change the ETMv3 error message
to only print when ETMv3 is detected, and add a new error message for
the not present case.
Signed-off-by: James Clark <james.clark@arm.com>
---
tools/perf/arch/arm/util/cs-etm.c | 64 +++++++++++++++++++++++--------
1 file changed, 48 insertions(+), 16 deletions(-)
diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c
index 07be32d99805..2763c6758b91 100644
--- a/tools/perf/arch/arm/util/cs-etm.c
+++ b/tools/perf/arch/arm/util/cs-etm.c
@@ -66,9 +66,25 @@ static const char * const metadata_ete_ro[] = {
[CS_ETE_TS_SOURCE] = "ts_source",
};
-static bool cs_etm_is_etmv4(struct auxtrace_record *itr, int cpu);
+enum cs_etm_version { CS_NOT_PRESENT, CS_ETMV3, CS_ETMV4, CS_ETE };
+
+static bool cs_etm_pmu_file_present(struct auxtrace_record *itr, int cpu,
+ const char *file);
static bool cs_etm_is_ete(struct auxtrace_record *itr, int cpu);
+static enum cs_etm_version cs_etm_get_version(struct auxtrace_record *itr,
+ int cpu)
+{
+ if (cs_etm_is_ete(itr, cpu))
+ return CS_ETE;
+ else if (cs_etm_pmu_file_present(itr, cpu, metadata_etmv4_ro[CS_ETMV4_TRCIDR0]))
+ return CS_ETMV4;
+ else if (cs_etm_pmu_file_present(itr, cpu, metadata_etmv3_ro[CS_ETM_ETMCCER]))
+ return CS_ETMV3;
+
+ return CS_NOT_PRESENT;
+}
+
static int cs_etm_validate_context_id(struct auxtrace_record *itr,
struct evsel *evsel, int cpu)
{
@@ -87,7 +103,7 @@ static int cs_etm_validate_context_id(struct auxtrace_record *itr,
return 0;
/* Not supported in etmv3 */
- if (!cs_etm_is_etmv4(itr, cpu)) {
+ if (cs_etm_get_version(itr, cpu) == CS_ETMV3) {
pr_err("%s: contextid not supported in ETMv3, disable with %s/contextid=0/\n",
CORESIGHT_ETM_PMU_NAME, CORESIGHT_ETM_PMU_NAME);
return -EINVAL;
@@ -154,7 +170,7 @@ static int cs_etm_validate_timestamp(struct auxtrace_record *itr,
perf_pmu__format_bits(cs_etm_pmu, "timestamp")))
return 0;
- if (!cs_etm_is_etmv4(itr, cpu)) {
+ if (cs_etm_get_version(itr, cpu) == CS_ETMV3) {
pr_err("%s: timestamp not supported in ETMv3, disable with %s/timestamp=0/\n",
CORESIGHT_ETM_PMU_NAME, CORESIGHT_ETM_PMU_NAME);
return -EINVAL;
@@ -218,6 +234,11 @@ static int cs_etm_validate_config(struct auxtrace_record *itr,
}
perf_cpu_map__for_each_cpu_skip_any(cpu, idx, intersect_cpus) {
+ if (cs_etm_get_version(itr, cpu.cpu) == CS_NOT_PRESENT) {
+ pr_err("%s: Not found on CPU %d. Check hardware and firmware support and that all Coresight drivers are loaded\n",
+ CORESIGHT_ETM_PMU_NAME, cpu.cpu);
+ return -EINVAL;
+ }
err = cs_etm_validate_context_id(itr, evsel, cpu.cpu);
if (err)
break;
@@ -548,13 +569,13 @@ cs_etm_info_priv_size(struct auxtrace_record *itr __maybe_unused,
/* Event can be "any" CPU so count all online CPUs. */
intersect_cpus = perf_cpu_map__new_online_cpus();
}
+ /* Count number of each type of ETM. Don't count if that CPU has CS_NOT_PRESENT. */
perf_cpu_map__for_each_cpu_skip_any(cpu, idx, intersect_cpus) {
- if (cs_etm_is_ete(itr, cpu.cpu))
- ete++;
- else if (cs_etm_is_etmv4(itr, cpu.cpu))
- etmv4++;
- else
- etmv3++;
+ enum cs_etm_version v = cs_etm_get_version(itr, cpu.cpu);
+
+ ete += v == CS_ETE;
+ etmv4 += v == CS_ETMV4;
+ etmv3 += v == CS_ETMV3;
}
perf_cpu_map__put(intersect_cpus);
@@ -564,7 +585,8 @@ cs_etm_info_priv_size(struct auxtrace_record *itr __maybe_unused,
(etmv3 * CS_ETMV3_PRIV_SIZE));
}
-static bool cs_etm_is_etmv4(struct auxtrace_record *itr, int cpu)
+static bool cs_etm_pmu_file_present(struct auxtrace_record *itr, int cpu,
+ const char *file)
{
bool ret = false;
char path[PATH_MAX];
@@ -574,9 +596,7 @@ static bool cs_etm_is_etmv4(struct auxtrace_record *itr, int cpu)
container_of(itr, struct cs_etm_recording, itr);
struct perf_pmu *cs_etm_pmu = ptr->cs_etm_pmu;
- /* Take any of the RO files for ETMv4 and see if it present */
- snprintf(path, PATH_MAX, "cpu%d/%s",
- cpu, metadata_etmv4_ro[CS_ETMV4_TRCIDR0]);
+ snprintf(path, PATH_MAX, "cpu%d/%s", cpu, file);
scan = perf_pmu__scan_file(cs_etm_pmu, path, "%x", &val);
/* The file was read successfully, we have a winner */
@@ -735,21 +755,26 @@ static void cs_etm_get_metadata(int cpu, u32 *offset,
struct perf_pmu *cs_etm_pmu = ptr->cs_etm_pmu;
/* first see what kind of tracer this cpu is affined to */
- if (cs_etm_is_ete(itr, cpu)) {
+ switch (cs_etm_get_version(itr, cpu)) {
+ case CS_ETE:
magic = __perf_cs_ete_magic;
cs_etm_save_ete_header(&info->priv[*offset], itr, cpu);
/* How much space was used */
increment = CS_ETE_PRIV_MAX;
nr_trc_params = CS_ETE_PRIV_MAX - CS_ETM_COMMON_BLK_MAX_V1;
- } else if (cs_etm_is_etmv4(itr, cpu)) {
+ break;
+
+ case CS_ETMV4:
magic = __perf_cs_etmv4_magic;
cs_etm_save_etmv4_header(&info->priv[*offset], itr, cpu);
/* How much space was used */
increment = CS_ETMV4_PRIV_MAX;
nr_trc_params = CS_ETMV4_PRIV_MAX - CS_ETMV4_TRCCONFIGR;
- } else {
+ break;
+
+ case CS_ETMV3:
magic = __perf_cs_etmv3_magic;
/* Get configuration register */
info->priv[*offset + CS_ETM_ETMCR] = cs_etm_get_config(itr);
@@ -767,6 +792,13 @@ static void cs_etm_get_metadata(int cpu, u32 *offset,
/* How much space was used */
increment = CS_ETM_PRIV_MAX;
nr_trc_params = CS_ETM_PRIV_MAX - CS_ETM_ETMCR;
+ break;
+
+ default:
+ case CS_NOT_PRESENT:
+ /* Unreachable, CPUs already validated in cs_etm_validate_config() */
+ assert(true);
+ return;
}
/* Build generic header portion */
--
2.34.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v2] arm64/mm: pmd_mkinvalid() must handle swap pmds
From: Ryan Roberts @ 2024-04-30 13:31 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Mark Rutland, Anshuman Khandual,
Andrew Morton, Zi Yan, Aneesh Kumar K.V
Cc: Ryan Roberts, linux-arm-kernel, linux-mm, linux-kernel, stable
__split_huge_pmd_locked() can be called for a present THP, devmap or
(non-present) migration entry. It calls pmdp_invalidate()
unconditionally on the pmdp and only determines if it is present or not
based on the returned old pmd.
But arm64's pmd_mkinvalid(), called by pmdp_invalidate(),
unconditionally sets the PMD_PRESENT_INVALID flag, which causes future
pmd_present() calls to return true - even for a swap pmd. Therefore any
lockless pgtable walker could see the migration entry pmd in this state
and start interpretting the fields (e.g. pmd_pfn()) as if it were
present, leading to BadThings (TM). GUP-fast appears to be one such
lockless pgtable walker.
While the obvious fix is for core-mm to avoid such calls for non-present
pmds (pmdp_invalidate() will also issue TLBI which is not necessary for
this case either), all other arches that implement pmd_mkinvalid() do it
in such a way that it is robust to being called with a non-present pmd.
So it is simpler and safer to make arm64 robust too. This approach means
we can even add tests to debug_vm_pgtable.c to validate the required
behaviour.
This is a theoretical bug found during code review. I don't have any
test case to trigger it in practice.
Cc: stable@vger.kernel.org
Fixes: 53fa117bb33c ("arm64/mm: Enable THP migration")
Signed-off-by: Ryan Roberts <ryan.roberts@arm.com>
---
Hi all,
v1 of this fix [1] took the approach of fixing core-mm to never call
pmdp_invalidate() on a non-present pmd. But Zi Yan highlighted that only arm64
suffers this problem; all other arches are robust. So his suggestion was to
instead make arm64 robust in the same way and add tests to validate it. Despite
my stated reservations in the context of the v1 discussion, having thought on it
for a bit, I now agree with Zi Yan. Hence this post.
Andrew has v1 in mm-unstable at the moment, so probably the best thing to do is
remove it from there and have this go in through the arm64 tree? Assuming there
is agreement that this approach is right one.
This applies on top of v6.9-rc5. Passes all the mm selftests on arm64.
[1] https://lore.kernel.org/linux-mm/20240425170704.3379492-1-ryan.roberts@arm.com/
Thanks,
Ryan
arch/arm64/include/asm/pgtable.h | 12 +++++--
mm/debug_vm_pgtable.c | 61 ++++++++++++++++++++++++++++++++
2 files changed, 71 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index afdd56d26ad7..7d580271a46d 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -511,8 +511,16 @@ static inline int pmd_trans_huge(pmd_t pmd)
static inline pmd_t pmd_mkinvalid(pmd_t pmd)
{
- pmd = set_pmd_bit(pmd, __pgprot(PMD_PRESENT_INVALID));
- pmd = clear_pmd_bit(pmd, __pgprot(PMD_SECT_VALID));
+ /*
+ * If not valid then either we are already present-invalid or we are
+ * not-present (i.e. none or swap entry). We must not convert
+ * not-present to present-invalid. Unbelievably, the core-mm may call
+ * pmd_mkinvalid() for a swap entry and all other arches can handle it.
+ */
+ if (pmd_valid(pmd)) {
+ pmd = set_pmd_bit(pmd, __pgprot(PMD_PRESENT_INVALID));
+ pmd = clear_pmd_bit(pmd, __pgprot(PMD_SECT_VALID));
+ }
return pmd;
}
diff --git a/mm/debug_vm_pgtable.c b/mm/debug_vm_pgtable.c
index 65c19025da3d..7e9c387d06b0 100644
--- a/mm/debug_vm_pgtable.c
+++ b/mm/debug_vm_pgtable.c
@@ -956,6 +956,65 @@ static void __init hugetlb_basic_tests(struct pgtable_debug_args *args) { }
#endif /* CONFIG_HUGETLB_PAGE */
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+#if !defined(__HAVE_ARCH_PMDP_INVALIDATE) && defined(CONFIG_ARCH_ENABLE_THP_MIGRATION)
+static void __init swp_pmd_mkinvalid_tests(struct pgtable_debug_args *args)
+{
+ unsigned long max_swap_offset;
+ swp_entry_t swp_set, swp_clear, swp_convert;
+ pmd_t pmd_set, pmd_clear;
+
+ /*
+ * See generic_max_swapfile_size(): probe the maximum offset, then
+ * create swap entry will all possible bits set and a swap entry will
+ * all bits clear.
+ */
+ max_swap_offset = swp_offset(pmd_to_swp_entry(swp_entry_to_pmd(swp_entry(0, ~0UL))));
+ swp_set = swp_entry((1 << MAX_SWAPFILES_SHIFT) - 1, max_swap_offset);
+ swp_clear = swp_entry(0, 0);
+
+ /* Convert to pmd. */
+ pmd_set = swp_entry_to_pmd(swp_set);
+ pmd_clear = swp_entry_to_pmd(swp_clear);
+
+ /*
+ * Sanity check that the pmds are not-present, not-huge and swap entry
+ * is recoverable without corruption.
+ */
+ WARN_ON(pmd_present(pmd_set));
+ WARN_ON(pmd_trans_huge(pmd_set));
+ swp_convert = pmd_to_swp_entry(pmd_set);
+ WARN_ON(swp_type(swp_set) != swp_type(swp_convert));
+ WARN_ON(swp_offset(swp_set) != swp_offset(swp_convert));
+ WARN_ON(pmd_present(pmd_clear));
+ WARN_ON(pmd_trans_huge(pmd_clear));
+ swp_convert = pmd_to_swp_entry(pmd_clear);
+ WARN_ON(swp_type(swp_clear) != swp_type(swp_convert));
+ WARN_ON(swp_offset(swp_clear) != swp_offset(swp_convert));
+
+ /* Now invalidate the pmd. */
+ pmd_set = pmd_mkinvalid(pmd_set);
+ pmd_clear = pmd_mkinvalid(pmd_clear);
+
+ /*
+ * Since its a swap pmd, invalidation should effectively be a noop and
+ * the checks we already did should give the same answer. Check the
+ * invalidation didn't corrupt any fields.
+ */
+ WARN_ON(pmd_present(pmd_set));
+ WARN_ON(pmd_trans_huge(pmd_set));
+ swp_convert = pmd_to_swp_entry(pmd_set);
+ WARN_ON(swp_type(swp_set) != swp_type(swp_convert));
+ WARN_ON(swp_offset(swp_set) != swp_offset(swp_convert));
+ WARN_ON(pmd_present(pmd_clear));
+ WARN_ON(pmd_trans_huge(pmd_clear));
+ swp_convert = pmd_to_swp_entry(pmd_clear);
+ WARN_ON(swp_type(swp_clear) != swp_type(swp_convert));
+ WARN_ON(swp_offset(swp_clear) != swp_offset(swp_convert));
+}
+#else
+static void __init swp_pmd_mkinvalid_tests(struct pgtable_debug_args *args) { }
+#endif /* !__HAVE_ARCH_PMDP_INVALIDATE && CONFIG_ARCH_ENABLE_THP_MIGRATION */
+
static void __init pmd_thp_tests(struct pgtable_debug_args *args)
{
pmd_t pmd;
@@ -982,6 +1041,8 @@ static void __init pmd_thp_tests(struct pgtable_debug_args *args)
WARN_ON(!pmd_trans_huge(pmd_mkinvalid(pmd_mkhuge(pmd))));
WARN_ON(!pmd_present(pmd_mkinvalid(pmd_mkhuge(pmd))));
#endif /* __HAVE_ARCH_PMDP_INVALIDATE */
+
+ swp_pmd_mkinvalid_tests(args);
}
#ifdef CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD
--
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox