diff mbox series

iommu: fix ARM_SMMU vs QCOM_SCM compilation

Message ID 20211010023350.978638-1-dmitry.baryshkov@linaro.org (mailing list archive)
State Not Applicable
Headers show
Series iommu: fix ARM_SMMU vs QCOM_SCM compilation | expand

Commit Message

Dmitry Baryshkov Oct. 10, 2021, 2:33 a.m. UTC
After commit 424953cf3c66 ("qcom_scm: hide Kconfig symbol") arm-smmu got
qcom_smmu_impl_init() call guarded by IS_ENABLED(CONFIG_ARM_SMMU_QCOM).
However the CONFIG_ARM_SMMU_QCOM Kconfig entry does not exist, so the
qcom_smmu_impl_init() is never called.

So, let's fix this by always calling qcom_smmu_impl_init(). It does not
touch the smmu passed unless the device is a non-Qualcomm one. Make
ARM_SMMU select QCOM_SCM for ARCH_QCOM.

Fixes: 424953cf3c66 ("qcom_scm: hide Kconfig symbol")
Cc: Arnd Bergmann <arnd@arndb.de>
Reported-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/iommu/Kconfig                      | 1 +
 drivers/iommu/arm/arm-smmu/Makefile        | 3 +--
 drivers/iommu/arm/arm-smmu/arm-smmu-impl.c | 9 +++++++--
 3 files changed, 9 insertions(+), 4 deletions(-)

Comments

Bjorn Andersson Oct. 10, 2021, 4:16 a.m. UTC | #1
On Sat 09 Oct 21:33 CDT 2021, Dmitry Baryshkov wrote:

> After commit 424953cf3c66 ("qcom_scm: hide Kconfig symbol") arm-smmu got
> qcom_smmu_impl_init() call guarded by IS_ENABLED(CONFIG_ARM_SMMU_QCOM).
> However the CONFIG_ARM_SMMU_QCOM Kconfig entry does not exist, so the
> qcom_smmu_impl_init() is never called.
> 
> So, let's fix this by always calling qcom_smmu_impl_init(). It does not
> touch the smmu passed unless the device is a non-Qualcomm one. Make
> ARM_SMMU select QCOM_SCM for ARCH_QCOM.
> 

Arnd's intention was to not force QCOM_SCM to be built on non-Qualcomm
devices. But as Daniel experienced, attempting to boot most Qualcomm
boards without this results in a instant reboot.

I think it's okay if we tinker with CONFIG_ARM_SMMU_QCOM for v5.16, but
we're getting late in v5.15 so I would prefer if we make sure this works
out of the box.

Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>

Regards,
Bjorn

> Fixes: 424953cf3c66 ("qcom_scm: hide Kconfig symbol")
> Cc: Arnd Bergmann <arnd@arndb.de>
> Reported-by: Daniel Lezcano <daniel.lezcano@linaro.org>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
>  drivers/iommu/Kconfig                      | 1 +
>  drivers/iommu/arm/arm-smmu/Makefile        | 3 +--
>  drivers/iommu/arm/arm-smmu/arm-smmu-impl.c | 9 +++++++--
>  3 files changed, 9 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
> index c5c71b7ab7e8..a4593e53fe7d 100644
> --- a/drivers/iommu/Kconfig
> +++ b/drivers/iommu/Kconfig
> @@ -309,6 +309,7 @@ config ARM_SMMU
>  	tristate "ARM Ltd. System MMU (SMMU) Support"
>  	depends on ARM64 || ARM || (COMPILE_TEST && !GENERIC_ATOMIC64)
>  	select IOMMU_API
> +	select QCOM_SCM
>  	select IOMMU_IO_PGTABLE_LPAE
>  	select ARM_DMA_USE_IOMMU if ARM
>  	help
> diff --git a/drivers/iommu/arm/arm-smmu/Makefile b/drivers/iommu/arm/arm-smmu/Makefile
> index b0cc01aa20c9..e240a7bcf310 100644
> --- a/drivers/iommu/arm/arm-smmu/Makefile
> +++ b/drivers/iommu/arm/arm-smmu/Makefile
> @@ -1,5 +1,4 @@
>  # SPDX-License-Identifier: GPL-2.0
>  obj-$(CONFIG_QCOM_IOMMU) += qcom_iommu.o
>  obj-$(CONFIG_ARM_SMMU) += arm_smmu.o
> -arm_smmu-objs += arm-smmu.o arm-smmu-impl.o arm-smmu-nvidia.o
> -arm_smmu-$(CONFIG_ARM_SMMU_QCOM) += arm-smmu-qcom.o
> +arm_smmu-objs += arm-smmu.o arm-smmu-impl.o arm-smmu-nvidia.o arm-smmu-qcom.o
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c b/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c
> index 2c25cce38060..8199185dd262 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c
> @@ -215,8 +215,13 @@ struct arm_smmu_device *arm_smmu_impl_init(struct arm_smmu_device *smmu)
>  	    of_device_is_compatible(np, "nvidia,tegra186-smmu"))
>  		return nvidia_smmu_impl_init(smmu);
>  
> -	if (IS_ENABLED(CONFIG_ARM_SMMU_QCOM))
> -		smmu = qcom_smmu_impl_init(smmu);
> +	/*
> +	 * qcom_smmu_impl_init() will not touch smmu if the device is not
> +	 * a Qualcomm one.
> +	 */
> +	smmu = qcom_smmu_impl_init(smmu);
> +	if (IS_ERR(smmu))
> +		return smmu;
>  
>  	if (of_device_is_compatible(np, "marvell,ap806-smmu-500"))
>  		smmu->impl = &mrvl_mmu500_impl;
> -- 
> 2.30.2
>
Steev Klimaszewski Oct. 10, 2021, 4:34 a.m. UTC | #2
On 10/9/21 9:33 PM, Dmitry Baryshkov wrote:
> After commit 424953cf3c66 ("qcom_scm: hide Kconfig symbol") arm-smmu got
> qcom_smmu_impl_init() call guarded by IS_ENABLED(CONFIG_ARM_SMMU_QCOM).
> However the CONFIG_ARM_SMMU_QCOM Kconfig entry does not exist, so the
> qcom_smmu_impl_init() is never called.
>
> So, let's fix this by always calling qcom_smmu_impl_init(). It does not
> touch the smmu passed unless the device is a non-Qualcomm one. Make
> ARM_SMMU select QCOM_SCM for ARCH_QCOM.
>
> Fixes: 424953cf3c66 ("qcom_scm: hide Kconfig symbol")
> Cc: Arnd Bergmann <arnd@arndb.de>
> Reported-by: Daniel Lezcano <daniel.lezcano@linaro.org>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
>   drivers/iommu/Kconfig                      | 1 +
>   drivers/iommu/arm/arm-smmu/Makefile        | 3 +--
>   drivers/iommu/arm/arm-smmu/arm-smmu-impl.c | 9 +++++++--
>   3 files changed, 9 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
> index c5c71b7ab7e8..a4593e53fe7d 100644
> --- a/drivers/iommu/Kconfig
> +++ b/drivers/iommu/Kconfig
> @@ -309,6 +309,7 @@ config ARM_SMMU
>   	tristate "ARM Ltd. System MMU (SMMU) Support"
>   	depends on ARM64 || ARM || (COMPILE_TEST && !GENERIC_ATOMIC64)
>   	select IOMMU_API
> +	select QCOM_SCM
>   	select IOMMU_IO_PGTABLE_LPAE
>   	select ARM_DMA_USE_IOMMU if ARM
>   	help
> diff --git a/drivers/iommu/arm/arm-smmu/Makefile b/drivers/iommu/arm/arm-smmu/Makefile
> index b0cc01aa20c9..e240a7bcf310 100644
> --- a/drivers/iommu/arm/arm-smmu/Makefile
> +++ b/drivers/iommu/arm/arm-smmu/Makefile
> @@ -1,5 +1,4 @@
>   # SPDX-License-Identifier: GPL-2.0
>   obj-$(CONFIG_QCOM_IOMMU) += qcom_iommu.o
>   obj-$(CONFIG_ARM_SMMU) += arm_smmu.o
> -arm_smmu-objs += arm-smmu.o arm-smmu-impl.o arm-smmu-nvidia.o
> -arm_smmu-$(CONFIG_ARM_SMMU_QCOM) += arm-smmu-qcom.o
> +arm_smmu-objs += arm-smmu.o arm-smmu-impl.o arm-smmu-nvidia.o arm-smmu-qcom.o
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c b/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c
> index 2c25cce38060..8199185dd262 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c
> @@ -215,8 +215,13 @@ struct arm_smmu_device *arm_smmu_impl_init(struct arm_smmu_device *smmu)
>   	    of_device_is_compatible(np, "nvidia,tegra186-smmu"))
>   		return nvidia_smmu_impl_init(smmu);
>   
> -	if (IS_ENABLED(CONFIG_ARM_SMMU_QCOM))
> -		smmu = qcom_smmu_impl_init(smmu);
> +	/*
> +	 * qcom_smmu_impl_init() will not touch smmu if the device is not
> +	 * a Qualcomm one.
> +	 */
> +	smmu = qcom_smmu_impl_init(smmu);
> +	if (IS_ERR(smmu))
> +		return smmu;
>   
>   	if (of_device_is_compatible(np, "marvell,ap806-smmu-500"))
>   		smmu->impl = &mrvl_mmu500_impl;

Without this applied, my Lenovo Yoga C630 just boot loops with 
424953cf3c66 applied when it gets to the smmu.  This fixes it.

Tested-By: Steev Klimaszewski <steev@kali.org>
Arnd Bergmann Oct. 10, 2021, 5:42 p.m. UTC | #3
On Sun, Oct 10, 2021 at 6:17 AM Bjorn Andersson
<bjorn.andersson@linaro.org> wrote:
>
> On Sat 09 Oct 21:33 CDT 2021, Dmitry Baryshkov wrote:
>
> > After commit 424953cf3c66 ("qcom_scm: hide Kconfig symbol") arm-smmu got
> > qcom_smmu_impl_init() call guarded by IS_ENABLED(CONFIG_ARM_SMMU_QCOM).
> > However the CONFIG_ARM_SMMU_QCOM Kconfig entry does not exist, so the
> > qcom_smmu_impl_init() is never called.
> >
> > So, let's fix this by always calling qcom_smmu_impl_init(). It does not
> > touch the smmu passed unless the device is a non-Qualcomm one. Make
> > ARM_SMMU select QCOM_SCM for ARCH_QCOM.

Sorry about this bug. I was sure I had it working, but I lost part of the commit
during a rebase, and my randconfig builds still succeeded without it, so I
sent a wrong version.

> Arnd's intention was to not force QCOM_SCM to be built on non-Qualcomm
> devices. But as Daniel experienced, attempting to boot most Qualcomm
> boards without this results in a instant reboot.
>
> I think it's okay if we tinker with CONFIG_ARM_SMMU_QCOM for v5.16, but
> we're getting late in v5.15 so I would prefer if we make sure this works
> out of the box.

Yes, makes sense. For reference, see below for how I would fix this properly,
this is what I had intended to have in the patch. Feel free to pick
either version
as the immediate bugfix. I'll give the below a little more randconfig testing
overnight though. The pasted version of the patch is probably
whitespace-damaged,
let me know if you would like me to send it as a proper patch.

       Arnd

8<-----
Subject: iommu: fix ARM_SMMU_QCOM compilation

My previous bugfix ended up making things worse for the QCOM IOMMU
driver when it forgot to add the Kconfig symbol that is getting used to
control the compilation of the SMMU implementation specific code
for Qualcomm.

Fixes: 424953cf3c66 ("qcom_scm: hide Kconfig symbol")
Reported-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Reported-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
----
diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index c5c71b7ab7e8..2dfe744ddd97 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -311,6 +311,7 @@ config ARM_SMMU
        select IOMMU_API
        select IOMMU_IO_PGTABLE_LPAE
        select ARM_DMA_USE_IOMMU if ARM
+       select QCOM_SCM if ARM_SMMU_QCOM
        help
          Support for implementations of the ARM System MMU architecture
          versions 1 and 2.
@@ -355,6 +356,13 @@ config ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT
          'arm-smmu.disable_bypass' will continue to override this
          config.

+config ARM_SMMU_QCOM
+       def_bool y
+       depends on ARM_SMMU && ARCH_QCOM
+       help
+         When running on a Qualcomm platform that has the custom variant
+         of the ARM SMMU, this needs to be built into the SMMU driver.
+
 config ARM_SMMU_V3
        tristate "ARM Ltd. System MMU Version 3 (SMMUv3) Support"
        depends on ARM64
Steev Klimaszewski Oct. 11, 2021, 4:06 a.m. UTC | #4
On 10/10/21 12:42 PM, Arnd Bergmann wrote:
> On Sun, Oct 10, 2021 at 6:17 AM Bjorn Andersson
> <bjorn.andersson@linaro.org> wrote:
>> On Sat 09 Oct 21:33 CDT 2021, Dmitry Baryshkov wrote:
>>
>>> After commit 424953cf3c66 ("qcom_scm: hide Kconfig symbol") arm-smmu got
>>> qcom_smmu_impl_init() call guarded by IS_ENABLED(CONFIG_ARM_SMMU_QCOM).
>>> However the CONFIG_ARM_SMMU_QCOM Kconfig entry does not exist, so the
>>> qcom_smmu_impl_init() is never called.
>>>
>>> So, let's fix this by always calling qcom_smmu_impl_init(). It does not
>>> touch the smmu passed unless the device is a non-Qualcomm one. Make
>>> ARM_SMMU select QCOM_SCM for ARCH_QCOM.
> Sorry about this bug. I was sure I had it working, but I lost part of the commit
> during a rebase, and my randconfig builds still succeeded without it, so I
> sent a wrong version.
>
>> Arnd's intention was to not force QCOM_SCM to be built on non-Qualcomm
>> devices. But as Daniel experienced, attempting to boot most Qualcomm
>> boards without this results in a instant reboot.
>>
>> I think it's okay if we tinker with CONFIG_ARM_SMMU_QCOM for v5.16, but
>> we're getting late in v5.15 so I would prefer if we make sure this works
>> out of the box.
> Yes, makes sense. For reference, see below for how I would fix this properly,
> this is what I had intended to have in the patch. Feel free to pick
> either version
> as the immediate bugfix. I'll give the below a little more randconfig testing
> overnight though. The pasted version of the patch is probably
> whitespace-damaged,
> let me know if you would like me to send it as a proper patch.
>
>         Arnd
>
> 8<-----
> Subject: iommu: fix ARM_SMMU_QCOM compilation
>
> My previous bugfix ended up making things worse for the QCOM IOMMU
> driver when it forgot to add the Kconfig symbol that is getting used to
> control the compilation of the SMMU implementation specific code
> for Qualcomm.
>
> Fixes: 424953cf3c66 ("qcom_scm: hide Kconfig symbol")
> Reported-by: Daniel Lezcano <daniel.lezcano@linaro.org>
> Reported-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> ----
> diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
> index c5c71b7ab7e8..2dfe744ddd97 100644
> --- a/drivers/iommu/Kconfig
> +++ b/drivers/iommu/Kconfig
> @@ -311,6 +311,7 @@ config ARM_SMMU
>          select IOMMU_API
>          select IOMMU_IO_PGTABLE_LPAE
>          select ARM_DMA_USE_IOMMU if ARM
> +       select QCOM_SCM if ARM_SMMU_QCOM
>          help
>            Support for implementations of the ARM System MMU architecture
>            versions 1 and 2.
> @@ -355,6 +356,13 @@ config ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT
>            'arm-smmu.disable_bypass' will continue to override this
>            config.
>
> +config ARM_SMMU_QCOM
> +       def_bool y
> +       depends on ARM_SMMU && ARCH_QCOM
> +       help
> +         When running on a Qualcomm platform that has the custom variant
> +         of the ARM SMMU, this needs to be built into the SMMU driver.
> +
>   config ARM_SMMU_V3
>          tristate "ARM Ltd. System MMU Version 3 (SMMUv3) Support"
>          depends on ARM64

FWIW, I tested this patch on the Lenovo Yoga C630 with Dmitry's patch 
backed out, and this does the right thing as well.

So if we go this route instead of the other patch, Tested-By: Steev 
Klimaszewski <steev@kali.org>
Dmitry Baryshkov Oct. 11, 2021, 4:11 a.m. UTC | #5
On Sun, 10 Oct 2021 at 20:42, Arnd Bergmann <arnd@arndb.de> wrote:
>
> On Sun, Oct 10, 2021 at 6:17 AM Bjorn Andersson
> <bjorn.andersson@linaro.org> wrote:
> >
> > On Sat 09 Oct 21:33 CDT 2021, Dmitry Baryshkov wrote:
> >
> > > After commit 424953cf3c66 ("qcom_scm: hide Kconfig symbol") arm-smmu got
> > > qcom_smmu_impl_init() call guarded by IS_ENABLED(CONFIG_ARM_SMMU_QCOM).
> > > However the CONFIG_ARM_SMMU_QCOM Kconfig entry does not exist, so the
> > > qcom_smmu_impl_init() is never called.
> > >
> > > So, let's fix this by always calling qcom_smmu_impl_init(). It does not
> > > touch the smmu passed unless the device is a non-Qualcomm one. Make
> > > ARM_SMMU select QCOM_SCM for ARCH_QCOM.
>
> Sorry about this bug. I was sure I had it working, but I lost part of the commit
> during a rebase, and my randconfig builds still succeeded without it, so I
> sent a wrong version.
>
> > Arnd's intention was to not force QCOM_SCM to be built on non-Qualcomm
> > devices. But as Daniel experienced, attempting to boot most Qualcomm
> > boards without this results in a instant reboot.
> >
> > I think it's okay if we tinker with CONFIG_ARM_SMMU_QCOM for v5.16, but
> > we're getting late in v5.15 so I would prefer if we make sure this works
> > out of the box.
>
> Yes, makes sense. For reference, see below for how I would fix this properly,
> this is what I had intended to have in the patch. Feel free to pick
> either version
> as the immediate bugfix. I'll give the below a little more randconfig testing
> overnight though. The pasted version of the patch is probably
> whitespace-damaged,
> let me know if you would like me to send it as a proper patch.
>
>        Arnd
>
> 8<-----
> Subject: iommu: fix ARM_SMMU_QCOM compilation
>
> My previous bugfix ended up making things worse for the QCOM IOMMU
> driver when it forgot to add the Kconfig symbol that is getting used to
> control the compilation of the SMMU implementation specific code
> for Qualcomm.
>
> Fixes: 424953cf3c66 ("qcom_scm: hide Kconfig symbol")
> Reported-by: Daniel Lezcano <daniel.lezcano@linaro.org>
> Reported-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> ----
> diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
> index c5c71b7ab7e8..2dfe744ddd97 100644
> --- a/drivers/iommu/Kconfig
> +++ b/drivers/iommu/Kconfig
> @@ -311,6 +311,7 @@ config ARM_SMMU
>         select IOMMU_API
>         select IOMMU_IO_PGTABLE_LPAE
>         select ARM_DMA_USE_IOMMU if ARM
> +       select QCOM_SCM if ARM_SMMU_QCOM
>         help
>           Support for implementations of the ARM System MMU architecture
>           versions 1 and 2.
> @@ -355,6 +356,13 @@ config ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT
>           'arm-smmu.disable_bypass' will continue to override this
>           config.
>
> +config ARM_SMMU_QCOM
> +       def_bool y
> +       depends on ARM_SMMU && ARCH_QCOM
> +       help
> +         When running on a Qualcomm platform that has the custom variant
> +         of the ARM SMMU, this needs to be built into the SMMU driver.
> +
>  config ARM_SMMU_V3
>         tristate "ARM Ltd. System MMU Version 3 (SMMUv3) Support"
>         depends on ARM64

The patch seems correct, but it becomes overcomplicated. What about:
- restoring QCOM_SCM stubs
- making ARM_SMMU select QCOM_SCM if ARM_SMMU_QCOM

This would have almost the same result as with your patch, but without
extra ARM_SMMU_QCOM Kconfig symbol.
Arnd Bergmann Oct. 11, 2021, 6:08 a.m. UTC | #6
On Mon, Oct 11, 2021 at 6:11 AM Dmitry Baryshkov
<dmitry.baryshkov@linaro.org> wrote:
> On Sun, 10 Oct 2021 at 20:42, Arnd Bergmann <arnd@arndb.de> wrote:
>
> The patch seems correct, but it becomes overcomplicated. What about:
> - restoring QCOM_SCM stubs

The stubs are what has led to the previous bugs in this area to often
go unnoticed for too long, as illustrated by your suggestion

> - making ARM_SMMU select QCOM_SCM if ARM_SMMU_QCOM

I assume you meant "select QCOM_SCM if ARCH_QCOM",
after we stop using ARM_SMMU_QCOM?

> This would have almost the same result as with your patch, but without
> extra ARM_SMMU_QCOM Kconfig symbol.

The "almost" is the problem: consider the case of

CONFIG_ARM=y
CONFIG_COMPILE_TEST=y
CONFIG_ARCH_QCOM=n
CONFIG_ARM_SMMU=y
CONFIG_DRM_MSM=m
CONFIG_QCOM_SCM=m (selected by DRM_MSM)

The stubs here lead to ARM_SMMU linking against the QCOM_SCM
driver from built-in code, which fails because QCOM_SCM itself
is a loadable module.

We can move the "select QCOM_SCM" in the ARM_SMMU_QCOM
symbol if we make that a tristate though, if you want to separate it
a little more.

        Arnd
Dmitry Baryshkov Oct. 11, 2021, 9:09 a.m. UTC | #7
On Mon, 11 Oct 2021 at 09:09, Arnd Bergmann <arnd@arndb.de> wrote:
>
> On Mon, Oct 11, 2021 at 6:11 AM Dmitry Baryshkov
> <dmitry.baryshkov@linaro.org> wrote:
> > On Sun, 10 Oct 2021 at 20:42, Arnd Bergmann <arnd@arndb.de> wrote:
> >
> > The patch seems correct, but it becomes overcomplicated. What about:
> > - restoring QCOM_SCM stubs
>
> The stubs are what has led to the previous bugs in this area to often
> go unnoticed for too long, as illustrated by your suggestion
>
> > - making ARM_SMMU select QCOM_SCM if ARM_SMMU_QCOM
>
> I assume you meant "select QCOM_SCM if ARCH_QCOM",
> after we stop using ARM_SMMU_QCOM?
>
> > This would have almost the same result as with your patch, but without
> > extra ARM_SMMU_QCOM Kconfig symbol.
>
> The "almost" is the problem: consider the case of
>
> CONFIG_ARM=y
> CONFIG_COMPILE_TEST=y
> CONFIG_ARCH_QCOM=n
> CONFIG_ARM_SMMU=y
> CONFIG_DRM_MSM=m
> CONFIG_QCOM_SCM=m (selected by DRM_MSM)
>
> The stubs here lead to ARM_SMMU linking against the QCOM_SCM
> driver from built-in code, which fails because QCOM_SCM itself
> is a loadable module.

I see. The idealist in me wishes to change my suggestion to
'select QCOM_SCM if ARCH_QCOM || COMPILE_TEST'
but I have the subtle feeling that this also might fail somehow.

>
> We can move the "select QCOM_SCM" in the ARM_SMMU_QCOM
> symbol if we make that a tristate though, if you want to separate it
> a little more.

This would complicate things a bit, as we would no longer be able to
use 'arm-smmu-$(CONFIG_ARM_SMMU_QCOM) +=' construct.
Arnd Bergmann Oct. 11, 2021, 9:56 a.m. UTC | #8
On Mon, Oct 11, 2021 at 11:10 AM Dmitry Baryshkov
<dmitry.baryshkov@linaro.org> wrote:
>
> On Mon, 11 Oct 2021 at 09:09, Arnd Bergmann <arnd@arndb.de> wrote:
> >
> > On Mon, Oct 11, 2021 at 6:11 AM Dmitry Baryshkov
> > <dmitry.baryshkov@linaro.org> wrote:
> > > On Sun, 10 Oct 2021 at 20:42, Arnd Bergmann <arnd@arndb.de> wrote:
> > >
> > > The patch seems correct, but it becomes overcomplicated. What about:
> > > - restoring QCOM_SCM stubs
> >
> > The stubs are what has led to the previous bugs in this area to often
> > go unnoticed for too long, as illustrated by your suggestion
> >
> > > - making ARM_SMMU select QCOM_SCM if ARM_SMMU_QCOM
> >
> > I assume you meant "select QCOM_SCM if ARCH_QCOM",
> > after we stop using ARM_SMMU_QCOM?
> >
> > > This would have almost the same result as with your patch, but without
> > > extra ARM_SMMU_QCOM Kconfig symbol.
> >
> > The "almost" is the problem: consider the case of
> >
> > CONFIG_ARM=y
> > CONFIG_COMPILE_TEST=y
> > CONFIG_ARCH_QCOM=n
> > CONFIG_ARM_SMMU=y
> > CONFIG_DRM_MSM=m
> > CONFIG_QCOM_SCM=m (selected by DRM_MSM)
> >
> > The stubs here lead to ARM_SMMU linking against the QCOM_SCM
> > driver from built-in code, which fails because QCOM_SCM itself
> > is a loadable module.
>
> I see. The idealist in me wishes to change my suggestion to
> 'select QCOM_SCM if ARCH_QCOM || COMPILE_TEST'
> but I have the subtle feeling that this also might fail somehow.

I think that would actually work, but it has the nasty side-effect
that simply flipping 'CONFIG_COMPILE_TEST' changes what
the kernel does, rather than just hiding or unhiding additional
options.

> > We can move the "select QCOM_SCM" in the ARM_SMMU_QCOM
> > symbol if we make that a tristate though, if you want to separate it
> > a little more.
>
> This would complicate things a bit, as we would no longer be able to
> use 'arm-smmu-$(CONFIG_ARM_SMMU_QCOM) +=' construct.

I'm fairly sure we could still use that, Kbuild is smart enough
to include both 'file-m +=' and 'file-y += ' in 'file.ko', see
scripts/Makefile.lib:

# If $(foo-objs), $(foo-y), $(foo-m), or $(foo-) exists, foo.o is a
composite object
multi-obj-y := $(call multi-search, $(obj-y), .o, -objs -y)
multi-obj-m := $(call multi-search, $(obj-m), .o, -objs -y -m)
multi-obj-ym := $(multi-obj-y) $(multi-obj-m)

# Replace multi-part objects by their individual parts,
# including built-in.a from subdirectories
real-obj-y := $(call real-search, $(obj-y), .o, -objs -y)
real-obj-m := $(call real-search, $(obj-m), .o, -objs -y -m)

What doesn't work is having a built-in driver in a directory that is
guarded with a =m symbol, or including a =m object into a =y
module.

        Arnd
Dmitry Baryshkov Oct. 12, 2021, 3:34 a.m. UTC | #9
On Mon, 11 Oct 2021 at 12:57, Arnd Bergmann <arnd@arndb.de> wrote:
>
> On Mon, Oct 11, 2021 at 11:10 AM Dmitry Baryshkov
> <dmitry.baryshkov@linaro.org> wrote:
> >
> > On Mon, 11 Oct 2021 at 09:09, Arnd Bergmann <arnd@arndb.de> wrote:
> > >
> > > On Mon, Oct 11, 2021 at 6:11 AM Dmitry Baryshkov
> > > <dmitry.baryshkov@linaro.org> wrote:
> > > > On Sun, 10 Oct 2021 at 20:42, Arnd Bergmann <arnd@arndb.de> wrote:
> > > >
> > > > The patch seems correct, but it becomes overcomplicated. What about:
> > > > - restoring QCOM_SCM stubs
> > >
> > > The stubs are what has led to the previous bugs in this area to often
> > > go unnoticed for too long, as illustrated by your suggestion
> > >
> > > > - making ARM_SMMU select QCOM_SCM if ARM_SMMU_QCOM
> > >
> > > I assume you meant "select QCOM_SCM if ARCH_QCOM",
> > > after we stop using ARM_SMMU_QCOM?
> > >
> > > > This would have almost the same result as with your patch, but without
> > > > extra ARM_SMMU_QCOM Kconfig symbol.
> > >
> > > The "almost" is the problem: consider the case of
> > >
> > > CONFIG_ARM=y
> > > CONFIG_COMPILE_TEST=y
> > > CONFIG_ARCH_QCOM=n
> > > CONFIG_ARM_SMMU=y
> > > CONFIG_DRM_MSM=m
> > > CONFIG_QCOM_SCM=m (selected by DRM_MSM)
> > >
> > > The stubs here lead to ARM_SMMU linking against the QCOM_SCM
> > > driver from built-in code, which fails because QCOM_SCM itself
> > > is a loadable module.
> >
> > I see. The idealist in me wishes to change my suggestion to
> > 'select QCOM_SCM if ARCH_QCOM || COMPILE_TEST'
> > but I have the subtle feeling that this also might fail somehow.
>
> I think that would actually work, but it has the nasty side-effect
> that simply flipping 'CONFIG_COMPILE_TEST' changes what
> the kernel does, rather than just hiding or unhiding additional
> options.
>
> > > We can move the "select QCOM_SCM" in the ARM_SMMU_QCOM
> > > symbol if we make that a tristate though, if you want to separate it
> > > a little more.
> >
> > This would complicate things a bit, as we would no longer be able to
> > use 'arm-smmu-$(CONFIG_ARM_SMMU_QCOM) +=' construct.
>
> I'm fairly sure we could still use that, Kbuild is smart enough
> to include both 'file-m +=' and 'file-y += ' in 'file.ko', see
> scripts/Makefile.lib:
>
> # If $(foo-objs), $(foo-y), $(foo-m), or $(foo-) exists, foo.o is a
> composite object
> multi-obj-y := $(call multi-search, $(obj-y), .o, -objs -y)
> multi-obj-m := $(call multi-search, $(obj-m), .o, -objs -y -m)
> multi-obj-ym := $(multi-obj-y) $(multi-obj-m)
>
> # Replace multi-part objects by their individual parts,
> # including built-in.a from subdirectories
> real-obj-y := $(call real-search, $(obj-y), .o, -objs -y)
> real-obj-m := $(call real-search, $(obj-m), .o, -objs -y -m)

Ah, I thought Kbuild would accept only  foo-y, please excuse me.

>
> What doesn't work is having a built-in driver in a directory that is
> guarded with a =m symbol, or including a =m object into a =y
> module.
>
>         Arnd
Dmitry Baryshkov Oct. 12, 2021, 3:35 a.m. UTC | #10
On Sun, 10 Oct 2021 at 20:42, Arnd Bergmann <arnd@arndb.de> wrote:
>
> On Sun, Oct 10, 2021 at 6:17 AM Bjorn Andersson
> <bjorn.andersson@linaro.org> wrote:
> >
> > On Sat 09 Oct 21:33 CDT 2021, Dmitry Baryshkov wrote:
> >
> > > After commit 424953cf3c66 ("qcom_scm: hide Kconfig symbol") arm-smmu got
> > > qcom_smmu_impl_init() call guarded by IS_ENABLED(CONFIG_ARM_SMMU_QCOM).
> > > However the CONFIG_ARM_SMMU_QCOM Kconfig entry does not exist, so the
> > > qcom_smmu_impl_init() is never called.
> > >
> > > So, let's fix this by always calling qcom_smmu_impl_init(). It does not
> > > touch the smmu passed unless the device is a non-Qualcomm one. Make
> > > ARM_SMMU select QCOM_SCM for ARCH_QCOM.
>
> Sorry about this bug. I was sure I had it working, but I lost part of the commit
> during a rebase, and my randconfig builds still succeeded without it, so I
> sent a wrong version.
>
> > Arnd's intention was to not force QCOM_SCM to be built on non-Qualcomm
> > devices. But as Daniel experienced, attempting to boot most Qualcomm
> > boards without this results in a instant reboot.
> >
> > I think it's okay if we tinker with CONFIG_ARM_SMMU_QCOM for v5.16, but
> > we're getting late in v5.15 so I would prefer if we make sure this works
> > out of the box.
>
> Yes, makes sense. For reference, see below for how I would fix this properly,
> this is what I had intended to have in the patch. Feel free to pick
> either version
> as the immediate bugfix. I'll give the below a little more randconfig testing
> overnight though. The pasted version of the patch is probably
> whitespace-damaged,
> let me know if you would like me to send it as a proper patch.
>
>        Arnd
>
> 8<-----
> Subject: iommu: fix ARM_SMMU_QCOM compilation
>
> My previous bugfix ended up making things worse for the QCOM IOMMU
> driver when it forgot to add the Kconfig symbol that is getting used to
> control the compilation of the SMMU implementation specific code
> for Qualcomm.
>
> Fixes: 424953cf3c66 ("qcom_scm: hide Kconfig symbol")
> Reported-by: Daniel Lezcano <daniel.lezcano@linaro.org>
> Reported-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>

Let's get either of them in.

> ----
> diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
> index c5c71b7ab7e8..2dfe744ddd97 100644
> --- a/drivers/iommu/Kconfig
> +++ b/drivers/iommu/Kconfig
> @@ -311,6 +311,7 @@ config ARM_SMMU
>         select IOMMU_API
>         select IOMMU_IO_PGTABLE_LPAE
>         select ARM_DMA_USE_IOMMU if ARM
> +       select QCOM_SCM if ARM_SMMU_QCOM
>         help
>           Support for implementations of the ARM System MMU architecture
>           versions 1 and 2.
> @@ -355,6 +356,13 @@ config ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT
>           'arm-smmu.disable_bypass' will continue to override this
>           config.
>
> +config ARM_SMMU_QCOM
> +       def_bool y
> +       depends on ARM_SMMU && ARCH_QCOM
> +       help
> +         When running on a Qualcomm platform that has the custom variant
> +         of the ARM SMMU, this needs to be built into the SMMU driver.
> +
>  config ARM_SMMU_V3
>         tristate "ARM Ltd. System MMU Version 3 (SMMUv3) Support"
>         depends on ARM64
diff mbox series

Patch

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index c5c71b7ab7e8..a4593e53fe7d 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -309,6 +309,7 @@  config ARM_SMMU
 	tristate "ARM Ltd. System MMU (SMMU) Support"
 	depends on ARM64 || ARM || (COMPILE_TEST && !GENERIC_ATOMIC64)
 	select IOMMU_API
+	select QCOM_SCM
 	select IOMMU_IO_PGTABLE_LPAE
 	select ARM_DMA_USE_IOMMU if ARM
 	help
diff --git a/drivers/iommu/arm/arm-smmu/Makefile b/drivers/iommu/arm/arm-smmu/Makefile
index b0cc01aa20c9..e240a7bcf310 100644
--- a/drivers/iommu/arm/arm-smmu/Makefile
+++ b/drivers/iommu/arm/arm-smmu/Makefile
@@ -1,5 +1,4 @@ 
 # SPDX-License-Identifier: GPL-2.0
 obj-$(CONFIG_QCOM_IOMMU) += qcom_iommu.o
 obj-$(CONFIG_ARM_SMMU) += arm_smmu.o
-arm_smmu-objs += arm-smmu.o arm-smmu-impl.o arm-smmu-nvidia.o
-arm_smmu-$(CONFIG_ARM_SMMU_QCOM) += arm-smmu-qcom.o
+arm_smmu-objs += arm-smmu.o arm-smmu-impl.o arm-smmu-nvidia.o arm-smmu-qcom.o
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c b/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c
index 2c25cce38060..8199185dd262 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c
@@ -215,8 +215,13 @@  struct arm_smmu_device *arm_smmu_impl_init(struct arm_smmu_device *smmu)
 	    of_device_is_compatible(np, "nvidia,tegra186-smmu"))
 		return nvidia_smmu_impl_init(smmu);
 
-	if (IS_ENABLED(CONFIG_ARM_SMMU_QCOM))
-		smmu = qcom_smmu_impl_init(smmu);
+	/*
+	 * qcom_smmu_impl_init() will not touch smmu if the device is not
+	 * a Qualcomm one.
+	 */
+	smmu = qcom_smmu_impl_init(smmu);
+	if (IS_ERR(smmu))
+		return smmu;
 
 	if (of_device_is_compatible(np, "marvell,ap806-smmu-500"))
 		smmu->impl = &mrvl_mmu500_impl;