Re: [PATCH v2] printk: Add a short description string to kmsg_dump()
On 02/07/2024 22:29, Kees Cook wrote: On Tue, Jul 02, 2024 at 02:26:04PM +0200, Jocelyn Falempe wrote: kmsg_dump doesn't forward the panic reason string to the kmsg_dumper callback. This patch adds a new struct kmsg_dump_detail, that will hold the reason and description, and pass it to the dump() callback. Thanks! I like this much better. :) To avoid updating all kmsg_dump() call, it adds a kmsg_dump_desc() function and a macro for backward compatibility. I've written this for drm_panic, but it can be useful for other kmsg_dumper. It allows to see the panic reason, like "sysrq triggered crash" or "VFS: Unable to mount root fs on " on the drm panic screen. v2: * Use a struct kmsg_dump_detail to hold the reason and description pointer, for more flexibility if we want to add other parameters. (Kees Cook) * Fix powerpc/nvram_64 build, as I didn't update the forward declaration of oops_to_nvram() The versioning history commonly goes after the "---". ok, I was not aware of this. [...] diff --git a/include/linux/kmsg_dump.h b/include/linux/kmsg_dump.h index 906521c2329c..65f5a47727bc 100644 --- a/include/linux/kmsg_dump.h +++ b/include/linux/kmsg_dump.h @@ -39,6 +39,17 @@ struct kmsg_dump_iter { u64 next_seq; }; +/** + *struct kmsg_dump_detail - kernel crash detail Is kern-doc happy with this? I think there is supposed to be a space between the "*" and the first word: /** * struct kmsg... Good catch, yes there is a space missing. I just checked with "make htmldocs", and in fact include/linux/kmsg_dump.h is not indexed for kernel documentation. And you can't find the definition of struct kmsg_dumper in the online doc. https://www.kernel.org/doc/html/latest/search.html?q=kmsg_dumper Otherwise looks good to me! Thanks. As this patch touches different subsystems, do you know on which tree it should land ? -- Jocelyn
Re: [PATCH v2] printk: Add a short description string to kmsg_dump()
On Tue 2024-07-02 14:26:04, Jocelyn Falempe wrote: > kmsg_dump doesn't forward the panic reason string to the kmsg_dumper > callback. > This patch adds a new struct kmsg_dump_detail, that will hold the > reason and description, and pass it to the dump() callback. > > To avoid updating all kmsg_dump() call, it adds a kmsg_dump_desc() > function and a macro for backward compatibility. > > I've written this for drm_panic, but it can be useful for other > kmsg_dumper. > It allows to see the panic reason, like "sysrq triggered crash" > or "VFS: Unable to mount root fs on " on the drm panic screen. > > v2: > * Use a struct kmsg_dump_detail to hold the reason and description >pointer, for more flexibility if we want to add other parameters. >(Kees Cook) > * Fix powerpc/nvram_64 build, as I didn't update the forward >declaration of oops_to_nvram() > > Signed-off-by: Jocelyn Falempe Looks good to me. With the minor fixes suggested by Kees: Acked-by: Petr Mladek Best Regards, Petr
Re: [PATCH v2] printk: Add a short description string to kmsg_dump()
On Wed 2024-07-03 09:57:26, Jocelyn Falempe wrote: > > > On 02/07/2024 22:29, Kees Cook wrote: > > On Tue, Jul 02, 2024 at 02:26:04PM +0200, Jocelyn Falempe wrote: > > > kmsg_dump doesn't forward the panic reason string to the kmsg_dumper > > > callback. > > > This patch adds a new struct kmsg_dump_detail, that will hold the > > > reason and description, and pass it to the dump() callback. > > > > Thanks! I like this much better. :) > > > > > > > > To avoid updating all kmsg_dump() call, it adds a kmsg_dump_desc() > > > function and a macro for backward compatibility. > > > > > > I've written this for drm_panic, but it can be useful for other > > > kmsg_dumper. > > > It allows to see the panic reason, like "sysrq triggered crash" > > > or "VFS: Unable to mount root fs on " on the drm panic screen. > > > > > > v2: > > > * Use a struct kmsg_dump_detail to hold the reason and description > > > pointer, for more flexibility if we want to add other parameters. > > > (Kees Cook) > > > * Fix powerpc/nvram_64 build, as I didn't update the forward > > > declaration of oops_to_nvram() > > > > The versioning history commonly goes after the "---". > > ok, I was not aware of this. > > > > > [...] > > > diff --git a/include/linux/kmsg_dump.h b/include/linux/kmsg_dump.h > > > index 906521c2329c..65f5a47727bc 100644 > > > --- a/include/linux/kmsg_dump.h > > > +++ b/include/linux/kmsg_dump.h > > > @@ -39,6 +39,17 @@ struct kmsg_dump_iter { > > > u64 next_seq; > > > }; > > > +/** > > > + *struct kmsg_dump_detail - kernel crash detail > > > > Is kern-doc happy with this? I think there is supposed to be a space > > between the "*" and the first word: > > > > /** > >* struct kmsg... > > > > > Good catch, yes there is a space missing. > > I just checked with "make htmldocs", and in fact include/linux/kmsg_dump.h > is not indexed for kernel documentation. > And you can't find the definition of struct kmsg_dumper in the online doc. > https://www.kernel.org/doc/html/latest/search.html?q=kmsg_dumper > > > Otherwise looks good to me! > > > > Thanks. > > As this patch touches different subsystems, do you know on which tree it > should land ? Andrew usually takes patches against kernel/panic.c. Or you could take it via the DRM tree, especially if you already have the code using the string. Also I could take it via the printk tree. The only complication is that I am going to be away the following two weeks and would come back in the middle of the merge window. I do not expect much problems with this change but... Best Regards, Petr
Re: [PATCH] ASoC: fsl_xcvr: Improve suspend/resume flow in fsl_xcvr_trigger()
On Fri, Jun 28, 2024 at 5:44 PM Chancel Liu wrote: > > In the current flow all interrupts are disabled in runtime suspend > phase. However interrupts enablement only exists in fsl_xcvr_prepare(). > After resume fsl_xcvr_prepare() may not be called so it will cause all > interrupts still disabled even if resume from suspend. Interrupts > should be explictily enabled after resume. > > Also, DPATH reset setting only exists in fsl_xcvr_prepare(). After > resume from suspend DPATH should be reset otherwise there'll be channel > swap issue. > > Signed-off-by: Chancel Liu Acked-by: Shengjiu Wang Best regards Shengjiu Wang > --- > sound/soc/fsl/fsl_xcvr.c | 43 +--- > 1 file changed, 23 insertions(+), 20 deletions(-) > > diff --git a/sound/soc/fsl/fsl_xcvr.c b/sound/soc/fsl/fsl_xcvr.c > index 337da46a2f90..bf9a4e90978e 100644 > --- a/sound/soc/fsl/fsl_xcvr.c > +++ b/sound/soc/fsl/fsl_xcvr.c > @@ -529,16 +529,6 @@ static int fsl_xcvr_prepare(struct snd_pcm_substream > *substream, > break; > } > > - ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_IER0, > -FSL_XCVR_IRQ_EARC_ALL, > FSL_XCVR_IRQ_EARC_ALL); > - if (ret < 0) { > - dev_err(dai->dev, "Error while setting IER0: %d\n", ret); > - return ret; > - } > - > - /* set DPATH RESET */ > - m_ctl |= FSL_XCVR_EXT_CTRL_DPTH_RESET(tx); > - v_ctl |= FSL_XCVR_EXT_CTRL_DPTH_RESET(tx); > ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_CTRL, m_ctl, > v_ctl); > if (ret < 0) { > dev_err(dai->dev, "Error while setting EXT_CTRL: %d\n", ret); > @@ -679,6 +669,15 @@ static int fsl_xcvr_trigger(struct snd_pcm_substream > *substream, int cmd, > case SNDRV_PCM_TRIGGER_START: > case SNDRV_PCM_TRIGGER_RESUME: > case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: > + /* set DPATH RESET */ > + ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_CTRL, > +FSL_XCVR_EXT_CTRL_DPTH_RESET(tx), > +FSL_XCVR_EXT_CTRL_DPTH_RESET(tx)); > + if (ret < 0) { > + dev_err(dai->dev, "Failed to set DPATH RESET: %d\n", > ret); > + return ret; > + } > + > if (tx) { > switch (xcvr->mode) { > case FSL_XCVR_MODE_EARC: > @@ -711,6 +710,13 @@ static int fsl_xcvr_trigger(struct snd_pcm_substream > *substream, int cmd, > return ret; > } > > + ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_IER0, > +FSL_XCVR_IRQ_EARC_ALL, > FSL_XCVR_IRQ_EARC_ALL); > + if (ret < 0) { > + dev_err(dai->dev, "Error while setting IER0: %d\n", > ret); > + return ret; > + } > + > /* clear DPATH RESET */ > ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_CTRL, > FSL_XCVR_EXT_CTRL_DPTH_RESET(tx), > @@ -733,6 +739,13 @@ static int fsl_xcvr_trigger(struct snd_pcm_substream > *substream, int cmd, > return ret; > } > > + ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_IER0, > +FSL_XCVR_IRQ_EARC_ALL, 0); > + if (ret < 0) { > + dev_err(dai->dev, "Failed to clear IER0: %d\n", ret); > + return ret; > + } > + > if (tx) { > switch (xcvr->mode) { > case FSL_XCVR_MODE_SPDIF: > @@ -1411,16 +1424,6 @@ static int fsl_xcvr_runtime_suspend(struct device *dev) > struct fsl_xcvr *xcvr = dev_get_drvdata(dev); > int ret; > > - /* > -* Clear interrupts, when streams starts or resumes after > -* suspend, interrupts are enabled in prepare(), so no need > -* to enable interrupts in resume(). > -*/ > - ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_IER0, > -FSL_XCVR_IRQ_EARC_ALL, 0); > - if (ret < 0) > - dev_err(dev, "Failed to clear IER0: %d\n", ret); > - > if (!xcvr->soc_data->spdif_only) { > /* Assert M0+ reset */ > ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_CTRL, > -- > 2.43.0 >
Re: [PowerPC] [PASEMI] Issue with the identification of ATA drives after the of/irq updates 2024-05-29
On 3. Jul 2024, at 08:40, Marc Zyngier wrote: This isn't a DTS. This is a listing of all the nodes, not something I can use to feed the kernel. I explained how to generate it. Download the compiled device tree for the Nemo board: http://www.xenosoft.de/fdt-nemo-board.zip No, thank you. You know already the device tree: https://lists.ozlabs.org/pipermail/linuxppc-dev/2021-November/236587.html
[PATCH 17/20] ASoC: arizona: convert to of_property_for_each_u32_new()
Simplify code using of_property_for_each_u32_new() as the two additional parameters in of_property_for_each_u32() are not used here. Signed-off-by: Luca Ceresoli --- sound/soc/codecs/arizona.c | 12 +--- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index 7434aeeda292..1a64b9815809 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c @@ -2786,15 +2786,13 @@ int arizona_of_get_audio_pdata(struct arizona *arizona) { struct arizona_pdata *pdata = &arizona->pdata; struct device_node *np = arizona->dev->of_node; - struct property *prop; - const __be32 *cur; u32 val; u32 pdm_val[ARIZONA_MAX_PDM_SPK]; int ret; int count = 0; count = 0; - of_property_for_each_u32(np, "wlf,inmode", prop, cur, val) { + of_property_for_each_u32_new(np, "wlf,inmode", val) { if (count == ARRAY_SIZE(pdata->inmode)) break; @@ -2803,7 +2801,7 @@ int arizona_of_get_audio_pdata(struct arizona *arizona) } count = 0; - of_property_for_each_u32(np, "wlf,dmic-ref", prop, cur, val) { + of_property_for_each_u32_new(np, "wlf,dmic-ref", val) { if (count == ARRAY_SIZE(pdata->dmic_ref)) break; @@ -2812,7 +2810,7 @@ int arizona_of_get_audio_pdata(struct arizona *arizona) } count = 0; - of_property_for_each_u32(np, "wlf,out-mono", prop, cur, val) { + of_property_for_each_u32_new(np, "wlf,out-mono", val) { if (count == ARRAY_SIZE(pdata->out_mono)) break; @@ -2821,7 +2819,7 @@ int arizona_of_get_audio_pdata(struct arizona *arizona) } count = 0; - of_property_for_each_u32(np, "wlf,max-channels-clocked", prop, cur, val) { + of_property_for_each_u32_new(np, "wlf,max-channels-clocked", val) { if (count == ARRAY_SIZE(pdata->max_channels_clocked)) break; @@ -2830,7 +2828,7 @@ int arizona_of_get_audio_pdata(struct arizona *arizona) } count = 0; - of_property_for_each_u32(np, "wlf,out-volume-limit", prop, cur, val) { + of_property_for_each_u32_new(np, "wlf,out-volume-limit", val) { if (count == ARRAY_SIZE(pdata->out_vol_limit)) break; -- 2.34.1
[PATCH 16/20] mfd: ti_am335x_tscadc: convert to of_property_for_each_u32_new()
Simplify code using of_property_for_each_u32_new() as the two additional parameters in of_property_for_each_u32() are not used here. Signed-off-by: Luca Ceresoli --- drivers/mfd/ti_am335x_tscadc.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/mfd/ti_am335x_tscadc.c b/drivers/mfd/ti_am335x_tscadc.c index 4bbd542d753e..a2e6112f885f 100644 --- a/drivers/mfd/ti_am335x_tscadc.c +++ b/drivers/mfd/ti_am335x_tscadc.c @@ -119,8 +119,6 @@ static int ti_tscadc_probe(struct platform_device *pdev) struct clk *clk; struct device_node *node; struct mfd_cell *cell; - struct property *prop; - const __be32 *cur; bool use_tsc = false, use_mag = false; u32 val; int err; @@ -167,7 +165,7 @@ static int ti_tscadc_probe(struct platform_device *pdev) } node = of_get_child_by_name(pdev->dev.of_node, "adc"); - of_property_for_each_u32(node, "ti,adc-channels", prop, cur, val) { + of_property_for_each_u32_new(node, "ti,adc-channels", val) { adc_channels++; if (val > 7) { dev_err(&pdev->dev, " PIN numbers are 0..7 (not %d)\n", -- 2.34.1
[PATCH 18/20] powerpc/xive: convert to of_property_for_each_u32_new()
Simplify code using of_property_for_each_u32_new() as the two additional parameters in of_property_for_each_u32() are not used here. Signed-off-by: Luca Ceresoli --- arch/powerpc/sysdev/xive/native.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/arch/powerpc/sysdev/xive/native.c b/arch/powerpc/sysdev/xive/native.c index 517b963e3e6a..de31a1588303 100644 --- a/arch/powerpc/sysdev/xive/native.c +++ b/arch/powerpc/sysdev/xive/native.c @@ -559,9 +559,7 @@ bool __init xive_native_init(void) struct device_node *np; struct resource r; void __iomem *tima; - struct property *prop; u8 max_prio = 7; - const __be32 *p; u32 val, cpu; s64 rc; @@ -592,7 +590,7 @@ bool __init xive_native_init(void) max_prio = val - 1; /* Iterate the EQ sizes and pick one */ - of_property_for_each_u32(np, "ibm,xive-eq-sizes", prop, p, val) { + of_property_for_each_u32_new(np, "ibm,xive-eq-sizes", val) { xive_queue_shift = val; if (val == PAGE_SHIFT) break; -- 2.34.1
[PATCH 19/20] powerpc/xive: convert to of_property_for_each_u32_new()
Simplify code using of_property_for_each_u32_new() as the two additional parameters in of_property_for_each_u32() are not used here. In this case only the 'prop' variable can be removed and not 'reg', because 'reg' is used in _previous_ lines of the same function. There is no side effect because the of_property_for_each_u32() macro being removed would anyway write 'reg' bwfore reading its value, and 'reg' is not used in _following_ lines. Signed-off-by: Luca Ceresoli --- arch/powerpc/sysdev/xive/spapr.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/powerpc/sysdev/xive/spapr.c b/arch/powerpc/sysdev/xive/spapr.c index e45419264391..ffa6ca5db183 100644 --- a/arch/powerpc/sysdev/xive/spapr.c +++ b/arch/powerpc/sysdev/xive/spapr.c @@ -814,7 +814,6 @@ bool __init xive_spapr_init(void) struct device_node *np; struct resource r; void __iomem *tima; - struct property *prop; u8 max_prio; u32 val; u32 len; @@ -866,7 +865,7 @@ bool __init xive_spapr_init(void) } /* Iterate the EQ sizes and pick one */ - of_property_for_each_u32(np, "ibm,xive-eq-sizes", prop, reg, val) { + of_property_for_each_u32_new(np, "ibm,xive-eq-sizes", val) { xive_queue_shift = val; if (val == PAGE_SHIFT) break; -- 2.34.1
[PATCH 20/20] of: deprecate and rename of_property_for_each_u32()
of_property_for_each_u32() is meant to disappear. All the call sites not using the 3rd and 4th arguments have already been replaced by of_property_for_each_u32_new(). Deprecate the old macro. Also rename it to minimize the number of new usages and encourage conversion to the of_property_for_each_u32_new() macro in not(-yet)-upstream code. Signed-off-by: Luca Ceresoli --- Notes: * The following files have not been build-tested simply because I haven't managed to have a config that enables them so far: drivers/irqchip/irq-pic32-evic.c drivers/pinctrl/pinctrl-k210.c * These have not been converted yet as they are not trivial, and they will need to use a more specific function that does the lookup they need and returns the result: drivers/clk/clk-si5351.c drivers/clk/clk.c --- .clang-format| 2 +- drivers/clk/clk-si5351.c | 4 ++-- drivers/clk/clk.c| 2 +- drivers/irqchip/irq-pic32-evic.c | 2 +- drivers/pinctrl/pinctrl-k210.c | 2 +- include/linux/of.h | 3 ++- 6 files changed, 8 insertions(+), 7 deletions(-) diff --git a/.clang-format b/.clang-format index db25cde2651a..a91b9bb39d9b 100644 --- a/.clang-format +++ b/.clang-format @@ -569,8 +569,8 @@ ForEachMacros: - 'nr_node_for_each_safe' - 'of_for_each_phandle' - 'of_property_for_each_string' - - 'of_property_for_each_u32' - 'of_property_for_each_u32_new' + - 'of_property_for_each_u32_old' - 'pci_bus_for_each_resource' - 'pci_dev_for_each_resource' - 'pcl_for_each_chunk' diff --git a/drivers/clk/clk-si5351.c b/drivers/clk/clk-si5351.c index 4ce83c5265b8..ff990b15d616 100644 --- a/drivers/clk/clk-si5351.c +++ b/drivers/clk/clk-si5351.c @@ -1191,7 +1191,7 @@ static int si5351_dt_parse(struct i2c_client *client, * property silabs,pll-source : , [<..>] * allow to selectively set pll source */ - of_property_for_each_u32(np, "silabs,pll-source", prop, p, num) { + of_property_for_each_u32_old(np, "silabs,pll-source", prop, p, num) { if (num >= 2) { dev_err(&client->dev, "invalid pll %d on pll-source prop\n", num); @@ -1232,7 +1232,7 @@ static int si5351_dt_parse(struct i2c_client *client, pdata->pll_reset[0] = true; pdata->pll_reset[1] = true; - of_property_for_each_u32(np, "silabs,pll-reset-mode", prop, p, num) { + of_property_for_each_u32_old(np, "silabs,pll-reset-mode", prop, p, num) { if (num >= 2) { dev_err(&client->dev, "invalid pll %d on pll-reset-mode prop\n", num); diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 8ea168c00997..aae940c18459 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -5383,7 +5383,7 @@ const char *of_clk_get_parent_name(const struct device_node *np, int index) /* if there is an indices property, use it to transfer the index * specified into an array offset for the clock-output-names property. */ - of_property_for_each_u32(clkspec.np, "clock-indices", prop, vp, pv) { + of_property_for_each_u32_old(clkspec.np, "clock-indices", prop, vp, pv) { if (index == pv) { index = count; break; diff --git a/drivers/irqchip/irq-pic32-evic.c b/drivers/irqchip/irq-pic32-evic.c index 1d9bb28d13e5..d9aec87f8b59 100644 --- a/drivers/irqchip/irq-pic32-evic.c +++ b/drivers/irqchip/irq-pic32-evic.c @@ -196,7 +196,7 @@ static void __init pic32_ext_irq_of_init(struct irq_domain *domain) int i = 0; const char *pname = "microchip,external-irqs"; - of_property_for_each_u32(node, pname, prop, p, hwirq) { + of_property_for_each_u32_old(node, pname, prop, p, hwirq) { if (i >= ARRAY_SIZE(priv->ext_irqs)) { pr_warn("More than %d external irq, skip rest\n", ARRAY_SIZE(priv->ext_irqs)); diff --git a/drivers/pinctrl/pinctrl-k210.c b/drivers/pinctrl/pinctrl-k210.c index b6d1ed9ec9a3..03acca8b01ef 100644 --- a/drivers/pinctrl/pinctrl-k210.c +++ b/drivers/pinctrl/pinctrl-k210.c @@ -797,7 +797,7 @@ static int k210_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev, if (ret < 0) goto exit; - of_property_for_each_u32(np, "pinmux", prop, p, pinmux_group) { + of_property_for_each_u32_old(np, "pinmux", prop, p, pinmux_group) { const char *group_name, *func_name; u32 pin = FIELD_GET(K210_PG_PIN, pinmux_group); u32 func = FIELD_GET(K210_PG_FUNC, pinmux_group); diff --git a/include/linux/of.h b/include/linux/of.h index 756847539384..15c291ab6e71 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -1429,7 +1429,8 @@ static inline int of_property_read_s32(const struct device_node *np, err == 0;
Re: [PowerPC] [PASEMI] Issue with the identification of ATA drives after the of/irq updates 2024-05-29
On Wed, 03 Jul 2024 11:26:17 +0100, Christian Zigotzky wrote: > > On 3. Jul 2024, at 08:40, Marc Zyngier wrote: > > This isn't a DTS. This is a listing of all the nodes, not something I > can use to feed the kernel. I explained how to generate it. > > Download the compiled device tree for the Nemo board: > http://www.xenosoft.de/fdt-nemo-board.zip > > No, thank you. > > > > You know already the device tree: > https://lists.ozlabs.org/pipermail/linuxppc-dev/2021-November/236587.html Do you think I keep this sort of things from almost three years ago? I have better things to do. Now, either you provide the required information in the required form or you don't. Either you test the proposed patches or you don't. If you do, great, and I'll do my best to help you. If you don't, also great, because I can go back to the stuff I'm actually interested in (i.e. not your machine). This is your call, and only yours. M. -- Without deviation from the norm, progress is not possible.
[PATCH 01/20] of: add of_property_for_each_u32_new()
The of_property_for_each_u32() macro needs five parameters, two of which are often only used internally by the macro itself (in the for() clause). Now that the kernel uses C11 to build these two parameters can be avoided by declaring them internally. Add a new macro for that, which is meant to eventually replace the existing one. Since two variables cannot be declared in the for clause, declare one struct that contain the two variables we actually need. Since the variables inside this struct are not meant to be used by users of this macro, give the struct instance the noticeable name "_it" so it is visible during code reviews, helping to avoid new code to use it directly. Signed-off-by: Luca Ceresoli --- .clang-format | 1 + include/linux/of.h | 11 --- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/.clang-format b/.clang-format index ccc9b93972a9..db25cde2651a 100644 --- a/.clang-format +++ b/.clang-format @@ -570,6 +570,7 @@ ForEachMacros: - 'of_for_each_phandle' - 'of_property_for_each_string' - 'of_property_for_each_u32' + - 'of_property_for_each_u32_new' - 'pci_bus_for_each_resource' - 'pci_dev_for_each_resource' - 'pcl_for_each_chunk' diff --git a/include/linux/of.h b/include/linux/of.h index a0bedd038a05..756847539384 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -430,11 +430,9 @@ extern int of_detach_node(struct device_node *); #define of_match_ptr(_ptr) (_ptr) /* - * struct property *prop; - * const __be32 *p; * u32 u; * - * of_property_for_each_u32(np, "propname", prop, p, u) + * of_property_for_each_u32_new(np, "propname", u) * printk("U32 value: %x\n", u); */ const __be32 *of_prop_next_u32(struct property *prop, const __be32 *cur, @@ -1437,6 +1435,13 @@ static inline int of_property_read_s32(const struct device_node *np, p; \ p = of_prop_next_u32(prop, p, &u)) +#define of_property_for_each_u32_new(np, propname, u) \ + for (struct {struct property *prop; const __be32 *item; } _it = \ + {of_find_property(np, propname, NULL), \ +of_prop_next_u32(_it.prop, NULL, &u)}; \ +_it.item; \ +_it.item = of_prop_next_u32(_it.prop, _it.item, &u)) + #define of_property_for_each_string(np, propname, prop, s) \ for (prop = of_find_property(np, propname, NULL), \ s = of_prop_next_string(prop, NULL);\ -- 2.34.1
[PATCH 02/20] clk: convert to of_property_for_each_u32_new()
Simplify code using of_property_for_each_u32_new() as the two additional parameters in of_property_for_each_u32() are not used here. Signed-off-by: Luca Ceresoli --- drivers/clk/clk.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 8cca52be993f..8ea168c00997 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -5504,14 +5504,12 @@ static int parent_ready(struct device_node *np) int of_clk_detect_critical(struct device_node *np, int index, unsigned long *flags) { - struct property *prop; - const __be32 *cur; uint32_t idx; if (!np || !flags) return -EINVAL; - of_property_for_each_u32(np, "clock-critical", prop, cur, idx) + of_property_for_each_u32_new(np, "clock-critical", idx) if (index == idx) *flags |= CLK_IS_CRITICAL; -- 2.34.1
[PATCH 03/20] clk: qcom: convert to of_property_for_each_u32_new()
Simplify code using of_property_for_each_u32_new() as the two additional parameters in of_property_for_each_u32() are not used here. Signed-off-by: Luca Ceresoli --- drivers/clk/qcom/common.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/clk/qcom/common.c b/drivers/clk/qcom/common.c index 48f81e3a5e80..43e4918dc4e9 100644 --- a/drivers/clk/qcom/common.c +++ b/drivers/clk/qcom/common.c @@ -226,11 +226,9 @@ EXPORT_SYMBOL_GPL(qcom_cc_register_sleep_clk); static void qcom_cc_drop_protected(struct device *dev, struct qcom_cc *cc) { struct device_node *np = dev->of_node; - struct property *prop; - const __be32 *p; u32 i; - of_property_for_each_u32(np, "protected-clocks", prop, p, i) { + of_property_for_each_u32_new(np, "protected-clocks", i) { if (i >= cc->num_rclks) continue; -- 2.34.1
[PATCH 00/20] Simplify of_property_for_each_u32()
[Note: to reduce the noise I have trimmed the get_maintainers list manually. Should you want to be removed, or someone else added, to future versions, just tell me. Sorry for the noise.] This series aims at simplifying of_property_for_each_u32() as well as making it more difficult to misuse it in the future. The long-term goal is changing this pattern: struct property *prop; const __be32 *p; u32 val; of_property_for_each_u32(np, "xyz", prop, p, val) { ... } to this: u32 val; of_property_for_each_u32(np, "xyz", val) { ... } So, removing the 3rd and 4th arguments which are typically meant to be internal. Those two parameters used to be unavoidable until the kernel moved to building with the C11 standard unconditionally. Since then, it is now possible to get rid of them. However a few users of of_property_for_each_u32() do actually use those arguments, which complicates the transition. For this reason this series does the following: * Add of_property_for_each_u32_new(), which does not have those two arguments (patch 1) * Convert _almost_ every usage to of_property_for_each_u32_new() * Rename of_property_for_each_u32() to of_property_for_each_u32_old() and deprecate it, as a incentive to code not (yet) in mainline to upgrade to the *_new() version (last patch) The plan for the next series is to additionally: * Convert the few remaining of_property_for_each_u32_old() instantes to of_property_for_each_u32_new() * Remove of_property_for_each_u32_old() * Rename of_property_for_each_u32_new() to of_property_for_each_u32() Signed-off-by: Luca Ceresoli --- Luca Ceresoli (20): of: add of_property_for_each_u32_new() clk: convert to of_property_for_each_u32_new() clk: qcom: convert to of_property_for_each_u32_new() clk: sunxi: clk-simple-gates: convert to of_property_for_each_u32_new() clk: sunxi: clk-sun8i-bus-gates: convert to of_property_for_each_u32_new() clocksource/drivers/samsung_pwm: convert to of_property_for_each_u32_new() bus: ti-sysc: convert to of_property_for_each_u32_new() lk: clk-conf: convert to of_property_for_each_u32_new() gpio: brcmstb: convert to of_property_for_each_u32_new() pinctrl: s32cc: convert to of_property_for_each_u32_new() irqchip/atmel-aic: convert to of_property_for_each_u32_new() iio: adc: ti_am335x_adc: convert to of_property_for_each_u32_new() pwm: samsung: convert to of_property_for_each_u32_new() tty: sysrq: convert to of_property_for_each_u32_new() usb: usb251xb: convert to of_property_for_each_u32_new() mfd: ti_am335x_tscadc: convert to of_property_for_each_u32_new() ASoC: arizona: convert to of_property_for_each_u32_new() powerpc/xive: convert to of_property_for_each_u32_new() powerpc/xive: convert to of_property_for_each_u32_new() of: deprecate and rename of_property_for_each_u32() .clang-format | 3 ++- arch/powerpc/sysdev/xive/native.c | 4 +--- arch/powerpc/sysdev/xive/spapr.c| 3 +-- drivers/bus/ti-sysc.c | 4 +--- drivers/clk/clk-conf.c | 4 +--- drivers/clk/clk-si5351.c| 4 ++-- drivers/clk/clk.c | 6 ++ drivers/clk/qcom/common.c | 4 +--- drivers/clk/sunxi/clk-simple-gates.c| 4 +--- drivers/clk/sunxi/clk-sun8i-bus-gates.c | 4 +--- drivers/clocksource/samsung_pwm_timer.c | 4 +--- drivers/gpio/gpio-brcmstb.c | 5 + drivers/iio/adc/ti_am335x_adc.c | 4 +--- drivers/irqchip/irq-atmel-aic-common.c | 4 +--- drivers/irqchip/irq-pic32-evic.c| 2 +- drivers/mfd/ti_am335x_tscadc.c | 4 +--- drivers/pinctrl/nxp/pinctrl-s32cc.c | 4 +--- drivers/pinctrl/pinctrl-k210.c | 2 +- drivers/pwm/pwm-samsung.c | 4 +--- drivers/tty/sysrq.c | 4 +--- drivers/usb/misc/usb251xb.c | 4 +--- include/linux/of.h | 14 ++ sound/soc/codecs/arizona.c | 12 +--- 23 files changed, 39 insertions(+), 68 deletions(-) --- base-commit: e937d48ed96381e9620d9c81fbc1ce666f5b7358 change-id: 20240701-of_property_for_each_u32-460fd02a5d0c Best regards, -- Luca Ceresoli
[PATCH 04/20] clk: sunxi: clk-simple-gates: convert to of_property_for_each_u32_new()
Simplify code using of_property_for_each_u32_new() as the two additional parameters in of_property_for_each_u32() are not used here. Signed-off-by: Luca Ceresoli --- drivers/clk/sunxi/clk-simple-gates.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/clk/sunxi/clk-simple-gates.c b/drivers/clk/sunxi/clk-simple-gates.c index 0399627c226a..a30d14937e0b 100644 --- a/drivers/clk/sunxi/clk-simple-gates.c +++ b/drivers/clk/sunxi/clk-simple-gates.c @@ -21,11 +21,9 @@ static void __init sunxi_simple_gates_setup(struct device_node *node, { struct clk_onecell_data *clk_data; const char *clk_parent, *clk_name; - struct property *prop; struct resource res; void __iomem *clk_reg; void __iomem *reg; - const __be32 *p; int number, i = 0, j; u8 clk_bit; u32 index; @@ -47,7 +45,7 @@ static void __init sunxi_simple_gates_setup(struct device_node *node, if (!clk_data->clks) goto err_free_data; - of_property_for_each_u32(node, "clock-indices", prop, p, index) { + of_property_for_each_u32_new(node, "clock-indices", index) { of_property_read_string_index(node, "clock-output-names", i, &clk_name); -- 2.34.1
[PATCH 05/20] clk: sunxi: clk-sun8i-bus-gates: convert to of_property_for_each_u32_new()
Simplify code using of_property_for_each_u32_new() as the two additional parameters in of_property_for_each_u32() are not used here. Signed-off-by: Luca Ceresoli --- drivers/clk/sunxi/clk-sun8i-bus-gates.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/clk/sunxi/clk-sun8i-bus-gates.c b/drivers/clk/sunxi/clk-sun8i-bus-gates.c index b87f331f63c9..21f036457a86 100644 --- a/drivers/clk/sunxi/clk-sun8i-bus-gates.c +++ b/drivers/clk/sunxi/clk-sun8i-bus-gates.c @@ -24,11 +24,9 @@ static void __init sun8i_h3_bus_gates_init(struct device_node *node) const char *parents[PARENT_MAX]; struct clk_onecell_data *clk_data; const char *clk_name; - struct property *prop; struct resource res; void __iomem *clk_reg; void __iomem *reg; - const __be32 *p; int number, i; u8 clk_bit; int index; @@ -58,7 +56,7 @@ static void __init sun8i_h3_bus_gates_init(struct device_node *node) goto err_free_data; i = 0; - of_property_for_each_u32(node, "clock-indices", prop, p, index) { + of_property_for_each_u32_new(node, "clock-indices", index) { of_property_read_string_index(node, "clock-output-names", i, &clk_name); -- 2.34.1
[PATCH 06/20] clocksource/drivers/samsung_pwm: convert to of_property_for_each_u32_new()
Simplify code using of_property_for_each_u32_new() as the two additional parameters in of_property_for_each_u32() are not used here. Signed-off-by: Luca Ceresoli --- drivers/clocksource/samsung_pwm_timer.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/clocksource/samsung_pwm_timer.c b/drivers/clocksource/samsung_pwm_timer.c index 6e46781bc9ac..b5ae411bc077 100644 --- a/drivers/clocksource/samsung_pwm_timer.c +++ b/drivers/clocksource/samsung_pwm_timer.c @@ -418,8 +418,6 @@ void __init samsung_pwm_clocksource_init(void __iomem *base, static int __init samsung_pwm_alloc(struct device_node *np, const struct samsung_pwm_variant *variant) { - struct property *prop; - const __be32 *cur; u32 val; int i, ret; @@ -427,7 +425,7 @@ static int __init samsung_pwm_alloc(struct device_node *np, for (i = 0; i < SAMSUNG_PWM_NUM; ++i) pwm.irq[i] = irq_of_parse_and_map(np, i); - of_property_for_each_u32(np, "samsung,pwm-outputs", prop, cur, val) { + of_property_for_each_u32_new(np, "samsung,pwm-outputs", val) { if (val >= SAMSUNG_PWM_NUM) { pr_warn("%s: invalid channel index in samsung,pwm-outputs property\n", __func__); continue; -- 2.34.1
[PATCH 07/20] bus: ti-sysc: convert to of_property_for_each_u32_new()
Simplify code using of_property_for_each_u32_new() as the two additional parameters in of_property_for_each_u32() are not used here. Signed-off-by: Luca Ceresoli --- drivers/bus/ti-sysc.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c index 8767e04d6c89..3d19777f1e31 100644 --- a/drivers/bus/ti-sysc.c +++ b/drivers/bus/ti-sysc.c @@ -2291,11 +2291,9 @@ static int sysc_init_idlemode(struct sysc *ddata, u8 *idlemodes, const char *name) { struct device_node *np = ddata->dev->of_node; - struct property *prop; - const __be32 *p; u32 val; - of_property_for_each_u32(np, name, prop, p, val) { + of_property_for_each_u32_new(np, name, val) { if (val >= SYSC_NR_IDLEMODES) { dev_err(ddata->dev, "invalid idlemode: %i\n", val); return -EINVAL; -- 2.34.1
[PATCH 08/20] lk: clk-conf: convert to of_property_for_each_u32_new()
Simplify code using of_property_for_each_u32_new() as the two additional parameters in of_property_for_each_u32() are not used here. Signed-off-by: Luca Ceresoli --- drivers/clk/clk-conf.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/clk/clk-conf.c b/drivers/clk/clk-conf.c index 1a4e6340f95c..290dd1230bad 100644 --- a/drivers/clk/clk-conf.c +++ b/drivers/clk/clk-conf.c @@ -81,13 +81,11 @@ static int __set_clk_parents(struct device_node *node, bool clk_supplier) static int __set_clk_rates(struct device_node *node, bool clk_supplier) { struct of_phandle_args clkspec; - struct property *prop; - const __be32 *cur; int rc, index = 0; struct clk *clk; u32 rate; - of_property_for_each_u32(node, "assigned-clock-rates", prop, cur, rate) { + of_property_for_each_u32_new(node, "assigned-clock-rates", rate) { if (rate) { rc = of_parse_phandle_with_args(node, "assigned-clocks", "#clock-cells", index, &clkspec); -- 2.34.1
[PATCH 09/20] gpio: brcmstb: convert to of_property_for_each_u32_new()
Simplify code using of_property_for_each_u32_new() as the two additional parameters in of_property_for_each_u32() are not used here. Signed-off-by: Luca Ceresoli --- drivers/gpio/gpio-brcmstb.c | 5 + 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/gpio/gpio-brcmstb.c b/drivers/gpio/gpio-brcmstb.c index 8dce78ea7139..77557bc596cd 100644 --- a/drivers/gpio/gpio-brcmstb.c +++ b/drivers/gpio/gpio-brcmstb.c @@ -591,8 +591,6 @@ static int brcmstb_gpio_probe(struct platform_device *pdev) void __iomem *reg_base; struct brcmstb_gpio_priv *priv; struct resource *res; - struct property *prop; - const __be32 *p; u32 bank_width; int num_banks = 0; int num_gpios = 0; @@ -636,8 +634,7 @@ static int brcmstb_gpio_probe(struct platform_device *pdev) flags = BGPIOF_BIG_ENDIAN_BYTE_ORDER; #endif - of_property_for_each_u32(np, "brcm,gpio-bank-widths", prop, p, - bank_width) { + of_property_for_each_u32_new(np, "brcm,gpio-bank-widths", bank_width) { struct brcmstb_gpio_bank *bank; struct gpio_chip *gc; -- 2.34.1
[PATCH 10/20] pinctrl: s32cc: convert to of_property_for_each_u32_new()
Simplify code using of_property_for_each_u32_new() as the two additional parameters in of_property_for_each_u32() are not used here. Signed-off-by: Luca Ceresoli --- drivers/pinctrl/nxp/pinctrl-s32cc.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/pinctrl/nxp/pinctrl-s32cc.c b/drivers/pinctrl/nxp/pinctrl-s32cc.c index f0cad2c501f7..6aeb93af77ed 100644 --- a/drivers/pinctrl/nxp/pinctrl-s32cc.c +++ b/drivers/pinctrl/nxp/pinctrl-s32cc.c @@ -735,9 +735,7 @@ static int s32_pinctrl_parse_groups(struct device_node *np, struct s32_pin_group *grp, struct s32_pinctrl_soc_info *info) { - const __be32 *p; struct device *dev; - struct property *prop; unsigned int *pins, *sss; int i, npins; u32 pinmux; @@ -768,7 +766,7 @@ static int s32_pinctrl_parse_groups(struct device_node *np, return -ENOMEM; i = 0; - of_property_for_each_u32(np, "pinmux", prop, p, pinmux) { + of_property_for_each_u32_new(np, "pinmux", pinmux) { pins[i] = get_pin_no(pinmux); sss[i] = get_pin_func(pinmux); -- 2.34.1
[PATCH 11/20] irqchip/atmel-aic: convert to of_property_for_each_u32_new()
Simplify code using of_property_for_each_u32_new() as the two additional parameters in of_property_for_each_u32() are not used here. Signed-off-by: Luca Ceresoli --- drivers/irqchip/irq-atmel-aic-common.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/irqchip/irq-atmel-aic-common.c b/drivers/irqchip/irq-atmel-aic-common.c index 072bd227b6c6..543ea249df53 100644 --- a/drivers/irqchip/irq-atmel-aic-common.c +++ b/drivers/irqchip/irq-atmel-aic-common.c @@ -111,8 +111,6 @@ static void __init aic_common_ext_irq_of_init(struct irq_domain *domain) struct device_node *node = irq_domain_get_of_node(domain); struct irq_chip_generic *gc; struct aic_chip_data *aic; - struct property *prop; - const __be32 *p; u32 hwirq; gc = irq_get_domain_generic_chip(domain, 0); @@ -120,7 +118,7 @@ static void __init aic_common_ext_irq_of_init(struct irq_domain *domain) aic = gc->private; aic->ext_irqs |= 1; - of_property_for_each_u32(node, "atmel,external-irqs", prop, p, hwirq) { + of_property_for_each_u32_new(node, "atmel,external-irqs", hwirq) { gc = irq_get_domain_generic_chip(domain, hwirq); if (!gc) { pr_warn("AIC: external irq %d >= %d skip it\n", -- 2.34.1
[PATCH 12/20] iio: adc: ti_am335x_adc: convert to of_property_for_each_u32_new()
Simplify code using of_property_for_each_u32_new() as the two additional parameters in of_property_for_each_u32() are not used here. Signed-off-by: Luca Ceresoli --- drivers/iio/adc/ti_am335x_adc.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c index 95fa857e8aad..ca0f542ebc77 100644 --- a/drivers/iio/adc/ti_am335x_adc.c +++ b/drivers/iio/adc/ti_am335x_adc.c @@ -564,13 +564,11 @@ static int tiadc_parse_dt(struct platform_device *pdev, struct tiadc_device *adc_dev) { struct device_node *node = pdev->dev.of_node; - struct property *prop; - const __be32 *cur; int channels = 0; u32 val; int i; - of_property_for_each_u32(node, "ti,adc-channels", prop, cur, val) { + of_property_for_each_u32_new(node, "ti,adc-channels", val) { adc_dev->channel_line[channels] = val; /* Set Default values for optional DT parameters */ -- 2.34.1
[PATCH 14/20] tty: sysrq: convert to of_property_for_each_u32_new()
Simplify code using of_property_for_each_u32_new() as the two additional parameters in of_property_for_each_u32() are not used here. Signed-off-by: Luca Ceresoli --- drivers/tty/sysrq.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c index e5974b8239c9..719376dda5c1 100644 --- a/drivers/tty/sysrq.c +++ b/drivers/tty/sysrq.c @@ -770,8 +770,6 @@ static void sysrq_of_get_keyreset_config(void) { u32 key; struct device_node *np; - struct property *prop; - const __be32 *p; np = of_find_node_by_path("/chosen/linux,sysrq-reset-seq"); if (!np) { @@ -782,7 +780,7 @@ static void sysrq_of_get_keyreset_config(void) /* Reset in case a __weak definition was present */ sysrq_reset_seq_len = 0; - of_property_for_each_u32(np, "keyset", prop, p, key) { + of_property_for_each_u32_new(np, "keyset", key) { if (key == KEY_RESERVED || key > KEY_MAX || sysrq_reset_seq_len == SYSRQ_KEY_RESET_MAX) break; -- 2.34.1
[PATCH 13/20] pwm: samsung: convert to of_property_for_each_u32_new()
Simplify code using of_property_for_each_u32_new() as the two additional parameters in of_property_for_each_u32() are not used here. Signed-off-by: Luca Ceresoli --- drivers/pwm/pwm-samsung.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/pwm/pwm-samsung.c b/drivers/pwm/pwm-samsung.c index efb60c9f0cb3..fef02a0b023e 100644 --- a/drivers/pwm/pwm-samsung.c +++ b/drivers/pwm/pwm-samsung.c @@ -510,8 +510,6 @@ static int pwm_samsung_parse_dt(struct pwm_chip *chip) struct samsung_pwm_chip *our_chip = to_samsung_pwm_chip(chip); struct device_node *np = pwmchip_parent(chip)->of_node; const struct of_device_id *match; - struct property *prop; - const __be32 *cur; u32 val; match = of_match_node(samsung_pwm_matches, np); @@ -520,7 +518,7 @@ static int pwm_samsung_parse_dt(struct pwm_chip *chip) memcpy(&our_chip->variant, match->data, sizeof(our_chip->variant)); - of_property_for_each_u32(np, "samsung,pwm-outputs", prop, cur, val) { + of_property_for_each_u32_new(np, "samsung,pwm-outputs", val) { if (val >= SAMSUNG_PWM_NUM) { dev_err(pwmchip_parent(chip), "%s: invalid channel index in samsung,pwm-outputs property\n", -- 2.34.1
[PATCH 15/20] usb: usb251xb: convert to of_property_for_each_u32_new()
Simplify code using of_property_for_each_u32_new() as the two additional parameters in of_property_for_each_u32() are not used here. Signed-off-by: Luca Ceresoli --- drivers/usb/misc/usb251xb.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/usb/misc/usb251xb.c b/drivers/usb/misc/usb251xb.c index 7da404f55a6d..490004dbb9d8 100644 --- a/drivers/usb/misc/usb251xb.c +++ b/drivers/usb/misc/usb251xb.c @@ -382,11 +382,9 @@ static void usb251xb_get_ports_field(struct usb251xb *hub, bool ds_only, u8 *fld) { struct device *dev = hub->dev; - struct property *prop; - const __be32 *p; u32 port; - of_property_for_each_u32(dev->of_node, prop_name, prop, p, port) { + of_property_for_each_u32_new(dev->of_node, prop_name, port) { if ((port >= ds_only ? 1 : 0) && (port <= port_cnt)) *fld |= BIT(port); else -- 2.34.1
Re: [RFC PATCH v3 00/11] powerpc: Add support for ftrace direct and BPF trampolines
On Fri, Jun 21, 2024 at 12:24:03AM +0530, Naveen N Rao wrote: > This is v3 of the patches posted here: > http://lkml.kernel.org/r/cover.1718008093.git.nav...@kernel.org > > Since v2, I have addressed review comments from Steven and Masahiro > along with a few fixes. Patches 7-11 are new in this series and add > support for ftrace direct and bpf trampolines. > > This series depends on the patch series from Benjamin Gray adding > support for patch_ulong(): > http://lkml.kernel.org/r/20240515024445.236364-1-bg...@linux.ibm.com > > > - Naveen Hello Naveen, I've noticed an issue with `kstack()` in bpftrace [1] when using `kfunc` compared to `kprobe`. Despite trying all three modes specified in the documentation (bpftrace, perf, or raw), the stack isn't unwinding properly with `kfunc`. [1] https://github.com/bpftrace/bpftrace/blob/master/man/adoc/bpftrace.adoc#kstack for mode in modes; do run bpftrace with kfunc disable cpu kill bpftrace run bpftrace with kprobe enable cpu kill bpftrace # ./kprobe_vs_kfunc.sh + bpftrace -e 'kfunc:vmlinux:build_sched_domains {@[kstack(bpftrace), comm, tid]=count();}' Attaching 1 probe... + chcpu -d 2-3 CPU 2 disabled CPU 3 disabled + kill 35214 @[ bpf_prog_cfd8d6c8bb4898ce+972 , cpuhp/2, 33]: 1 @[ bpf_prog_cfd8d6c8bb4898ce+972 , cpuhp/3, 38]: 1 + bpftrace -e 'kprobe:build_sched_domains {@[kstack(bpftrace), comm, tid]=count();}' Attaching 1 probe... + chcpu -e 2-3 CPU 2 enabled CPU 3 enabled + kill 35221 @[ 0x8007642bdfb4 partition_sched_domains_locked+1304 rebuild_sched_domains_locked+216 cpuset_handle_hotplug+1148 sched_cpu_activate+664 cpuhp_invoke_callback+480 cpuhp_thread_fun+244 smpboot_thread_fn+460 kthread+308 start_kernel_thread+20 , cpuhp/3, 38]: 1 @[ 0x8007524b34a4 partition_sched_domains_locked+1304 rebuild_sched_domains_locked+216 cpuset_handle_hotplug+1148 sched_cpu_activate+664 cpuhp_invoke_callback+480 cpuhp_thread_fun+244 smpboot_thread_fn+460 kthread+308 start_kernel_thread+20 , cpuhp/2, 33]: 1 + bpftrace -e 'kfunc:vmlinux:build_sched_domains {@[kstack(perf), comm, tid]=count();}' Attaching 1 probe... + chcpu -d 2-3 CPU 2 disabled CPU 3 disabled + kill 35229 @[ c00803433454 bpf_prog_cfd8d6c8bb4898ce+960 , cpuhp/3, 38]: 1 @[ c00803433454 bpf_prog_cfd8d6c8bb4898ce+960 , cpuhp/2, 33]: 1 + bpftrace -e 'kprobe:build_sched_domains {@[kstack(perf), comm, tid]=count();}' Attaching 1 probe... + chcpu -e 2-3 CPU 2 enabled CPU 3 enabled + kill 35235 @[ 8007524b379c 0x8007524b379c c0206268 partition_sched_domains_locked+1304 c02cbf08 rebuild_sched_domains_locked+216 c02cfd5c cpuset_handle_hotplug+1148 c01b3178 sched_cpu_activate+664 c0156fc0 cpuhp_invoke_callback+480 c0157974 cpuhp_thread_fun+244 c019ddec smpboot_thread_fn+460 c01932c4 kthread+308 c000dd58 start_kernel_thread+20 , cpuhp/2, 33]: 1 @[ 8007642b9b6c 0x8007642b9b6c c0206268 partition_sched_domains_locked+1304 c02cbf08 rebuild_sched_domains_locked+216 c02cfd5c cpuset_handle_hotplug+1148 c01b3178 sched_cpu_activate+664 c0156fc0 cpuhp_invoke_callback+480 c0157974 cpuhp_thread_fun+244 c019ddec smpboot_thread_fn+460 c01932c4 kthread+308 c000dd58 start_kernel_thread+20 , cpuhp/3, 38]: 1 + bpftrace -e 'kfunc:vmlinux:build_sched_domains {@[kstack(raw), comm, tid]=count();}' Attaching 1 probe... + chcpu -d 2-3 CPU 2 disabled CPU 3 disabled + kill 35243 @[ c0080343346c , cpuhp/3, 38]: 1 @[ c0080343346c , cpuhp/2, 33]: 1 + bpftrace -e 'kprobe:build_sched_domains {@[kstack(raw), comm, tid]=count();}' Attaching 1 probe... + chcpu -e 2-3 CPU 2 enabled CPU 3 enabled + kill 35249 @[ 8007642befac c0206268 c02cbf08 c02cfd5c c01b3178 c0156fc0 c0157974 c019ddec c01932c4 c000dd58 , cpuhp/3, 38]: 1 @[ 8007524b425c c0206268 c02cbf08 c02cfd5c c01b3178 c0156fc0 c0157974 c019ddec c01932c4 c000dd58 , cpuhp/2, 33]: 1 > > > Naveen N Rao (11): > powerpc/kprobes: Use ftrace to determine if a probe is at function > entry > powerpc/ftrace: Unify 32-bit and 64-bit ftrace entry code > powerpc/module_64: Convert #ifdef to IS_ENABLED() > powerpc/ftrace: Remove pointer to struct module from dyn_arch_ftrace > kbuild: Add generic hook for architectures to use before the final > vmlinux link > powerpc64/ftrace: Move ftrace sequence out of line > powerpc/ftrace: Add support for DYNAMIC_FTRACE_WITH_CALL_OPS > powerpc/ftrace: Add support for DYNAMIC_FTRACE_WI
Re: [PowerPC] [PASEMI] Issue with the identification of ATA drives after the of/irq updates 2024-05-29
Rob Herring writes: > On Tue, Jul 2, 2024 at 10:54 AM Marc Zyngier wrote: >> >> On Sun, 30 Jun 2024 11:21:55 +0100, >> Christian Zigotzky wrote: >> > >> > Hello, >> > >> > There is an issue with the identification of ATA drives with our >> > P.A. Semi Nemo boards [1] after the >> > commit "of/irq: Factor out parsing of interrupt-map parent >> > phandle+args from of_irq_parse_raw()" [2]. >> >> [snip] >> >> My earlier request for valuable debug information still stands. But >> while you're at it, can you please give the following hack a go? >> >> M. >> >> --- a/drivers/of/irq.c >> +++ b/drivers/of/irq.c >> @@ -282,8 +282,10 @@ int of_irq_parse_raw(const __be32 *addr, struct >> of_phandle_args *out_irq) >> >> oldimap = imap; >> imap = of_irq_parse_imap_parent(oldimap, imaplen, >> out_irq); >> - if (!imap) >> - goto fail; >> + if (!imap) { >> + match = 0; >> + break; >> + } > > AFAICT reading the DT, I don't think this would fix it. imap should > only be null if malformed. This case to me looks like interrupt-map > has the correct cell sizes, but just never matches to do the mapping. > So maybe imaplen is off and that causes us to end up here, but if > there's an error I don't see it. A boot with DEBUG enabled in > drivers/of/irq.c would help. > >> >> match &= of_device_is_available(out_irq->np); >> if (match) >> >> This may not be the final workaround even if it solves your boot >> problem, but will at least give us a hint at what is going wrong. >> >> I have the fuzzy feeling that we may be able to lob this broken system >> as part of the of_irq_imap_abusers[] array, which would solve things >> pretty "neatly". > > I think this would work and would consolidate the work-arounds. It > would need either "pasemi,rootbus" or "pa-pxp" added to the list. Not sure if it helps, but there's already some code in arch/powerpc to "fixup" the nemo device tree at boot. I'm not sure if it's actually the problem here, but it might be, it does renumber some interrupts. Or possibly it could be tweaked to fix whatever the issue is. The code is in fixup_device_tree_pasemi(): https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/powerpc/kernel/prom_init.c?h=v6.10-rc5#n3114 cheers
Re: [PATCH 09/20] gpio: brcmstb: convert to of_property_for_each_u32_new()
On Wed, Jul 3, 2024 at 12:38 PM Luca Ceresoli wrote: > > Simplify code using of_property_for_each_u32_new() as the two additional > parameters in of_property_for_each_u32() are not used here. > > Signed-off-by: Luca Ceresoli > --- > drivers/gpio/gpio-brcmstb.c | 5 + > 1 file changed, 1 insertion(+), 4 deletions(-) > > diff --git a/drivers/gpio/gpio-brcmstb.c b/drivers/gpio/gpio-brcmstb.c > index 8dce78ea7139..77557bc596cd 100644 > --- a/drivers/gpio/gpio-brcmstb.c > +++ b/drivers/gpio/gpio-brcmstb.c > @@ -591,8 +591,6 @@ static int brcmstb_gpio_probe(struct platform_device > *pdev) > void __iomem *reg_base; > struct brcmstb_gpio_priv *priv; > struct resource *res; > - struct property *prop; > - const __be32 *p; > u32 bank_width; > int num_banks = 0; > int num_gpios = 0; > @@ -636,8 +634,7 @@ static int brcmstb_gpio_probe(struct platform_device > *pdev) > flags = BGPIOF_BIG_ENDIAN_BYTE_ORDER; > #endif > > - of_property_for_each_u32(np, "brcm,gpio-bank-widths", prop, p, > - bank_width) { > + of_property_for_each_u32_new(np, "brcm,gpio-bank-widths", bank_width) > { > struct brcmstb_gpio_bank *bank; > struct gpio_chip *gc; > > > -- > 2.34.1 > Acked-by: Bartosz Golaszewski
Re: [PATCH 19/20] powerpc/xive: convert to of_property_for_each_u32_new()
Luca Ceresoli writes: > Simplify code using of_property_for_each_u32_new() as the two additional > parameters in of_property_for_each_u32() are not used here. > > In this case only the 'prop' variable can be removed and not 'reg', > because 'reg' is used in _previous_ lines of the same function. There > is no side effect because the of_property_for_each_u32() macro being > removed would anyway write 'reg' bwfore reading its value, and 'reg' > is not used in _following_ lines. > > Signed-off-by: Luca Ceresoli > --- > arch/powerpc/sysdev/xive/spapr.c | 3 +-- > 1 file changed, 1 insertion(+), 2 deletions(-) Acked-by: Michael Ellerman (powerpc) cheers
Re: [PATCH V5 05/17] tools/perf: Add support to capture and parse raw instruction in powerpc using dso__data_read_offset utility
> On 3 Jul 2024, at 6:54 AM, Namhyung Kim wrote: > > On Mon, Jul 01, 2024 at 10:04:18AM +0530, Athira Rajeev wrote: >> Add support to capture and parse raw instruction in powerpc. >> Currently, the perf tool infrastructure uses two ways to disassemble >> and understand the instruction. One is objdump and other option is >> via libcapstone. >> >> Currently, the perf tool infrastructure uses "--no-show-raw-insn" option >> with "objdump" while disassemble. Example from powerpc with this option >> for an instruction address is: >> >> Snippet from: >> objdump --start-address= --stop-address= -d >> --no-show-raw-insn -C >> >> c10224b4: lwz r10,0(r9) >> >> This line "lwz r10,0(r9)" is parsed to extract instruction name, >> registers names and offset. Also to find whether there is a memory >> reference in the operands, "memory_ref_char" field of objdump is used. >> For x86, "(" is used as memory_ref_char to tackle instructions of the >> form "mov (%rax), %rcx". >> >> In case of powerpc, not all instructions using "(" are the only memory >> instructions. Example, above instruction can also be of extended form (X >> form) "lwzx r10,0,r19". Inorder to easy identify the instruction category >> and extract the source/target registers, patch adds support to use raw >> instruction for powerpc. Approach used is to read the raw instruction >> directly from the DSO file using "dso__data_read_offset" utility which >> is already implemented in perf infrastructure in "util/dso.c". >> >> Example: >> >> 38 01 81 e8 ld r4,312(r1) >> >> Here "38 01 81 e8" is the raw instruction representation. In powerpc, >> this translates to instruction form: "ld RT,DS(RA)" and binary code >> as: >> >> | 58 | RT | RA | DS | | >> - >> 06 1116 30 31 >> >> Function "symbol__disassemble_dso" is updated to read raw instruction >> directly from DSO using dso__data_read_offset utility. In case of >> above example, this captures: >> line:38 01 81 e8 >> >> The above works well when perf report is invoked with only sort keys for >> data type ie type and typeoff. Because there is no instruction level >> annotation needed if only data type information is requested for. For >> annotating sample, along with type and typeoff sort key, "sym" sort key >> is also needed. And by default invoking just "perf report" uses sort key >> "sym" that displays the symbol information. >> >> With approach changes in powerpc which first reads DSO for raw >> instruction, "perf annotate" and "perf report" + a key breaks since >> it doesn't do the instruction level disassembly. >> >> Snippet of result from perf report: >> >> Samples: 1K of event 'mem-loads', 4000 Hz, Event count (approx.): 937238 >> do_work /usr/bin/pmlogger [Percent: local period] >> Percent│ea230010 >> │3a550010 >> │3a60 >> >> │38f60001 >> │39490008 >> │42400438 >> 51.44 │81290008 >> │7d485378 >> >> Here, raw instruction is displayed in the output instead of human >> readable annotated form. >> >> One way to get the appropriate data is to specify "--objdump path", by >> which code annotation will be done. But the default behaviour will be >> changed. To fix this breakage, check if "sym" sort key is set. If so >> fallback and use the libcapstone/objdump way of disassmbling the sample. >> >> With the changes and "perf report" >> >> Samples: 1K of event 'mem-loads', 4000 Hz, Event count (approx.): 937238 >> do_work /usr/bin/pmlogger [Percent: local period] >> Percent│ldr17,16(r3) >> │addi r18,r21,16 >> │lir19,0 >> >> │ 8b0: rldiclr10,r10,63,33 >> │addi r10,r10,1 >> │mtctr r10 >> │ ↓ b 8e4 >> │ 8c0: addi r7,r22,1 >> │addi r10,r9,8 >> │ ↓ bdz d00 >> 51.44 │lwz r9,8(r9) >> │mrr8,r10 >> │cmpw r20,r9 >> >> Signed-off-by: Athira Rajeev >> --- >> tools/perf/util/disasm.c | 101 +++ >> 1 file changed, 101 insertions(+) >> >> diff --git a/tools/perf/util/disasm.c b/tools/perf/util/disasm.c >> index ddb861a0b043..e400dcab4029 100644 >> --- a/tools/perf/util/disasm.c >> +++ b/tools/perf/util/disasm.c >> @@ -25,6 +25,7 @@ >> #include "srcline.h" >> #include "symbol.h" >> #include "util.h" >> +#include "sort.h" >> >> static regex_t file_lineno; >> >> @@ -1645,6 +1646,91 @@ static int symbol__disassemble_capstone(char >> *filename, struct symbol *sym, >> } >> #endif >> >> +static int symbol__disassemble_dso(char *filename, struct symbol *sym, > > Again, I still think this should be named to symbol__disassemble_raw() > because it only uses the raw binary codes. Using dso__data_read_offset > is not important here and it's j
Re: [PowerPC] [PASEMI] Issue with the identification of ATA drives after the of/irq updates 2024-05-29
Hi Michael, On Wed, 03 Jul 2024 12:30:38 +0100, Michael Ellerman wrote: > > Rob Herring writes: > > On Tue, Jul 2, 2024 at 10:54 AM Marc Zyngier wrote: > >> > >> On Sun, 30 Jun 2024 11:21:55 +0100, > >> Christian Zigotzky wrote: > >> > > >> > Hello, > >> > > >> > There is an issue with the identification of ATA drives with our > >> > P.A. Semi Nemo boards [1] after the > >> > commit "of/irq: Factor out parsing of interrupt-map parent > >> > phandle+args from of_irq_parse_raw()" [2]. > >> > >> [snip] > >> > >> My earlier request for valuable debug information still stands. But > >> while you're at it, can you please give the following hack a go? > >> > >> M. > >> > >> --- a/drivers/of/irq.c > >> +++ b/drivers/of/irq.c > >> @@ -282,8 +282,10 @@ int of_irq_parse_raw(const __be32 *addr, struct > >> of_phandle_args *out_irq) > >> > >> oldimap = imap; > >> imap = of_irq_parse_imap_parent(oldimap, imaplen, > >> out_irq); > >> - if (!imap) > >> - goto fail; > >> + if (!imap) { > >> + match = 0; > >> + break; > >> + } > > > > AFAICT reading the DT, I don't think this would fix it. imap should > > only be null if malformed. This case to me looks like interrupt-map > > has the correct cell sizes, but just never matches to do the mapping. > > So maybe imaplen is off and that causes us to end up here, but if > > there's an error I don't see it. A boot with DEBUG enabled in > > drivers/of/irq.c would help. > > > >> > >> match &= of_device_is_available(out_irq->np); > >> if (match) > >> > >> This may not be the final workaround even if it solves your boot > >> problem, but will at least give us a hint at what is going wrong. > >> > >> I have the fuzzy feeling that we may be able to lob this broken system > >> as part of the of_irq_imap_abusers[] array, which would solve things > >> pretty "neatly". > > > > I think this would work and would consolidate the work-arounds. It > > would need either "pasemi,rootbus" or "pa-pxp" added to the list. > > Not sure if it helps, but there's already some code in arch/powerpc to > "fixup" the nemo device tree at boot. > > I'm not sure if it's actually the problem here, but it might be, it does > renumber some interrupts. Or possibly it could be tweaked to fix > whatever the issue is. > > The code is in fixup_device_tree_pasemi(): > > > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/powerpc/kernel/prom_init.c?h=v6.10-rc5#n3114 Ah, that's quite interesting, thanks for the pointer. I can see two possibilities here: - either we remove the interrupt-map from the DT (no idea if that is possible) - or we patch the interrupt-map to be slightly more useful and actually match its input Thanks, M. -- Without deviation from the norm, progress is not possible.
Re: [PATCH] tpm: atmel: Drop PPC64 specific MMIO setup
"Rob Herring (Arm)" writes: > The PPC64 specific MMIO setup open codes DT address functions rather > than using standard address parsing functions. The open-coded version > fails to handle any address translation and is not endian safe. > > I haven't found any evidence of what platform used this. The only thing > that turned up was a PPC405 platform, but that is 32-bit and PPC405 > support is being removed as well. CONFIG_TCG_ATMEL is not enabled for > any powerpc config and never was. The support was added in 2005 and > hasn't been touched since. I found a post on the tpm list which says it was used in JS21, which would make sense given the time frame: https://lore.kernel.org/all/526ea6ff.2080...@linux.vnet.ibm.com/ As near as I can tell this was on a single machine type (the js21 circa 2006). The firmware on the machine didn't support establishing a root of trust, so use of the TPM was as a practical matter effective only for the other functions like random number generation and key management. The number of users who used the TPM for this on this machine was likely very small 7 years ago. The number of those machines still in service today is likely smaller still. The cross section of those two small numbers combined with those who want to run on a shiny new kernel has to be quickly approaching zero. The SLOF (firmware) code does confirm that, and includes the same compatible value as below, so I think that's pretty definitive: https://github.com/qemu/SLOF/blob/master/board-js2x/slof/tpm.fs \ Atmel TPM. new-device 500 1 set-unit s" tpm" 2dup device-name device-type s" AT97SC3201" compatible I used to have a JS21, but it got scrapped in a cleanup a few years back. I strongly doubt any others still exist, I couldn't find any on ebay :) > Rather than try to modernize and fix this code, just remove it. Acked-by: Michael Ellerman (powerpc) cheers > diff --git a/drivers/char/tpm/Kconfig b/drivers/char/tpm/Kconfig > index e63a6a17793c..9b655e9fc7ab 100644 > --- a/drivers/char/tpm/Kconfig > +++ b/drivers/char/tpm/Kconfig > @@ -162,7 +162,7 @@ config TCG_NSC > > config TCG_ATMEL > tristate "Atmel TPM Interface" > - depends on PPC64 || HAS_IOPORT_MAP > + depends on HAS_IOPORT_MAP > depends on HAS_IOPORT > help > If you have a TPM security chip from Atmel say Yes and it > diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c > index 9fb2defa9dc4..622c4abe8cb3 100644 > --- a/drivers/char/tpm/tpm_atmel.c > +++ b/drivers/char/tpm/tpm_atmel.c > @@ -15,7 +15,67 @@ > */ > > #include "tpm.h" > -#include "tpm_atmel.h" > + > +struct tpm_atmel_priv { > + int region_size; > + int have_region; > + unsigned long base; > + void __iomem *iobase; > +}; > + > +#define atmel_getb(chip, offset) inb(atmel_get_priv(chip)->base + offset) > +#define atmel_putb(val, chip, offset) \ > + outb(val, atmel_get_priv(chip)->base + offset) > +#define atmel_request_region request_region > +#define atmel_release_region release_region > +/* Atmel definitions */ > +enum tpm_atmel_addr { > + TPM_ATMEL_BASE_ADDR_LO = 0x08, > + TPM_ATMEL_BASE_ADDR_HI = 0x09 > +}; > + > +static inline int tpm_read_index(int base, int index) > +{ > + outb(index, base); > + return inb(base+1) & 0xFF; > +} > + > +/* Verify this is a 1.1 Atmel TPM */ > +static int atmel_verify_tpm11(void) > +{ > + > + /* verify that it is an Atmel part */ > + if (tpm_read_index(TPM_ADDR, 4) != 'A' || > + tpm_read_index(TPM_ADDR, 5) != 'T' || > + tpm_read_index(TPM_ADDR, 6) != 'M' || > + tpm_read_index(TPM_ADDR, 7) != 'L') > + return 1; > + > + /* query chip for its version number */ > + if (tpm_read_index(TPM_ADDR, 0x00) != 1 || > + tpm_read_index(TPM_ADDR, 0x01) != 1) > + return 1; > + > + /* This is an atmel supported part */ > + return 0; > +} > + > +/* Determine where to talk to device */ > +static void __iomem * atmel_get_base_addr(unsigned long *base, int > *region_size) > +{ > + int lo, hi; > + > + if (atmel_verify_tpm11() != 0) > + return NULL; > + > + lo = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_LO); > + hi = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_HI); > + > + *base = (hi << 8) | lo; > + *region_size = 2; > + > + return ioport_map(*base, *region_size); > +} > > /* write status bits */ > enum tpm_atmel_write_status { > @@ -142,7 +202,6 @@ static void atml_plat_remove(void) > tpm_chip_unregister(chip); > if (priv->have_region) > atmel_release_region(priv->base, priv->region_size); > - atmel_put_base_addr(priv->iobase); > platform_device_unregister(pdev); > } > > @@ -211,7 +270,6 @@ static int __init init_atmel(void) > err_unreg_dev: > platform_device_unregister(pdev); > err_rel_reg: > - atmel_put_base_addr(iobase); > if (have_region) >
Re: linux-next: manual merge of the powerpc tree with the mm tree
Stephen Rothwell writes: > Hi all, > > Today's linux-next merge of the powerpc tree got a conflict in: > > arch/powerpc/mm/nohash/Makefile > ... > diff --cc arch/powerpc/mm/nohash/Makefile > index 90e846f0c46c,86d0fe434824.. > --- a/arch/powerpc/mm/nohash/Makefile > +++ b/arch/powerpc/mm/nohash/Makefile > @@@ -1,8 -1,7 +1,7 @@@ > # SPDX-License-Identifier: GPL-2.0 > > obj-y += mmu_context.o tlb.o tlb_low.o kup.o > -obj-$(CONFIG_PPC_BOOK3E_64) += tlb_low_64e.o book3e_pgtable.o > +obj-$(CONFIG_PPC_BOOK3E_64) += tlb_64e.o tlb_low_64e.o > book3e_pgtable.o > - obj-$(CONFIG_40x) += 40x.o > obj-$(CONFIG_44x) += 44x.o > obj-$(CONFIG_PPC_8xx) += 8xx.o > obj-$(CONFIG_PPC_E500) += e500.o Thanks, looks right. cheers
Re: [PATCH 17/20] ASoC: arizona: convert to of_property_for_each_u32_new()
On Wed, Jul 03, 2024 at 12:37:01PM +0200, Luca Ceresoli wrote: > Simplify code using of_property_for_each_u32_new() as the two additional > parameters in of_property_for_each_u32() are not used here. Acked-by: Mark Brown signature.asc Description: PGP signature
Re: [PATCH 17/20] ASoC: arizona: convert to of_property_for_each_u32_new()
On 03/07/2024 11:37, Luca Ceresoli wrote: Simplify code using of_property_for_each_u32_new() as the two additional parameters in of_property_for_each_u32() are not used here. Signed-off-by: Luca Ceresoli --- sound/soc/codecs/arizona.c | 12 +--- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index 7434aeeda292..1a64b9815809 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c @@ -2786,15 +2786,13 @@ int arizona_of_get_audio_pdata(struct arizona *arizona) { struct arizona_pdata *pdata = &arizona->pdata; struct device_node *np = arizona->dev->of_node; - struct property *prop; - const __be32 *cur; u32 val; u32 pdm_val[ARIZONA_MAX_PDM_SPK]; int ret; int count = 0; count = 0; - of_property_for_each_u32(np, "wlf,inmode", prop, cur, val) { + of_property_for_each_u32_new(np, "wlf,inmode", val) { if (count == ARRAY_SIZE(pdata->inmode)) break; @@ -2803,7 +2801,7 @@ int arizona_of_get_audio_pdata(struct arizona *arizona) } count = 0; - of_property_for_each_u32(np, "wlf,dmic-ref", prop, cur, val) { + of_property_for_each_u32_new(np, "wlf,dmic-ref", val) { if (count == ARRAY_SIZE(pdata->dmic_ref)) break; @@ -2812,7 +2810,7 @@ int arizona_of_get_audio_pdata(struct arizona *arizona) } count = 0; - of_property_for_each_u32(np, "wlf,out-mono", prop, cur, val) { + of_property_for_each_u32_new(np, "wlf,out-mono", val) { if (count == ARRAY_SIZE(pdata->out_mono)) break; @@ -2821,7 +2819,7 @@ int arizona_of_get_audio_pdata(struct arizona *arizona) } count = 0; - of_property_for_each_u32(np, "wlf,max-channels-clocked", prop, cur, val) { + of_property_for_each_u32_new(np, "wlf,max-channels-clocked", val) { if (count == ARRAY_SIZE(pdata->max_channels_clocked)) break; @@ -2830,7 +2828,7 @@ int arizona_of_get_audio_pdata(struct arizona *arizona) } count = 0; - of_property_for_each_u32(np, "wlf,out-volume-limit", prop, cur, val) { + of_property_for_each_u32_new(np, "wlf,out-volume-limit", val) { if (count == ARRAY_SIZE(pdata->out_vol_limit)) break; Reviewed-by: Richard Fitzgerald
Re: [PATCH 11/20] irqchip/atmel-aic: convert to of_property_for_each_u32_new()
On 03/07/2024 at 12:36, Luca Ceresoli wrote: Simplify code using of_property_for_each_u32_new() as the two additional parameters in of_property_for_each_u32() are not used here. Signed-off-by: Luca Ceresoli Acked-by: Nicolas Ferre --- drivers/irqchip/irq-atmel-aic-common.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/irqchip/irq-atmel-aic-common.c b/drivers/irqchip/irq-atmel-aic-common.c index 072bd227b6c6..543ea249df53 100644 --- a/drivers/irqchip/irq-atmel-aic-common.c +++ b/drivers/irqchip/irq-atmel-aic-common.c @@ -111,8 +111,6 @@ static void __init aic_common_ext_irq_of_init(struct irq_domain *domain) struct device_node *node = irq_domain_get_of_node(domain); struct irq_chip_generic *gc; struct aic_chip_data *aic; - struct property *prop; - const __be32 *p; u32 hwirq; gc = irq_get_domain_generic_chip(domain, 0); @@ -120,7 +118,7 @@ static void __init aic_common_ext_irq_of_init(struct irq_domain *domain) aic = gc->private; aic->ext_irqs |= 1; - of_property_for_each_u32(node, "atmel,external-irqs", prop, p, hwirq) { + of_property_for_each_u32_new(node, "atmel,external-irqs", hwirq) { gc = irq_get_domain_generic_chip(domain, hwirq); if (!gc) { pr_warn("AIC: external irq %d >= %d skip it\n", -- 2.34.1
Re: [PATCH V5 04/17] tools/perf: Add disasm_line__parse to parse raw instruction for powerpc
> On 3 Jul 2024, at 6:46 AM, Namhyung Kim wrote: > > On Mon, Jul 01, 2024 at 10:04:17AM +0530, Athira Rajeev wrote: >> Currently, the perf tool infrastructure disasm_line__parse function to >> parse disassembled line. >> >> Example snippet from objdump: >> objdump --start-address= --stop-address= -d >> --no-show-raw-insn -C >> >> c10224b4: lwz r10,0(r9) >> >> This line "lwz r10,0(r9)" is parsed to extract instruction name, >> registers names and offset. In powerpc, the approach for data type >> profiling uses raw instruction instead of result from objdump to identify >> the instruction category and extract the source/target registers. >> >> Example: 38 01 81 e8 ld r4,312(r1) >> >> Here "38 01 81 e8" is the raw instruction representation. Add function >> "disasm_line__parse_powerpc" to handle parsing of raw instruction. >> Also update "struct disasm_line" to save the binary code/ >> With the change, function captures: >> >> line -> "38 01 81 e8 ld r4,312(r1)" >> raw instruction "38 01 81 e8" >> >> Raw instruction is used later to extract the reg/offset fields. Macros >> are added to extract opcode and register fields. "struct disasm_line" >> is updated to carry union of "bytes" and "raw_insn" of 32 bit to carry raw >> code (raw). Function "disasm_line__parse_powerpc fills the raw >> instruction hex value and can use macros to get opcode. There is no >> changes in existing code paths, which parses the disassembled code. >> The size of raw instruction depends on architecture. In case of powerpc, >> the parsing the disasm line needs to handle cases for reading binary code >> directly from DSO as well as parsing the objdump result. Hence adding >> the logic into separate function instead of updating "disasm_line__parse". >> The architecture using the instruction name and present approach is >> not altered. Since this approach targets powerpc, the macro >> implementation is added for powerpc as of now. >> >> Since the disasm_line__parse is used in other cases (perf annotate) and >> not only data tye profiling, the powerpc callback includes changes to >> work with binary code as well as mneumonic representation. Also in case >> if the DSO read fails and libcapstone is not supported, the approach >> fallback to use objdump as option. Hence as option, patch has changes to >> ensure objdump option also works well. >> >> Signed-off-by: Athira Rajeev >> --- >> tools/include/linux/string.h | 2 + >> tools/lib/string.c| 13 >> .../perf/arch/powerpc/annotate/instructions.c | 1 + >> tools/perf/arch/powerpc/util/dwarf-regs.c | 9 +++ >> tools/perf/util/annotate.h| 5 +- >> tools/perf/util/disasm.c | 59 ++- >> 6 files changed, 87 insertions(+), 2 deletions(-) >> >> diff --git a/tools/include/linux/string.h b/tools/include/linux/string.h >> index db5c99318c79..0acb1fc14e19 100644 >> --- a/tools/include/linux/string.h >> +++ b/tools/include/linux/string.h >> @@ -46,5 +46,7 @@ extern char * __must_check skip_spaces(const char *); >> >> extern char *strim(char *); >> >> +extern void remove_spaces(char *s); >> + >> extern void *memchr_inv(const void *start, int c, size_t bytes); >> #endif /* _TOOLS_LINUX_STRING_H_ */ >> diff --git a/tools/lib/string.c b/tools/lib/string.c >> index 8b6892f959ab..3126d2cff716 100644 >> --- a/tools/lib/string.c >> +++ b/tools/lib/string.c >> @@ -153,6 +153,19 @@ char *strim(char *s) >> return skip_spaces(s); >> } >> >> +/* >> + * remove_spaces - Removes whitespaces from @s >> + */ >> +void remove_spaces(char *s) >> +{ >> + char *d = s; >> + >> + do { >> + while (*d == ' ') >> + ++d; >> + } while ((*s++ = *d++)); >> +} >> + >> /** >> * strreplace - Replace all occurrences of character in string. >> * @s: The string to operate on. >> diff --git a/tools/perf/arch/powerpc/annotate/instructions.c >> b/tools/perf/arch/powerpc/annotate/instructions.c >> index a3f423c27cae..d57fd023ef9c 100644 >> --- a/tools/perf/arch/powerpc/annotate/instructions.c >> +++ b/tools/perf/arch/powerpc/annotate/instructions.c >> @@ -55,6 +55,7 @@ static int powerpc__annotate_init(struct arch *arch, char >> *cpuid __maybe_unused) >> arch->initialized = true; >> arch->associate_instruction_ops = powerpc__associate_instruction_ops; >> arch->objdump.comment_char = '#'; >> + annotate_opts.show_asm_raw = true; >> } >> >> return 0; >> diff --git a/tools/perf/arch/powerpc/util/dwarf-regs.c >> b/tools/perf/arch/powerpc/util/dwarf-regs.c >> index 0c4f4caf53ac..430623ca5612 100644 >> --- a/tools/perf/arch/powerpc/util/dwarf-regs.c >> +++ b/tools/perf/arch/powerpc/util/dwarf-regs.c >> @@ -98,3 +98,12 @@ int regs_query_register_offset(const char *name) >> return roff->ptregs_offset; >> return -EINVAL; >> } >> + >> +#define PPC_OP(op) (((op) >> 26) & 0x3F) >> +#define PPC_RA(a) (((a) >> 16) & 0x1f) >> +#define PPC_RT(t) (((t) >> 21) & 0x1f) >> +#define PPC_RB(b) (((b)
[PATCH] PCI: Fix crash during pci_dev hot-unplug on pseries KVM guest
With CONFIG_PCI_DYNAMIC_OF_NODES [1], a hot-plug and hot-unplug sequence of a PCI device attached to a PCI-bridge causes following kernel Oops on a pseries KVM guest: RTAS: event: 2, Type: Hotplug Event (229), Severity: 1 Kernel attempted to read user page (10ec0048) - exploit attempt? (uid: 0) BUG: Unable to handle kernel data access on read at 0x10ec0048 Faulting instruction address: 0xc12d8728 Oops: Kernel access of bad area, sig: 11 [#1] LE PAGE_SIZE=64K MMU=Radix SMP NR_CPUS=2048 NUMA pSeries NIP [c12d8728] __of_changeset_entry_invert+0x10/0x1ac LR [c12da7f0] __of_changeset_revert_entries+0x98/0x180 Call Trace: [cbcc3970] [c12daa60] of_changeset_revert+0x58/0xd8 [cbcc39c0] [c0d0ed78] of_pci_remove_node+0x74/0xb0 [cbcc39f0] [c0cdcfe0] pci_stop_bus_device+0xf4/0x138 [cbcc3a30] [c0cdd140] pci_stop_and_remove_bus_device_locked+0x34/0x64 [cbcc3a60] [c0cf3780] remove_store+0xf0/0x108 [cbcc3ab0] [c0e89e04] dev_attr_store+0x34/0x78 [cbcc3ad0] [c07f8dd4] sysfs_kf_write+0x70/0xa4 [cbcc3af0] [c07f7248] kernfs_fop_write_iter+0x1d0/0x2e0 [cbcc3b40] [c06c9b08] vfs_write+0x27c/0x558 [cbcc3bf0] [c06ca168] ksys_write+0x90/0x170 [cbcc3c40] [c0033248] system_call_exception+0xf8/0x290 [cbcc3e50] [c000d05c] system_call_vectored_common+0x15c/0x2ec A git bisect pointed this regression to be introduced via [1] that added a mechanism to create device tree nodes for parent PCI bridges when a PCI device is hot-plugged. The Oops is caused when `pci_stop_dev()` tries to remove a non-existing device-tree node associated with the pci_dev that was earlier hot-plugged and was attached under a pci-bridge. The PCI dev header `dev->hdr_type` being 0, results a conditional check done with `pci_is_bridge()` into false. Consequently, a call to `of_pci_make_dev_node()` to create a device node is never made. When at a later point in time, in the device node removal path, a memcpy is attempted in `__of_changeset_entry_invert()`; since the device node was never created, results in an Oops due to kernel read access to a bad address. To fix this issue the patch updates `pci_stop_dev()` to ensure that a call to `of_pci_remove_node()` is only made for pci-bridge devices. [1] commit 407d1a51921e ("PCI: Create device tree node for bridge") Fixes: 407d1a51921e ("PCI: Create device tree node for bridge") Reported-by: Kowshik Jois B S Tested-by: Kowshik Jois B S Signed-off-by: Amit Machhiwal --- drivers/pci/remove.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index d749ea8250d6..4e51c64af416 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c @@ -22,7 +22,8 @@ static void pci_stop_dev(struct pci_dev *dev) device_release_driver(&dev->dev); pci_proc_detach_device(dev); pci_remove_sysfs_dev_files(dev); - of_pci_remove_node(dev); + if (pci_is_bridge(dev)) + of_pci_remove_node(dev); pci_dev_assign_added(dev, false); } base-commit: e9d22f7a6655941fc8b2b942ed354ec780936b3e -- 2.45.2
Re: [PATCH 12/20] iio: adc: ti_am335x_adc: convert to of_property_for_each_u32_new()
On Wed, 03 Jul 2024 12:36:56 +0200 Luca Ceresoli wrote: > Simplify code using of_property_for_each_u32_new() as the two additional > parameters in of_property_for_each_u32() are not used here. > > Signed-off-by: Luca Ceresoli Acked-by: Jonathan Cameron
Re: [PowerPC] [PASEMI] Issue with the identification of ATA drives after the of/irq updates 2024-05-29
On 03.07.24 12:41, Marc Zyngier wrote: On Wed, 03 Jul 2024 11:26:17 +0100, Christian Zigotzky wrote: On 3. Jul 2024, at 08:40, Marc Zyngier wrote: This isn't a DTS. This is a listing of all the nodes, not something I can use to feed the kernel. I explained how to generate it. Download the compiled device tree for the Nemo board: http://www.xenosoft.de/fdt-nemo-board.zip No, thank you. You know already the device tree: https://lists.ozlabs.org/pipermail/linuxppc-dev/2021-November/236587.html Do you think I keep this sort of things from almost three years ago? I have better things to do. Now, either you provide the required information in the required form or you don't. Either you test the proposed patches or you don't. If you do, great, and I'll do my best to help you. If you don't, also great, because I can go back to the stuff I'm actually interested in (i.e. not your machine). This is your call, and only yours. M. OK, here is the dts file: https://github.com/chzigotzky/kernels/blob/main/dtb_src/X1000/nemo.dts Thanks for your help.
Re: [PATCH v2] printk: Add a short description string to kmsg_dump()
On Wed, Jul 03, 2024 at 10:22:11AM +0200, Petr Mladek wrote: > On Wed 2024-07-03 09:57:26, Jocelyn Falempe wrote: > > > > > > On 02/07/2024 22:29, Kees Cook wrote: > > > On Tue, Jul 02, 2024 at 02:26:04PM +0200, Jocelyn Falempe wrote: > > > > kmsg_dump doesn't forward the panic reason string to the kmsg_dumper > > > > callback. > > > > This patch adds a new struct kmsg_dump_detail, that will hold the > > > > reason and description, and pass it to the dump() callback. > > > > > > Thanks! I like this much better. :) > > > > > > > > > > > To avoid updating all kmsg_dump() call, it adds a kmsg_dump_desc() > > > > function and a macro for backward compatibility. > > > > > > > > I've written this for drm_panic, but it can be useful for other > > > > kmsg_dumper. > > > > It allows to see the panic reason, like "sysrq triggered crash" > > > > or "VFS: Unable to mount root fs on " on the drm panic screen. > > > > > > > > v2: > > > > * Use a struct kmsg_dump_detail to hold the reason and description > > > > pointer, for more flexibility if we want to add other parameters. > > > > (Kees Cook) > > > > * Fix powerpc/nvram_64 build, as I didn't update the forward > > > > declaration of oops_to_nvram() > > > > > > The versioning history commonly goes after the "---". > > > > ok, I was not aware of this. > > > > > > > [...] > > > > diff --git a/include/linux/kmsg_dump.h b/include/linux/kmsg_dump.h > > > > index 906521c2329c..65f5a47727bc 100644 > > > > --- a/include/linux/kmsg_dump.h > > > > +++ b/include/linux/kmsg_dump.h > > > > @@ -39,6 +39,17 @@ struct kmsg_dump_iter { > > > > u64 next_seq; > > > > }; > > > > +/** > > > > + *struct kmsg_dump_detail - kernel crash detail > > > > > > Is kern-doc happy with this? I think there is supposed to be a space > > > between the "*" and the first word: > > > > > > /** > > >* struct kmsg... > > > > > > > > Good catch, yes there is a space missing. > > > > I just checked with "make htmldocs", and in fact include/linux/kmsg_dump.h > > is not indexed for kernel documentation. > > And you can't find the definition of struct kmsg_dumper in the online doc. > > https://www.kernel.org/doc/html/latest/search.html?q=kmsg_dumper > > > > > Otherwise looks good to me! > > > > > > > Thanks. > > > > As this patch touches different subsystems, do you know on which tree it > > should land ? > > Andrew usually takes patches against kernel/panic.c. > > Or you could take it via the DRM tree, especially if you already have the code > using the string. > > Also I could take it via the printk tree. The only complication is > that I am going to be away the following two weeks and would come > back in the middle of the merge window. I do not expect much problems > with this change but... If DRM doesn't want to carry it, I can put it in through the pstore tree. Let me know! :) -- Kees Cook
Re: [PATCH] ASoC: fsl_xcvr: Improve suspend/resume flow in fsl_xcvr_trigger()
On Fri, 28 Jun 2024 18:43:54 +0900, Chancel Liu wrote: > In the current flow all interrupts are disabled in runtime suspend > phase. However interrupts enablement only exists in fsl_xcvr_prepare(). > After resume fsl_xcvr_prepare() may not be called so it will cause all > interrupts still disabled even if resume from suspend. Interrupts > should be explictily enabled after resume. > > Also, DPATH reset setting only exists in fsl_xcvr_prepare(). After > resume from suspend DPATH should be reset otherwise there'll be channel > swap issue. > > [...] Applied to https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next Thanks! [1/1] ASoC: fsl_xcvr: Improve suspend/resume flow in fsl_xcvr_trigger() commit: c288f0a1c08efa65f9e3bb7954eb3cefb966c97d All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted. You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed. If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced. Please add any relevant lists and maintainers to the CCs when replying to this mail. Thanks, Mark
Re: [PATCH v2] printk: Add a short description string to kmsg_dump()
On 03/07/2024 18:27, Kees Cook wrote: On Wed, Jul 03, 2024 at 10:22:11AM +0200, Petr Mladek wrote: On Wed 2024-07-03 09:57:26, Jocelyn Falempe wrote: On 02/07/2024 22:29, Kees Cook wrote: On Tue, Jul 02, 2024 at 02:26:04PM +0200, Jocelyn Falempe wrote: kmsg_dump doesn't forward the panic reason string to the kmsg_dumper callback. This patch adds a new struct kmsg_dump_detail, that will hold the reason and description, and pass it to the dump() callback. Thanks! I like this much better. :) To avoid updating all kmsg_dump() call, it adds a kmsg_dump_desc() function and a macro for backward compatibility. I've written this for drm_panic, but it can be useful for other kmsg_dumper. It allows to see the panic reason, like "sysrq triggered crash" or "VFS: Unable to mount root fs on " on the drm panic screen. v2: * Use a struct kmsg_dump_detail to hold the reason and description pointer, for more flexibility if we want to add other parameters. (Kees Cook) * Fix powerpc/nvram_64 build, as I didn't update the forward declaration of oops_to_nvram() The versioning history commonly goes after the "---". ok, I was not aware of this. [...] diff --git a/include/linux/kmsg_dump.h b/include/linux/kmsg_dump.h index 906521c2329c..65f5a47727bc 100644 --- a/include/linux/kmsg_dump.h +++ b/include/linux/kmsg_dump.h @@ -39,6 +39,17 @@ struct kmsg_dump_iter { u64 next_seq; }; +/** + *struct kmsg_dump_detail - kernel crash detail Is kern-doc happy with this? I think there is supposed to be a space between the "*" and the first word: /** * struct kmsg... Good catch, yes there is a space missing. I just checked with "make htmldocs", and in fact include/linux/kmsg_dump.h is not indexed for kernel documentation. And you can't find the definition of struct kmsg_dumper in the online doc. https://www.kernel.org/doc/html/latest/search.html?q=kmsg_dumper Otherwise looks good to me! Thanks. As this patch touches different subsystems, do you know on which tree it should land ? Andrew usually takes patches against kernel/panic.c. Or you could take it via the DRM tree, especially if you already have the code using the string. If it's not taken in Andrew's tree next week, I will see if I can push it to the drm-misc tree. I think there is a very low chance of conflicts. Also I could take it via the printk tree. The only complication is that I am going to be away the following two weeks and would come back in the middle of the merge window. I do not expect much problems with this change but... If DRM doesn't want to carry it, I can put it in through the pstore tree. Let me know! :) Thanks for the proposition, I will see how it goes, it would be nice to have it in time for the v6.11 merge window. Best regards, -- Jocelyn
[PATCH 0/2] dt-bindings: soc: fsl: convert fsl,qe to yaml
Convert fsl,qe to yaml and fix ls1043 dtb check warnings. Signed-off-by: Frank Li --- Frank Li (2): dt-bindings: soc: fsl: cpm_qe: convert to yaml format arm64: dts: fsl-ls1043a: change uqe to uqe-bus and remove #address-cells .../bindings/soc/fsl/cpm_qe/fsl,qe-firmware.yaml | 48 ++ .../bindings/soc/fsl/cpm_qe/fsl,qe-ic.yaml | 47 ++ .../bindings/soc/fsl/cpm_qe/fsl,qe-muram.yaml | 71 .../bindings/soc/fsl/cpm_qe/fsl,qe-si.yaml | 40 + .../bindings/soc/fsl/cpm_qe/fsl,qe-siram.yaml | 39 + .../devicetree/bindings/soc/fsl/cpm_qe/fsl,qe.yaml | 148 + .../devicetree/bindings/soc/fsl/cpm_qe/qe.txt | 178 - arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi | 7 +- 8 files changed, 394 insertions(+), 184 deletions(-) --- base-commit: 0b58e108042b0ed28a71cd7edf517555b233 change-id: 20240703-ls_qe_warning-f8a81f53ea23 Best regards, --- Frank Li
[PATCH 1/2] dt-bindings: soc: fsl: cpm_qe: convert to yaml format
Convert binding doc qe.txt to yaml format. Split it to fsl,qe-firmware.yaml, fsl,qe-ic.yaml, fsl,qe-muram.yaml, fsl,qe-si.yaml fsl,qe-siram.yaml, fsl,qe.yaml. Additional Changes: - Fix error in example. - Change to low case for hex value. - Remove fsl,qe-num-riscs and fsl,qe-snums from required list. - Add #address-cell and #size-cell. - Add interrupts description for qe-ic. - Add compatible string fsl,ls1043-qe-si for fsl,qe-si.yaml - Add compatible string fsl,ls1043-qe-siram for fsl,qe-siram.yaml - Add child node for fsl,qe.yaml Fix below warning: arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dtb: /soc/uqe@240/muram@1: failed to match any schema with compatible: ['fsl,qe-muram', 'fsl,cpm-muram'] arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dtb: /soc/uqe@240/muram@1: failed to match any schema with compatible: ['fsl,qe-muram', 'fsl,cpm-muram'] arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dtb: /soc/uqe@240/muram@1/data-only@0: failed to match any schema with compatible: ['fsl,qe-muram-data', 'fsl,cpm-muram-data'] arch/arm64/boot/dts/freescale/fsl-ls1043a-qds.dtb: /soc/uqe@240: failed to match any schema with compatible: ['fsl,qe', 'simple-bus'] arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dtb: /soc/uqe@240/muram@1/data-only@0: failed to match any schema with compatible: ['fsl,qe-muram-data', 'fsl,cpm-muram-data'] arch/arm64/boot/dts/freescale/fsl-ls1043a-qds.dtb: /soc/uqe@240/qeic@80: failed to match any schema with compatible: ['fsl,qe-ic'] Signed-off-by: Frank Li --- .../bindings/soc/fsl/cpm_qe/fsl,qe-firmware.yaml | 48 ++ .../bindings/soc/fsl/cpm_qe/fsl,qe-ic.yaml | 47 ++ .../bindings/soc/fsl/cpm_qe/fsl,qe-muram.yaml | 71 .../bindings/soc/fsl/cpm_qe/fsl,qe-si.yaml | 40 + .../bindings/soc/fsl/cpm_qe/fsl,qe-siram.yaml | 39 + .../devicetree/bindings/soc/fsl/cpm_qe/fsl,qe.yaml | 148 + .../devicetree/bindings/soc/fsl/cpm_qe/qe.txt | 178 - 7 files changed, 393 insertions(+), 178 deletions(-) diff --git a/Documentation/devicetree/bindings/soc/fsl/cpm_qe/fsl,qe-firmware.yaml b/Documentation/devicetree/bindings/soc/fsl/cpm_qe/fsl,qe-firmware.yaml new file mode 100644 index 0..53b07d4edc773 --- /dev/null +++ b/Documentation/devicetree/bindings/soc/fsl/cpm_qe/fsl,qe-firmware.yaml @@ -0,0 +1,48 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/soc/fsl/cpm_qe/fsl,qe-firmware.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Freescale QUICC Engine module Firmware Node + +maintainers: + - Frank Li + +description: | + This node defines a firmware binary that is embedded in the device tree, for + the purpose of passing the firmware from bootloader to the kernel, or from + the hypervisor to the guest. + + The firmware node itself contains the firmware binary contents, a compatible + property, and any firmware-specific properties. The node should be placed + inside a QE node that needs it. Doing so eliminates the need for a + fsl,firmware-phandle property. Other QE nodes that need the same firmware + should define an fsl,firmware-phandle property that points to the firmware node + in the first QE node. + + The fsl,firmware property can be specified in the DTS (possibly using incbin) + or can be inserted by the boot loader at boot time. + +properties: + compatible: +enum: + - fsl,qe-firmware + + fsl,firmware: +$ref: /schemas/types.yaml#/definitions/uint8-array +description: + A standard property. This property contains the firmware binary "blob". + +required: + - compatible + - fsl,firmware + +additionalProperties: false + +examples: + - | +qe-firmware { +compatible = "fsl,qe-firmware"; +fsl,firmware = <0x70 0xcd 0x00 0x00 0x01 0x46 0x45>; +}; diff --git a/Documentation/devicetree/bindings/soc/fsl/cpm_qe/fsl,qe-ic.yaml b/Documentation/devicetree/bindings/soc/fsl/cpm_qe/fsl,qe-ic.yaml new file mode 100644 index 0..8267ad00727b1 --- /dev/null +++ b/Documentation/devicetree/bindings/soc/fsl/cpm_qe/fsl,qe-ic.yaml @@ -0,0 +1,47 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/soc/fsl/cpm_qe/fsl,qe-ic.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Freescale QUICC Engine module Interrupt Controller (IC) + +maintainers: + - Frank Li + +properties: + compatible: +const: fsl,qe-ic + + reg: +maxItems: 1 + + interrupts: +items: + - description: QE interrupt + - description: QE critical + - description: QE error +minItems: 1 + + interrupt-controller: true + + "#interrupt-cells": +const: 1 + +required: + - compatible + - reg + - interrupt-controller + - "#interrupt-cells" + +additionalProperties: false + +examples: + - | +interrupt-controller@80 { +c
[PATCH 2/2] arm64: dts: fsl-ls1043a: change uqe to uqe-bus and remove #address-cells
Change node name 'uqe' to 'uqe-bus'. Remove #address-cells and #size-cells for nodes, which have not child node. Fix below CHECK_DTBS warning: arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dtb: uqe@240: si@700: '#address-cells', '#size-cells' do not match any of the regexes: 'pinctrl-[0-9]+' from schema $id: http://devicetree.org/schemas/soc/fsl/cpm_qe/fsl,qe.yaml# arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dtb: uqe@240: siram@1000: '#address-cells', '#size-cells' do not match any of the regexes: 'pinctrl-[0-9]+' from schema $id: http://devicetree.org/schemas/soc/fsl/cpm_qe/fsl,qe.yaml# arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dtb: uqe@240: $nodename:0: 'uqe@240' does not match '^([a-z][a-z0-9\\-]+-bus|bus|localbus|soc|axi|ahb|apb)(@.+)?$' from schema $id: http://devicetree.org/schemas/soc/fsl/cpm_qe/fsl,qe.yaml# arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dtb: uqe@240: Unevaluated properties are not allowed ('#address-cells', '#size-cells', 'qeic@80', 'ucc@2000', 'ucc@2200' were unexpected) from schema $id: http://devicetree.org/schemas/soc/fsl/cpm_qe/fsl,qe.yaml# arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dtb: qeic@80: '#address-cells' does not match any of the regexes: 'pinctrl-[0-9]+' from schema $id: http://devicetree.org/schemas/soc/fsl/cpm_qe/fsl,qe-ic.yaml# arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dtb: si@700: '#address-cells', '#size-cells' do not match any of the regexes: 'pinctrl-[0-9]+' from schema $id: http://devicetree.org/schemas/soc/fsl/cpm_qe/fsl,qe-si.yaml# arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dtb: siram@1000: '#address-cells', '#size-cells' do not match any of the regexes: 'pinctrl-[0-9]+' from schema $id: http://devicetree.org/schemas/soc/fsl/cpm_qe/fsl,qe-siram.yaml# Signed-off-by: Frank Li --- arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi | 7 +-- 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi index 17f4e31711209..c116a03fe872b 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi @@ -653,7 +653,7 @@ gpio4: gpio@233 { #interrupt-cells = <2>; }; - uqe: uqe@240 { + uqe: uqe-bus@240 { #address-cells = <1>; #size-cells = <1>; compatible = "fsl,qe", "simple-bus"; @@ -667,7 +667,6 @@ uqe: uqe@240 { qeic: qeic@80 { compatible = "fsl,qe-ic"; reg = <0x80 0x80>; - #address-cells = <0>; interrupt-controller; #interrupt-cells = <1>; interrupts = , @@ -675,16 +674,12 @@ qeic: qeic@80 { }; si1: si@700 { - #address-cells = <1>; - #size-cells = <0>; compatible = "fsl,ls1043-qe-si", "fsl,t1040-qe-si"; reg = <0x700 0x80>; }; siram1: siram@1000 { - #address-cells = <1>; - #size-cells = <1>; compatible = "fsl,ls1043-qe-siram", "fsl,t1040-qe-siram"; reg = <0x1000 0x800>; -- 2.34.1
Re: [PATCH 20/20] of: deprecate and rename of_property_for_each_u32()
On Wed, Jul 03, 2024 at 12:37:04PM +0200, Luca Ceresoli wrote: > of_property_for_each_u32() is meant to disappear. All the call sites not > using the 3rd and 4th arguments have already been replaced by > of_property_for_each_u32_new(). > > Deprecate the old macro. Also rename it to minimize the number of new > usages and encourage conversion to the of_property_for_each_u32_new() macro > in not(-yet)-upstream code. > > Signed-off-by: Luca Ceresoli > > --- > > Notes: > > * The following files have not been build-tested simply because I haven't >managed to have a config that enables them so far: > > drivers/irqchip/irq-pic32-evic.c > drivers/pinctrl/pinctrl-k210.c > > * These have not been converted yet as they are not trivial, and they will >need to use a more specific function that does the lookup they need and >returns the result: > > drivers/clk/clk-si5351.c I would do something like this: sz = of_property_read_variable_u32_array(np, "silabs,pll-source", array, 2, 4); if (sz >= 2) pdata->pll_src[array[0]] = val_to_src(array[1]); if (sz >= 4) pdata->pll_src[array[2]] = val_to_src(array[3]); > drivers/clk/clk.c Wouldn't this work: 8<-- diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 8cca52be993f..33a8cc193556 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -5371,6 +5371,7 @@ const char *of_clk_get_parent_name(const struct device_node *np, int index) int rc; int count; struct clk *clk; + bool found = false; rc = of_parse_phandle_with_args(np, "clocks", "#clock-cells", index, &clkspec); @@ -5383,15 +5384,16 @@ const char *of_clk_get_parent_name(const struct device_node *np, int index) /* if there is an indices property, use it to transfer the index * specified into an array offset for the clock-output-names property. */ - of_property_for_each_u32(clkspec.np, "clock-indices", prop, vp, pv) { + of_property_for_each_u32_new(clkspec.np, "clock-indices", pv) { if (index == pv) { index = count; + found = true; break; } count++; } /* We went off the end of 'clock-indices' without finding it */ - if (prop && !vp) + if (of_property_present(clkspec.np, "clock-indices") && !found) return NULL; if (of_property_read_string_index(clkspec.np, "clock-output-names",
Re: [PATCH 00/20] Simplify of_property_for_each_u32()
On Wed, Jul 03, 2024 at 12:36:44PM +0200, Luca Ceresoli wrote: > [Note: to reduce the noise I have trimmed the get_maintainers list > manually. Should you want to be removed, or someone else added, to future > versions, just tell me. Sorry for the noise.] > > This series aims at simplifying of_property_for_each_u32() as well as > making it more difficult to misuse it in the future. > > The long-term goal is changing this pattern: > > struct property *prop; > const __be32 *p; > u32 val; > > of_property_for_each_u32(np, "xyz", prop, p, val) { ... } > > to this: > > u32 val; > > of_property_for_each_u32(np, "xyz", val) { ... } > > So, removing the 3rd and 4th arguments which are typically meant to be > internal. Those two parameters used to be unavoidable until the kernel > moved to building with the C11 standard unconditionally. Since then, it is > now possible to get rid of them. However a few users of > of_property_for_each_u32() do actually use those arguments, which > complicates the transition. For this reason this series does the following: > > * Add of_property_for_each_u32_new(), which does not have those two >arguments (patch 1) > * Convert _almost_ every usage to of_property_for_each_u32_new() > * Rename of_property_for_each_u32() to of_property_for_each_u32_old() and >deprecate it, as a incentive to code not (yet) in mainline to upgrade >to the *_new() version (last patch) I don't really see the point of introducing the _old variant. Let's get this done in one step. > > The plan for the next series is to additionally: > > * Convert the few remaining of_property_for_each_u32_old() instantes to >of_property_for_each_u32_new() > * Remove of_property_for_each_u32_old() > * Rename of_property_for_each_u32_new() to of_property_for_each_u32() Honestly, I think there's few enough users we could just convert the whole thing in one patch. It's all got to go thru 1 tree anyways. If there's new cases in -next, then I'd be happy to send it to Linus at the end of the merge window. Rob
[PATCH 0/2] dt-bindings: soc: add reset syscon for reboot node
Add ls1028 reset syscon and fix below warnings. syscon@1e6: compatible: 'anyOf' conditional failed, one must be fixed: ['syscon'] is too short 'syscon' is not one of ['al,alpine-sysfabric-service', ... Signed-off-by: Frank Li --- Frank Li (2): dt-bindings: soc: fsl: Add fsl,ls1028a-reset for reset syscon node arm64: dts: fsl-ls1028a.dtsi: add fsl,ls1028-reset for syscon .../bindings/soc/fsl/fsl,ls1028a-reset.yaml| 56 ++ arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi | 17 --- 2 files changed, 64 insertions(+), 9 deletions(-) --- base-commit: 0b58e108042b0ed28a71cd7edf517555b233 change-id: 20240703-ls_reset_syscon-9507b9750397 Best regards, --- Frank Li
[PATCH 1/2] dt-bindings: soc: fsl: Add fsl,ls1028a-reset for reset syscon node
ls1028a has a reset module that includes reboot, reset control word, and service processor control. Add platform specific compatible string to fix the below warning. syscon@1e6: compatible: 'anyOf' conditional failed, one must be fixed: ['syscon'] is too short 'syscon' is not one of ['al,alpine-sysfabric-service', ...] Signed-off-by: Frank Li --- .../bindings/soc/fsl/fsl,ls1028a-reset.yaml| 56 ++ 1 file changed, 56 insertions(+) diff --git a/Documentation/devicetree/bindings/soc/fsl/fsl,ls1028a-reset.yaml b/Documentation/devicetree/bindings/soc/fsl/fsl,ls1028a-reset.yaml new file mode 100644 index 0..31295be910130 --- /dev/null +++ b/Documentation/devicetree/bindings/soc/fsl/fsl,ls1028a-reset.yaml @@ -0,0 +1,56 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas//soc/fsl/fsl,ls1028a-reset.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Freescale Layerscape Reset Registers Module + +maintainers: + - Frank Li + +description: + Reset Module includes chip reset, service processor control and Reset Control + Word (RCW) status. + +properties: + $nodename: +pattern: "^syscon@[0-9a-f]+$" + + compatible: +items: + - enum: + - fsl,ls1028a-reset + - const: syscon + - const: simple-mfd + + reg: +maxItems: 1 + + little-endian: true + + reboot: +$ref: /schemas/power/reset/syscon-reboot.yaml# +unevaluatedProperties: false + +required: + - compatible + - reg + - reboot + +additionalProperties: false + +examples: + - | +syscon@1e6 { +compatible = "fsl,ls1028a-reset", "syscon", "simple-mfd"; +reg = <0x1e6 0x1>; +little-endian; + +reboot { +compatible = "syscon-reboot"; +offset = <0>; +mask = <0x02>; +}; +}; + -- 2.34.1
[PATCH 2/2] arm64: dts: fsl-ls1028a.dtsi: add fsl,ls1028-reset for syscon
Add platform specific compatiable string 'fsl,ls1028-reset' for syscon and move reboot node under reset syscon node to fix below warning. syscon@1e6: compatible: 'anyOf' conditional failed, one must be fixed: ['syscon'] is too short 'syscon' is not one of ['al,alpine-sysfabric-service', ... Signed-off-by: Frank Li --- arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi | 17 - 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi index 6b6e3ee950e53..fd93e66c071e1 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi @@ -112,13 +112,6 @@ optee: optee { }; }; - reboot { - compatible = "syscon-reboot"; - regmap = <&rst>; - offset = <0>; - mask = <0x02>; - }; - timer { compatible = "arm,armv8-timer"; interrupts = ; little-endian; + + reboot { + compatible = "syscon-reboot"; + offset = <0>; + mask = <0x02>; + }; }; sfp: efuse@1e8 { -- 2.34.1
Re: [PATCH v2 07/10] soc: fsl: cpm1: qmc: Introduce functions to get a channel from a phandle list
On Mon, Jul 01, 2024 at 01:30:34PM +0200, Herve Codina wrote: > qmc_chan_get_byphandle() and the resource managed version retrieve a > channel from a simple phandle. > > Extend the API and introduce qmc_chan_get_byphandles_index() and the > resource managed version in order to retrieve a channel from a phandle > list using the provided index to identify the phandle in the list. These two PowerPC patches seem trivial enough and have got no response, unless someone objects I'll go ahead and apply them. signature.asc Description: PGP signature
Re: [PATCH 13/20] pwm: samsung: convert to of_property_for_each_u32_new()
Hello, On Wed, Jul 03, 2024 at 12:36:57PM +0200, Luca Ceresoli wrote: > Simplify code using of_property_for_each_u32_new() as the two additional > parameters in of_property_for_each_u32() are not used here. > > Signed-off-by: Luca Ceresoli > --- > drivers/pwm/pwm-samsung.c | 4 +--- > 1 file changed, 1 insertion(+), 3 deletions(-) > > diff --git a/drivers/pwm/pwm-samsung.c b/drivers/pwm/pwm-samsung.c > index efb60c9f0cb3..fef02a0b023e 100644 > --- a/drivers/pwm/pwm-samsung.c > +++ b/drivers/pwm/pwm-samsung.c > @@ -510,8 +510,6 @@ static int pwm_samsung_parse_dt(struct pwm_chip *chip) > struct samsung_pwm_chip *our_chip = to_samsung_pwm_chip(chip); > struct device_node *np = pwmchip_parent(chip)->of_node; > const struct of_device_id *match; > - struct property *prop; > - const __be32 *cur; > u32 val; > > match = of_match_node(samsung_pwm_matches, np); > @@ -520,7 +518,7 @@ static int pwm_samsung_parse_dt(struct pwm_chip *chip) > > memcpy(&our_chip->variant, match->data, sizeof(our_chip->variant)); > > - of_property_for_each_u32(np, "samsung,pwm-outputs", prop, cur, val) { > + of_property_for_each_u32_new(np, "samsung,pwm-outputs", val) { > if (val >= SAMSUNG_PWM_NUM) { > dev_err(pwmchip_parent(chip), > "%s: invalid channel index in > samsung,pwm-outputs property\n", > Acked-by: Uwe Kleine-König Feel free to merge this together with the change from the first patch. Best regards Uwe signature.asc Description: PGP signature
[PATCH v2 0/8] mm/mprotect: Fix dax puds
[Based on mm-unstable, commit 31334cf98dbd, July 2nd] v2: - Added tags - Fix wrong pmd helper used in powerpc - Added patch "mm/x86: arch_check_zapped_pud()" [Rick] - Do proper dirty bit shifts for shadow stack on puds [Dave] - Add missing page_table_check hooks in pudp_establish() [Dave] v1: https://lore.kernel.org/r/20240621142504.1940209-1-pet...@redhat.com Dax supports pud pages for a while, but mprotect on puds was missing since the start. This series tries to fix that by providing pud handling in mprotect(). The goal is to add more types of pud mappings like hugetlb or pfnmaps. This series paves way for it by fixing known pud entries. Considering nobody reported this until when I looked at those other types of pud mappings, I am thinking maybe it doesn't need to be a fix for stable and this may not need to be backported. I would guess whoever cares about mprotect() won't care 1G dax puds yet, vice versa. I hope fixing that in new kernels would be fine, but I'm open to suggestions. There're a few small things changed to teach mprotect work on PUDs. E.g. it will need to start with dropping NUMA_HUGE_PTE_UPDATES which may stop making sense when there can be more than one type of huge pte. OTOH, we'll also need to push the mmu notifiers from pmd to pud layers, which might need some attention but so far I think it's safe. For such details, please refer to each patch's commit message. The mprotect() pud process should be straightforward, as I kept it as simple as possible. There's no NUMA handled as dax simply doesn't support that. There's also no userfault involvements as file memory (even if work with userfault-wp async mode) will need to split a pud, so pud entry doesn't need to yet know userfault's existance (but hugetlb entries will; that's also for later). Tests = What I did test: - cross-build tests that I normally cover [1] - smoke tested on x86_64 the simplest program [2] on dev_dax 1G PUD mprotect() using QEMU's nvdimm emulations [3] and ndctl to create namespaces with proper alignments, which used to throw "bad pud" but now it'll run through all fine. I checked sigbus happens if with illegal access on protected puds. What I didn't test: - fsdax: I wanted to also give it a shot, but only until then I noticed it doesn't seem to be supported (according to dax_iomap_fault(), which will always fallback on PUD_ORDER). I did remember it was supported before, I could miss something important there.. please shoot if so. - userfault wp-async: I also wanted to test userfault-wp async be able to split huge puds (here it's simply a clear_pud.. though), but it won't work for devdax anyway due to not allowed to do smaller than 1G faults in this case. So skip too. - Power, as no hardware on hand. Thanks, [1] https://gitlab.com/peterx/lkb-harness/-/blob/main/config.json [2] https://github.com/xzpeter/clibs/blob/master/misc/dax.c [3] https://github.com/qemu/qemu/blob/master/docs/nvdimm.txt Peter Xu (8): mm/dax: Dump start address in fault handler mm/mprotect: Remove NUMA_HUGE_PTE_UPDATES mm/mprotect: Push mmu notifier to PUDs mm/powerpc: Add missing pud helpers mm/x86: Make pud_leaf() only cares about PSE bit mm/x86: arch_check_zapped_pud() mm/x86: Add missing pud helpers mm/mprotect: fix dax pud handlings arch/powerpc/include/asm/book3s/64/pgtable.h | 3 + arch/powerpc/mm/book3s64/pgtable.c | 20 ++ arch/x86/include/asm/pgtable.h | 68 +++--- arch/x86/mm/pgtable.c| 18 + drivers/dax/device.c | 6 +- include/linux/huge_mm.h | 24 +++ include/linux/pgtable.h | 7 ++ include/linux/vm_event_item.h| 1 - mm/huge_memory.c | 56 ++- mm/mprotect.c| 74 mm/vmstat.c | 1 - 11 files changed, 233 insertions(+), 45 deletions(-) -- 2.45.0
[PATCH v2 1/8] mm/dax: Dump start address in fault handler
Currently the dax fault handler dumps the vma range when dynamic debugging enabled. That's mostly not useful. Dump the (aligned) address instead with the order info. Signed-off-by: Peter Xu --- drivers/dax/device.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/dax/device.c b/drivers/dax/device.c index eb61598247a9..714174844ca5 100644 --- a/drivers/dax/device.c +++ b/drivers/dax/device.c @@ -235,9 +235,9 @@ static vm_fault_t dev_dax_huge_fault(struct vm_fault *vmf, unsigned int order) int id; struct dev_dax *dev_dax = filp->private_data; - dev_dbg(&dev_dax->dev, "%s: %s (%#lx - %#lx) order:%d\n", current->comm, - (vmf->flags & FAULT_FLAG_WRITE) ? "write" : "read", - vmf->vma->vm_start, vmf->vma->vm_end, order); + dev_dbg(&dev_dax->dev, "%s: op=%s addr=%#lx order=%d\n", current->comm, + (vmf->flags & FAULT_FLAG_WRITE) ? "write" : "read", + vmf->address & ~((1UL << (order + PAGE_SHIFT)) - 1), order); id = dax_read_lock(); if (order == 0) -- 2.45.0
[PATCH v2 2/8] mm/mprotect: Remove NUMA_HUGE_PTE_UPDATES
In 2013, commit 72403b4a0fbd ("mm: numa: return the number of base pages altered by protection changes") introduced "numa_huge_pte_updates" vmstat entry, trying to capture how many huge ptes (in reality, PMD thps at that time) are marked by NUMA balancing. This patch proposes to remove it for some reasons. Firstly, the name is misleading. We can have more than one way to have a "huge pte" at least nowadays, and that's also the major goal of this patch, where it paves way for PUD handling in change protection code paths. PUDs are coming not only for dax (which has already came and yet broken..), but also for pfnmaps and hugetlb pages. The name will simply stop making sense when PUD will start to be involved in mprotect() world. It'll also make it not reasonable either if we boost the counter for both pmd/puds. In short, current accounting won't be right when PUD comes, so the scheme was only suitable at that point in time where PUD wasn't even possible. Secondly, the accounting was simply not right from the start as long as it was also affected by other call sites besides NUMA. mprotect() is one, while userfaultfd-wp also leverages change protection path to modify pgtables. If it wants to do right it needs to check the caller but it never did; at least mprotect() should be there even in 2013. It gives me the impression that nobody is seriously using this field, and it's also impossible to be serious. We may want to do it right if any NUMA developers would like it to exist, but we should do that with all above resolved, on both considering PUDs, but also on correct accountings. That should be able to be done on top when there's a real need of such. Cc: Huang Ying Cc: Mel Gorman Cc: Alex Thorlton Cc: Rik van Riel Signed-off-by: Peter Xu --- include/linux/vm_event_item.h | 1 - mm/mprotect.c | 8 +--- mm/vmstat.c | 1 - 3 files changed, 1 insertion(+), 9 deletions(-) diff --git a/include/linux/vm_event_item.h b/include/linux/vm_event_item.h index 747943bc8cc2..2a3797fb6742 100644 --- a/include/linux/vm_event_item.h +++ b/include/linux/vm_event_item.h @@ -59,7 +59,6 @@ enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT, OOM_KILL, #ifdef CONFIG_NUMA_BALANCING NUMA_PTE_UPDATES, - NUMA_HUGE_PTE_UPDATES, NUMA_HINT_FAULTS, NUMA_HINT_FAULTS_LOCAL, NUMA_PAGE_MIGRATE, diff --git a/mm/mprotect.c b/mm/mprotect.c index 222ab434da54..21172272695e 100644 --- a/mm/mprotect.c +++ b/mm/mprotect.c @@ -363,7 +363,6 @@ static inline long change_pmd_range(struct mmu_gather *tlb, pmd_t *pmd; unsigned long next; long pages = 0; - unsigned long nr_huge_updates = 0; struct mmu_notifier_range range; range.start = 0; @@ -411,11 +410,8 @@ static inline long change_pmd_range(struct mmu_gather *tlb, ret = change_huge_pmd(tlb, vma, pmd, addr, newprot, cp_flags); if (ret) { - if (ret == HPAGE_PMD_NR) { + if (ret == HPAGE_PMD_NR) pages += HPAGE_PMD_NR; - nr_huge_updates++; - } - /* huge pmd was handled */ goto next; } @@ -435,8 +431,6 @@ static inline long change_pmd_range(struct mmu_gather *tlb, if (range.start) mmu_notifier_invalidate_range_end(&range); - if (nr_huge_updates) - count_vm_numa_events(NUMA_HUGE_PTE_UPDATES, nr_huge_updates); return pages; } diff --git a/mm/vmstat.c b/mm/vmstat.c index 73d791d1caad..53656227f70d 100644 --- a/mm/vmstat.c +++ b/mm/vmstat.c @@ -1313,7 +1313,6 @@ const char * const vmstat_text[] = { #ifdef CONFIG_NUMA_BALANCING "numa_pte_updates", - "numa_huge_pte_updates", "numa_hint_faults", "numa_hint_faults_local", "numa_pages_migrated", -- 2.45.0
[PATCH v2 3/8] mm/mprotect: Push mmu notifier to PUDs
mprotect() does mmu notifiers in PMD levels. It's there since 2014 of commit a5338093bfb4 ("mm: move mmu notifier call from change_protection to change_pmd_range"). At that time, the issue was that NUMA balancing can be applied on a huge range of VM memory, even if nothing was populated. The notification can be avoided in this case if no valid pmd detected, which includes either THP or a PTE pgtable page. Now to pave way for PUD handling, this isn't enough. We need to generate mmu notifications even on PUD entries properly. mprotect() is currently broken on PUD (e.g., one can easily trigger kernel error with dax 1G mappings already), this is the start to fix it. To fix that, this patch proposes to push such notifications to the PUD layers. There is risk on regressing the problem Rik wanted to resolve before, but I think it shouldn't really happen, and I still chose this solution because of a few reasons: 1) Consider a large VM that should definitely contain more than GBs of memory, it's highly likely that PUDs are also none. In this case there will have no regression. 2) KVM has evolved a lot over the years to get rid of rmap walks, which might be the major cause of the previous soft-lockup. At least TDP MMU already got rid of rmap as long as not nested (which should be the major use case, IIUC), then the TDP MMU pgtable walker will simply see empty VM pgtable (e.g. EPT on x86), the invalidation of a full empty region in most cases could be pretty fast now, comparing to 2014. 3) KVM has explicit code paths now to even give way for mmu notifiers just like this one, e.g. in commit d02c357e5bfa ("KVM: x86/mmu: Retry fault before acquiring mmu_lock if mapping is changing"). It'll also avoid contentions that may also contribute to a soft-lockup. 4) Stick with PMD layer simply don't work when PUD is there... We need one way or another to fix PUD mappings on mprotect(). Pushing it to PUD should be the safest approach as of now, e.g. there's yet no sign of huge P4D coming on any known archs. Cc: k...@vger.kernel.org Cc: Sean Christopherson Cc: Paolo Bonzini Cc: David Rientjes Cc: Rik van Riel Signed-off-by: Peter Xu --- mm/mprotect.c | 26 -- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/mm/mprotect.c b/mm/mprotect.c index 21172272695e..fb8bf3ff7cd9 100644 --- a/mm/mprotect.c +++ b/mm/mprotect.c @@ -363,9 +363,6 @@ static inline long change_pmd_range(struct mmu_gather *tlb, pmd_t *pmd; unsigned long next; long pages = 0; - struct mmu_notifier_range range; - - range.start = 0; pmd = pmd_offset(pud, addr); do { @@ -383,14 +380,6 @@ static inline long change_pmd_range(struct mmu_gather *tlb, if (pmd_none(*pmd)) goto next; - /* invoke the mmu notifier if the pmd is populated */ - if (!range.start) { - mmu_notifier_range_init(&range, - MMU_NOTIFY_PROTECTION_VMA, 0, - vma->vm_mm, addr, end); - mmu_notifier_invalidate_range_start(&range); - } - _pmd = pmdp_get_lockless(pmd); if (is_swap_pmd(_pmd) || pmd_trans_huge(_pmd) || pmd_devmap(_pmd)) { if ((next - addr != HPAGE_PMD_SIZE) || @@ -428,9 +417,6 @@ static inline long change_pmd_range(struct mmu_gather *tlb, cond_resched(); } while (pmd++, addr = next, addr != end); - if (range.start) - mmu_notifier_invalidate_range_end(&range); - return pages; } @@ -438,10 +424,13 @@ static inline long change_pud_range(struct mmu_gather *tlb, struct vm_area_struct *vma, p4d_t *p4d, unsigned long addr, unsigned long end, pgprot_t newprot, unsigned long cp_flags) { + struct mmu_notifier_range range; pud_t *pud; unsigned long next; long pages = 0, ret; + range.start = 0; + pud = pud_offset(p4d, addr); do { next = pud_addr_end(addr, end); @@ -450,10 +439,19 @@ static inline long change_pud_range(struct mmu_gather *tlb, return ret; if (pud_none_or_clear_bad(pud)) continue; + if (!range.start) { + mmu_notifier_range_init(&range, + MMU_NOTIFY_PROTECTION_VMA, 0, + vma->vm_mm, addr, end); + mmu_notifier_invalidate_range_start(&range); + } pages += change_pmd_range(tlb, vma, pud, addr, next, newprot, cp_flags); } while (pud++, addr = next, addr != end); + if (range.start) + mmu_notifier_invalidate_range_end(&range); + return pages;
[PATCH v2 4/8] mm/powerpc: Add missing pud helpers
These new helpers will be needed for pud entry updates soon. Introduce them by referencing the pmd ones. Namely: - pudp_invalidate() - pud_modify() Cc: Michael Ellerman Cc: Nicholas Piggin Cc: Christophe Leroy Cc: linuxppc-dev@lists.ozlabs.org Cc: Aneesh Kumar K.V Signed-off-by: Peter Xu --- arch/powerpc/include/asm/book3s/64/pgtable.h | 3 +++ arch/powerpc/mm/book3s64/pgtable.c | 20 2 files changed, 23 insertions(+) diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h index 519b1743a0f4..5da92ba68a45 100644 --- a/arch/powerpc/include/asm/book3s/64/pgtable.h +++ b/arch/powerpc/include/asm/book3s/64/pgtable.h @@ -1124,6 +1124,7 @@ extern pmd_t pfn_pmd(unsigned long pfn, pgprot_t pgprot); extern pud_t pfn_pud(unsigned long pfn, pgprot_t pgprot); extern pmd_t mk_pmd(struct page *page, pgprot_t pgprot); extern pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot); +extern pud_t pud_modify(pud_t pud, pgprot_t newprot); extern void set_pmd_at(struct mm_struct *mm, unsigned long addr, pmd_t *pmdp, pmd_t pmd); extern void set_pud_at(struct mm_struct *mm, unsigned long addr, @@ -1384,6 +1385,8 @@ static inline pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, #define __HAVE_ARCH_PMDP_INVALIDATE extern pmd_t pmdp_invalidate(struct vm_area_struct *vma, unsigned long address, pmd_t *pmdp); +extern pud_t pudp_invalidate(struct vm_area_struct *vma, unsigned long address, +pud_t *pudp); #define pmd_move_must_withdraw pmd_move_must_withdraw struct spinlock; diff --git a/arch/powerpc/mm/book3s64/pgtable.c b/arch/powerpc/mm/book3s64/pgtable.c index f4d8d3c40e5c..5a4a75369043 100644 --- a/arch/powerpc/mm/book3s64/pgtable.c +++ b/arch/powerpc/mm/book3s64/pgtable.c @@ -176,6 +176,17 @@ pmd_t pmdp_invalidate(struct vm_area_struct *vma, unsigned long address, return __pmd(old_pmd); } +pud_t pudp_invalidate(struct vm_area_struct *vma, unsigned long address, + pud_t *pudp) +{ + unsigned long old_pud; + + VM_WARN_ON_ONCE(!pud_present(*pudp)); + old_pud = pud_hugepage_update(vma->vm_mm, address, pudp, _PAGE_PRESENT, _PAGE_INVALID); + flush_pud_tlb_range(vma, address, address + HPAGE_PUD_SIZE); + return __pud(old_pud); +} + pmd_t pmdp_huge_get_and_clear_full(struct vm_area_struct *vma, unsigned long addr, pmd_t *pmdp, int full) { @@ -259,6 +270,15 @@ pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot) pmdv &= _HPAGE_CHG_MASK; return pmd_set_protbits(__pmd(pmdv), newprot); } + +pud_t pud_modify(pud_t pud, pgprot_t newprot) +{ + unsigned long pudv; + + pudv = pud_val(pud); + pudv &= _HPAGE_CHG_MASK; + return pud_set_protbits(__pud(pudv), newprot); +} #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ /* For use by kexec, called with MMU off */ -- 2.45.0
[PATCH v2 5/8] mm/x86: Make pud_leaf() only cares about PSE bit
An entry should be reported as PUD leaf even if it's PROT_NONE, in which case PRESENT bit isn't there. I hit bad pud without this when testing dax 1G on zapping a PROT_NONE PUD. Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Borislav Petkov Cc: Dave Hansen Cc: x...@kernel.org Acked-by: Dave Hansen Signed-off-by: Peter Xu --- arch/x86/include/asm/pgtable.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index 65b8e5bb902c..25fc6d809572 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h @@ -1073,8 +1073,7 @@ static inline pmd_t *pud_pgtable(pud_t pud) #define pud_leaf pud_leaf static inline bool pud_leaf(pud_t pud) { - return (pud_val(pud) & (_PAGE_PSE | _PAGE_PRESENT)) == - (_PAGE_PSE | _PAGE_PRESENT); + return pud_val(pud) & _PAGE_PSE; } static inline int pud_bad(pud_t pud) -- 2.45.0
[PATCH v2 6/8] mm/x86: arch_check_zapped_pud()
Introduce arch_check_zapped_pud() to sanity check shadow stack on PUD zaps. It has the same logic of the PMD helper. One thing to mention is, it might be a good idea to use page_table_check in the future for trapping wrong setups of shadow stack pgtable entries [1]. That is left for the future as a separate effort. [1] https://lore.kernel.org/all/59d518698f664e07c036a5098833d7b56b953305.ca...@intel.com Cc: "Edgecombe, Rick P" Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Borislav Petkov Cc: Dave Hansen Cc: x...@kernel.org Signed-off-by: Peter Xu --- arch/x86/include/asm/pgtable.h | 10 ++ arch/x86/mm/pgtable.c | 7 +++ include/linux/pgtable.h| 7 +++ mm/huge_memory.c | 4 +++- 4 files changed, 27 insertions(+), 1 deletion(-) diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index 25fc6d809572..cdf044c2ad6e 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h @@ -169,6 +169,13 @@ static inline int pud_young(pud_t pud) return pud_flags(pud) & _PAGE_ACCESSED; } +static inline bool pud_shstk(pud_t pud) +{ + return cpu_feature_enabled(X86_FEATURE_SHSTK) && + (pud_flags(pud) & (_PAGE_RW | _PAGE_DIRTY | _PAGE_PSE)) == + (_PAGE_DIRTY | _PAGE_PSE); +} + static inline int pte_write(pte_t pte) { /* @@ -1662,6 +1669,9 @@ void arch_check_zapped_pte(struct vm_area_struct *vma, pte_t pte); #define arch_check_zapped_pmd arch_check_zapped_pmd void arch_check_zapped_pmd(struct vm_area_struct *vma, pmd_t pmd); +#define arch_check_zapped_pud arch_check_zapped_pud +void arch_check_zapped_pud(struct vm_area_struct *vma, pud_t pud); + #ifdef CONFIG_XEN_PV #define arch_has_hw_nonleaf_pmd_young arch_has_hw_nonleaf_pmd_young static inline bool arch_has_hw_nonleaf_pmd_young(void) diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c index 93e54ba91fbf..564b8945951e 100644 --- a/arch/x86/mm/pgtable.c +++ b/arch/x86/mm/pgtable.c @@ -926,3 +926,10 @@ void arch_check_zapped_pmd(struct vm_area_struct *vma, pmd_t pmd) VM_WARN_ON_ONCE(!(vma->vm_flags & VM_SHADOW_STACK) && pmd_shstk(pmd)); } + +void arch_check_zapped_pud(struct vm_area_struct *vma, pud_t pud) +{ + /* See note in arch_check_zapped_pte() */ + VM_WARN_ON_ONCE(!(vma->vm_flags & VM_SHADOW_STACK) && + pud_shstk(pud)); +} diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h index 2a6a3cccfc36..2289e9f7aa1b 100644 --- a/include/linux/pgtable.h +++ b/include/linux/pgtable.h @@ -447,6 +447,13 @@ static inline void arch_check_zapped_pmd(struct vm_area_struct *vma, } #endif +#ifndef arch_check_zapped_pud +static inline void arch_check_zapped_pud(struct vm_area_struct *vma, +pud_t pud) +{ +} +#endif + #ifndef __HAVE_ARCH_PTEP_GET_AND_CLEAR static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long address, diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 251d6932130f..017377920d18 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -2278,12 +2278,14 @@ int zap_huge_pud(struct mmu_gather *tlb, struct vm_area_struct *vma, pud_t *pud, unsigned long addr) { spinlock_t *ptl; + pud_t orig_pud; ptl = __pud_trans_huge_lock(pud, vma); if (!ptl) return 0; - pudp_huge_get_and_clear_full(vma, addr, pud, tlb->fullmm); + orig_pud = pudp_huge_get_and_clear_full(vma, addr, pud, tlb->fullmm); + arch_check_zapped_pud(vma, orig_pud); tlb_remove_pud_tlb_entry(tlb, pud, addr); if (vma_is_special_huge(vma)) { spin_unlock(ptl); -- 2.45.0
[PATCH v2 7/8] mm/x86: Add missing pud helpers
These new helpers will be needed for pud entry updates soon. Introduce these helpers by referencing the pmd ones. Namely: - pudp_invalidate() - pud_modify() Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Borislav Petkov Cc: Dave Hansen Cc: x...@kernel.org Signed-off-by: Peter Xu --- arch/x86/include/asm/pgtable.h | 55 +- arch/x86/mm/pgtable.c | 11 +++ 2 files changed, 58 insertions(+), 8 deletions(-) diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index cdf044c2ad6e..701593c53f3b 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h @@ -782,6 +782,12 @@ static inline pmd_t pmd_mkinvalid(pmd_t pmd) __pgprot(pmd_flags(pmd) & ~(_PAGE_PRESENT|_PAGE_PROTNONE))); } +static inline pud_t pud_mkinvalid(pud_t pud) +{ + return pfn_pud(pud_pfn(pud), + __pgprot(pud_flags(pud) & ~(_PAGE_PRESENT|_PAGE_PROTNONE))); +} + static inline u64 flip_protnone_guard(u64 oldval, u64 val, u64 mask); static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) @@ -829,14 +835,8 @@ static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot) pmd_result = __pmd(val); /* -* To avoid creating Write=0,Dirty=1 PMDs, pte_modify() needs to avoid: -* 1. Marking Write=0 PMDs Dirty=1 -* 2. Marking Dirty=1 PMDs Write=0 -* -* The first case cannot happen because the _PAGE_CHG_MASK will filter -* out any Dirty bit passed in newprot. Handle the second case by -* going through the mksaveddirty exercise. Only do this if the old -* value was Write=1 to avoid doing this on Shadow Stack PTEs. +* Avoid creating shadow stack PMD by accident. See comment in +* pte_modify(). */ if (oldval & _PAGE_RW) pmd_result = pmd_mksaveddirty(pmd_result); @@ -846,6 +846,29 @@ static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot) return pmd_result; } +static inline pud_t pud_modify(pud_t pud, pgprot_t newprot) +{ + pudval_t val = pud_val(pud), oldval = val; + pud_t pud_result; + + val &= _HPAGE_CHG_MASK; + val |= check_pgprot(newprot) & ~_HPAGE_CHG_MASK; + val = flip_protnone_guard(oldval, val, PHYSICAL_PUD_PAGE_MASK); + + pud_result = __pud(val); + + /* +* Avoid creating shadow stack PUD by accident. See comment in +* pte_modify(). +*/ + if (oldval & _PAGE_RW) + pud_result = pud_mksaveddirty(pud_result); + else + pud_result = pud_clear_saveddirty(pud_result); + + return pud_result; +} + /* * mprotect needs to preserve PAT and encryption bits when updating * vm_page_prot @@ -1384,10 +1407,26 @@ static inline pmd_t pmdp_establish(struct vm_area_struct *vma, } #endif +static inline pud_t pudp_establish(struct vm_area_struct *vma, + unsigned long address, pud_t *pudp, pud_t pud) +{ + page_table_check_pud_set(vma->vm_mm, pudp, pud); + if (IS_ENABLED(CONFIG_SMP)) { + return xchg(pudp, pud); + } else { + pud_t old = *pudp; + WRITE_ONCE(*pudp, pud); + return old; + } +} + #define __HAVE_ARCH_PMDP_INVALIDATE_AD extern pmd_t pmdp_invalidate_ad(struct vm_area_struct *vma, unsigned long address, pmd_t *pmdp); +pud_t pudp_invalidate(struct vm_area_struct *vma, unsigned long address, + pud_t *pudp); + /* * Page table pages are page-aligned. The lower half of the top * level is used for userspace and the top half for the kernel. diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c index 564b8945951e..9d97a1b99160 100644 --- a/arch/x86/mm/pgtable.c +++ b/arch/x86/mm/pgtable.c @@ -641,6 +641,17 @@ pmd_t pmdp_invalidate_ad(struct vm_area_struct *vma, unsigned long address, } #endif +#ifdef CONFIG_TRANSPARENT_HUGEPAGE +pud_t pudp_invalidate(struct vm_area_struct *vma, unsigned long address, +pud_t *pudp) +{ + VM_WARN_ON_ONCE(!pud_present(*pudp)); + pud_t old = pudp_establish(vma, address, pudp, pud_mkinvalid(*pudp)); + flush_pud_tlb_range(vma, address, address + HPAGE_PUD_SIZE); + return old; +} +#endif + /** * reserve_top_address - reserves a hole in the top of kernel address space * @reserve - size of hole to reserve -- 2.45.0
[PATCH v2 8/8] mm/mprotect: fix dax pud handlings
This is only relevant to the two archs that support PUD dax, aka, x86_64 and ppc64. PUD THPs do not yet exist elsewhere, and hugetlb PUDs do not count in this case. DAX have had PUD mappings for years, but change protection path never worked. When the path is triggered in any form (a simple test program would be: call mprotect() on a 1G dev_dax mapping), the kernel will report "bad pud". This patch should fix that. The new change_huge_pud() tries to keep everything simple. For example, it doesn't optimize write bit as that will need even more PUD helpers. It's not too bad anyway to have one more write fault in the worst case once for 1G range; may be a bigger thing for each PAGE_SIZE, though. Neither does it support userfault-wp bits, as there isn't such PUD mappings that is supported; file mappings always need a split there. The same to TLB shootdown: the pmd path (which was for x86 only) has the trick of using _ad() version of pmdp_invalidate*() which can avoid one redundant TLB, but let's also leave that for later. Again, the larger the mapping, the smaller of such effect. Another thing worth mention is this path needs to be careful on handling "retry" event for change_huge_pud() (where it can return 0): it isn't like change_huge_pmd(), as the pmd version is safe with all conditions handled in change_pte_range() later, thanks to Hugh's new pte_offset_map_lock(). In short, change_pte_range() is simply smarter than change_pmd_range() now after the shmem thp collapse rework. For that reason, change_pud_range() will need proper retry if it races with something else when a huge PUD changed from under us. Cc: Dan Williams Cc: Matthew Wilcox Cc: Dave Jiang Cc: Hugh Dickins Cc: Kirill A. Shutemov Cc: Vlastimil Babka Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Borislav Petkov Cc: Dave Hansen Cc: Michael Ellerman Cc: Aneesh Kumar K.V Cc: Oscar Salvador Cc: x...@kernel.org Cc: linuxppc-dev@lists.ozlabs.org Fixes: a00cc7d9dd93 ("mm, x86: add support for PUD-sized transparent hugepages") Fixes: 27af67f35631 ("powerpc/book3s64/mm: enable transparent pud hugepage") Signed-off-by: Peter Xu --- include/linux/huge_mm.h | 24 +++ mm/huge_memory.c| 52 + mm/mprotect.c | 40 --- 3 files changed, 108 insertions(+), 8 deletions(-) diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h index cee3c5da8f0e..2ebebadfbe47 100644 --- a/include/linux/huge_mm.h +++ b/include/linux/huge_mm.h @@ -348,6 +348,17 @@ void split_huge_pmd_address(struct vm_area_struct *vma, unsigned long address, void __split_huge_pud(struct vm_area_struct *vma, pud_t *pud, unsigned long address); +#ifdef CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD +int change_huge_pud(struct mmu_gather *tlb, struct vm_area_struct *vma, + pud_t *pudp, unsigned long addr, pgprot_t newprot, + unsigned long cp_flags); +#else +static inline int +change_huge_pud(struct mmu_gather *tlb, struct vm_area_struct *vma, + pud_t *pudp, unsigned long addr, pgprot_t newprot, + unsigned long cp_flags) { return 0; } +#endif + #define split_huge_pud(__vma, __pud, __address) \ do {\ pud_t *pud = (__pud); \ @@ -591,6 +602,19 @@ static inline int next_order(unsigned long *orders, int prev) { return 0; } + +static inline void __split_huge_pud(struct vm_area_struct *vma, pud_t *pud, + unsigned long address) +{ +} + +static inline int change_huge_pud(struct mmu_gather *tlb, + struct vm_area_struct *vma, pud_t *pudp, + unsigned long addr, pgprot_t newprot, + unsigned long cp_flags) +{ + return 0; +} #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ static inline int split_folio_to_list_to_order(struct folio *folio, diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 017377920d18..4998452f7c49 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -2099,6 +2099,53 @@ int change_huge_pmd(struct mmu_gather *tlb, struct vm_area_struct *vma, return ret; } +/* + * Returns: + * + * - 0: if pud leaf changed from under us + * - 1: if pud can be skipped + * - HPAGE_PUD_NR: if pud was successfully processed + */ +#ifdef CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD +int change_huge_pud(struct mmu_gather *tlb, struct vm_area_struct *vma, + pud_t *pudp, unsigned long addr, pgprot_t newprot, + unsigned long cp_flags) +{ + struct mm_struct *mm = vma->vm_mm; + pud_t oldpud, entry; + spinlock_t *ptl; + + tlb_change_page_size(tlb, HPAGE_PUD_SIZE); + + /* NUMA balancing doesn't apply to dax */ + if (cp_flags & MM_CP_PROT_NUMA) +
Re: [PATCH] perf report: Calling available function for stats printing
On Fri, 28 Jun 2024 14:32:24 -0400, Abhishek Dubey wrote: > For printing dump_trace, just use existing stats_print() > function. > > Applied to perf-tools-next, thanks! Best regards, Namhyung
Re: [PATCH 05/20] clk: sunxi: clk-sun8i-bus-gates: convert to of_property_for_each_u32_new()
On Wed, 03 Jul 2024 12:36:49 +0200 Luca Ceresoli wrote: > Simplify code using of_property_for_each_u32_new() as the two additional > parameters in of_property_for_each_u32() are not used here. > > Signed-off-by: Luca Ceresoli Reviewed-by: Andre Przywara Cheers, Andre > --- > drivers/clk/sunxi/clk-sun8i-bus-gates.c | 4 +--- > 1 file changed, 1 insertion(+), 3 deletions(-) > > diff --git a/drivers/clk/sunxi/clk-sun8i-bus-gates.c > b/drivers/clk/sunxi/clk-sun8i-bus-gates.c > index b87f331f63c9..21f036457a86 100644 > --- a/drivers/clk/sunxi/clk-sun8i-bus-gates.c > +++ b/drivers/clk/sunxi/clk-sun8i-bus-gates.c > @@ -24,11 +24,9 @@ static void __init sun8i_h3_bus_gates_init(struct > device_node *node) > const char *parents[PARENT_MAX]; > struct clk_onecell_data *clk_data; > const char *clk_name; > - struct property *prop; > struct resource res; > void __iomem *clk_reg; > void __iomem *reg; > - const __be32 *p; > int number, i; > u8 clk_bit; > int index; > @@ -58,7 +56,7 @@ static void __init sun8i_h3_bus_gates_init(struct > device_node *node) > goto err_free_data; > > i = 0; > - of_property_for_each_u32(node, "clock-indices", prop, p, index) { > + of_property_for_each_u32_new(node, "clock-indices", index) { > of_property_read_string_index(node, "clock-output-names", > i, &clk_name); > >
Re: [PATCH 04/20] clk: sunxi: clk-simple-gates: convert to of_property_for_each_u32_new()
On Wed, 03 Jul 2024 12:36:48 +0200 Luca Ceresoli wrote: > Simplify code using of_property_for_each_u32_new() as the two additional > parameters in of_property_for_each_u32() are not used here. > > Signed-off-by: Luca Ceresoli Reviewed-by: Andre Przywara Cheers, Andre > --- > drivers/clk/sunxi/clk-simple-gates.c | 4 +--- > 1 file changed, 1 insertion(+), 3 deletions(-) > > diff --git a/drivers/clk/sunxi/clk-simple-gates.c > b/drivers/clk/sunxi/clk-simple-gates.c > index 0399627c226a..a30d14937e0b 100644 > --- a/drivers/clk/sunxi/clk-simple-gates.c > +++ b/drivers/clk/sunxi/clk-simple-gates.c > @@ -21,11 +21,9 @@ static void __init sunxi_simple_gates_setup(struct > device_node *node, > { > struct clk_onecell_data *clk_data; > const char *clk_parent, *clk_name; > - struct property *prop; > struct resource res; > void __iomem *clk_reg; > void __iomem *reg; > - const __be32 *p; > int number, i = 0, j; > u8 clk_bit; > u32 index; > @@ -47,7 +45,7 @@ static void __init sunxi_simple_gates_setup(struct > device_node *node, > if (!clk_data->clks) > goto err_free_data; > > - of_property_for_each_u32(node, "clock-indices", prop, p, index) { > + of_property_for_each_u32_new(node, "clock-indices", index) { > of_property_read_string_index(node, "clock-output-names", > i, &clk_name); > >
Re: [PATCH v2 07/10] soc: fsl: cpm1: qmc: Introduce functions to get a channel from a phandle list
Mark Brown writes: > On Mon, Jul 01, 2024 at 01:30:34PM +0200, Herve Codina wrote: >> qmc_chan_get_byphandle() and the resource managed version retrieve a >> channel from a simple phandle. >> >> Extend the API and introduce qmc_chan_get_byphandles_index() and the >> resource managed version in order to retrieve a channel from a phandle >> list using the provided index to identify the phandle in the list. > > These two PowerPC patches seem trivial enough and have got no response, > unless someone objects I'll go ahead and apply them. Ack. MAINTAINERS says: FREESCALE QUICC ENGINE LIBRARY M: Qiang Zhao L: linuxppc-dev@lists.ozlabs.org S: Maintained F: drivers/soc/fsl/qe/ F: include/soc/fsl/qe/ But I see no email from that address since January 2021: https://lore.kernel.org/all/?q=f%3Aqiang.zhao%40nxp.com And actually drivers/soc/fsl was marked orphan in April, maybe this should be also. Or does Herve want to take over maintaining it? cheers
Re: [PowerPC] [PASEMI] Issue with the identification of ATA drives after the of/irq updates 2024-05-29
On 02.07.24 18:54, Marc Zyngier wrote: On Sun, 30 Jun 2024 11:21:55 +0100, Christian Zigotzky wrote: Hello, There is an issue with the identification of ATA drives with our P.A. Semi Nemo boards [1] after the commit "of/irq: Factor out parsing of interrupt-map parent phandle+args from of_irq_parse_raw()" [2]. [snip] My earlier request for valuable debug information still stands. But while you're at it, can you please give the following hack a go? M. --- a/drivers/of/irq.c +++ b/drivers/of/irq.c @@ -282,8 +282,10 @@ int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq) oldimap = imap; imap = of_irq_parse_imap_parent(oldimap, imaplen, out_irq); - if (!imap) - goto fail; + if (!imap) { + match = 0; + break; + } match &= of_device_is_available(out_irq->np); if (match) This may not be the final workaround even if it solves your boot problem, but will at least give us a hint at what is going wrong. I have the fuzzy feeling that we may be able to lob this broken system as part of the of_irq_imap_abusers[] array, which would solve things pretty "neatly". M. We tested this patch yesterday and it solves the boot problem. Thanks
[PATCH 0/4] cpufreq: Make cpufreq_driver->exit() return void
Make exit() return void, since it isn't used by the core. Based on initial patches sent by Lizhe [1]. Rafael, I will take this through my tree for 6.11. -- Viresh [1] https://lore.kernel.org/all/20240410132132.3526-1-sensor1...@163.com/ Lizhe (1): cpufreq: Make cpufreq_driver->exit() return void Viresh Kumar (3): cpufreq: nforce2: Remove empty exit() callback cpufreq: loongson2: Remove empty exit() callback cpufreq: pcc: Remove empty exit() callback drivers/cpufreq/acpi-cpufreq.c | 4 +--- drivers/cpufreq/amd-pstate.c | 7 ++- drivers/cpufreq/apple-soc-cpufreq.c| 4 +--- drivers/cpufreq/bmips-cpufreq.c| 4 +--- drivers/cpufreq/cppc_cpufreq.c | 3 +-- drivers/cpufreq/cpufreq-dt.c | 3 +-- drivers/cpufreq/cpufreq-nforce2.c | 6 -- drivers/cpufreq/e_powersaver.c | 3 +-- drivers/cpufreq/intel_pstate.c | 8 +++- drivers/cpufreq/loongson2_cpufreq.c| 6 -- drivers/cpufreq/mediatek-cpufreq-hw.c | 4 +--- drivers/cpufreq/mediatek-cpufreq.c | 4 +--- drivers/cpufreq/omap-cpufreq.c | 3 +-- drivers/cpufreq/pasemi-cpufreq.c | 6 ++ drivers/cpufreq/pcc-cpufreq.c | 6 -- drivers/cpufreq/powernow-k6.c | 5 ++--- drivers/cpufreq/powernow-k7.c | 3 +-- drivers/cpufreq/powernow-k8.c | 6 ++ drivers/cpufreq/powernv-cpufreq.c | 4 +--- drivers/cpufreq/ppc_cbe_cpufreq.c | 3 +-- drivers/cpufreq/qcom-cpufreq-hw.c | 4 +--- drivers/cpufreq/qoriq-cpufreq.c| 4 +--- drivers/cpufreq/scmi-cpufreq.c | 4 +--- drivers/cpufreq/scpi-cpufreq.c | 4 +--- drivers/cpufreq/sh-cpufreq.c | 4 +--- drivers/cpufreq/sparc-us2e-cpufreq.c | 3 +-- drivers/cpufreq/sparc-us3-cpufreq.c| 3 +-- drivers/cpufreq/speedstep-centrino.c | 10 +++--- drivers/cpufreq/tegra194-cpufreq.c | 4 +--- drivers/cpufreq/vexpress-spc-cpufreq.c | 5 ++--- include/linux/cpufreq.h| 2 +- 31 files changed, 37 insertions(+), 102 deletions(-) -- 2.31.1.272.g89b43f80a514
[PATCH 4/4] cpufreq: Make cpufreq_driver->exit() return void
From: Lizhe The cpufreq core doesn't check the return type of the exit() callback and there is not much the core can do on failures at that point. Just drop the returned value and make it return void. Signed-off-by: Lizhe [ Viresh: Reworked the patches to fix all missing changes together. ] Signed-off-by: Viresh Kumar --- drivers/cpufreq/acpi-cpufreq.c | 4 +--- drivers/cpufreq/amd-pstate.c | 7 ++- drivers/cpufreq/apple-soc-cpufreq.c| 4 +--- drivers/cpufreq/bmips-cpufreq.c| 4 +--- drivers/cpufreq/cppc_cpufreq.c | 3 +-- drivers/cpufreq/cpufreq-dt.c | 3 +-- drivers/cpufreq/e_powersaver.c | 3 +-- drivers/cpufreq/intel_pstate.c | 8 +++- drivers/cpufreq/mediatek-cpufreq-hw.c | 4 +--- drivers/cpufreq/mediatek-cpufreq.c | 4 +--- drivers/cpufreq/omap-cpufreq.c | 3 +-- drivers/cpufreq/pasemi-cpufreq.c | 6 ++ drivers/cpufreq/powernow-k6.c | 5 ++--- drivers/cpufreq/powernow-k7.c | 3 +-- drivers/cpufreq/powernow-k8.c | 6 ++ drivers/cpufreq/powernv-cpufreq.c | 4 +--- drivers/cpufreq/ppc_cbe_cpufreq.c | 3 +-- drivers/cpufreq/qcom-cpufreq-hw.c | 4 +--- drivers/cpufreq/qoriq-cpufreq.c| 4 +--- drivers/cpufreq/scmi-cpufreq.c | 4 +--- drivers/cpufreq/scpi-cpufreq.c | 4 +--- drivers/cpufreq/sh-cpufreq.c | 4 +--- drivers/cpufreq/sparc-us2e-cpufreq.c | 3 +-- drivers/cpufreq/sparc-us3-cpufreq.c| 3 +-- drivers/cpufreq/speedstep-centrino.c | 10 +++--- drivers/cpufreq/tegra194-cpufreq.c | 4 +--- drivers/cpufreq/vexpress-spc-cpufreq.c | 5 ++--- include/linux/cpufreq.h| 2 +- 28 files changed, 37 insertions(+), 84 deletions(-) diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c index fa2664f9f259..a8ca625a98b8 100644 --- a/drivers/cpufreq/acpi-cpufreq.c +++ b/drivers/cpufreq/acpi-cpufreq.c @@ -906,7 +906,7 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) return result; } -static int acpi_cpufreq_cpu_exit(struct cpufreq_policy *policy) +static void acpi_cpufreq_cpu_exit(struct cpufreq_policy *policy) { struct acpi_cpufreq_data *data = policy->driver_data; @@ -919,8 +919,6 @@ static int acpi_cpufreq_cpu_exit(struct cpufreq_policy *policy) free_cpumask_var(data->freqdomain_cpus); kfree(policy->freq_table); kfree(data); - - return 0; } static int acpi_cpufreq_resume(struct cpufreq_policy *policy) diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c index 80eaa58f1405..c1f48a0d69b6 100644 --- a/drivers/cpufreq/amd-pstate.c +++ b/drivers/cpufreq/amd-pstate.c @@ -1090,7 +1090,7 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy) return ret; } -static int amd_pstate_cpu_exit(struct cpufreq_policy *policy) +static void amd_pstate_cpu_exit(struct cpufreq_policy *policy) { struct amd_cpudata *cpudata = policy->driver_data; @@ -1098,8 +1098,6 @@ static int amd_pstate_cpu_exit(struct cpufreq_policy *policy) freq_qos_remove_request(&cpudata->req[0]); policy->fast_switch_possible = false; kfree(cpudata); - - return 0; } static int amd_pstate_cpu_resume(struct cpufreq_policy *policy) @@ -1542,7 +1540,7 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy) return ret; } -static int amd_pstate_epp_cpu_exit(struct cpufreq_policy *policy) +static void amd_pstate_epp_cpu_exit(struct cpufreq_policy *policy) { struct amd_cpudata *cpudata = policy->driver_data; @@ -1552,7 +1550,6 @@ static int amd_pstate_epp_cpu_exit(struct cpufreq_policy *policy) } pr_debug("CPU %d exiting\n", policy->cpu); - return 0; } static void amd_pstate_epp_update_limit(struct cpufreq_policy *policy) diff --git a/drivers/cpufreq/apple-soc-cpufreq.c b/drivers/cpufreq/apple-soc-cpufreq.c index 021f423705e1..af34c22fa273 100644 --- a/drivers/cpufreq/apple-soc-cpufreq.c +++ b/drivers/cpufreq/apple-soc-cpufreq.c @@ -305,7 +305,7 @@ static int apple_soc_cpufreq_init(struct cpufreq_policy *policy) return ret; } -static int apple_soc_cpufreq_exit(struct cpufreq_policy *policy) +static void apple_soc_cpufreq_exit(struct cpufreq_policy *policy) { struct apple_cpu_priv *priv = policy->driver_data; @@ -313,8 +313,6 @@ static int apple_soc_cpufreq_exit(struct cpufreq_policy *policy) dev_pm_opp_remove_all_dynamic(priv->cpu_dev); iounmap(priv->reg_base); kfree(priv); - - return 0; } static struct cpufreq_driver apple_soc_cpufreq_driver = { diff --git a/drivers/cpufreq/bmips-cpufreq.c b/drivers/cpufreq/bmips-cpufreq.c index 39221a9a187a..17a4c174553d 100644 --- a/drivers/cpufreq/bmips-cpufreq.c +++ b/drivers/cpufreq/bmips-cpufreq.c @@ -121,11 +121,9 @@ static int bmips_cpufreq_target_index(struct cpufreq_policy *policy,