Re: (subset) [PATCH 2/2] arm64: dts: qcom: sm8250: Enable per-process page tables.

2022-07-02 Thread Bjorn Andersson
On Tue, 14 Jun 2022 16:01:36 -0700, Emma Anholt wrote:
> This is an SMMU for the adreno gpu, and adding this compatible lets
> the driver use per-fd page tables, which are required for security
> between GPU clients.
> 
> 

Applied, thanks!

[2/2] arm64: dts: qcom: sm8250: Enable per-process page tables.
  commit: 213d7368723709cf4567488e63dd667802378202

Best regards,
-- 
Bjorn Andersson 
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: (subset) [PATCH 4/4] ARM: dts: qcom: sdx65: Add Shared memory manager support

2022-06-28 Thread Bjorn Andersson
On Mon, 2 May 2022 14:07:45 +0530, Rohit Agarwal wrote:
> Add smem node to support shared memory manager on SDX65 platform.
> 
> 

Applied, thanks!

[4/4] ARM: dts: qcom: sdx65: Add Shared memory manager support
  commit: e378b965330d99e8622eb369021d0dac01591046

Best regards,
-- 
Bjorn Andersson 
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 2/2] iommu/arm-smmu-qcom: Add SC8280XP support

2022-05-03 Thread Bjorn Andersson
Add the Qualcomm SC8280XP platform to the list of compatible for which
the Qualcomm-impl of the ARM SMMU should apply.

Signed-off-by: Bjorn Andersson 
---
 drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c 
b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
index ba6298c7140e..7820711c4560 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
@@ -408,6 +408,7 @@ static const struct of_device_id __maybe_unused 
qcom_smmu_impl_of_match[] = {
{ .compatible = "qcom,sc7180-smmu-500" },
{ .compatible = "qcom,sc7280-smmu-500" },
{ .compatible = "qcom,sc8180x-smmu-500" },
+   { .compatible = "qcom,sc8280xp-smmu-500" },
{ .compatible = "qcom,sdm630-smmu-v2" },
{ .compatible = "qcom,sdm845-smmu-500" },
{ .compatible = "qcom,sm6125-smmu-500" },
-- 
2.35.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 0/2] iommu/arm-smmu-qcom: Add SC8280XP support

2022-05-03 Thread Bjorn Andersson
This adds the compatible for the Qualcomm SC8280XP platform and associate the
Qualcomm impl in the ARM SMMU driver to it.

Bjorn Andersson (2):
  dt-bindings: arm-smmu: Add compatible for Qualcomm SC8280XP
  iommu/arm-smmu-qcom: Add SC8280XP support

 Documentation/devicetree/bindings/iommu/arm,smmu.yaml | 1 +
 drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c| 1 +
 2 files changed, 2 insertions(+)

-- 
2.35.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 1/2] dt-bindings: arm-smmu: Add compatible for Qualcomm SC8280XP

2022-05-03 Thread Bjorn Andersson
Add compatible for the Qualcomm SC8280XP platform to the ARM SMMU
DeviceTree binding.

Signed-off-by: Bjorn Andersson 
---
 Documentation/devicetree/bindings/iommu/arm,smmu.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml 
b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
index da5381c8ee11..ba38ce054062 100644
--- a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
+++ b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
@@ -37,6 +37,7 @@ properties:
   - qcom,sc7180-smmu-500
   - qcom,sc7280-smmu-500
   - qcom,sc8180x-smmu-500
+  - qcom,sc8280xp-smmu-500
   - qcom,sdm845-smmu-500
   - qcom,sdx55-smmu-500
   - qcom,sm6350-smmu-500
-- 
2.35.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v2 7/7] ARM: dts: qcom: sdx65: Add Shared memory manager support

2022-04-12 Thread Bjorn Andersson
On Mon 11 Apr 04:50 CDT 2022, Rohit Agarwal wrote:

> Add smem node to support shared memory manager on SDX65 platform.
> 
> Signed-off-by: Rohit Agarwal 
> ---
>  arch/arm/boot/dts/qcom-sdx65.dtsi | 6 ++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/qcom-sdx65.dtsi 
> b/arch/arm/boot/dts/qcom-sdx65.dtsi
> index 210e55c..8fef644 100644
> --- a/arch/arm/boot/dts/qcom-sdx65.dtsi
> +++ b/arch/arm/boot/dts/qcom-sdx65.dtsi
> @@ -113,6 +113,12 @@
>   };
>   };
>  
> + smem {
> + compatible = "qcom,smem";
> + memory-region = <_mem>;
> + hwlocks = <_mutex 3>;
> + };

As you only have the single region, please move the compatible and
hwlocks properties into the _mem node (see sm8450.dtsi in arm64 as
an example).

I've applied the other dts changes.

Thanks,
Bjorn

> +
>   soc: soc {
>   #address-cells = <1>;
>   #size-cells = <1>;
> -- 
> 2.7.4
> 
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH] iommu/arm-smmu-qcom: Fix TTBR0 read

2021-11-08 Thread Bjorn Andersson
On Mon 08 Nov 09:17 PST 2021, Rob Clark wrote:

> From: Rob Clark 
> 
> It is a 64b register, lets not lose the upper bits.
> 
> Fixes: ab5df7b953d8 ("iommu/arm-smmu-qcom: Add an adreno-smmu-priv callback 
> to get pagefault info")
> Signed-off-by: Rob Clark 

Reviewed-by: Bjorn Andersson 

Regards,
Bjorn

> ---
>  drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c 
> b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> index 55690af1b25d..c998960495b4 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> @@ -51,7 +51,7 @@ static void qcom_adreno_smmu_get_fault_info(const void 
> *cookie,
>   info->fsynr1 = arm_smmu_cb_read(smmu, cfg->cbndx, ARM_SMMU_CB_FSYNR1);
>   info->far = arm_smmu_cb_readq(smmu, cfg->cbndx, ARM_SMMU_CB_FAR);
>   info->cbfrsynra = arm_smmu_gr1_read(smmu, 
> ARM_SMMU_GR1_CBFRSYNRA(cfg->cbndx));
> - info->ttbr0 = arm_smmu_cb_read(smmu, cfg->cbndx, ARM_SMMU_CB_TTBR0);
> + info->ttbr0 = arm_smmu_cb_readq(smmu, cfg->cbndx, ARM_SMMU_CB_TTBR0);
>   info->contextidr = arm_smmu_cb_read(smmu, cfg->cbndx, 
> ARM_SMMU_CB_CONTEXTIDR);
>  }
>  
> -- 
> 2.31.1
> 
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH] iommu: fix ARM_SMMU vs QCOM_SCM compilation

2021-10-09 Thread Bjorn Andersson
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 

Regards,
Bjorn

> Fixes: 424953cf3c66 ("qcom_scm: hide Kconfig symbol")
> Cc: Arnd Bergmann 
> Reported-by: Daniel Lezcano 
> Signed-off-by: Dmitry Baryshkov 
> ---
>  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 = _mmu500_impl;
> -- 
> 2.30.2
> 
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 1/2] iommu: arm-smmu-qcom: Add compatible for qcm2290

2021-10-01 Thread Bjorn Andersson
On Fri 01 Oct 07:00 PDT 2021, Loic Poulain wrote:

> Signed-off-by: Loic Poulain 
> ---
>  drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c 
> b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> index 55690af..d105186 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> @@ -412,6 +412,7 @@ static const struct of_device_id __maybe_unused 
> qcom_smmu_impl_of_match[] = {
>   { .compatible = "qcom,sm8150-smmu-500" },
>   { .compatible = "qcom,sm8250-smmu-500" },
>   { .compatible = "qcom,sm8350-smmu-500" },
> + { .compatible = "qcom,qcm2290-smmu-500" },

Would be nice if we kept the alphabetical sort order on these and in the
binding.

With that, please feel free to add my R-b

Regards,
Bjorn

>   { }
>  };
>  
> -- 
> 2.7.4
> 
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 2/2] [v2] qcom_scm: hide Kconfig symbol

2021-09-29 Thread Bjorn Andersson
On Tue 28 Sep 02:50 CDT 2021, Arnd Bergmann wrote:

> From: Arnd Bergmann 
> 
> Now that SCM can be a loadable module, we have to add another
> dependency to avoid link failures when ipa or adreno-gpu are
> built-in:
> 
> aarch64-linux-ld: drivers/net/ipa/ipa_main.o: in function `ipa_probe':
> ipa_main.c:(.text+0xfc4): undefined reference to `qcom_scm_is_available'
> 
> ld.lld: error: undefined symbol: qcom_scm_is_available
> >>> referenced by adreno_gpu.c
> >>>   gpu/drm/msm/adreno/adreno_gpu.o:(adreno_zap_shader_load) in 
> >>> archive drivers/built-in.a
> 
> This can happen when CONFIG_ARCH_QCOM is disabled and we don't select
> QCOM_MDT_LOADER, but some other module selects QCOM_SCM. Ideally we'd
> use a similar dependency here to what we have for QCOM_RPROC_COMMON,
> but that causes dependency loops from other things selecting QCOM_SCM.
> 
> This appears to be an endless problem, so try something different this
> time:
> 
>  - CONFIG_QCOM_SCM becomes a hidden symbol that nothing 'depends on'
>but that is simply selected by all of its users
> 
>  - All the stubs in include/linux/qcom_scm.h can go away
> 
>  - arm-smccc.h needs to provide a stub for __arm_smccc_smc() to
>allow compile-testing QCOM_SCM on all architectures.
> 
>  - To avoid a circular dependency chain involving RESET_CONTROLLER
>and PINCTRL_SUNXI, drop the 'select RESET_CONTROLLER' statement.
>According to my testing this still builds fine, and the QCOM
>platform selects this symbol already.
> 
> Acked-by: Kalle Valo 
> Signed-off-by: Arnd Bergmann 
> ---
> Changes in v2:
>   - drop the 'select RESET_CONTROLLER' line, rather than adding
> more of the same
> ---
>  drivers/firmware/Kconfig|  5 +-
>  drivers/gpu/drm/msm/Kconfig |  4 +-
>  drivers/iommu/Kconfig   |  2 +-
>  drivers/media/platform/Kconfig  |  2 +-
>  drivers/mmc/host/Kconfig|  2 +-
>  drivers/net/ipa/Kconfig |  1 +
>  drivers/net/wireless/ath/ath10k/Kconfig |  2 +-
>  drivers/pinctrl/qcom/Kconfig|  3 +-
>  include/linux/arm-smccc.h   | 10 
>  include/linux/qcom_scm.h| 71 -
>  10 files changed, 20 insertions(+), 82 deletions(-)
> 
> diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
> index 220a58cf0a44..cda7d7162cbb 100644
> --- a/drivers/firmware/Kconfig
> +++ b/drivers/firmware/Kconfig
> @@ -203,10 +203,7 @@ config INTEL_STRATIX10_RSU
> Say Y here if you want Intel RSU support.
>  
>  config QCOM_SCM
> - tristate "Qcom SCM driver"
> - depends on ARM || ARM64
> - depends on HAVE_ARM_SMCCC
> - select RESET_CONTROLLER
> + tristate
>  
>  config QCOM_SCM_DOWNLOAD_MODE_DEFAULT
>   bool "Qualcomm download mode enabled by default"
> diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig
> index e9c6af78b1d7..3ddf739a6f9b 100644
> --- a/drivers/gpu/drm/msm/Kconfig
> +++ b/drivers/gpu/drm/msm/Kconfig
> @@ -17,7 +17,7 @@ config DRM_MSM
>   select DRM_SCHED
>   select SHMEM
>   select TMPFS
> - select QCOM_SCM if ARCH_QCOM
> + select QCOM_SCM
>   select WANT_DEV_COREDUMP
>   select SND_SOC_HDMI_CODEC if SND_SOC
>   select SYNC_FILE
> @@ -55,7 +55,7 @@ config DRM_MSM_GPU_SUDO
>  
>  config DRM_MSM_HDMI_HDCP
>   bool "Enable HDMI HDCP support in MSM DRM driver"
> - depends on DRM_MSM && QCOM_SCM
> + depends on DRM_MSM
>   default y
>   help
> Choose this option to enable HDCP state machine
> diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
> index 124c41adeca1..989c83acbfee 100644
> --- a/drivers/iommu/Kconfig
> +++ b/drivers/iommu/Kconfig
> @@ -308,7 +308,7 @@ config APPLE_DART
>  config ARM_SMMU
>   tristate "ARM Ltd. System MMU (SMMU) Support"
>   depends on ARM64 || ARM || (COMPILE_TEST && !GENERIC_ATOMIC64)
> - depends on QCOM_SCM || !QCOM_SCM #if QCOM_SCM=m this can't be =y
> + select QCOM_SCM
>   select IOMMU_API
>   select IOMMU_IO_PGTABLE_LPAE
>   select ARM_DMA_USE_IOMMU if ARM

As noted in the RFC, I think you also need to fix QCOM_IOMMU.

In particular (iirc) since all the users of the iommu might be modules,
which would prevent QCOM_IOMMU from being selected.

The rest looks good.

Regards,
Bjorn

> diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
> index 157c924686e4..80321e03809a 100644
> --- a/drivers/media/platform/Kconfig
> +++ b/drivers/media/platform/Kconfig
> @@ -565,7 +565,7 @@ config VIDEO_QCOM_VENUS
>   depends on VIDEO_DEV && VIDEO_V4L2 && QCOM_SMEM
>   depends on (ARCH_QCOM && IOMMU_DMA) || COMPILE_TEST
>   select QCOM_MDT_LOADER if ARCH_QCOM
> - select QCOM_SCM if ARCH_QCOM
> + select QCOM_SCM
>   select VIDEOBUF2_DMA_CONTIG
>   select V4L2_MEM2MEM_DEV
>   help
> diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
> index 

Re: [PATCH] [RFC] qcom_scm: hide Kconfig symbol

2021-09-29 Thread Bjorn Andersson
On Wed 29 Sep 05:04 CDT 2021, Arnd Bergmann wrote:

> On Wed, Sep 29, 2021 at 11:51 AM Will Deacon  wrote:
> > On Mon, Sep 27, 2021 at 05:22:13PM +0200, Arnd Bergmann wrote:
> > >
> > > diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
> > > index 124c41adeca1..989c83acbfee 100644
> > > --- a/drivers/iommu/Kconfig
> > > +++ b/drivers/iommu/Kconfig
> > > @@ -308,7 +308,7 @@ config APPLE_DART
> > >  config ARM_SMMU
> > >   tristate "ARM Ltd. System MMU (SMMU) Support"
> > >   depends on ARM64 || ARM || (COMPILE_TEST && !GENERIC_ATOMIC64)
> > > - depends on QCOM_SCM || !QCOM_SCM #if QCOM_SCM=m this can't be =y
> > > + select QCOM_SCM
> > >   select IOMMU_API
> > >   select IOMMU_IO_PGTABLE_LPAE
> > >   select ARM_DMA_USE_IOMMU if ARM
> >
> > I don't want to get in the way of this patch because I'm also tired of the
> > randconfig failures caused by QCOM_SCM. However, ARM_SMMU is applicable to
> > a wide variety of (non-qcom) SoCs and so it seems a shame to require the
> > QCOM_SCM code to be included for all of those when it's not strictly needed
> > at all.
> 
> Good point, I agree that needs to be fixed. I think this additional
> change should do the trick:
> 

ARM_SMMU and QCOM_IOMMU are two separate implementations and both uses
QCOM_SCM. So both of them should select QCOM_SCM.

"Unfortunately" the Qualcomm portion of ARM_SMMU is builtin
unconditionally, so going with something like select QCOM_SCM if
ARCH_QCOM would still require the stubs in qcom_scm.h.

Regards,
Bjorn

> --- a/drivers/iommu/Kconfig
> +++ b/drivers/iommu/Kconfig
> @@ -308,7 +308,6 @@ config APPLE_DART
>  config ARM_SMMU
> tristate "ARM Ltd. System MMU (SMMU) Support"
> depends on ARM64 || ARM || (COMPILE_TEST && !GENERIC_ATOMIC64)
> -   select QCOM_SCM
> select IOMMU_API
> select IOMMU_IO_PGTABLE_LPAE
> select ARM_DMA_USE_IOMMU if ARM
> @@ -438,7 +437,7 @@ config QCOM_IOMMU
> # Note: iommu drivers cannot (yet?) be built as modules
> bool "Qualcomm IOMMU Support"
> depends on ARCH_QCOM || (COMPILE_TEST && !GENERIC_ATOMIC64)
> -   depends on QCOM_SCM=y
> +   select QCOM_SCM
> select IOMMU_API
> select IOMMU_IO_PGTABLE_LPAE
> select ARM_DMA_USE_IOMMU
> 
> I'll see if that causes any problems for the randconfig builds.
> 
>Arnd
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH] [RFC] qcom_scm: hide Kconfig symbol

2021-09-27 Thread Bjorn Andersson
On Mon 27 Sep 13:15 PDT 2021, Arnd Bergmann wrote:

> On Mon, Sep 27, 2021 at 9:52 PM Bjorn Andersson
>  wrote:
> > On Mon 27 Sep 08:22 PDT 2021, Arnd Bergmann wrote:
> > > From: Arnd Bergmann 
> > >
> > >  - To avoid a circular dependency chain involving RESET_CONTROLLER
> > >and PINCTRL_SUNXI, change the 'depends on RESET_CONTROLLER' in
> > >the latter one to 'select'.
> >
> > Can you please help me understand why this is part of the same patch?
> 
> This can be done as a preparatory patch if we decide to do it this way,
> for the review it seemed better to spell out that this is required.
> 
> I still hope that we can avoid adding another 'select RESET_CONTROLLER'
> if someone can figure out what to do instead.
> 

Okay, thanks.

> The problem here is that QCOM_SCM selects RESET_CONTROLLER,
> and turning that into 'depends on' would in turn mean that any driver that
> wants to select QCOM_SCM would have to have the same RESET_CONTROLLER
> dependency.
> 

Right, and that will just be another thing we'll get wrong across the
tree.

> An easier option might be to find a way to build QCOM_SCM without
> RESET_CONTROLLER for compile testing purposes. I don't know
> what would break from that.
> 

Afaict the reset API is properly stubbed and RESET_CONTROLLER is a bool,
so I think we can simply drop the "select" and the kernel will still
compile fine in all combinations.

When it comes to runtime, we currently select RESET_CONTROLLER from the
Qualcomm common clocks. If that is dropped (why would it...) it seems
possible to build a custom kernel for msm8916 that we can boot and miss
the stubbed out "mss restart" reset line from the SCM.


So, let's just drop the select RESET_CONTROLLER from SCM for now.

Regards,
Bjorn
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH] [RFC] qcom_scm: hide Kconfig symbol

2021-09-27 Thread Bjorn Andersson
On Mon 27 Sep 08:22 PDT 2021, Arnd Bergmann wrote:

> From: Arnd Bergmann 
> 
> Now that SCM can be a loadable module, we have to add another
> dependency to avoid link failures when ipa or adreno-gpu are
> built-in:
> 
> aarch64-linux-ld: drivers/net/ipa/ipa_main.o: in function `ipa_probe':
> ipa_main.c:(.text+0xfc4): undefined reference to `qcom_scm_is_available'
> 
> ld.lld: error: undefined symbol: qcom_scm_is_available
> >>> referenced by adreno_gpu.c
> >>>   gpu/drm/msm/adreno/adreno_gpu.o:(adreno_zap_shader_load) in 
> >>> archive drivers/built-in.a
> 
> This can happen when CONFIG_ARCH_QCOM is disabled and we don't select
> QCOM_MDT_LOADER, but some other module selects QCOM_SCM. Ideally we'd
> use a similar dependency here to what we have for QCOM_RPROC_COMMON,
> but that causes dependency loops from other things selecting QCOM_SCM.
> 
> This appears to be an endless problem, so try something different this
> time:
> 
>  - CONFIG_QCOM_SCM becomes a hidden symbol that nothing 'depends on'
>but that is simply selected by all of its users
> 
>  - All the stubs in include/linux/qcom_scm.h can go away
> 
>  - arm-smccc.h needs to provide a stub for __arm_smccc_smc() to
>allow compile-testing QCOM_SCM on all architectures.
> 
>  - To avoid a circular dependency chain involving RESET_CONTROLLER
>and PINCTRL_SUNXI, change the 'depends on RESET_CONTROLLER' in
>the latter one to 'select'.

Can you please help me understand why this is part of the same patch?

> 
> The last bit is rather annoying, as drivers should generally never
> 'select' another subsystem, and about half the users of the reset
> controller interface do this anyway.
> 
> Nevertheless, this version seems to pass all my randconfig tests
> and is more robust than any of the prior versions.
> 
> Comments?
> 

I like it!

It's less confusing than the current scheme, so should be easier to
get right. And I like the fact that we don't need the stubs anymore.


@John, could you please have a look at this as well, wrt GKI.

Regards,
Bjorn

> Signed-off-by: Arnd Bergmann 
> ---
>  drivers/firmware/Kconfig|  4 +-
>  drivers/gpu/drm/msm/Kconfig |  4 +-
>  drivers/iommu/Kconfig   |  2 +-
>  drivers/media/platform/Kconfig  |  2 +-
>  drivers/mmc/host/Kconfig|  2 +-
>  drivers/net/ipa/Kconfig |  1 +
>  drivers/net/wireless/ath/ath10k/Kconfig |  2 +-
>  drivers/pinctrl/qcom/Kconfig|  3 +-
>  drivers/pinctrl/sunxi/Kconfig   |  6 +--
>  include/linux/arm-smccc.h   | 10 
>  include/linux/qcom_scm.h| 71 -
>  11 files changed, 23 insertions(+), 84 deletions(-)
> 
> diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
> index 220a58cf0a44..f7dd82ef0b9c 100644
> --- a/drivers/firmware/Kconfig
> +++ b/drivers/firmware/Kconfig
> @@ -203,9 +203,7 @@ config INTEL_STRATIX10_RSU
> Say Y here if you want Intel RSU support.
>  
>  config QCOM_SCM
> - tristate "Qcom SCM driver"
> - depends on ARM || ARM64
> - depends on HAVE_ARM_SMCCC
> + tristate
>   select RESET_CONTROLLER
>  
>  config QCOM_SCM_DOWNLOAD_MODE_DEFAULT
> diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig
> index e9c6af78b1d7..3ddf739a6f9b 100644
> --- a/drivers/gpu/drm/msm/Kconfig
> +++ b/drivers/gpu/drm/msm/Kconfig
> @@ -17,7 +17,7 @@ config DRM_MSM
>   select DRM_SCHED
>   select SHMEM
>   select TMPFS
> - select QCOM_SCM if ARCH_QCOM
> + select QCOM_SCM
>   select WANT_DEV_COREDUMP
>   select SND_SOC_HDMI_CODEC if SND_SOC
>   select SYNC_FILE
> @@ -55,7 +55,7 @@ config DRM_MSM_GPU_SUDO
>  
>  config DRM_MSM_HDMI_HDCP
>   bool "Enable HDMI HDCP support in MSM DRM driver"
> - depends on DRM_MSM && QCOM_SCM
> + depends on DRM_MSM
>   default y
>   help
> Choose this option to enable HDCP state machine
> diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
> index 124c41adeca1..989c83acbfee 100644
> --- a/drivers/iommu/Kconfig
> +++ b/drivers/iommu/Kconfig
> @@ -308,7 +308,7 @@ config APPLE_DART
>  config ARM_SMMU
>   tristate "ARM Ltd. System MMU (SMMU) Support"
>   depends on ARM64 || ARM || (COMPILE_TEST && !GENERIC_ATOMIC64)
> - depends on QCOM_SCM || !QCOM_SCM #if QCOM_SCM=m this can't be =y
> + select QCOM_SCM
>   select IOMMU_API
>   select IOMMU_IO_PGTABLE_LPAE
>   select ARM_DMA_USE_IOMMU if ARM
> diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
> index 157c924686e4..80321e03809a 100644
> --- a/drivers/media/platform/Kconfig
> +++ b/drivers/media/platform/Kconfig
> @@ -565,7 +565,7 @@ config VIDEO_QCOM_VENUS
>   depends on VIDEO_DEV && VIDEO_V4L2 && QCOM_SMEM
>   depends on (ARCH_QCOM && IOMMU_DMA) || COMPILE_TEST
>   select QCOM_MDT_LOADER if ARCH_QCOM
> - select QCOM_SCM if ARCH_QCOM
> + select QCOM_SCM
>  

Re: [PATCH] firmware: QCOM_SCM: Allow qcom_scm driver to be loadable as a permenent module

2021-07-23 Thread Bjorn Andersson
On Wed 21 Jul 16:07 CDT 2021, Saravana Kannan wrote:

> On Wed, Jul 21, 2021 at 1:23 PM Bjorn Andersson
>  wrote:
> >
> > On Wed 21 Jul 13:00 CDT 2021, Saravana Kannan wrote:
> >
> > > On Wed, Jul 21, 2021 at 10:24 AM John Stultz  
> > > wrote:
> > > >
> > > > On Wed, Jul 21, 2021 at 4:54 AM Greg Kroah-Hartman
> > > >  wrote:
> > > > >
> > > > > On Wed, Jul 07, 2021 at 04:53:20AM +, John Stultz wrote:
> > > > > > Allow the qcom_scm driver to be loadable as a permenent module.
> > > > >
> > > > > This feels like a regression, it should be allowed to be a module.
> > > >
> > > > I'm sorry, I'm not sure I'm following you, Greg.  This patch is trying
> > > > to enable the driver to be able to be loaded as a module.
> > >
> > > I think the mix up might be that Greg mentally read "permanent module"
> > > as "builtin"?
> > >
> > > "permanent module" is just something that can't be unloaded once it's
> > > loaded. It's not "builtin".
> > >
> >
> > Afaict there's nothing in this patch that makes it more or less
> > permanent.
> 
> The lack of a module_exit() makes it a permanent module. If you do
> lsmod, it'll mark this as "[permanent]".
> 

Cool, I didn't know that.

Thanks,
Bjorn
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH] firmware: QCOM_SCM: Allow qcom_scm driver to be loadable as a permenent module

2021-07-21 Thread Bjorn Andersson
On Wed 21 Jul 13:00 CDT 2021, Saravana Kannan wrote:

> On Wed, Jul 21, 2021 at 10:24 AM John Stultz  wrote:
> >
> > On Wed, Jul 21, 2021 at 4:54 AM Greg Kroah-Hartman
> >  wrote:
> > >
> > > On Wed, Jul 07, 2021 at 04:53:20AM +, John Stultz wrote:
> > > > Allow the qcom_scm driver to be loadable as a permenent module.
> > >
> > > This feels like a regression, it should be allowed to be a module.
> >
> > I'm sorry, I'm not sure I'm following you, Greg.  This patch is trying
> > to enable the driver to be able to be loaded as a module.
> 
> I think the mix up might be that Greg mentally read "permanent module"
> as "builtin"?
> 
> "permanent module" is just something that can't be unloaded once it's
> loaded. It's not "builtin".
> 

Afaict there's nothing in this patch that makes it more or less
permanent. The module will be quite permanent (in practice) because
several other core modules reference symbols in the qcom_scm module.

But thanks to a previous patch, the qcom_scm device comes with
suppress_bind_attrs, to prevent that the device goes away from a simple
unbind operation - which the API and client drivers aren't designed to
handle.

So, it would have been better in this case to omit the word "permanent"
from the commit message, but the change is good and I don't want to
rebase my tree to drop that word.

Thanks,
Bjorn

> -Saravana
> 
> >
> > > > This still uses the "depends on QCOM_SCM || !QCOM_SCM" bit to
> > > > ensure that drivers that call into the qcom_scm driver are
> > > > also built as modules. While not ideal in some cases its the
> > > > only safe way I can find to avoid build errors without having
> > > > those drivers select QCOM_SCM and have to force it on (as
> > > > QCOM_SCM=n can be valid for those drivers).
> > > >
> > > > Reviving this now that Saravana's fw_devlink defaults to on,
> > > > which should avoid loading troubles seen before.
> > >
> > > fw_devlink was supposed to resolve these issues and _allow_ code to be
> > > built as modules and not forced to be built into the kernel.
> >
> > Right. I'm re-submitting this patch to enable a driver to work as a
> > module, because earlier attempts to submit it ran into boot trouble
> > because fw_devlink wasn't yet enabled.
> >
> > I worry something in my description made it seem otherwise, so let me
> > know how you read it and I'll try to avoid such confusion in the
> > future.
> >
> > thanks
> > -john
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH] firmware: QCOM_SCM: Allow qcom_scm driver to be loadable as a permenent module

2021-07-21 Thread Bjorn Andersson
On Mon 19 Jul 16:53 CDT 2021, Saravana Kannan wrote:

> On Mon, Jul 19, 2021 at 12:36 PM Bjorn Andersson
>  wrote:
> >
> > On Mon 19 Jul 14:00 CDT 2021, John Stultz wrote:
> >
> > > On Fri, Jul 16, 2021 at 10:01 PM Bjorn Andersson
> > >  wrote:
> > > > On Tue 06 Jul 23:53 CDT 2021, John Stultz wrote:
> > > > > Allow the qcom_scm driver to be loadable as a permenent module.
> > > > >
> > > > > This still uses the "depends on QCOM_SCM || !QCOM_SCM" bit to
> > > > > ensure that drivers that call into the qcom_scm driver are
> > > > > also built as modules. While not ideal in some cases its the
> > > > > only safe way I can find to avoid build errors without having
> > > > > those drivers select QCOM_SCM and have to force it on (as
> > > > > QCOM_SCM=n can be valid for those drivers).
> > > > >
> > > > > Reviving this now that Saravana's fw_devlink defaults to on,
> > > > > which should avoid loading troubles seen before.
> > > > >
> > > >
> > > > Are you (in this last paragraph) saying that all those who have been
> > > > burnt by fw_devlink during the last months and therefor run with it
> > > > disabled will have a less fun experience once this is merged?
> > > >
> 
> Bjorn,
> 
> I jump in and help with any reports of issues with fw_devlink if I'm
> cc'ed. Please feel free to add me and I'll help fix any issues you
> have with fw_devlink=on.
> 

Thanks Saravana, unfortunately I've only heard these reports second hand
so far, not been able to reproduce them on my own. I appreciate your
support and will certainly reach out if I need some assistance.

> > >
> > > I guess potentially. So way back when this was originally submitted,
> > > some folks had trouble booting if it was set as a module due to it
> > > loading due to the deferred_probe_timeout expiring.
> > > My attempts to change the default timeout value to be larger ran into
> > > trouble, but Saravana's fw_devlink does manage to resolve things
> > > properly for this case.
> > >
> >
> > Unfortunately I see really weird things coming out of that, e.g. display
> > on my db845c is waiting for the USB hub on PCIe to load its firmware,
> > which typically times out after 60 seconds.
> >
> > I've stared at it quite a bit and I don't understand how they are
> > related.
> 
> Can you please add me to any email thread with the details? I'd be
> happy to help.
> 
> First step is to make sure all the devices probe as with
> fw_devlink=permissive. After that if you are still seeing issues, it's
> generally timing issues in the driver. But if the actual timing issue
> is identified (by you or whoever knows the driver seeing the issue),
> then I can help with fixes or suggestions for fixes.
> 
> > > But if folks are having issues w/ fw_devlink, and have it disabled,
> > > and set QCOM_SCM=m they could still trip over the issue with the
> > > timeout firing before it is loaded (especially if they are loading
> > > modules from late mounted storage rather than ramdisk).
> > >
> >
> > I guess we'll have to force QCOM_SCM=y in the defconfig and hope people
> > don't make it =m.
> >
> > > > (I'm picking this up, but I don't fancy the idea that some people are
> > > > turning the boot process into a lottery)
> > >
> > > Me neither, and I definitely think the deferred_probe_timeout logic is
> > > way too fragile, which is why I'm eager for fw_devlink as it's a much
> > > less racy approach to handling module loading dependencies.
> >
> > Right, deferred_probe_timeout is the main issue here. Without it we
> > might get some weird probe deferral runs, but either some driver is
> > missing or it settles eventually.
> >
> > With deferred_probe_timeout it's rather common for me to see things
> > end up probe out of order (even more now with fw_devlink finding cyclic
> > dependencies) and deferred_probe_timeout just breaking things.
> 
> Again, please CC me on these threads and I'd be happy to help.
> 
> >
> > > So if you
> > > want to hold on this, while any remaining fw_devlink issues get
> > > sorted, that's fine.  But I'd also not cast too much ire at
> > > fw_devlink, as the global probe timeout approach for handling optional
> > > links isn't great, and we need a better solution.
> > >
> >
> > There's no end to the possible and valid ways you can setup your
> > defconfig and run into the probe deferral issues, so I see no point in
> > holding this one back any longer. I just hope that one day it will be
> > possible to boot the upstream kernel in a reliable fashion.
> 
> Might not be believable, but I'm hoping fw_devlink helps you meet this goal :)
> 

Sounds good, I hope so too :)

Regards,
Bjorn
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH] firmware: QCOM_SCM: Allow qcom_scm driver to be loadable as a permenent module

2021-07-19 Thread Bjorn Andersson
On Mon 19 Jul 14:00 CDT 2021, John Stultz wrote:

> On Fri, Jul 16, 2021 at 10:01 PM Bjorn Andersson
>  wrote:
> > On Tue 06 Jul 23:53 CDT 2021, John Stultz wrote:
> > > Allow the qcom_scm driver to be loadable as a permenent module.
> > >
> > > This still uses the "depends on QCOM_SCM || !QCOM_SCM" bit to
> > > ensure that drivers that call into the qcom_scm driver are
> > > also built as modules. While not ideal in some cases its the
> > > only safe way I can find to avoid build errors without having
> > > those drivers select QCOM_SCM and have to force it on (as
> > > QCOM_SCM=n can be valid for those drivers).
> > >
> > > Reviving this now that Saravana's fw_devlink defaults to on,
> > > which should avoid loading troubles seen before.
> > >
> >
> > Are you (in this last paragraph) saying that all those who have been
> > burnt by fw_devlink during the last months and therefor run with it
> > disabled will have a less fun experience once this is merged?
> >
> 
> I guess potentially. So way back when this was originally submitted,
> some folks had trouble booting if it was set as a module due to it
> loading due to the deferred_probe_timeout expiring.
> My attempts to change the default timeout value to be larger ran into
> trouble, but Saravana's fw_devlink does manage to resolve things
> properly for this case.
> 

Unfortunately I see really weird things coming out of that, e.g. display
on my db845c is waiting for the USB hub on PCIe to load its firmware,
which typically times out after 60 seconds.

I've stared at it quite a bit and I don't understand how they are
related.

> But if folks are having issues w/ fw_devlink, and have it disabled,
> and set QCOM_SCM=m they could still trip over the issue with the
> timeout firing before it is loaded (especially if they are loading
> modules from late mounted storage rather than ramdisk).
> 

I guess we'll have to force QCOM_SCM=y in the defconfig and hope people
don't make it =m.

> > (I'm picking this up, but I don't fancy the idea that some people are
> > turning the boot process into a lottery)
> 
> Me neither, and I definitely think the deferred_probe_timeout logic is
> way too fragile, which is why I'm eager for fw_devlink as it's a much
> less racy approach to handling module loading dependencies.

Right, deferred_probe_timeout is the main issue here. Without it we
might get some weird probe deferral runs, but either some driver is
missing or it settles eventually.

With deferred_probe_timeout it's rather common for me to see things
end up probe out of order (even more now with fw_devlink finding cyclic
dependencies) and deferred_probe_timeout just breaking things.

> So if you
> want to hold on this, while any remaining fw_devlink issues get
> sorted, that's fine.  But I'd also not cast too much ire at
> fw_devlink, as the global probe timeout approach for handling optional
> links isn't great, and we need a better solution.
> 

There's no end to the possible and valid ways you can setup your
defconfig and run into the probe deferral issues, so I see no point in
holding this one back any longer. I just hope that one day it will be
possible to boot the upstream kernel in a reliable fashion.

Thanks,
Bjorn
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH] firmware: QCOM_SCM: Allow qcom_scm driver to be loadable as a permenent module

2021-07-16 Thread Bjorn Andersson
On Tue 06 Jul 23:53 CDT 2021, John Stultz wrote:

> Allow the qcom_scm driver to be loadable as a permenent module.
> 
> This still uses the "depends on QCOM_SCM || !QCOM_SCM" bit to
> ensure that drivers that call into the qcom_scm driver are
> also built as modules. While not ideal in some cases its the
> only safe way I can find to avoid build errors without having
> those drivers select QCOM_SCM and have to force it on (as
> QCOM_SCM=n can be valid for those drivers).
> 
> Reviving this now that Saravana's fw_devlink defaults to on,
> which should avoid loading troubles seen before.
> 

Are you (in this last paragraph) saying that all those who have been
burnt by fw_devlink during the last months and therefor run with it
disabled will have a less fun experience once this is merged?


(I'm picking this up, but I don't fancy the idea that some people are
turning the boot process into a lottery)

Regards,
Bjorn

> Cc: Catalin Marinas 
> Cc: Will Deacon 
> Cc: Andy Gross 
> Cc: Bjorn Andersson 
> Cc: Joerg Roedel 
> Cc: Thomas Gleixner 
> Cc: Marc Zyngier 
> Cc: Linus Walleij 
> Cc: Vinod Koul 
> Cc: Kalle Valo 
> Cc: Maulik Shah 
> Cc: Saravana Kannan 
> Cc: Todd Kjos 
> Cc: Greg Kroah-Hartman 
> Cc: linux-arm-...@vger.kernel.org
> Cc: iommu@lists.linux-foundation.org
> Cc: linux-g...@vger.kernel.org
> Acked-by: Kalle Valo 
> Acked-by: Greg Kroah-Hartman 
> Acked-by: Will Deacon 
> Reviewed-by: Bjorn Andersson 
> Signed-off-by: John Stultz 
> ---
> v3:
> * Fix __arm_smccc_smc build issue reported by
>   kernel test robot 
> v4:
> * Add "depends on QCOM_SCM || !QCOM_SCM" bit to ath10k
>   config that requires it.
> v5:
> * Fix QCOM_QCM typo in Kconfig, it should be QCOM_SCM
> ---
>  drivers/firmware/Kconfig| 2 +-
>  drivers/firmware/Makefile   | 3 ++-
>  drivers/firmware/qcom_scm.c | 4 
>  drivers/iommu/Kconfig   | 2 ++
>  drivers/net/wireless/ath/ath10k/Kconfig | 1 +
>  5 files changed, 10 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
> index db0ea2d2d75a..af53778edc7e 100644
> --- a/drivers/firmware/Kconfig
> +++ b/drivers/firmware/Kconfig
> @@ -235,7 +235,7 @@ config INTEL_STRATIX10_RSU
> Say Y here if you want Intel RSU support.
>  
>  config QCOM_SCM
> - bool
> + tristate "Qcom SCM driver"
>   depends on ARM || ARM64
>   depends on HAVE_ARM_SMCCC
>   select RESET_CONTROLLER
> diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
> index 5e013b6a3692..523173cbff33 100644
> --- a/drivers/firmware/Makefile
> +++ b/drivers/firmware/Makefile
> @@ -17,7 +17,8 @@ obj-$(CONFIG_ISCSI_IBFT)+= iscsi_ibft.o
>  obj-$(CONFIG_FIRMWARE_MEMMAP)+= memmap.o
>  obj-$(CONFIG_RASPBERRYPI_FIRMWARE) += raspberrypi.o
>  obj-$(CONFIG_FW_CFG_SYSFS)   += qemu_fw_cfg.o
> -obj-$(CONFIG_QCOM_SCM)   += qcom_scm.o qcom_scm-smc.o 
> qcom_scm-legacy.o
> +obj-$(CONFIG_QCOM_SCM)   += qcom-scm.o
> +qcom-scm-objs += qcom_scm.o qcom_scm-smc.o qcom_scm-legacy.o
>  obj-$(CONFIG_TI_SCI_PROTOCOL)+= ti_sci.o
>  obj-$(CONFIG_TRUSTED_FOUNDATIONS) += trusted_foundations.o
>  obj-$(CONFIG_TURRIS_MOX_RWTM)+= turris-mox-rwtm.o
> diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c
> index ee9cb545e73b..bb9ce3f92931 100644
> --- a/drivers/firmware/qcom_scm.c
> +++ b/drivers/firmware/qcom_scm.c
> @@ -1296,6 +1296,7 @@ static const struct of_device_id qcom_scm_dt_match[] = {
>   { .compatible = "qcom,scm" },
>   {}
>  };
> +MODULE_DEVICE_TABLE(of, qcom_scm_dt_match);
>  
>  static struct platform_driver qcom_scm_driver = {
>   .driver = {
> @@ -1312,3 +1313,6 @@ static int __init qcom_scm_init(void)
>   return platform_driver_register(_scm_driver);
>  }
>  subsys_initcall(qcom_scm_init);
> +
> +MODULE_DESCRIPTION("Qualcomm Technologies, Inc. SCM driver");
> +MODULE_LICENSE("GPL v2");
> diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
> index 07b7c25cbed8..f61516c17589 100644
> --- a/drivers/iommu/Kconfig
> +++ b/drivers/iommu/Kconfig
> @@ -253,6 +253,7 @@ config SPAPR_TCE_IOMMU
>  config ARM_SMMU
>   tristate "ARM Ltd. System MMU (SMMU) Support"
>   depends on ARM64 || ARM || (COMPILE_TEST && !GENERIC_ATOMIC64)
> + depends on QCOM_SCM || !QCOM_SCM #if QCOM_SCM=m this can't be =y
>   select IOMMU_API
>   select IOMMU_IO_PGTABLE_LPAE
>   select ARM_DMA_USE_IOMMU if ARM
> @@ -382,6 +383,7 @@ config QCOM_IOMMU
>   # Note: iommu drivers cannot (yet?) be built as modules
>  

Re: [PATCH v5 0/5] iommu/arm-smmu: adreno-smmu page fault handling

2021-07-06 Thread Bjorn Andersson
On Sun 04 Jul 13:20 CDT 2021, Rob Clark wrote:

> I suspect you are getting a dpu fault, and need:
> 
> https://lore.kernel.org/linux-arm-msm/CAF6AEGvTjTUQXqom-xhdh456tdLscbVFPQ+iud1H1gHc8A2=h...@mail.gmail.com/
> 
> I suppose Bjorn was expecting me to send that patch
> 

No, I left that discussion with the same understanding as you... But I
ended up side tracked by some other craziness.

Did you post this somewhere or would you still like me to test it and
spin a patch?

Regards,
Bjorn

> BR,
> -R
> 
> On Sun, Jul 4, 2021 at 5:53 AM Dmitry Baryshkov
>  wrote:
> >
> > Hi,
> >
> > I've had splash screen disabled on my RB3. However once I've enabled it,
> > I've got the attached crash during the boot on the msm/msm-next. It
> > looks like it is related to this particular set of changes.
> >
> > On 11/06/2021 00:44, Rob Clark wrote:
> > > From: Rob Clark 
> > >
> > > This picks up an earlier series[1] from Jordan, and adds additional
> > > support needed to generate GPU devcore dumps on iova faults.  Original
> > > description:
> > >
> > > This is a stack to add an Adreno GPU specific handler for pagefaults. The 
> > > first
> > > patch starts by wiring up report_iommu_fault for arm-smmu. The next patch 
> > > adds
> > > a adreno-smmu-priv function hook to capture a handful of important 
> > > debugging
> > > registers such as TTBR0, CONTEXTIDR, FSYNR0 and others. This is used by 
> > > the
> > > third patch to print more detailed information on page fault such as the 
> > > TTBR0
> > > for the pagetable that caused the fault and the source of the fault as
> > > determined by a combination of the FSYNR1 register and an internal GPU
> > > register.
> > >
> > > This code provides a solid base that we can expand on later for even more
> > > extensive GPU side page fault debugging capabilities.
> > >
> > > v5: [Rob] Use RBBM_STATUS3.SMMU_STALLED_ON_FAULT to detect case where
> > >  GPU snapshotting needs to avoid crashdumper, and check the
> > >  RBBM_STATUS3.SMMU_STALLED_ON_FAULT in GPU hang irq paths
> > > v4: [Rob] Add support to stall SMMU on fault, and let the GPU driver
> > >  resume translation after it has had a chance to snapshot the GPUs
> > >  state
> > > v3: Always clear FSR even if the target driver is going to handle resume
> > > v2: Fix comment wording and function pointer check per Rob Clark
> > >
> > > [1] 
> > > https://lore.kernel.org/dri-devel/20210225175135.91922-1-jcro...@codeaurora.org/
> > >
> > > Jordan Crouse (3):
> > >iommu/arm-smmu: Add support for driver IOMMU fault handlers
> > >iommu/arm-smmu-qcom: Add an adreno-smmu-priv callback to get pagefault
> > >  info
> > >drm/msm: Improve the a6xx page fault handler
> > >
> > > Rob Clark (2):
> > >iommu/arm-smmu-qcom: Add stall support
> > >drm/msm: devcoredump iommu fault support
> > >
> > >   drivers/gpu/drm/msm/adreno/a5xx_gpu.c   |  23 +++-
> > >   drivers/gpu/drm/msm/adreno/a6xx_gpu.c   | 110 +++-
> > >   drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c |  42 ++--
> > >   drivers/gpu/drm/msm/adreno/adreno_gpu.c |  15 +++
> > >   drivers/gpu/drm/msm/msm_gem.h   |   1 +
> > >   drivers/gpu/drm/msm/msm_gem_submit.c|   1 +
> > >   drivers/gpu/drm/msm/msm_gpu.c   |  48 +
> > >   drivers/gpu/drm/msm/msm_gpu.h   |  17 +++
> > >   drivers/gpu/drm/msm/msm_gpummu.c|   5 +
> > >   drivers/gpu/drm/msm/msm_iommu.c |  22 +++-
> > >   drivers/gpu/drm/msm/msm_mmu.h   |   5 +-
> > >   drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c  |  50 +
> > >   drivers/iommu/arm/arm-smmu/arm-smmu.c   |   9 +-
> > >   drivers/iommu/arm/arm-smmu/arm-smmu.h   |   2 +
> > >   include/linux/adreno-smmu-priv.h|  38 ++-
> > >   15 files changed, 367 insertions(+), 21 deletions(-)
> > >
> >
> >
> > --
> > With best wishes
> > Dmitry
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v5 3/5] drm/msm: Improve the a6xx page fault handler

2021-06-24 Thread Bjorn Andersson
On Thu 10 Jun 16:44 CDT 2021, Rob Clark wrote:
[..]
> diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c
> index 50d881794758..6975b95c3c29 100644
> --- a/drivers/gpu/drm/msm/msm_iommu.c
> +++ b/drivers/gpu/drm/msm/msm_iommu.c
> @@ -211,8 +211,17 @@ static int msm_fault_handler(struct iommu_domain 
> *domain, struct device *dev,
>   unsigned long iova, int flags, void *arg)
>  {
>   struct msm_iommu *iommu = arg;
> + struct adreno_smmu_priv *adreno_smmu = dev_get_drvdata(iommu->base.dev);
> + struct adreno_smmu_fault_info info, *ptr = NULL;
> +
> + if (adreno_smmu->get_fault_info) {

This seemed reasonable when I read it last time, but I didn't realize
that the msm_fault_handler() is installed for all msm_iommu instances.

So while we're trying to recover from the boot splash and setup the new
framebuffer we end up here with iommu->base.dev being the mdss device.
Naturally drvdata of mdss is not a struct adreno_smmu_priv.

> + adreno_smmu->get_fault_info(adreno_smmu->cookie, );

So here we just jump straight out into hyperspace, never to return.

Not sure how to wire this up to avoid the problem, but right now I don't
think we can boot any device with a boot splash.

Regards,
Bjorn

> + ptr = 
> + }
> +
>   if (iommu->base.handler)
> - return iommu->base.handler(iommu->base.arg, iova, flags);
> + return iommu->base.handler(iommu->base.arg, iova, flags, ptr);
> +
>   pr_warn_ratelimited("*** fault: iova=%16lx, flags=%d\n", iova, flags);
>   return 0;
>  }
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v5 4/5] iommu/arm-smmu-qcom: Add stall support

2021-06-14 Thread Bjorn Andersson
On Thu 10 Jun 16:44 CDT 2021, Rob Clark wrote:

> From: Rob Clark 
> 
> Add, via the adreno-smmu-priv interface, a way for the GPU to request
> the SMMU to stall translation on faults, and then later resume the
> translation, either retrying or terminating the current translation.
> 
> This will be used on the GPU side to "freeze" the GPU while we snapshot
> useful state for devcoredump.
> 
> Signed-off-by: Rob Clark 

Reviewed-by: Bjorn Andersson 

Regards,
Bjorn

> ---
>  drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 33 ++
>  include/linux/adreno-smmu-priv.h   |  7 +
>  2 files changed, 40 insertions(+)
> 
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c 
> b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> index b2e31ea84128..61fc645c1325 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> @@ -13,6 +13,7 @@ struct qcom_smmu {
>   struct arm_smmu_device smmu;
>   bool bypass_quirk;
>   u8 bypass_cbndx;
> + u32 stall_enabled;
>  };
>  
>  static struct qcom_smmu *to_qcom_smmu(struct arm_smmu_device *smmu)
> @@ -23,12 +24,17 @@ static struct qcom_smmu *to_qcom_smmu(struct 
> arm_smmu_device *smmu)
>  static void qcom_adreno_smmu_write_sctlr(struct arm_smmu_device *smmu, int 
> idx,
>   u32 reg)
>  {
> + struct qcom_smmu *qsmmu = to_qcom_smmu(smmu);
> +
>   /*
>* On the GPU device we want to process subsequent transactions after a
>* fault to keep the GPU from hanging
>*/
>   reg |= ARM_SMMU_SCTLR_HUPCF;
>  
> + if (qsmmu->stall_enabled & BIT(idx))
> + reg |= ARM_SMMU_SCTLR_CFCFG;
> +
>   arm_smmu_cb_write(smmu, idx, ARM_SMMU_CB_SCTLR, reg);
>  }
>  
> @@ -48,6 +54,31 @@ static void qcom_adreno_smmu_get_fault_info(const void 
> *cookie,
>   info->contextidr = arm_smmu_cb_read(smmu, cfg->cbndx, 
> ARM_SMMU_CB_CONTEXTIDR);
>  }
>  
> +static void qcom_adreno_smmu_set_stall(const void *cookie, bool enabled)
> +{
> + struct arm_smmu_domain *smmu_domain = (void *)cookie;
> + struct arm_smmu_cfg *cfg = _domain->cfg;
> + struct qcom_smmu *qsmmu = to_qcom_smmu(smmu_domain->smmu);
> +
> + if (enabled)
> + qsmmu->stall_enabled |= BIT(cfg->cbndx);
> + else
> + qsmmu->stall_enabled &= ~BIT(cfg->cbndx);
> +}
> +
> +static void qcom_adreno_smmu_resume_translation(const void *cookie, bool 
> terminate)
> +{
> + struct arm_smmu_domain *smmu_domain = (void *)cookie;
> + struct arm_smmu_cfg *cfg = _domain->cfg;
> + struct arm_smmu_device *smmu = smmu_domain->smmu;
> + u32 reg = 0;
> +
> + if (terminate)
> + reg |= ARM_SMMU_RESUME_TERMINATE;
> +
> + arm_smmu_cb_write(smmu, cfg->cbndx, ARM_SMMU_CB_RESUME, reg);
> +}
> +
>  #define QCOM_ADRENO_SMMU_GPU_SID 0
>  
>  static bool qcom_adreno_smmu_is_gpu_device(struct device *dev)
> @@ -173,6 +204,8 @@ static int qcom_adreno_smmu_init_context(struct 
> arm_smmu_domain *smmu_domain,
>   priv->get_ttbr1_cfg = qcom_adreno_smmu_get_ttbr1_cfg;
>   priv->set_ttbr0_cfg = qcom_adreno_smmu_set_ttbr0_cfg;
>   priv->get_fault_info = qcom_adreno_smmu_get_fault_info;
> + priv->set_stall = qcom_adreno_smmu_set_stall;
> + priv->resume_translation = qcom_adreno_smmu_resume_translation;
>  
>   return 0;
>  }
> diff --git a/include/linux/adreno-smmu-priv.h 
> b/include/linux/adreno-smmu-priv.h
> index 53fe32fb9214..c637e0997f6d 100644
> --- a/include/linux/adreno-smmu-priv.h
> +++ b/include/linux/adreno-smmu-priv.h
> @@ -45,6 +45,11 @@ struct adreno_smmu_fault_info {
>   * TTBR0 translation is enabled with the specified cfg
>   * @get_fault_info: Called by the GPU fault handler to get information about
>   *  the fault
> + * @set_stall: Configure whether stall on fault (CFCFG) is enabled.  Call
> + * before set_ttbr0_cfg().  If stalling on fault is enabled,
> + * the GPU driver must call resume_translation()
> + * @resume_translation: Resume translation after a fault
> + *
>   *
>   * The GPU driver (drm/msm) and adreno-smmu work together for controlling
>   * the GPU's SMMU instance.  This is by necessity, as the GPU is directly
> @@ -60,6 +65,8 @@ struct adreno_smmu_priv {
>  const struct io_pgtable_cfg *(*get_ttbr1_cfg)(const void *cookie);
>  int (*set_ttbr0_cfg)(const void *cookie, const struct io_pgtable_cfg 
> *cfg);
>  void (*get_fault_info)(const void *cookie, struct adreno_smmu_fault_info 
> *info);
> +void (*set_stall)(const void *cookie, bool enabled);
> +void (*resume_translation)(const void *cookie, bool terminate);
>  };
>  
>  #endif /* __ADRENO_SMMU_PRIV_H */
> -- 
> 2.31.1
> 
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v5 3/5] drm/msm: Improve the a6xx page fault handler

2021-06-14 Thread Bjorn Andersson
On Thu 10 Jun 16:44 CDT 2021, Rob Clark wrote:

> From: Jordan Crouse 
> 
> Use the new adreno-smmu-priv fault info function to get more SMMU
> debug registers and print the current TTBR0 to debug per-instance
> pagetables and figure out which GPU block generated the request.
> 

Acked-by: Bjorn Andersson 

Regards,
Bjorn

> Signed-off-by: Jordan Crouse 
> Signed-off-by: Rob Clark 
> ---
>  drivers/gpu/drm/msm/adreno/a5xx_gpu.c |  4 +-
>  drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 76 +--
>  drivers/gpu/drm/msm/msm_iommu.c   | 11 +++-
>  drivers/gpu/drm/msm/msm_mmu.h |  4 +-
>  4 files changed, 87 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c 
> b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
> index f46562c12022..eb030b00bff4 100644
> --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
> +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
> @@ -1075,7 +1075,7 @@ bool a5xx_idle(struct msm_gpu *gpu, struct 
> msm_ringbuffer *ring)
>   return true;
>  }
>  
> -static int a5xx_fault_handler(void *arg, unsigned long iova, int flags)
> +static int a5xx_fault_handler(void *arg, unsigned long iova, int flags, void 
> *data)
>  {
>   struct msm_gpu *gpu = arg;
>   pr_warn_ratelimited("*** gpu fault: iova=%08lx, flags=%d 
> (%u,%u,%u,%u)\n",
> @@ -1085,7 +1085,7 @@ static int a5xx_fault_handler(void *arg, unsigned long 
> iova, int flags)
>   gpu_read(gpu, REG_A5XX_CP_SCRATCH_REG(6)),
>   gpu_read(gpu, REG_A5XX_CP_SCRATCH_REG(7)));
>  
> - return -EFAULT;
> + return 0;
>  }
>  
>  static void a5xx_cp_err_irq(struct msm_gpu *gpu)
> diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c 
> b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> index c7f0ddb12d8f..fc19db10bff1 100644
> --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> @@ -1032,18 +1032,88 @@ static void a6xx_recover(struct msm_gpu *gpu)
>   msm_gpu_hw_init(gpu);
>  }
>  
> -static int a6xx_fault_handler(void *arg, unsigned long iova, int flags)
> +static const char *a6xx_uche_fault_block(struct msm_gpu *gpu, u32 mid)
> +{
> + static const char *uche_clients[7] = {
> + "VFD", "SP", "VSC", "VPC", "HLSQ", "PC", "LRZ",
> + };
> + u32 val;
> +
> + if (mid < 1 || mid > 3)
> + return "UNKNOWN";
> +
> + /*
> +  * The source of the data depends on the mid ID read from FSYNR1.
> +  * and the client ID read from the UCHE block
> +  */
> + val = gpu_read(gpu, REG_A6XX_UCHE_CLIENT_PF);
> +
> + /* mid = 3 is most precise and refers to only one block per client */
> + if (mid == 3)
> + return uche_clients[val & 7];
> +
> + /* For mid=2 the source is TP or VFD except when the client id is 0 */
> + if (mid == 2)
> + return ((val & 7) == 0) ? "TP" : "TP|VFD";
> +
> + /* For mid=1 just return "UCHE" as a catchall for everything else */
> + return "UCHE";
> +}
> +
> +static const char *a6xx_fault_block(struct msm_gpu *gpu, u32 id)
> +{
> + if (id == 0)
> + return "CP";
> + else if (id == 4)
> + return "CCU";
> + else if (id == 6)
> + return "CDP Prefetch";
> +
> + return a6xx_uche_fault_block(gpu, id);
> +}
> +
> +#define ARM_SMMU_FSR_TF BIT(1)
> +#define ARM_SMMU_FSR_PF  BIT(3)
> +#define ARM_SMMU_FSR_EF  BIT(4)
> +
> +static int a6xx_fault_handler(void *arg, unsigned long iova, int flags, void 
> *data)
>  {
>   struct msm_gpu *gpu = arg;
> + struct adreno_smmu_fault_info *info = data;
> + const char *type = "UNKNOWN";
>  
> - pr_warn_ratelimited("*** gpu fault: iova=%08lx, flags=%d 
> (%u,%u,%u,%u)\n",
> + /*
> +  * Print a default message if we couldn't get the data from the
> +  * adreno-smmu-priv
> +  */
> + if (!info) {
> + pr_warn_ratelimited("*** gpu fault: iova=%.16lx flags=%d 
> (%u,%u,%u,%u)\n",
>   iova, flags,
>   gpu_read(gpu, REG_A6XX_CP_SCRATCH_REG(4)),
>   gpu_read(gpu, REG_A6XX_CP_SCRATCH_REG(5)),
>   gpu_read(gpu, REG_A6XX_CP_SCRATCH_REG(6)),
>   gpu_read(gpu, REG_A6XX_CP_SCRATCH_REG(7)));
>  
> - return -EFAULT;
> + return 0;
> + }
> +
> + if (info->fsr & ARM_SMMU_

Re: [PATCH v5 2/5] iommu/arm-smmu-qcom: Add an adreno-smmu-priv callback to get pagefault info

2021-06-14 Thread Bjorn Andersson
On Thu 10 Jun 16:44 CDT 2021, Rob Clark wrote:

> From: Jordan Crouse 
> 
> Add a callback in adreno-smmu-priv to read interesting SMMU
> registers to provide an opportunity for a richer debug experience
> in the GPU driver.
> 
> Signed-off-by: Jordan Crouse 
> Signed-off-by: Rob Clark 

I presume this implies that more generic options has been discussed.
Regardless, if further conclusions are made in that regard I expect that
this could serve as a base for such efforts.

Reviewed-by: Bjorn Andersson 

Regards,
Bjorn

> ---
>  drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 17 
>  drivers/iommu/arm/arm-smmu/arm-smmu.h  |  2 ++
>  include/linux/adreno-smmu-priv.h   | 31 +-
>  3 files changed, 49 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c 
> b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> index 98b3a1c2a181..b2e31ea84128 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> @@ -32,6 +32,22 @@ static void qcom_adreno_smmu_write_sctlr(struct 
> arm_smmu_device *smmu, int idx,
>   arm_smmu_cb_write(smmu, idx, ARM_SMMU_CB_SCTLR, reg);
>  }
>  
> +static void qcom_adreno_smmu_get_fault_info(const void *cookie,
> + struct adreno_smmu_fault_info *info)
> +{
> + struct arm_smmu_domain *smmu_domain = (void *)cookie;
> + struct arm_smmu_cfg *cfg = _domain->cfg;
> + struct arm_smmu_device *smmu = smmu_domain->smmu;
> +
> + info->fsr = arm_smmu_cb_read(smmu, cfg->cbndx, ARM_SMMU_CB_FSR);
> + info->fsynr0 = arm_smmu_cb_read(smmu, cfg->cbndx, ARM_SMMU_CB_FSYNR0);
> + info->fsynr1 = arm_smmu_cb_read(smmu, cfg->cbndx, ARM_SMMU_CB_FSYNR1);
> + info->far = arm_smmu_cb_readq(smmu, cfg->cbndx, ARM_SMMU_CB_FAR);
> + info->cbfrsynra = arm_smmu_gr1_read(smmu, 
> ARM_SMMU_GR1_CBFRSYNRA(cfg->cbndx));
> + info->ttbr0 = arm_smmu_cb_read(smmu, cfg->cbndx, ARM_SMMU_CB_TTBR0);
> + info->contextidr = arm_smmu_cb_read(smmu, cfg->cbndx, 
> ARM_SMMU_CB_CONTEXTIDR);
> +}
> +
>  #define QCOM_ADRENO_SMMU_GPU_SID 0
>  
>  static bool qcom_adreno_smmu_is_gpu_device(struct device *dev)
> @@ -156,6 +172,7 @@ static int qcom_adreno_smmu_init_context(struct 
> arm_smmu_domain *smmu_domain,
>   priv->cookie = smmu_domain;
>   priv->get_ttbr1_cfg = qcom_adreno_smmu_get_ttbr1_cfg;
>   priv->set_ttbr0_cfg = qcom_adreno_smmu_set_ttbr0_cfg;
> + priv->get_fault_info = qcom_adreno_smmu_get_fault_info;
>  
>   return 0;
>  }
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.h 
> b/drivers/iommu/arm/arm-smmu/arm-smmu.h
> index c31a59d35c64..84c21c4b0691 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu.h
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.h
> @@ -224,6 +224,8 @@ enum arm_smmu_cbar_type {
>  #define ARM_SMMU_CB_FSYNR0   0x68
>  #define ARM_SMMU_FSYNR0_WNR  BIT(4)
>  
> +#define ARM_SMMU_CB_FSYNR1   0x6c
> +
>  #define ARM_SMMU_CB_S1_TLBIVA0x600
>  #define ARM_SMMU_CB_S1_TLBIASID  0x610
>  #define ARM_SMMU_CB_S1_TLBIVAL   0x620
> diff --git a/include/linux/adreno-smmu-priv.h 
> b/include/linux/adreno-smmu-priv.h
> index a889f28afb42..53fe32fb9214 100644
> --- a/include/linux/adreno-smmu-priv.h
> +++ b/include/linux/adreno-smmu-priv.h
> @@ -8,6 +8,32 @@
>  
>  #include 
>  
> +/**
> + * struct adreno_smmu_fault_info - container for key fault information
> + *
> + * @far: The faulting IOVA from ARM_SMMU_CB_FAR
> + * @ttbr0: The current TTBR0 pagetable from ARM_SMMU_CB_TTBR0
> + * @contextidr: The value of ARM_SMMU_CB_CONTEXTIDR
> + * @fsr: The fault status from ARM_SMMU_CB_FSR
> + * @fsynr0: The value of FSYNR0 from ARM_SMMU_CB_FSYNR0
> + * @fsynr1: The value of FSYNR1 from ARM_SMMU_CB_FSYNR0
> + * @cbfrsynra: The value of CBFRSYNRA from ARM_SMMU_GR1_CBFRSYNRA(idx)
> + *
> + * This struct passes back key page fault information to the GPU driver
> + * through the get_fault_info function pointer.
> + * The GPU driver can use this information to print informative
> + * log messages and provide deeper GPU specific insight into the fault.
> + */
> +struct adreno_smmu_fault_info {
> + u64 far;
> + u64 ttbr0;
> + u32 contextidr;
> + u32 fsr;
> + u32 fsynr0;
> + u32 fsynr1;
> + u32 cbfrsynra;
> +};
> +
>  /**
>   * struct adreno_smmu_priv - private interface between adreno-smmu and GPU
>   *
> @@ -17,6 +43,8 @@
>   * @set_ttbr0_cfg: Set the TTBR0 config for the GPUs context bank.  A
>   * NULL config disables TTBR0 translation, otherwise
>   *  

Re: [PATCH v5 1/5] iommu/arm-smmu: Add support for driver IOMMU fault handlers

2021-06-14 Thread Bjorn Andersson
On Thu 10 Jun 16:44 CDT 2021, Rob Clark wrote:

> From: Jordan Crouse 
> 
> Call report_iommu_fault() to allow upper-level drivers to register their
> own fault handlers.
> 
> Signed-off-by: Jordan Crouse 
> Signed-off-by: Rob Clark 
> Acked-by: Will Deacon 

Reviewed-by: Bjorn Andersson 

Regards,
Bjorn

> ---
>  drivers/iommu/arm/arm-smmu/arm-smmu.c | 9 +++--
>  1 file changed, 7 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c 
> b/drivers/iommu/arm/arm-smmu/arm-smmu.c
> index 6f72c4d208ca..b4b32d31fc06 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
> @@ -408,6 +408,7 @@ static irqreturn_t arm_smmu_context_fault(int irq, void 
> *dev)
>   struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
>   struct arm_smmu_device *smmu = smmu_domain->smmu;
>   int idx = smmu_domain->cfg.cbndx;
> + int ret;
>  
>   fsr = arm_smmu_cb_read(smmu, idx, ARM_SMMU_CB_FSR);
>   if (!(fsr & ARM_SMMU_FSR_FAULT))
> @@ -417,8 +418,12 @@ static irqreturn_t arm_smmu_context_fault(int irq, void 
> *dev)
>   iova = arm_smmu_cb_readq(smmu, idx, ARM_SMMU_CB_FAR);
>   cbfrsynra = arm_smmu_gr1_read(smmu, ARM_SMMU_GR1_CBFRSYNRA(idx));
>  
> - dev_err_ratelimited(smmu->dev,
> - "Unhandled context fault: fsr=0x%x, iova=0x%08lx, fsynr=0x%x, 
> cbfrsynra=0x%x, cb=%d\n",
> + ret = report_iommu_fault(domain, NULL, iova,
> + fsynr & ARM_SMMU_FSYNR0_WNR ? IOMMU_FAULT_WRITE : 
> IOMMU_FAULT_READ);
> +
> + if (ret == -ENOSYS)
> + dev_err_ratelimited(smmu->dev,
> + "Unhandled context fault: fsr=0x%x, iova=0x%08lx, fsynr=0x%x, 
> cbfrsynra=0x%x, cb=%d\n",
>   fsr, iova, fsynr, cbfrsynra, idx);
>  
>   arm_smmu_cb_write(smmu, idx, ARM_SMMU_CB_FSR, fsr);
> -- 
> 2.31.1
> 
> ___
> iommu mailing list
> iommu@lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/iommu
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH V2] iommu: arm-smmu-qcom: Add sm6125 compatible

2021-05-24 Thread Bjorn Andersson
On Sun 23 May 16:25 CDT 2021, Martin Botka wrote:

> Add compatible for SM6125 SoC
> 

Reviewed-by: Bjorn Andersson 

But please, don't forget to update the dt-binding.

Regards,
Bjorn

> Signed-off-by: Martin Botka 
> ---
> Changes in V2:
> Add commit description
>  drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c 
> b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> index 98b3a1c2a181..7455bcc92f43 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> @@ -333,6 +333,7 @@ static const struct of_device_id __maybe_unused 
> qcom_smmu_impl_of_match[] = {
>   { .compatible = "qcom,sc8180x-smmu-500" },
>   { .compatible = "qcom,sdm630-smmu-v2" },
>   { .compatible = "qcom,sdm845-smmu-500" },
> + { .compatible = "qcom,sm6125-smmu-500" },
>   { .compatible = "qcom,sm8150-smmu-500" },
>   { .compatible = "qcom,sm8250-smmu-500" },
>   { .compatible = "qcom,sm8350-smmu-500" },
> -- 
> 2.31.1
> 
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCHv3 1/2] iommu/arm-smmu-qcom: Add SC7280 SMMU compatible

2021-05-24 Thread Bjorn Andersson
On Tue 20 Apr 01:04 CDT 2021, Sai Prakash Ranjan wrote:

> Add compatible for SC7280 SMMU to use the Qualcomm Technologies, Inc.
> specific implementation.
> 

Reviewed-by: Bjorn Andersson 

Regards,
Bjorn

> Signed-off-by: Sai Prakash Ranjan 
> ---
>  drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c 
> b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> index 98b3a1c2a181..bea3ee0dabc2 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> @@ -166,6 +166,7 @@ static const struct of_device_id 
> qcom_smmu_client_of_match[] __maybe_unused = {
>   { .compatible = "qcom,mdss" },
>   { .compatible = "qcom,sc7180-mdss" },
>   { .compatible = "qcom,sc7180-mss-pil" },
> + { .compatible = "qcom,sc7280-mdss" },
>   { .compatible = "qcom,sc8180x-mdss" },
>   { .compatible = "qcom,sdm845-mdss" },
>   { .compatible = "qcom,sdm845-mss-pil" },
> @@ -330,6 +331,7 @@ static struct arm_smmu_device *qcom_smmu_create(struct 
> arm_smmu_device *smmu,
>  static const struct of_device_id __maybe_unused qcom_smmu_impl_of_match[] = {
>   { .compatible = "qcom,msm8998-smmu-v2" },
>   { .compatible = "qcom,sc7180-smmu-500" },
> + { .compatible = "qcom,sc7280-smmu-500" },
>   { .compatible = "qcom,sc8180x-smmu-500" },
>   { .compatible = "qcom,sdm630-smmu-v2" },
>   { .compatible = "qcom,sdm845-smmu-500" },
> -- 
> QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
> of Code Aurora Forum, hosted by The Linux Foundation
> 
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 0/3] iommu/arm-smmu: Qualcomm bootsplash/efifb

2021-05-24 Thread Bjorn Andersson
On Mon 24 May 07:03 CDT 2021, Lee Jones wrote:

> On Wed, 8 Jan 2020 at 09:16, Will Deacon  wrote:
> 
> > On Thu, Dec 26, 2019 at 02:17:06PM -0800, Bjorn Andersson wrote:
> > > These patches implements the stream mapping inheritance that's necessary
> > in
> > > order to not hit a security violation as the display hardware looses its
> > stream
> > > mapping during initialization of arm-smmu in various Qualcomm platforms.
> > >
> > > This was previously posted as an RFC [1], changes since then involves the
> > > rebase and migration of the read-back code to the Qualcomm specific
> > > implementation, the mapping is maintained indefinitely - to handle probe
> > > deferring clients - and rewritten commit messages.
> >
> > I don't think we should solve this in a Qualcomm-specific manner. Please
> > can
> > you take a look at the proposal from Thierry [1] and see whether or not it
> > works for you?
> >
> 
> Did this or Thierry's solution ever gain traction?
> 

There was a few pieces that landed in the common code which allowed us
to deal with the quirks of the Qualcomm platform (turned out that just
reading back the settings wasn't the only piece necessary).

The "generic" solution is essentially the second half of
qcom_smmu_cfg_probe(), which ensures that as the SMMU is reset it will
do so with bypass mappings for all stream mappings the boot loader left
us.

> Or are all the parties still 'solving' this downstream?
> 

I believe that Qualcomm has adopted the upstream solution in their
downstream kernel.

Regards,
Bjorn
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCHv2 2/2] iommu/arm-smmu-qcom: Move the adreno smmu specific impl earlier

2021-04-19 Thread Bjorn Andersson
On Fri 26 Feb 03:55 CST 2021, Sai Prakash Ranjan wrote:

> Adreno(GPU) SMMU and APSS(Application Processor SubSystem) SMMU
> both implement "arm,mmu-500" in some QTI SoCs and to run through
> adreno smmu specific implementation such as enabling split pagetables
> support, we need to match the "qcom,adreno-smmu" compatible first
> before apss smmu or else we will be running apps smmu implementation
> for adreno smmu and the additional features for adreno smmu is never
> set. For ex: we have "qcom,sc7280-smmu-500" compatible for both apps
> and adreno smmu implementing "arm,mmu-500", so the adreno smmu
> implementation is never reached because the current sequence checks
> for apps smmu compatible(qcom,sc7280-smmu-500) first and runs that
> specific impl and we never reach adreno smmu specific implementation.
> 
> Suggested-by: Akhil P Oommen 
> Signed-off-by: Sai Prakash Ranjan 

Sorry for taking my time thinking about this.

Reviewed-by: Bjorn Andersson 

Regards,
Bjorn

> ---
>  drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 12 +---
>  1 file changed, 9 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c 
> b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> index bea3ee0dabc2..03f048aebb80 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> @@ -345,11 +345,17 @@ struct arm_smmu_device *qcom_smmu_impl_init(struct 
> arm_smmu_device *smmu)
>  {
>   const struct device_node *np = smmu->dev->of_node;
>  
> - if (of_match_node(qcom_smmu_impl_of_match, np))
> - return qcom_smmu_create(smmu, _smmu_impl);
> -
> + /*
> +  * Do not change this order of implementation, i.e., first adreno
> +  * smmu impl and then apss smmu since we can have both implementing
> +  * arm,mmu-500 in which case we will miss setting adreno smmu specific
> +  * features if the order is changed.
> +  */
>   if (of_device_is_compatible(np, "qcom,adreno-smmu"))
>   return qcom_smmu_create(smmu, _adreno_smmu_impl);
>  
> + if (of_match_node(qcom_smmu_impl_of_match, np))
> + return qcom_smmu_create(smmu, _smmu_impl);
> +
>   return smmu;
>  }
> -- 
> QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
> of Code Aurora Forum, hosted by The Linux Foundation
> 
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCHv2 2/2] iommu/arm-smmu-qcom: Move the adreno smmu specific impl earlier

2021-03-11 Thread Bjorn Andersson
On Sat 27 Feb 07:53 CST 2021, Sai Prakash Ranjan wrote:

> Hi Bjorn,
> 
> On 2021-02-27 00:44, Bjorn Andersson wrote:
> > On Fri 26 Feb 12:23 CST 2021, Rob Clark wrote:
> > 
> > 
> > The current logic picks one of:
> > 1) is the compatible mentioned in qcom_smmu_impl_of_match[]
> > 2) is the compatible an adreno
> > 3) no quirks needed
> > 
> > The change flips the order of these, so the only way I can see this
> > change affecting things is if we expected a match on #2, but we got one
> > on #1.
> > 
> > Which implies that the instance that we want to act according to the
> > adreno impl was listed in qcom_smmu_impl_of_match[] - which either is
> > wrong, or there's a single instance that needs both behaviors.
> > 
> > (And I believe Jordan's answer confirms the latter - there's a single
> > SMMU instance that needs all them quirks at once)
> > 
> 
> Let me go through the problem statement in case my commit message wasn't
> clear. There are two SMMUs (APSS and GPU) on SC7280 and both are SMMU500
> (ARM SMMU IP).
> 
> APSS SMMU compatible - ("qcom,sc7280-smmu-500", "arm,mmu-500")
> GPU SMMU compatible - ("qcom,sc7280-smmu-500", "qcom,adreno-smmu", 
> "arm,mmu-500")
> 
> Now if we take SC7180 as an example, GPU SMMU was QSMMU(QCOM SMMU IP)
> and APSS SMMU was SMMU500(ARM SMMU IP).
> 
> APSS SMMU compatible - ("qcom,sc7180-smmu-500", "arm,mmu-500")
> GPU SMMU compatible - ("qcom,sc7180-smmu-v2", "qcom,adreno-smmu", 
> "qcom,smmu-v2")
> 
> Current code sequence without this patch,
> 
> if (of_match_node(qcom_smmu_impl_of_match, np))
>  return qcom_smmu_create(smmu, _smmu_impl);
> 
> if (of_device_is_compatible(np, "qcom,adreno-smmu"))
> return qcom_smmu_create(smmu, _adreno_smmu_impl);
> 
> Now if we look at the compatible for SC7180, there is no problem because
> the APSS SMMU will match the one in qcom_smmu_impl_of_match[] and GPU SMMU
> will match "qcom,adreno-smmu" because the compatible strings are different.
> But for SC7280, both the APSS SMMU and GPU SMMU 
> compatible("qcom,sc7280-smmu-500")
> are same. So GPU SMMU will match with the one in qcom_smmu_impl_of_match[]
> i.e.., "qcom,sc7280-smmu-500" which functionally doesn't cause any problem
> but we will miss settings for split pagetables which are part of GPU SMMU
> specific implementation.
> 
> We can avoid this with yet another new compatible for GPU SMMU something like
> "qcom,sc7280-adreno-smmu-500" but since we can handle this easily in the
> driver and since the IPs are same, meaning if there was a hardware quirk
> required, then we would need to apply to both of them and would this 
> additional
> compatible be of any help?
> 

No, I think you're doing the right thing of having them both. I just
didn't remember us doing that.

> Coming to the part of quirks now, you are right saying both SMMUs will need
> to have the same quirks in SC7280 and similar others where both are based on
> same IPs but those should probably be *hardware quirks* and if they are
> software based like the S2CR quirk depending on the firmware, then it might
> not be applicable to both. In case if it is applicable, then as Jordan 
> mentioned,
> we can add the same quirks in GPU SMMU implementation.
> 

I do suspect that at some point (probably sooner than later) we'd have
to support both inheriting of stream from the bootloader and the Adreno
"quirks" in the same instance.

But for now this is okay to me.

Regards,
Bjorn
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCHv2 2/2] iommu/arm-smmu-qcom: Move the adreno smmu specific impl earlier

2021-02-26 Thread Bjorn Andersson
On Fri 26 Feb 12:23 CST 2021, Rob Clark wrote:

> On Fri, Feb 26, 2021 at 9:24 AM Bjorn Andersson
>  wrote:
> >
> > On Fri 26 Feb 03:55 CST 2021, Sai Prakash Ranjan wrote:
> >
> > > Adreno(GPU) SMMU and APSS(Application Processor SubSystem) SMMU
> > > both implement "arm,mmu-500" in some QTI SoCs and to run through
> > > adreno smmu specific implementation such as enabling split pagetables
> > > support, we need to match the "qcom,adreno-smmu" compatible first
> > > before apss smmu or else we will be running apps smmu implementation
> > > for adreno smmu and the additional features for adreno smmu is never
> > > set. For ex: we have "qcom,sc7280-smmu-500" compatible for both apps
> > > and adreno smmu implementing "arm,mmu-500", so the adreno smmu
> > > implementation is never reached because the current sequence checks
> > > for apps smmu compatible(qcom,sc7280-smmu-500) first and runs that
> > > specific impl and we never reach adreno smmu specific implementation.
> > >
> >
> > So you're saying that you have a single SMMU instance that's compatible
> > with both an entry in qcom_smmu_impl_of_match[] and "qcom,adreno-smmu"?
> >
> > Per your proposed change we will pick the adreno ops _only_ for this
> > component, essentially disabling the non-Adreno quirks selected by the
> > qcom impl. As such keeping the non-adreno compatible in the
> > qcom_smmu_impl_init[] seems to only serve to obfuscate the situation.
> >
> > Don't we somehow need the combined set of quirks? (At least if we're
> > running this with a standard UEFI based boot flow?)
> >
> 
> are you thinking of the apps-smmu handover of display context bank?
> That shouldn't change, the only thing that changes is that gpu-smmu
> becomes an mmu-500, whereas previously only apps-smmu was..
> 

The current logic picks one of:
1) is the compatible mentioned in qcom_smmu_impl_of_match[]
2) is the compatible an adreno
3) no quirks needed

The change flips the order of these, so the only way I can see this
change affecting things is if we expected a match on #2, but we got one
on #1.

Which implies that the instance that we want to act according to the
adreno impl was listed in qcom_smmu_impl_of_match[] - which either is
wrong, or there's a single instance that needs both behaviors.

(And I believe Jordan's answer confirms the latter - there's a single
SMMU instance that needs all them quirks at once)

Regards,
Bjorn
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCHv2 2/2] iommu/arm-smmu-qcom: Move the adreno smmu specific impl earlier

2021-02-26 Thread Bjorn Andersson
On Fri 26 Feb 03:55 CST 2021, Sai Prakash Ranjan wrote:

> Adreno(GPU) SMMU and APSS(Application Processor SubSystem) SMMU
> both implement "arm,mmu-500" in some QTI SoCs and to run through
> adreno smmu specific implementation such as enabling split pagetables
> support, we need to match the "qcom,adreno-smmu" compatible first
> before apss smmu or else we will be running apps smmu implementation
> for adreno smmu and the additional features for adreno smmu is never
> set. For ex: we have "qcom,sc7280-smmu-500" compatible for both apps
> and adreno smmu implementing "arm,mmu-500", so the adreno smmu
> implementation is never reached because the current sequence checks
> for apps smmu compatible(qcom,sc7280-smmu-500) first and runs that
> specific impl and we never reach adreno smmu specific implementation.
> 

So you're saying that you have a single SMMU instance that's compatible
with both an entry in qcom_smmu_impl_of_match[] and "qcom,adreno-smmu"?

Per your proposed change we will pick the adreno ops _only_ for this
component, essentially disabling the non-Adreno quirks selected by the
qcom impl. As such keeping the non-adreno compatible in the
qcom_smmu_impl_init[] seems to only serve to obfuscate the situation.

Don't we somehow need the combined set of quirks? (At least if we're
running this with a standard UEFI based boot flow?)

Regards,
Bjorn

> Suggested-by: Akhil P Oommen 
> Signed-off-by: Sai Prakash Ranjan 
> ---
>  drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 12 +---
>  1 file changed, 9 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c 
> b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> index bea3ee0dabc2..03f048aebb80 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> @@ -345,11 +345,17 @@ struct arm_smmu_device *qcom_smmu_impl_init(struct 
> arm_smmu_device *smmu)
>  {
>   const struct device_node *np = smmu->dev->of_node;
>  
> - if (of_match_node(qcom_smmu_impl_of_match, np))
> - return qcom_smmu_create(smmu, _smmu_impl);
> -
> + /*
> +  * Do not change this order of implementation, i.e., first adreno
> +  * smmu impl and then apss smmu since we can have both implementing
> +  * arm,mmu-500 in which case we will miss setting adreno smmu specific
> +  * features if the order is changed.
> +  */
>   if (of_device_is_compatible(np, "qcom,adreno-smmu"))
>   return qcom_smmu_create(smmu, _adreno_smmu_impl);
>  
> + if (of_match_node(qcom_smmu_impl_of_match, np))
> + return qcom_smmu_create(smmu, _smmu_impl);
> +
>   return smmu;
>  }
> -- 
> QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
> of Code Aurora Forum, hosted by The Linux Foundation
> 
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 2/2] iommu/arm-smmu-qcom: Add Qualcomm SC8180X impl

2021-01-20 Thread Bjorn Andersson
The primary SMMU found in Qualcomm SC8180X platform needs to use the
Qualcomm implementation, so add a specific compatible for this.

Signed-off-by: Bjorn Andersson 
---
 drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c 
b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
index bcda17012aee..82c7edc6e025 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
@@ -166,6 +166,7 @@ static const struct of_device_id 
qcom_smmu_client_of_match[] __maybe_unused = {
{ .compatible = "qcom,mdss" },
{ .compatible = "qcom,sc7180-mdss" },
{ .compatible = "qcom,sc7180-mss-pil" },
+   { .compatible = "qcom,sc8180x-mdss" },
{ .compatible = "qcom,sdm845-mdss" },
{ .compatible = "qcom,sdm845-mss-pil" },
{ }
@@ -327,6 +328,7 @@ static struct arm_smmu_device *qcom_smmu_create(struct 
arm_smmu_device *smmu,
 static const struct of_device_id __maybe_unused qcom_smmu_impl_of_match[] = {
{ .compatible = "qcom,msm8998-smmu-v2" },
{ .compatible = "qcom,sc7180-smmu-500" },
+   { .compatible = "qcom,sc8180x-smmu-500" },
{ .compatible = "qcom,sdm630-smmu-v2" },
{ .compatible = "qcom,sdm845-smmu-500" },
{ .compatible = "qcom,sm8150-smmu-500" },
-- 
2.29.2

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 1/2] dt-bindings: arm-smmu-qcom: Add Qualcomm SC8180X compatible

2021-01-20 Thread Bjorn Andersson
Add compatible for the ARM SMMU found in the Qualcomm SC8180x platform.

Signed-off-by: Bjorn Andersson 
---
 Documentation/devicetree/bindings/iommu/arm,smmu.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml 
b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
index 3b63f2ae24db..c50198e17d52 100644
--- a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
+++ b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
@@ -34,6 +34,7 @@ properties:
 items:
   - enum:
   - qcom,sc7180-smmu-500
+  - qcom,sc8180x-smmu-500
   - qcom,sdm845-smmu-500
   - qcom,sm8150-smmu-500
   - qcom,sm8250-smmu-500
-- 
2.29.2

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH] iommu/arm-smmu-qcom: Initialize SCTLR of the bypass context

2021-01-05 Thread Bjorn Andersson
On SM8150 it's occasionally observed that the boot hangs in between the
writing of SMEs and context banks in arm_smmu_device_reset().

The problem seems to coincide with a display refresh happening after
updating the stream mapping, but before clearing - and there by
disabling translation - the context bank picked to emulate translation
bypass.

Resolve this by explicitly disabling the bypass context already in
cfg_probe.

Fixes: f9081b8ff593 ("iommu/arm-smmu-qcom: Implement S2CR quirk")
Signed-off-by: Bjorn Andersson 
---
 drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c 
b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
index 5dff7ffbef11..1b83d140742f 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
@@ -196,6 +196,8 @@ static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu)
 
set_bit(qsmmu->bypass_cbndx, smmu->context_map);
 
+   arm_smmu_cb_write(smmu, qsmmu->bypass_cbndx, ARM_SMMU_CB_SCTLR, 
0);
+
reg = FIELD_PREP(ARM_SMMU_CBAR_TYPE, 
CBAR_TYPE_S1_TRANS_S2_BYPASS);
arm_smmu_gr1_write(smmu, 
ARM_SMMU_GR1_CBAR(qsmmu->bypass_cbndx), reg);
}
-- 
2.29.2

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH -next] iommu: msm_iommu: Delete useless kfree code

2020-12-14 Thread Bjorn Andersson
On Mon 14 Dec 07:47 CST 2020, Zheng Yongjun wrote:

> The parameter of kfree function is NULL, so kfree code is useless, delete it.
> 
> Signed-off-by: Zheng Yongjun 

Reviewed-by: Bjorn Andersson 

Regards,
Bjorn

> ---
>  drivers/iommu/msm_iommu.c | 6 +-
>  1 file changed, 1 insertion(+), 5 deletions(-)
> 
> diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c
> index 3615cd6241c4..1286674a1322 100644
> --- a/drivers/iommu/msm_iommu.c
> +++ b/drivers/iommu/msm_iommu.c
> @@ -319,7 +319,7 @@ static struct iommu_domain 
> *msm_iommu_domain_alloc(unsigned type)
>  
>   priv = kzalloc(sizeof(*priv), GFP_KERNEL);
>   if (!priv)
> - goto fail_nomem;
> + return NULL;
>  
>   INIT_LIST_HEAD(>list_attached);
>  
> @@ -328,10 +328,6 @@ static struct iommu_domain 
> *msm_iommu_domain_alloc(unsigned type)
>   priv->domain.geometry.force_aperture = true;
>  
>   return >domain;
> -
> -fail_nomem:
> - kfree(priv);
> - return NULL;
>  }
>  
>  static void msm_iommu_domain_free(struct iommu_domain *domain)
> -- 
> 2.22.0
> 
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH] Revert "firmware: QCOM_SCM: Allow qcom_scm driver to be loadable as a permenent module"

2020-11-19 Thread Bjorn Andersson
On Thu, Nov 19, 2020 at 11:42 AM Thierry Reding
 wrote:
>
> From: Thierry Reding 
>
> Commit d0511b5496c0 ("firmware: QCOM_SCM: Allow qcom_scm driver to be
> loadable as a permenent module") causes the ARM SMMU driver to be built
> as a loadable module when using the Aarch64 default configuration. This
> in turn causes problems because if the loadable module is not shipped
> in an initial ramdisk, then the deferred probe timeout mechanism will
> cause all SMMU masters to probe without SMMU support and fall back to
> just plain DMA ops (not IOMMU-backed).
>
> Once the system has mounted the rootfs, the ARM SMMU driver will then
> be loaded, but since the ARM SMMU driver faults by default, this causes
> a slew of SMMU faults for the SMMU masters that have already been set
> up with plain DMA ops and cause these devices to malfunction.
>

FWIW I had the same issues on the Qualcomm platform and merged a patch
that turns QCOM_SCM=y in arm64 defconfig earlier today. So this should
hide the problem in next linux-next. (And it really should be =y in
defconfig regardless of this revert or not).

> Revert that commit to unbreak things while we look for an alternative
> solution.
>

I don't fancy the fact that we have a situation where if you're
unlucky to have probe deferrals lingering past late initcall things
will start to just break and this from a growing number of resource
types. But I also don't see any alternatives to fixing the kernel to
handle this gracefully.

Regards,
Bjorn
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v5 2/2] firmware: QCOM_SCM: Allow qcom_scm driver to be loadable as a permenent module

2020-11-05 Thread Bjorn Andersson
On Fri 30 Oct 19:38 CDT 2020, John Stultz wrote:

> Allow the qcom_scm driver to be loadable as a permenent module.
> 
> This still uses the "depends on QCOM_SCM || !QCOM_SCM" bit to
> ensure that drivers that call into the qcom_scm driver are
> also built as modules. While not ideal in some cases its the
> only safe way I can find to avoid build errors without having
> those drivers select QCOM_SCM and have to force it on (as
> QCOM_SCM=n can be valid for those drivers).
> 
> Cc: Catalin Marinas 
> Cc: Will Deacon 
> Cc: Andy Gross 
> Cc: Bjorn Andersson 
> Cc: Joerg Roedel 
> Cc: Thomas Gleixner 
> Cc: Jason Cooper 
> Cc: Marc Zyngier 
> Cc: Linus Walleij 
> Cc: Vinod Koul 
> Cc: Kalle Valo 
> Cc: Maulik Shah 
> Cc: Lina Iyer 
> Cc: Saravana Kannan 
> Cc: Todd Kjos 
> Cc: Greg Kroah-Hartman 
> Cc: linux-arm-...@vger.kernel.org
> Cc: iommu@lists.linux-foundation.org
> Cc: linux-g...@vger.kernel.org
> Acked-by: Greg Kroah-Hartman 
> Signed-off-by: John Stultz 

Reviewed-by: Bjorn Andersson 

Regards,
Bjorn

> ---
> v3:
> * Fix __arm_smccc_smc build issue reported by
>   kernel test robot 
> v4:
> * Add "depends on QCOM_SCM || !QCOM_SCM" bit to ath10k
>   config that requires it.
> v5:
> * Fix QCOM_QCM typo in Kconfig, it should be QCOM_SCM
> ---
>  drivers/firmware/Kconfig| 4 ++--
>  drivers/firmware/Makefile   | 3 ++-
>  drivers/firmware/qcom_scm.c | 4 
>  drivers/iommu/Kconfig   | 2 ++
>  drivers/net/wireless/ath/ath10k/Kconfig | 1 +
>  5 files changed, 11 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
> index 3315e3c215864..5e369928bc567 100644
> --- a/drivers/firmware/Kconfig
> +++ b/drivers/firmware/Kconfig
> @@ -235,8 +235,8 @@ config INTEL_STRATIX10_RSU
> Say Y here if you want Intel RSU support.
>  
>  config QCOM_SCM
> - bool
> - depends on ARM || ARM64
> + tristate "Qcom SCM driver"
> + depends on (ARM && HAVE_ARM_SMCCC) || ARM64
>   select RESET_CONTROLLER
>  
>  config QCOM_SCM_DOWNLOAD_MODE_DEFAULT
> diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
> index 5e013b6a3692e..523173cbff335 100644
> --- a/drivers/firmware/Makefile
> +++ b/drivers/firmware/Makefile
> @@ -17,7 +17,8 @@ obj-$(CONFIG_ISCSI_IBFT)+= iscsi_ibft.o
>  obj-$(CONFIG_FIRMWARE_MEMMAP)+= memmap.o
>  obj-$(CONFIG_RASPBERRYPI_FIRMWARE) += raspberrypi.o
>  obj-$(CONFIG_FW_CFG_SYSFS)   += qemu_fw_cfg.o
> -obj-$(CONFIG_QCOM_SCM)   += qcom_scm.o qcom_scm-smc.o 
> qcom_scm-legacy.o
> +obj-$(CONFIG_QCOM_SCM)   += qcom-scm.o
> +qcom-scm-objs += qcom_scm.o qcom_scm-smc.o qcom_scm-legacy.o
>  obj-$(CONFIG_TI_SCI_PROTOCOL)+= ti_sci.o
>  obj-$(CONFIG_TRUSTED_FOUNDATIONS) += trusted_foundations.o
>  obj-$(CONFIG_TURRIS_MOX_RWTM)+= turris-mox-rwtm.o
> diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c
> index 7be48c1bec96d..6f431b73e617d 100644
> --- a/drivers/firmware/qcom_scm.c
> +++ b/drivers/firmware/qcom_scm.c
> @@ -1280,6 +1280,7 @@ static const struct of_device_id qcom_scm_dt_match[] = {
>   { .compatible = "qcom,scm" },
>   {}
>  };
> +MODULE_DEVICE_TABLE(of, qcom_scm_dt_match);
>  
>  static struct platform_driver qcom_scm_driver = {
>   .driver = {
> @@ -1295,3 +1296,6 @@ static int __init qcom_scm_init(void)
>   return platform_driver_register(_scm_driver);
>  }
>  subsys_initcall(qcom_scm_init);
> +
> +MODULE_DESCRIPTION("Qualcomm Technologies, Inc. SCM driver");
> +MODULE_LICENSE("GPL v2");
> diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
> index 04878caf6da49..c64d7a2b65134 100644
> --- a/drivers/iommu/Kconfig
> +++ b/drivers/iommu/Kconfig
> @@ -248,6 +248,7 @@ config SPAPR_TCE_IOMMU
>  config ARM_SMMU
>   tristate "ARM Ltd. System MMU (SMMU) Support"
>   depends on ARM64 || ARM || (COMPILE_TEST && !GENERIC_ATOMIC64)
> + depends on QCOM_SCM || !QCOM_SCM #if QCOM_SCM=m this can't be =y
>   select IOMMU_API
>   select IOMMU_IO_PGTABLE_LPAE
>   select ARM_DMA_USE_IOMMU if ARM
> @@ -375,6 +376,7 @@ config QCOM_IOMMU
>   # Note: iommu drivers cannot (yet?) be built as modules
>   bool "Qualcomm IOMMU Support"
>   depends on ARCH_QCOM || (COMPILE_TEST && !GENERIC_ATOMIC64)
> + depends on QCOM_SCM=y
>   select IOMMU_API
>   select IOMMU_IO_PGTABLE_LPAE
>   select ARM_DMA_USE_IOMMU
> diff --git a/drivers/net/wireless/ath/ath10k/Kconfig 
> b/drivers/net/wireless/ath/ath10k/

Re: [PATCH v5 1/2] pinctrl: qcom: Allow pinctrl-msm code to be loadable as a module

2020-11-05 Thread Bjorn Andersson
On Fri 30 Oct 19:38 CDT 2020, John Stultz wrote:

> Tweaks to allow pinctrl-msm code to be loadable as a module.
> 
> This is needed in order to support having the qcom-scm driver,
> which pinctrl-msm calls into, configured as a module.
> 
> This requires that we tweak Kconfigs selecting PINCTRL_MSM to
> also depend on QCOM_SCM || QCOM_SCM=n so that we match the
> module setting of QCOM_SCM.
> 
> Unlike the previous revision of this patch:
>   https://lore.kernel.org/lkml/20200625001039.56174-5-john.stu...@linaro.org/
> this version reworks PINCTRL_MSM to be a visible option and
> instead of having the various SoC specific drivers select
> PINCTRL_MSM, this switches those configs to depend on
> PINCTRL_MSM. This avoids adding the oddish looking:
>   "depend on QCOM_SCM || QCOM_SCM=n"
> to every SoC specific driver, as that becomes a maintenance
> headache.
> 
> We also add PINCTRL_MSM to the arm64 defconfig to avoid
> surprises as otherwise PINCTRL_MSM/IPQ* options previously
> enabled, will be off.
> 

Reviewed-by: Bjorn Andersson 

Regards,
Bjorn

> Cc: Catalin Marinas 
> Cc: Will Deacon 
> Cc: Andy Gross 
> Cc: Bjorn Andersson 
> Cc: Joerg Roedel 
> Cc: Thomas Gleixner 
> Cc: Jason Cooper 
> Cc: Marc Zyngier 
> Cc: Linus Walleij 
> Cc: Vinod Koul 
> Cc: Kalle Valo 
> Cc: Maulik Shah 
> Cc: Lina Iyer 
> Cc: Saravana Kannan 
> Cc: Todd Kjos 
> Cc: Greg Kroah-Hartman 
> Cc: linux-arm-...@vger.kernel.org
> Cc: iommu@lists.linux-foundation.org
> Cc: linux-g...@vger.kernel.org
> Signed-off-by: John Stultz 
> ---
> v2:
> * Module description and whitespace fixes suggested by Bjorn
> * Added QCOM_SCM || QCOM_SCM=n bits on Kconfigs selecting
>   PINCTRL_MSM. Reported by both Todd and Bjorn.
> v3:
> * Make sure the QCOM_SCM || QCOM_SCM=n trick is commented
> v4:
> * Rework "select PINCTRL_MSM" to "depends on PINCTRL_MSM"
>   to consolidate the QCOM_SCM dependency.
> v5:
> * Add PINCTRL_MSM to arm64 defconfig
> ---
>  arch/arm64/configs/defconfig   |  1 +
>  drivers/pinctrl/qcom/Kconfig   | 49 +++---
>  drivers/pinctrl/qcom/pinctrl-msm.c |  2 ++
>  3 files changed, 28 insertions(+), 24 deletions(-)
> 
> diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
> index 17a2df6a263e8..45768828fdb8e 100644
> --- a/arch/arm64/configs/defconfig
> +++ b/arch/arm64/configs/defconfig
> @@ -483,6 +483,7 @@ CONFIG_PINCTRL_IMX8MP=y
>  CONFIG_PINCTRL_IMX8MQ=y
>  CONFIG_PINCTRL_IMX8QXP=y
>  CONFIG_PINCTRL_IMX8DXL=y
> +CONFIG_PINCTRL_MSM=y
>  CONFIG_PINCTRL_IPQ8074=y
>  CONFIG_PINCTRL_IPQ6018=y
>  CONFIG_PINCTRL_MSM8916=y
> diff --git a/drivers/pinctrl/qcom/Kconfig b/drivers/pinctrl/qcom/Kconfig
> index 5fe7b8aaf69d8..8bb786ed152dd 100644
> --- a/drivers/pinctrl/qcom/Kconfig
> +++ b/drivers/pinctrl/qcom/Kconfig
> @@ -2,7 +2,8 @@
>  if (ARCH_QCOM || COMPILE_TEST)
>  
>  config PINCTRL_MSM
> - bool
> + tristate "Qualcomm core pin controller driver"
> + depends on QCOM_SCM || !QCOM_SCM #if QCOM_SCM=m this can't be =y
>   select PINMUX
>   select PINCONF
>   select GENERIC_PINCONF
> @@ -13,7 +14,7 @@ config PINCTRL_MSM
>  config PINCTRL_APQ8064
>   tristate "Qualcomm APQ8064 pin controller driver"
>   depends on GPIOLIB && OF
> - select PINCTRL_MSM
> + depends on PINCTRL_MSM
>   help
> This is the pinctrl, pinmux, pinconf and gpiolib driver for the
> Qualcomm TLMM block found in the Qualcomm APQ8064 platform.
> @@ -21,7 +22,7 @@ config PINCTRL_APQ8064
>  config PINCTRL_APQ8084
>   tristate "Qualcomm APQ8084 pin controller driver"
>   depends on GPIOLIB && OF
> - select PINCTRL_MSM
> + depends on PINCTRL_MSM
>   help
> This is the pinctrl, pinmux, pinconf and gpiolib driver for the
> Qualcomm TLMM block found in the Qualcomm APQ8084 platform.
> @@ -29,7 +30,7 @@ config PINCTRL_APQ8084
>  config PINCTRL_IPQ4019
>   tristate "Qualcomm IPQ4019 pin controller driver"
>   depends on GPIOLIB && OF
> - select PINCTRL_MSM
> + depends on PINCTRL_MSM
>   help
> This is the pinctrl, pinmux, pinconf and gpiolib driver for the
> Qualcomm TLMM block found in the Qualcomm IPQ4019 platform.
> @@ -37,7 +38,7 @@ config PINCTRL_IPQ4019
>  config PINCTRL_IPQ8064
>   tristate "Qualcomm IPQ8064 pin controller driver"
>   depends on GPIOLIB && OF
> - select PINCTRL_MSM
> + depends on PINCTRL_MSM
>   help
> This is the pinctrl, pinmux, pinconf and gpiolib driver for the
>

Re: [PATCH v18 2/4] iommu/arm-smmu: Add a way for implementations to influence SCTLR

2020-11-03 Thread Bjorn Andersson
On Mon 02 Nov 12:18 CST 2020, Robin Murphy wrote:

> On 2020-11-02 17:14, Jordan Crouse wrote:
> > From: Rob Clark 
> > 
> > For the Adreno GPU's SMMU, we want SCTLR.HUPCF set to ensure that
> > pending translations are not terminated on iova fault.  Otherwise
> > a terminated CP read could hang the GPU by returning invalid
> > command-stream data.
> > 
> > Signed-off-by: Rob Clark 
> > Reviewed-by: Bjorn Andersson 
> > Signed-off-by: Jordan Crouse 
> > ---
> > 
> >   drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 6 ++
> >   drivers/iommu/arm/arm-smmu/arm-smmu.c  | 3 +++
> >   drivers/iommu/arm/arm-smmu/arm-smmu.h  | 3 +++
> >   3 files changed, 12 insertions(+)
> > 
> > diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c 
> > b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> > index 1e942eed2dfc..0663d7d26908 100644
> > --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> > +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> > @@ -129,6 +129,12 @@ static int qcom_adreno_smmu_init_context(struct 
> > arm_smmu_domain *smmu_domain,
> > (smmu_domain->cfg.fmt == ARM_SMMU_CTX_FMT_AARCH64))
> > pgtbl_cfg->quirks |= IO_PGTABLE_QUIRK_ARM_TTBR1;
> > +   /*
> > +* On the GPU device we want to process subsequent transactions after a
> > +* fault to keep the GPU from hanging
> > +*/
> > +   smmu_domain->cfg.sctlr_set |= ARM_SMMU_SCTLR_HUPCF;
> > +
> > /*
> >  * Initialize private interface with GPU:
> >  */
> > diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c 
> > b/drivers/iommu/arm/arm-smmu/arm-smmu.c
> > index dad7fa86fbd4..1f06ab219819 100644
> > --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
> > +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
> > @@ -617,6 +617,9 @@ void arm_smmu_write_context_bank(struct arm_smmu_device 
> > *smmu, int idx)
> > if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
> > reg |= ARM_SMMU_SCTLR_E;
> > +   reg |= cfg->sctlr_set;
> > +   reg &= ~cfg->sctlr_clr;
> 
> Since we now have a write_s2cr hook, I'm inclined to think that the
> consistency of a write_sctlr hook that could similarly apply its own
> arbitrary tweaks would make sense for this. Does anyone have any strong
> opinions?
> 

I like it.

Regards,
Bjorn

> Robin.
> 
> > +
> > arm_smmu_cb_write(smmu, idx, ARM_SMMU_CB_SCTLR, reg);
> >   }
> > diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.h 
> > b/drivers/iommu/arm/arm-smmu/arm-smmu.h
> > index 6c5ffeae..ddf2ca4c923d 100644
> > --- a/drivers/iommu/arm/arm-smmu/arm-smmu.h
> > +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.h
> > @@ -144,6 +144,7 @@ enum arm_smmu_cbar_type {
> >   #define ARM_SMMU_CB_SCTLR 0x0
> >   #define ARM_SMMU_SCTLR_S1_ASIDPNE BIT(12)
> >   #define ARM_SMMU_SCTLR_CFCFG  BIT(7)
> > +#define ARM_SMMU_SCTLR_HUPCF   BIT(8)
> >   #define ARM_SMMU_SCTLR_CFIE   BIT(6)
> >   #define ARM_SMMU_SCTLR_CFRE   BIT(5)
> >   #define ARM_SMMU_SCTLR_E  BIT(4)
> > @@ -341,6 +342,8 @@ struct arm_smmu_cfg {
> > u16 asid;
> > u16 vmid;
> > };
> > +   u32 sctlr_set;/* extra bits to set in 
> > SCTLR */
> > +   u32 sctlr_clr;/* bits to mask in SCTLR 
> > */
> > enum arm_smmu_cbar_type cbar;
> > enum arm_smmu_context_fmt   fmt;
> >   };
> > 
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v5 3/3] iommu/arm-smmu-qcom: Implement S2CR quirk

2020-10-19 Thread Bjorn Andersson
The firmware found in some Qualcomm platforms intercepts writes to S2CR
in order to replace bypass type streams with fault; and ignore S2CR
updates of type fault.

Detect this behavior and implement a custom write_s2cr function in order
to trick the firmware into supporting bypass streams by the means of
configuring the stream for translation using a reserved and disabled
context bank.

Also circumvent the problem of configuring faulting streams by
configuring the stream as bypass.

Signed-off-by: Bjorn Andersson 
---

Changes since v4:
- Made the bypass_cbndx an integer...
- Separated out the "quirk enabled or not" into a bool, rather than reusing
  (the valid) context bank 0 to represent this.
- Dropped the unused EXIDS handling.

 drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 67 ++
 1 file changed, 67 insertions(+)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c 
b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
index 48627fcf6bed..66ba4870659f 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
@@ -10,8 +10,15 @@
 
 struct qcom_smmu {
struct arm_smmu_device smmu;
+   bool bypass_quirk;
+   u8 bypass_cbndx;
 };
 
+static struct qcom_smmu *to_qcom_smmu(struct arm_smmu_device *smmu)
+{
+   return container_of(smmu, struct qcom_smmu, smmu);
+}
+
 static const struct of_device_id qcom_smmu_client_of_match[] __maybe_unused = {
{ .compatible = "qcom,adreno" },
{ .compatible = "qcom,mdp4" },
@@ -25,9 +32,33 @@ static const struct of_device_id qcom_smmu_client_of_match[] 
__maybe_unused = {
 
 static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu)
 {
+   unsigned int last_s2cr = ARM_SMMU_GR0_S2CR(smmu->num_mapping_groups - 
1);
+   struct qcom_smmu *qsmmu = to_qcom_smmu(smmu);
+   u32 reg;
u32 smr;
int i;
 
+   /*
+* With some firmware versions writes to S2CR of type FAULT are
+* ignored, and writing BYPASS will end up written as FAULT in the
+* register. Perform a write to S2CR to detect if this is the case and
+* if so reserve a context bank to emulate bypass streams.
+*/
+   reg = FIELD_PREP(ARM_SMMU_S2CR_TYPE, S2CR_TYPE_BYPASS) |
+ FIELD_PREP(ARM_SMMU_S2CR_CBNDX, 0xff) |
+ FIELD_PREP(ARM_SMMU_S2CR_PRIVCFG, S2CR_PRIVCFG_DEFAULT);
+   arm_smmu_gr0_write(smmu, last_s2cr, reg);
+   reg = arm_smmu_gr0_read(smmu, last_s2cr);
+   if (FIELD_GET(ARM_SMMU_S2CR_TYPE, reg) != S2CR_TYPE_BYPASS) {
+   qsmmu->bypass_quirk = true;
+   qsmmu->bypass_cbndx = smmu->num_context_banks - 1;
+
+   set_bit(qsmmu->bypass_cbndx, smmu->context_map);
+
+   reg = FIELD_PREP(ARM_SMMU_CBAR_TYPE, 
CBAR_TYPE_S1_TRANS_S2_BYPASS);
+   arm_smmu_gr1_write(smmu, 
ARM_SMMU_GR1_CBAR(qsmmu->bypass_cbndx), reg);
+   }
+
for (i = 0; i < smmu->num_mapping_groups; i++) {
smr = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_SMR(i));
 
@@ -45,6 +76,41 @@ static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu)
return 0;
 }
 
+static void qcom_smmu_write_s2cr(struct arm_smmu_device *smmu, int idx)
+{
+   struct arm_smmu_s2cr *s2cr = smmu->s2crs + idx;
+   struct qcom_smmu *qsmmu = to_qcom_smmu(smmu);
+   u32 cbndx = s2cr->cbndx;
+   u32 type = s2cr->type;
+   u32 reg;
+
+   if (qsmmu->bypass_quirk) {
+   if (type == S2CR_TYPE_BYPASS) {
+   /*
+* Firmware with quirky S2CR handling will substitute
+* BYPASS writes with FAULT, so point the stream to the
+* reserved context bank and ask for translation on the
+* stream
+*/
+   type = S2CR_TYPE_TRANS;
+   cbndx = qsmmu->bypass_cbndx;
+   } else if (type == S2CR_TYPE_FAULT) {
+   /*
+* Firmware with quirky S2CR handling will ignore FAULT
+* writes, so trick it to write FAULT by asking for a
+* BYPASS.
+*/
+   type = S2CR_TYPE_BYPASS;
+   cbndx = 0xff;
+   }
+   }
+
+   reg = FIELD_PREP(ARM_SMMU_S2CR_TYPE, type) |
+ FIELD_PREP(ARM_SMMU_S2CR_CBNDX, cbndx) |
+ FIELD_PREP(ARM_SMMU_S2CR_PRIVCFG, s2cr->privcfg);
+   arm_smmu_gr0_write(smmu, ARM_SMMU_GR0_S2CR(idx), reg);
+}
+
 static int qcom_smmu_def_domain_type(struct device *dev)
 {
const struct of_device_id *match =
@@ -86,6 +152,7 @@ static const struct arm_smmu_impl qcom_smmu_impl = {
.cfg_probe = qcom_smmu_cfg_probe,
.def_domain_type = qcom_smmu_def_domain_type,
.reset = qcom_smmu500_reset,
+   .write_s2cr = qcom

[PATCH v5 2/3] iommu/arm-smmu-qcom: Read back stream mappings

2020-10-19 Thread Bjorn Andersson
The Qualcomm boot loader configures stream mapping for the peripherals
that it accesses and in particular it sets up the stream mapping for the
display controller to be allowed to scan out a splash screen or EFI
framebuffer.

Read back the stream mappings during initialization and make the
arm-smmu driver maintain the streams in bypass mode.

Signed-off-by: Bjorn Andersson 
---

Changes since v4:
- Don't increment s2cr[i]->count, as this is not actually needed to survive
  probe deferral

 drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 23 ++
 1 file changed, 23 insertions(+)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c 
b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
index be4318044f96..48627fcf6bed 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
@@ -23,6 +23,28 @@ static const struct of_device_id qcom_smmu_client_of_match[] 
__maybe_unused = {
{ }
 };
 
+static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu)
+{
+   u32 smr;
+   int i;
+
+   for (i = 0; i < smmu->num_mapping_groups; i++) {
+   smr = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_SMR(i));
+
+   if (FIELD_GET(ARM_SMMU_SMR_VALID, smr)) {
+   smmu->smrs[i].id = FIELD_GET(ARM_SMMU_SMR_ID, smr);
+   smmu->smrs[i].mask = FIELD_GET(ARM_SMMU_SMR_MASK, smr);
+   smmu->smrs[i].valid = true;
+
+   smmu->s2crs[i].type = S2CR_TYPE_BYPASS;
+   smmu->s2crs[i].privcfg = S2CR_PRIVCFG_DEFAULT;
+   smmu->s2crs[i].cbndx = 0xff;
+   }
+   }
+
+   return 0;
+}
+
 static int qcom_smmu_def_domain_type(struct device *dev)
 {
const struct of_device_id *match =
@@ -61,6 +83,7 @@ static int qcom_smmu500_reset(struct arm_smmu_device *smmu)
 }
 
 static const struct arm_smmu_impl qcom_smmu_impl = {
+   .cfg_probe = qcom_smmu_cfg_probe,
.def_domain_type = qcom_smmu_def_domain_type,
.reset = qcom_smmu500_reset,
 };
-- 
2.28.0

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v5 1/3] iommu/arm-smmu: Allow implementation specific write_s2cr

2020-10-19 Thread Bjorn Andersson
The firmware found in some Qualcomm platforms intercepts writes to the
S2CR register in order to replace the BYPASS type with FAULT. Further
more it treats faults at this level as catastrophic and restarts the
device.

Add support for providing implementation specific versions of the S2CR
write function, to allow the Qualcomm driver to work around this
behavior.

Reviewed-by: Robin Murphy 
Signed-off-by: Bjorn Andersson 
---

Changes since v4:
- Return early instead of indenting the rest of the function

 drivers/iommu/arm/arm-smmu/arm-smmu.c | 13 ++---
 drivers/iommu/arm/arm-smmu/arm-smmu.h |  1 +
 2 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c 
b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index dad7fa86fbd4..bcbacf22331d 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -929,9 +929,16 @@ static void arm_smmu_write_smr(struct arm_smmu_device 
*smmu, int idx)
 static void arm_smmu_write_s2cr(struct arm_smmu_device *smmu, int idx)
 {
struct arm_smmu_s2cr *s2cr = smmu->s2crs + idx;
-   u32 reg = FIELD_PREP(ARM_SMMU_S2CR_TYPE, s2cr->type) |
- FIELD_PREP(ARM_SMMU_S2CR_CBNDX, s2cr->cbndx) |
- FIELD_PREP(ARM_SMMU_S2CR_PRIVCFG, s2cr->privcfg);
+   u32 reg;
+
+   if (smmu->impl && smmu->impl->write_s2cr) {
+   smmu->impl->write_s2cr(smmu, idx);
+   return;
+   }
+
+   reg = FIELD_PREP(ARM_SMMU_S2CR_TYPE, s2cr->type) |
+ FIELD_PREP(ARM_SMMU_S2CR_CBNDX, s2cr->cbndx) |
+ FIELD_PREP(ARM_SMMU_S2CR_PRIVCFG, s2cr->privcfg);
 
if (smmu->features & ARM_SMMU_FEAT_EXIDS && smmu->smrs &&
smmu->smrs[idx].valid)
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.h 
b/drivers/iommu/arm/arm-smmu/arm-smmu.h
index 1a746476927c..b71647eaa319 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.h
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.h
@@ -436,6 +436,7 @@ struct arm_smmu_impl {
int (*alloc_context_bank)(struct arm_smmu_domain *smmu_domain,
  struct arm_smmu_device *smmu,
  struct device *dev, int start);
+   void (*write_s2cr)(struct arm_smmu_device *smmu, int idx);
 };
 
 #define INVALID_SMENDX -1
-- 
2.28.0

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v5 0/3] iommu/arm-smmu-qcom: Support maintaining bootloader mappings

2020-10-19 Thread Bjorn Andersson
This is the revised fourth attempt of inheriting the stream mapping for
the framebuffer on many Qualcomm platforms, in order to not hit
catastrophic faults during arm-smmu initialization.

The new approach does, based on Robin's suggestion, take a much more
direct approach with the allocation of a context bank for bypass
emulation and use of this context bank pretty much isolated to the
Qualcomm specific implementation.

The patchset has been tested to boot DB845c and RB5 (with splash screen)
and Lenovo Yoga C630 (with EFI framebuffer).

Bjorn Andersson (3):
  iommu/arm-smmu: Allow implementation specific write_s2cr
  iommu/arm-smmu-qcom: Read back stream mappings
  iommu/arm-smmu-qcom: Implement S2CR quirk

 drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 90 ++
 drivers/iommu/arm/arm-smmu/arm-smmu.c  | 13 +++-
 drivers/iommu/arm/arm-smmu/arm-smmu.h  |  1 +
 3 files changed, 101 insertions(+), 3 deletions(-)

-- 
2.28.0

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v4 3/3] iommu/arm-smmu-qcom: Implement S2CR quirk

2020-10-19 Thread Bjorn Andersson
On Mon 19 Oct 09:04 CDT 2020, Robin Murphy wrote:

> On 2020-10-17 05:39, Bjorn Andersson wrote:
> > The firmware found in some Qualcomm platforms intercepts writes to S2CR
> > in order to replace bypass type streams with fault; and ignore S2CR
> > updates of type fault.
> > 
> > Detect this behavior and implement a custom write_s2cr function in order
> > to trick the firmware into supporting bypass streams by the means of
> > configuring the stream for translation using a reserved and disabled
> > context bank.
> > 
> > Also circumvent the problem of configuring faulting streams by
> > configuring the stream as bypass.
> > 
> > Signed-off-by: Bjorn Andersson 
> > ---
> > 
> > Changes since v3:
> > - Move the reservation of the "identity context bank" to the Qualcomm 
> > specific
> >implementation.
> > - Implement the S2CR quirk with the newly introduced write_s2cr callback.
> > 
> >   drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 68 ++
> >   1 file changed, 68 insertions(+)
> > 
> > diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c 
> > b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> > index 0089048342dd..c0f42d6a6e01 100644
> > --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> > +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> > @@ -10,8 +10,14 @@
> >   struct qcom_smmu {
> > struct arm_smmu_device smmu;
> > +   bool bypass_cbndx;
> 
> Nit: variables named "*ndx" usually hold an actual index value. If it's just
> a flag then maybe name it something like "use_bypass_context"?
> 
> >   };
> > +static struct qcom_smmu *to_qcom_smmu(struct arm_smmu_device *smmu)
> > +{
> > +   return container_of(smmu, struct qcom_smmu, smmu);
> > +}
> > +
> >   static const struct of_device_id qcom_smmu_client_of_match[] 
> > __maybe_unused = {
> > { .compatible = "qcom,adreno" },
> > { .compatible = "qcom,mdp4" },
> > @@ -25,9 +31,32 @@ static const struct of_device_id 
> > qcom_smmu_client_of_match[] __maybe_unused = {
> >   static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu)
> >   {
> > +   unsigned int last_s2cr = ARM_SMMU_GR0_S2CR(smmu->num_mapping_groups - 
> > 1);
> > +   struct qcom_smmu *qsmmu = to_qcom_smmu(smmu);
> > +   u32 reg;
> > u32 smr;
> > int i;
> > +   /*
> > +* With some firmware versions writes to S2CR of type FAULT are
> > +* ignored, and writing BYPASS will end up written as FAULT in the
> > +* register. Perform a write to S2CR to detect if this is the case and
> > +* if so reserve a context bank to emulate bypass streams.
> > +*/
> > +   reg = FIELD_PREP(ARM_SMMU_S2CR_TYPE, S2CR_TYPE_BYPASS) |
> > + FIELD_PREP(ARM_SMMU_S2CR_CBNDX, 0xff) |
> > + FIELD_PREP(ARM_SMMU_S2CR_PRIVCFG, S2CR_PRIVCFG_DEFAULT);
> > +   arm_smmu_gr0_write(smmu, last_s2cr, reg);
> > +   reg = arm_smmu_gr0_read(smmu, last_s2cr);
> > +   if (FIELD_GET(ARM_SMMU_S2CR_TYPE, reg) != S2CR_TYPE_BYPASS) {
> > +   qsmmu->bypass_cbndx = smmu->num_context_banks - 1;
> 
> Oh, so maybe the name is in fact OK but the type is wrong :/
> 
> I guess this does happens to work out, but for the wrong reason...
> 

Odd, but "it works on my machine"... Sorry about that.

> > +
> > +   set_bit(qsmmu->bypass_cbndx, smmu->context_map);
> > +
> > +   reg = FIELD_PREP(ARM_SMMU_CBAR_TYPE, 
> > CBAR_TYPE_S1_TRANS_S2_BYPASS);
> > +   arm_smmu_gr1_write(smmu, 
> > ARM_SMMU_GR1_CBAR(qsmmu->bypass_cbndx), reg);
> > +   }
> > +
> > for (i = 0; i < smmu->num_mapping_groups; i++) {
> > smr = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_SMR(i));
> > @@ -46,6 +75,44 @@ static int qcom_smmu_cfg_probe(struct arm_smmu_device 
> > *smmu)
> > return 0;
> >   }
> > +static void qcom_smmu_write_s2cr(struct arm_smmu_device *smmu, int idx)
> > +{
> > +   struct arm_smmu_s2cr *s2cr = smmu->s2crs + idx;
> > +   struct qcom_smmu *qsmmu = to_qcom_smmu(smmu);
> > +   u32 cbndx = s2cr->cbndx;
> > +   u32 type = s2cr->type;
> > +   u32 reg;
> > +
> > +   if (qsmmu->bypass_cbndx) {
> 
> Note that if we are talking indices here then 0 would be perfectly valid in
> general. This works out OK in practice given that we're always reserving the
> last implemented context above, and if we ever *did* only have one such that
> index 0 is the last then we're going 

Re: [PATCH v4 2/3] iommu/arm-smmu-qcom: Read back stream mappings

2020-10-19 Thread Bjorn Andersson
On Mon 19 Oct 09:03 CDT 2020, Robin Murphy wrote:

> On 2020-10-17 05:39, Bjorn Andersson wrote:
> > The Qualcomm boot loader configures stream mapping for the peripherals
> > that it accesses and in particular it sets up the stream mapping for the
> > display controller to be allowed to scan out a splash screen or EFI
> > framebuffer.
> > 
> > Read back the stream mappings during initialization and make the
> > arm-smmu driver maintain the streams in bypass mode.
> > 
> > Signed-off-by: Bjorn Andersson 
> > ---
> > 
> > Changes since v3:
> > - Extracted from different patch in v3.
> > - Now configures the stream as BYPASS, rather than translate, which should 
> > work
> >for platforms with working S2CR handling as well.
> > 
> >   drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 24 ++
> >   1 file changed, 24 insertions(+)
> > 
> > diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c 
> > b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> > index be4318044f96..0089048342dd 100644
> > --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> > +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> > @@ -23,6 +23,29 @@ static const struct of_device_id 
> > qcom_smmu_client_of_match[] __maybe_unused = {
> > { }
> >   };
> > +static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu)
> > +{
> > +   u32 smr;
> > +   int i;
> > +
> > +   for (i = 0; i < smmu->num_mapping_groups; i++) {
> > +   smr = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_SMR(i));
> > +
> > +   if (FIELD_GET(ARM_SMMU_SMR_VALID, smr)) {
> > +   smmu->smrs[i].id = FIELD_GET(ARM_SMMU_SMR_ID, smr);
> > +   smmu->smrs[i].mask = FIELD_GET(ARM_SMMU_SMR_MASK, smr);
> > +   smmu->smrs[i].valid = true;
> > +
> > +   smmu->s2crs[i].type = S2CR_TYPE_BYPASS;
> > +   smmu->s2crs[i].privcfg = S2CR_PRIVCFG_DEFAULT;
> > +   smmu->s2crs[i].cbndx = 0xff;
> > +   smmu->s2crs[i].count++;
> 
> FWIW I don't think you actually need to adjust the count here - the SMR
> being valid should already prevent the whole SME from being reassigned until
> the display probes, at which point it should "take over" the SMR based on
> matching values and claim the "initial" refcount. After that you're back
> into the standard flow. It might be a little unintuitive to have something
> in a valid but "unused" state, but arguably it's entirely accurate in terms
> of the software abstraction here.
> 
> Otherwise, you end up making boot-time SMRs - so potentially all SMRs after
> a kexec - effectively immutable, since even after Linux has taken control of
> the whole system such that they *could* be reassigned safely, there's still
> this undroppable refcount hanging around preventing it.
> 

I did increment the count here to make sure the stream mapping do
survive a probe deferral of the display controller (which is rather
common when you have some bridge chip hanging off it).

But after digging through the code further I've convinced myself that
the sme won't be freed while the device is pending probe deferral.

So I will drop this.

> That said, for a mobile SoC use-case if you have enough SMRs for all your
> stream IDs and don't have any kind of device hotplug, that restriction
> shouldn't make much difference in practice, so I'm not too concerned either
> way. Otherwise this is as nice and tidy as I'd hoped :)

I agree, I'm quite happy with where we are now!

Thanks,
Bjorn

> 
> Robin.
> 
> > +   }
> > +   }
> > +
> > +   return 0;
> > +}
> > +
> >   static int qcom_smmu_def_domain_type(struct device *dev)
> >   {
> > const struct of_device_id *match =
> > @@ -61,6 +84,7 @@ static int qcom_smmu500_reset(struct arm_smmu_device 
> > *smmu)
> >   }
> >   static const struct arm_smmu_impl qcom_smmu_impl = {
> > +   .cfg_probe = qcom_smmu_cfg_probe,
> > .def_domain_type = qcom_smmu_def_domain_type,
> > .reset = qcom_smmu500_reset,
> >   };
> > 
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v4 1/3] iommu/arm-smmu: Allow implementation specific write_s2cr

2020-10-16 Thread Bjorn Andersson
The firmware found in some Qualcomm platforms intercepts writes to the
S2CR register in order to replace the BYPASS type with FAULT. Further
more it treats faults at this level as catastrophic and restarts the
device.

Add support for providing implementation specific versions of the S2CR
write function, to allow the Qualcomm driver to work around this
behavior.

Signed-off-by: Bjorn Andersson 
---

Changes since v3:
- New patch

 drivers/iommu/arm/arm-smmu/arm-smmu.c | 22 ++
 drivers/iommu/arm/arm-smmu/arm-smmu.h |  1 +
 2 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c 
b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index dad7fa86fbd4..ed3f0428c110 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -929,14 +929,20 @@ static void arm_smmu_write_smr(struct arm_smmu_device 
*smmu, int idx)
 static void arm_smmu_write_s2cr(struct arm_smmu_device *smmu, int idx)
 {
struct arm_smmu_s2cr *s2cr = smmu->s2crs + idx;
-   u32 reg = FIELD_PREP(ARM_SMMU_S2CR_TYPE, s2cr->type) |
- FIELD_PREP(ARM_SMMU_S2CR_CBNDX, s2cr->cbndx) |
- FIELD_PREP(ARM_SMMU_S2CR_PRIVCFG, s2cr->privcfg);
-
-   if (smmu->features & ARM_SMMU_FEAT_EXIDS && smmu->smrs &&
-   smmu->smrs[idx].valid)
-   reg |= ARM_SMMU_S2CR_EXIDVALID;
-   arm_smmu_gr0_write(smmu, ARM_SMMU_GR0_S2CR(idx), reg);
+   u32 reg;
+
+   if (smmu->impl && smmu->impl->write_s2cr) {
+   smmu->impl->write_s2cr(smmu, idx);
+   } else {
+   reg = FIELD_PREP(ARM_SMMU_S2CR_TYPE, s2cr->type) |
+ FIELD_PREP(ARM_SMMU_S2CR_CBNDX, s2cr->cbndx) |
+ FIELD_PREP(ARM_SMMU_S2CR_PRIVCFG, s2cr->privcfg);
+
+   if (smmu->features & ARM_SMMU_FEAT_EXIDS && smmu->smrs &&
+   smmu->smrs[idx].valid)
+   reg |= ARM_SMMU_S2CR_EXIDVALID;
+   arm_smmu_gr0_write(smmu, ARM_SMMU_GR0_S2CR(idx), reg);
+   }
 }
 
 static void arm_smmu_write_sme(struct arm_smmu_device *smmu, int idx)
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.h 
b/drivers/iommu/arm/arm-smmu/arm-smmu.h
index 1a746476927c..b71647eaa319 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.h
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.h
@@ -436,6 +436,7 @@ struct arm_smmu_impl {
int (*alloc_context_bank)(struct arm_smmu_domain *smmu_domain,
  struct arm_smmu_device *smmu,
  struct device *dev, int start);
+   void (*write_s2cr)(struct arm_smmu_device *smmu, int idx);
 };
 
 #define INVALID_SMENDX -1
-- 
2.28.0

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v4 0/3] iommu/arm-smmu-qcom: Support maintaining bootloader mappings

2020-10-16 Thread Bjorn Andersson
This is the fourth attempt of inheriting the stream mapping for the framebuffer
on many Qualcomm platforms, in order to not hit catastrophic faults during
arm-smmu initialization.

The new approach does, based on Robin's suggestion, take a much more direct
approach with the allocation of a context bank for bypass emulation and use of
this context bank pretty much isolated to the Qualcomm specific implementation.

As before the patchset has been tested to boot DB845c (with splash screen) and
Lenovo Yoga C630 (with EFI framebuffer).

Bjorn Andersson (3):
  iommu/arm-smmu: Allow implementation specific write_s2cr
  iommu/arm-smmu-qcom: Read back stream mappings
  iommu/arm-smmu-qcom: Implement S2CR quirk

 drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 92 ++
 drivers/iommu/arm/arm-smmu/arm-smmu.c  | 22 --
 drivers/iommu/arm/arm-smmu/arm-smmu.h  |  1 +
 3 files changed, 107 insertions(+), 8 deletions(-)

-- 
2.28.0

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v4 2/3] iommu/arm-smmu-qcom: Read back stream mappings

2020-10-16 Thread Bjorn Andersson
The Qualcomm boot loader configures stream mapping for the peripherals
that it accesses and in particular it sets up the stream mapping for the
display controller to be allowed to scan out a splash screen or EFI
framebuffer.

Read back the stream mappings during initialization and make the
arm-smmu driver maintain the streams in bypass mode.

Signed-off-by: Bjorn Andersson 
---

Changes since v3:
- Extracted from different patch in v3.
- Now configures the stream as BYPASS, rather than translate, which should work
  for platforms with working S2CR handling as well.

 drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 24 ++
 1 file changed, 24 insertions(+)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c 
b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
index be4318044f96..0089048342dd 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
@@ -23,6 +23,29 @@ static const struct of_device_id qcom_smmu_client_of_match[] 
__maybe_unused = {
{ }
 };
 
+static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu)
+{
+   u32 smr;
+   int i;
+
+   for (i = 0; i < smmu->num_mapping_groups; i++) {
+   smr = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_SMR(i));
+
+   if (FIELD_GET(ARM_SMMU_SMR_VALID, smr)) {
+   smmu->smrs[i].id = FIELD_GET(ARM_SMMU_SMR_ID, smr);
+   smmu->smrs[i].mask = FIELD_GET(ARM_SMMU_SMR_MASK, smr);
+   smmu->smrs[i].valid = true;
+
+   smmu->s2crs[i].type = S2CR_TYPE_BYPASS;
+   smmu->s2crs[i].privcfg = S2CR_PRIVCFG_DEFAULT;
+   smmu->s2crs[i].cbndx = 0xff;
+   smmu->s2crs[i].count++;
+   }
+   }
+
+   return 0;
+}
+
 static int qcom_smmu_def_domain_type(struct device *dev)
 {
const struct of_device_id *match =
@@ -61,6 +84,7 @@ static int qcom_smmu500_reset(struct arm_smmu_device *smmu)
 }
 
 static const struct arm_smmu_impl qcom_smmu_impl = {
+   .cfg_probe = qcom_smmu_cfg_probe,
.def_domain_type = qcom_smmu_def_domain_type,
.reset = qcom_smmu500_reset,
 };
-- 
2.28.0

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v4 3/3] iommu/arm-smmu-qcom: Implement S2CR quirk

2020-10-16 Thread Bjorn Andersson
The firmware found in some Qualcomm platforms intercepts writes to S2CR
in order to replace bypass type streams with fault; and ignore S2CR
updates of type fault.

Detect this behavior and implement a custom write_s2cr function in order
to trick the firmware into supporting bypass streams by the means of
configuring the stream for translation using a reserved and disabled
context bank.

Also circumvent the problem of configuring faulting streams by
configuring the stream as bypass.

Signed-off-by: Bjorn Andersson 
---

Changes since v3:
- Move the reservation of the "identity context bank" to the Qualcomm specific
  implementation.
- Implement the S2CR quirk with the newly introduced write_s2cr callback.

 drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 68 ++
 1 file changed, 68 insertions(+)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c 
b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
index 0089048342dd..c0f42d6a6e01 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
@@ -10,8 +10,14 @@
 
 struct qcom_smmu {
struct arm_smmu_device smmu;
+   bool bypass_cbndx;
 };
 
+static struct qcom_smmu *to_qcom_smmu(struct arm_smmu_device *smmu)
+{
+   return container_of(smmu, struct qcom_smmu, smmu);
+}
+
 static const struct of_device_id qcom_smmu_client_of_match[] __maybe_unused = {
{ .compatible = "qcom,adreno" },
{ .compatible = "qcom,mdp4" },
@@ -25,9 +31,32 @@ static const struct of_device_id qcom_smmu_client_of_match[] 
__maybe_unused = {
 
 static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu)
 {
+   unsigned int last_s2cr = ARM_SMMU_GR0_S2CR(smmu->num_mapping_groups - 
1);
+   struct qcom_smmu *qsmmu = to_qcom_smmu(smmu);
+   u32 reg;
u32 smr;
int i;
 
+   /*
+* With some firmware versions writes to S2CR of type FAULT are
+* ignored, and writing BYPASS will end up written as FAULT in the
+* register. Perform a write to S2CR to detect if this is the case and
+* if so reserve a context bank to emulate bypass streams.
+*/
+   reg = FIELD_PREP(ARM_SMMU_S2CR_TYPE, S2CR_TYPE_BYPASS) |
+ FIELD_PREP(ARM_SMMU_S2CR_CBNDX, 0xff) |
+ FIELD_PREP(ARM_SMMU_S2CR_PRIVCFG, S2CR_PRIVCFG_DEFAULT);
+   arm_smmu_gr0_write(smmu, last_s2cr, reg);
+   reg = arm_smmu_gr0_read(smmu, last_s2cr);
+   if (FIELD_GET(ARM_SMMU_S2CR_TYPE, reg) != S2CR_TYPE_BYPASS) {
+   qsmmu->bypass_cbndx = smmu->num_context_banks - 1;
+
+   set_bit(qsmmu->bypass_cbndx, smmu->context_map);
+
+   reg = FIELD_PREP(ARM_SMMU_CBAR_TYPE, 
CBAR_TYPE_S1_TRANS_S2_BYPASS);
+   arm_smmu_gr1_write(smmu, 
ARM_SMMU_GR1_CBAR(qsmmu->bypass_cbndx), reg);
+   }
+
for (i = 0; i < smmu->num_mapping_groups; i++) {
smr = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_SMR(i));
 
@@ -46,6 +75,44 @@ static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu)
return 0;
 }
 
+static void qcom_smmu_write_s2cr(struct arm_smmu_device *smmu, int idx)
+{
+   struct arm_smmu_s2cr *s2cr = smmu->s2crs + idx;
+   struct qcom_smmu *qsmmu = to_qcom_smmu(smmu);
+   u32 cbndx = s2cr->cbndx;
+   u32 type = s2cr->type;
+   u32 reg;
+
+   if (qsmmu->bypass_cbndx) {
+   if (type == S2CR_TYPE_BYPASS) {
+   /*
+* Firmware with quirky S2CR handling will substitute
+* BYPASS writes with FAULT, so point the stream to the
+* reserved context bank and ask for translation on the
+* stream
+*/
+   type = S2CR_TYPE_TRANS;
+   cbndx = qsmmu->bypass_cbndx;
+   } else if (type == S2CR_TYPE_FAULT) {
+   /*
+* Firmware with quirky S2CR handling will ignore FAULT
+* writes, so trick it to write FAULT by asking for a
+* BYPASS.
+*/
+   type = S2CR_TYPE_BYPASS;
+   cbndx = 0xff;
+   }
+   }
+
+   reg = FIELD_PREP(ARM_SMMU_S2CR_TYPE, type) |
+ FIELD_PREP(ARM_SMMU_S2CR_CBNDX, cbndx) |
+ FIELD_PREP(ARM_SMMU_S2CR_PRIVCFG, s2cr->privcfg);
+
+   if (smmu->features & ARM_SMMU_FEAT_EXIDS && smmu->smrs && 
smmu->smrs[idx].valid)
+   reg |= ARM_SMMU_S2CR_EXIDVALID;
+   arm_smmu_gr0_write(smmu, ARM_SMMU_GR0_S2CR(idx), reg);
+}
+
 static int qcom_smmu_def_domain_type(struct device *dev)
 {
const struct of_device_id *match =
@@ -87,6 +154,7 @@ static const struct arm_smmu_impl qcom_smmu_impl = {
.cfg_probe = qcom_smmu_cfg_probe,
.def_domain_type = qcom_smmu_def_domain

Re: [PATCH v3 6/8] iommu/arm-smmu: Add impl hook for inherit boot mappings

2020-10-12 Thread Bjorn Andersson
On Mon 21 Sep 23:08 CEST 2020, Will Deacon wrote:

> On Sat, Sep 12, 2020 at 10:25:59PM -0500, Bjorn Andersson wrote:
> > On Fri 11 Sep 12:13 CDT 2020, Robin Murphy wrote:
> > > On 2020-09-04 16:55, Bjorn Andersson wrote:
> > > > Add a new operation to allow platform implementations to inherit any
> > > > stream mappings from the boot loader.
> > > 
> > > Is there a reason we need an explicit step for this? The aim of the
> > > cfg_probe hook is that the SMMU software state should all be set up by 
> > > then,
> > > and you can mess about with it however you like before arm_smmu_reset()
> > > actually commits anything to hardware. I would have thought you could
> > > permanently steal a context bank, configure it as your bypass hole, read 
> > > out
> > > the previous SME configuration and tweak smmu->smrs and smmu->s2crs
> > > appropriately all together "invisibly" at that point.
> > 
> > I did this because as of 6a79a5a3842b ("iommu/arm-smmu: Call
> > configuration impl hook before consuming features") we no longer have
> > setup pgsize_bitmap as we hit cfg_probe, which means that I need to
> > replicate this logic to set up the iommu_domain.
> > 
> > If I avoid setting up an iommu_domain for the identity context, as you
> > request in patch 8, this shouldn't be needed anymore.
> > 
> > > If that can't work, I'm very curious as to what I've overlooked.
> > > 
> > 
> > I believe that will work, I will rework the patches and try it out.
> 
> Did you get a chance to rework this?
> 

Finally got a chance to dig through this properly.

Initial results where positive and with an implementation of cfg_probe
in qcom_smmu_impl I'm able to probe the arm-smmu driver just fine - and
display (e.g. efifb) stays alive.

Unfortunately as the display driver (drivers/gpu/drm/msm) is about to
probe a new iommu domain is created, which due to its match against
qcom_smmu_client_of_match[] becomes of type IOMMU_DOMAIN_IDENTITY.
This results in a S2CR of BYPASS type, which the firmware intercepts and
turns the stream into a type FAULT.

So while the cfg_probe looks very reasonable we're still in need of a
mechanism to use the fake identity context for the iommu domain
associated with the display controller.


The workings of the display driver is that it gets the iommu domain
setup for byass and then after that creates a translation context for
this same stream where it maps the framebuffer.

For testing purposes I made def_domain_type always return 0 in the qcom
impl and the result is that we get a few page faults while probing the
display driver, but these are handled somewhat gracefully and the
initialization did proceed and the system comes up nicely (but in the
case that the display driver would probe defer this leads to an storm of
faults as the screen continues to be refreshed).

TL;DR I think we still need to have a way to get the arm-smmu driver to
allow the qcom implementation to configure identity domains to use
translation - but we can make the setup of the identity context a detail
of the qcom driver.

Regards,
Bjorn
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v3 6/8] iommu/arm-smmu: Add impl hook for inherit boot mappings

2020-09-24 Thread Bjorn Andersson
On Mon 21 Sep 16:08 CDT 2020, Will Deacon wrote:

> On Sat, Sep 12, 2020 at 10:25:59PM -0500, Bjorn Andersson wrote:
> > On Fri 11 Sep 12:13 CDT 2020, Robin Murphy wrote:
> > > On 2020-09-04 16:55, Bjorn Andersson wrote:
> > > > Add a new operation to allow platform implementations to inherit any
> > > > stream mappings from the boot loader.
> > > 
> > > Is there a reason we need an explicit step for this? The aim of the
> > > cfg_probe hook is that the SMMU software state should all be set up by 
> > > then,
> > > and you can mess about with it however you like before arm_smmu_reset()
> > > actually commits anything to hardware. I would have thought you could
> > > permanently steal a context bank, configure it as your bypass hole, read 
> > > out
> > > the previous SME configuration and tweak smmu->smrs and smmu->s2crs
> > > appropriately all together "invisibly" at that point.
> > 
> > I did this because as of 6a79a5a3842b ("iommu/arm-smmu: Call
> > configuration impl hook before consuming features") we no longer have
> > setup pgsize_bitmap as we hit cfg_probe, which means that I need to
> > replicate this logic to set up the iommu_domain.
> > 
> > If I avoid setting up an iommu_domain for the identity context, as you
> > request in patch 8, this shouldn't be needed anymore.
> > 
> > > If that can't work, I'm very curious as to what I've overlooked.
> > > 
> > 
> > I believe that will work, I will rework the patches and try it out.
> 
> Did you get a chance to rework this?
> 

Unfortunately not, I hope to get to this shortly.

Thanks,
Bjorn
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH] irqchip/qcom-pdc: Allow QCOM_PDC to be loadable as a permanent module

2020-09-15 Thread Bjorn Andersson
On Mon 14 Sep 21:04 UTC 2020, John Stultz wrote:

> Allows qcom-pdc driver to be loaded as a permanent module.
> 
> An earlier version of this patch was merged in a larger patchset
> but was reverted entirely when issues were found with other
> drivers, so now that Marc has provided a better solution in his
> Hybrid probing patch set, I wanted to re-submit this change.
> 

Reviewed-by: Bjorn Andersson 

> Cc: Andy Gross 
> Cc: Bjorn Andersson 
> Cc: Joerg Roedel 
> Cc: Thomas Gleixner 
> Cc: Jason Cooper 
> Cc: Marc Zyngier 
> Cc: Linus Walleij 
> Cc: Maulik Shah 
> Cc: Lina Iyer 
> Cc: Saravana Kannan 
> Cc: Todd Kjos 
> Cc: Greg Kroah-Hartman 
> Cc: linux-arm-...@vger.kernel.org
> Cc: iommu@lists.linux-foundation.org
> Cc: linux-g...@vger.kernel.org
> Signed-off-by: John Stultz 
> ---
>  drivers/irqchip/Kconfig| 2 +-
>  drivers/irqchip/qcom-pdc.c | 2 ++
>  2 files changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
> index bfc9719dbcdc..bb70b7177f94 100644
> --- a/drivers/irqchip/Kconfig
> +++ b/drivers/irqchip/Kconfig
> @@ -425,7 +425,7 @@ config GOLDFISH_PIC
>   for Goldfish based virtual platforms.
>  
>  config QCOM_PDC
> - bool "QCOM PDC"
> + tristate "QCOM PDC"
>   depends on ARCH_QCOM
>   select IRQ_DOMAIN_HIERARCHY
>   help
> diff --git a/drivers/irqchip/qcom-pdc.c b/drivers/irqchip/qcom-pdc.c
> index 8543fa23da10..59eb3c8473b0 100644
> --- a/drivers/irqchip/qcom-pdc.c
> +++ b/drivers/irqchip/qcom-pdc.c
> @@ -433,3 +433,5 @@ static int qcom_pdc_init(struct device_node *node, struct 
> device_node *parent)
>  IRQCHIP_HYBRID_DRIVER_BEGIN(qcom_pdc)
>  IRQCHIP_MATCH("qcom,pdc", qcom_pdc_init)
>  IRQCHIP_HYBRID_DRIVER_END(qcom_pdc)
> +MODULE_DESCRIPTION("Qualcomm Technologies, Inc. Power Domain Controller");
> +MODULE_LICENSE("GPL v2");
> -- 
> 2.17.1
> 
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v3 6/8] iommu/arm-smmu: Add impl hook for inherit boot mappings

2020-09-12 Thread Bjorn Andersson
On Fri 11 Sep 12:13 CDT 2020, Robin Murphy wrote:

> On 2020-09-04 16:55, Bjorn Andersson wrote:
> > Add a new operation to allow platform implementations to inherit any
> > stream mappings from the boot loader.
> 
> Is there a reason we need an explicit step for this? The aim of the
> cfg_probe hook is that the SMMU software state should all be set up by then,
> and you can mess about with it however you like before arm_smmu_reset()
> actually commits anything to hardware. I would have thought you could
> permanently steal a context bank, configure it as your bypass hole, read out
> the previous SME configuration and tweak smmu->smrs and smmu->s2crs
> appropriately all together "invisibly" at that point.

I did this because as of 6a79a5a3842b ("iommu/arm-smmu: Call
configuration impl hook before consuming features") we no longer have
setup pgsize_bitmap as we hit cfg_probe, which means that I need to
replicate this logic to set up the iommu_domain.

If I avoid setting up an iommu_domain for the identity context, as you
request in patch 8, this shouldn't be needed anymore.

> If that can't work, I'm very curious as to what I've overlooked.
> 

I believe that will work, I will rework the patches and try it out.

Thanks,
Bjorn

> Robin.
> 
> > Signed-off-by: Bjorn Andersson 
> > ---
> > 
> > Changes since v2:
> > - New patch/interface
> > 
> >   drivers/iommu/arm/arm-smmu/arm-smmu.c | 11 ++-
> >   drivers/iommu/arm/arm-smmu/arm-smmu.h |  6 ++
> >   2 files changed, 12 insertions(+), 5 deletions(-)
> > 
> > diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c 
> > b/drivers/iommu/arm/arm-smmu/arm-smmu.c
> > index eb5c6ca5c138..4c4d302cd747 100644
> > --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
> > +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
> > @@ -85,11 +85,6 @@ static inline void arm_smmu_rpm_put(struct 
> > arm_smmu_device *smmu)
> > pm_runtime_put_autosuspend(smmu->dev);
> >   }
> > -static struct arm_smmu_domain *to_smmu_domain(struct iommu_domain *dom)
> > -{
> > -   return container_of(dom, struct arm_smmu_domain, domain);
> > -}
> > -
> >   static struct platform_driver arm_smmu_driver;
> >   static struct iommu_ops arm_smmu_ops;
> > @@ -2188,6 +2183,12 @@ static int arm_smmu_device_probe(struct 
> > platform_device *pdev)
> > if (err)
> > return err;
> > +   if (smmu->impl->inherit_mappings) {
> > +   err = smmu->impl->inherit_mappings(smmu);
> > +   if (err)
> > +   return err;
> > +   }
> > +
> > if (smmu->version == ARM_SMMU_V2) {
> > if (smmu->num_context_banks > smmu->num_context_irqs) {
> > dev_err(dev,
> > diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.h 
> > b/drivers/iommu/arm/arm-smmu/arm-smmu.h
> > index 235d9a3a6ab6..f58164976e74 100644
> > --- a/drivers/iommu/arm/arm-smmu/arm-smmu.h
> > +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.h
> > @@ -378,6 +378,11 @@ struct arm_smmu_domain {
> > struct iommu_domain domain;
> >   };
> > +static inline struct arm_smmu_domain *to_smmu_domain(struct iommu_domain 
> > *dom)
> > +{
> > +   return container_of(dom, struct arm_smmu_domain, domain);
> > +}
> > +
> >   struct arm_smmu_master_cfg {
> > struct arm_smmu_device  *smmu;
> > s16 smendx[];
> > @@ -442,6 +447,7 @@ struct arm_smmu_impl {
> > int (*alloc_context_bank)(struct arm_smmu_domain *smmu_domain,
> >   struct arm_smmu_device *smmu,
> >   struct device *dev, int start);
> > +   int (*inherit_mappings)(struct arm_smmu_device *smmu);
> >   };
> >   #define INVALID_SMENDX-1
> > 
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v16 20/20] arm: dts: qcom: sc7180: Set the compatible string for the GPU SMMU

2020-09-04 Thread Bjorn Andersson
On Tue 01 Sep 11:46 CDT 2020, Rob Clark wrote:

> From: Rob Clark 
> 
> Set the qcom,adreno-smmu compatible string for the GPU SMMU to enable
> split pagetables and per-instance pagetables for drm/msm.
> 

Reviewed-by: Bjorn Andersson 

> Signed-off-by: Rob Clark 
> ---
>  arch/arm64/boot/dts/qcom/sc7180.dtsi | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi 
> b/arch/arm64/boot/dts/qcom/sc7180.dtsi
> index d46b3833e52f..f3bef1cad889 100644
> --- a/arch/arm64/boot/dts/qcom/sc7180.dtsi
> +++ b/arch/arm64/boot/dts/qcom/sc7180.dtsi
> @@ -1937,7 +1937,7 @@ opp-18000 {
>   };
>  
>   adreno_smmu: iommu@504 {
> - compatible = "qcom,sc7180-smmu-v2", "qcom,smmu-v2";
> + compatible = "qcom,sc7180-smmu-v2", "qcom,adreno-smmu", 
> "qcom,smmu-v2";
>   reg = <0 0x0504 0 0x1>;
>   #iommu-cells = <1>;
>   #global-interrupts = <2>;
> -- 
> 2.26.2
> 
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v16 19/20] arm: dts: qcom: sm845: Set the compatible string for the GPU SMMU

2020-09-04 Thread Bjorn Andersson
On Tue 01 Sep 11:46 CDT 2020, Rob Clark wrote:

> From: Jordan Crouse 
> 
> Set the qcom,adreno-smmu compatible string for the GPU SMMU to enable
> split pagetables and per-instance pagetables for drm/msm.
> 
> Signed-off-by: Jordan Crouse 
> Signed-off-by: Rob Clark 

Reviewed-by: Bjorn Andersson 

> ---
>  arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi | 9 +
>  arch/arm64/boot/dts/qcom/sdm845.dtsi   | 2 +-
>  2 files changed, 10 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi 
> b/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi
> index 64fc1bfd66fa..39f23cdcbd02 100644
> --- a/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi
> +++ b/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi
> @@ -633,6 +633,15 @@ _mdp {
>   status = "okay";
>  };
>  
> +/*
> + * Cheza fw does not properly program the GPU aperture to allow the
> + * GPU to update the SMMU pagetables for context switches.  Work
> + * around this by dropping the "qcom,adreno-smmu" compat string.
> + */
> +_smmu {
> + compatible = "qcom,sdm845-smmu-v2", "qcom,smmu-v2";
> +};
> +
>  _pil {
>   iommus = <_smmu 0x781 0x0>,
><_smmu 0x724 0x3>;
> diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi 
> b/arch/arm64/boot/dts/qcom/sdm845.dtsi
> index 2884577dcb77..76a8a34640ae 100644
> --- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
> +++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
> @@ -4058,7 +4058,7 @@ opp-25700 {
>   };
>  
>   adreno_smmu: iommu@504 {
> - compatible = "qcom,sdm845-smmu-v2", "qcom,smmu-v2";
> + compatible = "qcom,sdm845-smmu-v2", "qcom,adreno-smmu", 
> "qcom,smmu-v2";
>   reg = <0 0x504 0 0x1>;
>   #iommu-cells = <1>;
>   #global-interrupts = <2>;
> -- 
> 2.26.2
> 
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v3 5/8] iommu/arm-smmu-qcom: Consistently initialize stream mappings

2020-09-04 Thread Bjorn Andersson
Firmware that traps writes to S2CR to translate BYPASS into FAULT also
ignores writes of type FAULT. As such booting with "disable_bypass" set
will result in all S2CR registers left as configured by the bootloader.

This has been seen to result in indeterministic results, as these
mappings might linger and reference context banks that Linux is
reconfiguring.

Use the fact that BYPASS writes result in FAULT type to force all stream
mappings to FAULT.

Signed-off-by: Bjorn Andersson 
---

Changes since v2:
- None
 drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 18 +-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c 
b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
index 284761a1cd8e..70a1eaa52e14 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
@@ -195,6 +195,7 @@ static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu)
unsigned int last_s2cr = ARM_SMMU_GR0_S2CR(smmu->num_mapping_groups - 
1);
struct qcom_smmu *qsmmu = to_qcom_smmu(smmu);
u32 reg;
+   int i;
 
/*
 * With some firmware writes to S2CR of type FAULT are ignored, and
@@ -206,9 +207,24 @@ static int qcom_smmu_cfg_probe(struct arm_smmu_device 
*smmu)
  FIELD_PREP(ARM_SMMU_S2CR_PRIVCFG, S2CR_PRIVCFG_DEFAULT);
arm_smmu_gr0_write(smmu, last_s2cr, reg);
reg = arm_smmu_gr0_read(smmu, last_s2cr);
-   if (FIELD_GET(ARM_SMMU_S2CR_TYPE, reg) != S2CR_TYPE_BYPASS)
+   if (FIELD_GET(ARM_SMMU_S2CR_TYPE, reg) != S2CR_TYPE_BYPASS) {
qsmmu->bypass_broken = true;
 
+   /*
+* With firmware ignoring writes of type FAULT, booting the
+* Linux kernel with disable_bypass disabled (i.e. "enable
+* bypass") the initialization during probe will leave mappings
+* in an inconsistent state. Avoid this by configuring all
+* S2CRs to BYPASS.
+*/
+   for (i = 0; i < smmu->num_mapping_groups; i++) {
+   smmu->s2crs[i].type = S2CR_TYPE_BYPASS;
+   smmu->s2crs[i].privcfg = S2CR_PRIVCFG_DEFAULT;
+   smmu->s2crs[i].cbndx = 0xff;
+   smmu->s2crs[i].count = 0;
+   }
+   }
+
return 0;
 }
 
-- 
2.28.0

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v3 7/8] iommu/arm-smmu: Provide helper for allocating identity domain

2020-09-04 Thread Bjorn Andersson
Some platform implementations needs to be able to allocate a domain for
emulating identity mappings using a context bank without translation.
Provide a helper function to allocate such a domain.

Signed-off-by: Bjorn Andersson 
---

Changes since v2:
- Extracted from previous arm_smmu_setup_identity() implementation

 drivers/iommu/arm/arm-smmu/arm-smmu.c | 25 +
 drivers/iommu/arm/arm-smmu/arm-smmu.h |  2 ++
 2 files changed, 27 insertions(+)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c 
b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index 4c4d302cd747..3c06146dfdb9 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -1924,6 +1924,31 @@ static int arm_smmu_device_cfg_probe(struct 
arm_smmu_device *smmu)
return 0;
 }
 
+struct iommu_domain *arm_smmu_alloc_identity_domain(struct arm_smmu_device 
*smmu)
+{
+   struct iommu_domain *identity;
+   int ret;
+
+   /* Create a IDENTITY domain to use for all inherited streams */
+   identity = arm_smmu_domain_alloc(IOMMU_DOMAIN_IDENTITY);
+   if (!identity) {
+   dev_err(smmu->dev, "failed to create identity domain\n");
+   return ERR_PTR(-ENOMEM);
+   }
+
+   identity->pgsize_bitmap = smmu->pgsize_bitmap;
+   identity->type = IOMMU_DOMAIN_IDENTITY;
+   identity->ops = _smmu_ops;
+
+   ret = arm_smmu_init_domain_context(identity, smmu, NULL);
+   if (ret < 0) {
+   dev_err(smmu->dev, "failed to initialize identity domain: 
%d\n", ret);
+   return ERR_PTR(ret);
+   }
+
+   return identity;
+}
+
 struct arm_smmu_match_data {
enum arm_smmu_arch_version version;
enum arm_smmu_implementation model;
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.h 
b/drivers/iommu/arm/arm-smmu/arm-smmu.h
index f58164976e74..fbdf3d7ca70d 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.h
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.h
@@ -537,4 +537,6 @@ struct arm_smmu_device *qcom_adreno_smmu_impl_init(struct 
arm_smmu_device *smmu)
 void arm_smmu_write_context_bank(struct arm_smmu_device *smmu, int idx);
 int arm_mmu500_reset(struct arm_smmu_device *smmu);
 
+struct iommu_domain *arm_smmu_alloc_identity_domain(struct arm_smmu_device 
*smmu);
+
 #endif /* _ARM_SMMU_H */
-- 
2.28.0

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v3 4/8] iommu/arm-smmu-qcom: Emulate bypass by using context banks

2020-09-04 Thread Bjorn Andersson
Some firmware found on various Qualcomm platforms traps writes to S2CR
of type BYPASS and writes FAULT into the register. In particular, this
prevents us from marking the streams for the display controller as
BYPASS to allow continued scanout of the screen through the
initialization of the ARM SMMU.

This adds a Qualcomm specific cfg_probe function, which probes for the
broken behavior of the S2CR registers and implements a custom
alloc_context_bank() that when necessary allocates a context bank
(without translation) for these domains as well.

Signed-off-by: Bjorn Andersson 
---

Changes since v2:
- Move quirk from arm_smmudevice to qcom_smmu, as we localize the quirk
  handling to the Qualcomm specific implemntation.

 drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 52 ++
 1 file changed, 52 insertions(+)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c 
b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
index 229fc8ff8cea..284761a1cd8e 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
@@ -11,8 +11,14 @@
 
 struct qcom_smmu {
struct arm_smmu_device smmu;
+   bool bypass_broken;
 };
 
+static struct qcom_smmu *to_qcom_smmu(struct arm_smmu_device *smmu)
+{
+   return container_of(smmu, struct qcom_smmu, smmu);
+}
+
 #define QCOM_ADRENO_SMMU_GPU_SID 0
 
 static bool qcom_adreno_smmu_is_gpu_device(struct device *dev)
@@ -162,6 +168,50 @@ static const struct of_device_id 
qcom_smmu_client_of_match[] __maybe_unused = {
{ }
 };
 
+static int qcom_smmu_alloc_context_bank(struct arm_smmu_domain *smmu_domain,
+   struct arm_smmu_device *smmu,
+   struct device *dev, int start)
+{
+   struct iommu_domain *domain = _domain->domain;
+   struct qcom_smmu *qsmmu = to_qcom_smmu(smmu);
+
+   /* Keep identity domains as bypass, unless bypass is broken */
+   if (domain->type == IOMMU_DOMAIN_IDENTITY && !qsmmu->bypass_broken)
+   return ARM_SMMU_CBNDX_BYPASS;
+
+   /*
+* The identity domain to emulate bypass is the only domain without a
+* dev, use the last context bank for this to avoid collisions with
+* active contexts during initialization.
+*/
+   if (!dev)
+   start = smmu->num_context_banks - 1;
+
+   return __arm_smmu_alloc_bitmap(smmu->context_map, start, 
smmu->num_context_banks);
+}
+
+static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu)
+{
+   unsigned int last_s2cr = ARM_SMMU_GR0_S2CR(smmu->num_mapping_groups - 
1);
+   struct qcom_smmu *qsmmu = to_qcom_smmu(smmu);
+   u32 reg;
+
+   /*
+* With some firmware writes to S2CR of type FAULT are ignored, and
+* writing BYPASS will end up as FAULT in the register. Perform a write
+* to S2CR to detect if this is the case with the current firmware.
+*/
+   reg = FIELD_PREP(ARM_SMMU_S2CR_TYPE, S2CR_TYPE_BYPASS) |
+ FIELD_PREP(ARM_SMMU_S2CR_CBNDX, 0xff) |
+ FIELD_PREP(ARM_SMMU_S2CR_PRIVCFG, S2CR_PRIVCFG_DEFAULT);
+   arm_smmu_gr0_write(smmu, last_s2cr, reg);
+   reg = arm_smmu_gr0_read(smmu, last_s2cr);
+   if (FIELD_GET(ARM_SMMU_S2CR_TYPE, reg) != S2CR_TYPE_BYPASS)
+   qsmmu->bypass_broken = true;
+
+   return 0;
+}
+
 static int qcom_smmu_def_domain_type(struct device *dev)
 {
const struct of_device_id *match =
@@ -200,6 +250,8 @@ static int qcom_smmu500_reset(struct arm_smmu_device *smmu)
 }
 
 static const struct arm_smmu_impl qcom_smmu_impl = {
+   .alloc_context_bank = qcom_smmu_alloc_context_bank,
+   .cfg_probe = qcom_smmu_cfg_probe,
.def_domain_type = qcom_smmu_def_domain_type,
.reset = qcom_smmu500_reset,
 };
-- 
2.28.0

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v3 1/8] iommu/arm-smmu: Refactor context bank allocation

2020-09-04 Thread Bjorn Andersson
Extract the conditional invocation of the platform defined
alloc_context_bank() to a separate function to keep
arm_smmu_init_domain_context() cleaner.

Instead pass a reference to the arm_smmu_device as parameter to the
call. Also remove the count parameter, as this can be read from the
newly passed object.

This allows us to not assign smmu_domain->smmu before attempting to
allocate the context bank and as such we don't need to roll back this
assignment on failure.

Signed-off-by: Bjorn Andersson 
---

Note that this series applies ontop of:
https://lore.kernel.org/linux-arm-msm/20200901164707.2645413-1-robdcl...@gmail.com/

This could either go on its own, or be squashed with "[PATCH v16 14/20]
iommu/arm-smmu: Prepare for the adreno-smmu implementation" from Rob's series.

Changes since v2:
- New patch

 drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c |  6 --
 drivers/iommu/arm/arm-smmu/arm-smmu.c  | 23 --
 drivers/iommu/arm/arm-smmu/arm-smmu.h  |  3 ++-
 3 files changed, 19 insertions(+), 13 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c 
b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
index 2aa6249050ff..0663d7d26908 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
@@ -91,9 +91,10 @@ static int qcom_adreno_smmu_set_ttbr0_cfg(const void *cookie,
 }
 
 static int qcom_adreno_smmu_alloc_context_bank(struct arm_smmu_domain 
*smmu_domain,
-   struct device *dev, int start, int count)
+  struct arm_smmu_device *smmu,
+  struct device *dev, int start)
 {
-   struct arm_smmu_device *smmu = smmu_domain->smmu;
+   int count;
 
/*
 * Assign context bank 0 to the GPU device so the GPU hardware can
@@ -104,6 +105,7 @@ static int qcom_adreno_smmu_alloc_context_bank(struct 
arm_smmu_domain *smmu_doma
count = 1;
} else {
start = 1;
+   count = smmu->num_context_banks;
}
 
return __arm_smmu_alloc_bitmap(smmu->context_map, start, count);
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c 
b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index bbec5793faf8..e19d7bdc7674 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -623,6 +623,16 @@ void arm_smmu_write_context_bank(struct arm_smmu_device 
*smmu, int idx)
arm_smmu_cb_write(smmu, idx, ARM_SMMU_CB_SCTLR, reg);
 }
 
+static int arm_smmu_alloc_context_bank(struct arm_smmu_domain *smmu_domain,
+  struct arm_smmu_device *smmu,
+  struct device *dev, unsigned int start)
+{
+   if (smmu->impl && smmu->impl->alloc_context_bank)
+   return smmu->impl->alloc_context_bank(smmu_domain, smmu, dev, 
start);
+
+   return __arm_smmu_alloc_bitmap(smmu->context_map, start, 
smmu->num_context_banks);
+}
+
 static int arm_smmu_init_domain_context(struct iommu_domain *domain,
struct arm_smmu_device *smmu,
struct device *dev)
@@ -741,20 +751,13 @@ static int arm_smmu_init_domain_context(struct 
iommu_domain *domain,
goto out_unlock;
}
 
-   smmu_domain->smmu = smmu;
-
-   if (smmu->impl && smmu->impl->alloc_context_bank)
-   ret = smmu->impl->alloc_context_bank(smmu_domain, dev,
-   start, smmu->num_context_banks);
-   else
-   ret = __arm_smmu_alloc_bitmap(smmu->context_map, start,
- smmu->num_context_banks);
-
+   ret = arm_smmu_alloc_context_bank(smmu_domain, smmu, dev, start);
if (ret < 0) {
-   smmu_domain->smmu = NULL;
goto out_unlock;
}
 
+   smmu_domain->smmu = smmu;
+
cfg->cbndx = ret;
if (smmu->version < ARM_SMMU_V2) {
cfg->irptndx = atomic_inc_return(>irptndx);
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.h 
b/drivers/iommu/arm/arm-smmu/arm-smmu.h
index 2df3a70a8a41..ddf2ca4c923d 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.h
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.h
@@ -437,7 +437,8 @@ struct arm_smmu_impl {
irqreturn_t (*global_fault)(int irq, void *dev);
irqreturn_t (*context_fault)(int irq, void *dev);
int (*alloc_context_bank)(struct arm_smmu_domain *smmu_domain,
-   struct device *dev, int start, int max);
+ struct arm_smmu_device *smmu,
+ struct device *dev, int start);
 };
 
 #define INVALID_SMENDX -1
-- 
2.28.0

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v3 6/8] iommu/arm-smmu: Add impl hook for inherit boot mappings

2020-09-04 Thread Bjorn Andersson
Add a new operation to allow platform implementations to inherit any
stream mappings from the boot loader.

Signed-off-by: Bjorn Andersson 
---

Changes since v2:
- New patch/interface

 drivers/iommu/arm/arm-smmu/arm-smmu.c | 11 ++-
 drivers/iommu/arm/arm-smmu/arm-smmu.h |  6 ++
 2 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c 
b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index eb5c6ca5c138..4c4d302cd747 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -85,11 +85,6 @@ static inline void arm_smmu_rpm_put(struct arm_smmu_device 
*smmu)
pm_runtime_put_autosuspend(smmu->dev);
 }
 
-static struct arm_smmu_domain *to_smmu_domain(struct iommu_domain *dom)
-{
-   return container_of(dom, struct arm_smmu_domain, domain);
-}
-
 static struct platform_driver arm_smmu_driver;
 static struct iommu_ops arm_smmu_ops;
 
@@ -2188,6 +2183,12 @@ static int arm_smmu_device_probe(struct platform_device 
*pdev)
if (err)
return err;
 
+   if (smmu->impl->inherit_mappings) {
+   err = smmu->impl->inherit_mappings(smmu);
+   if (err)
+   return err;
+   }
+
if (smmu->version == ARM_SMMU_V2) {
if (smmu->num_context_banks > smmu->num_context_irqs) {
dev_err(dev,
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.h 
b/drivers/iommu/arm/arm-smmu/arm-smmu.h
index 235d9a3a6ab6..f58164976e74 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.h
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.h
@@ -378,6 +378,11 @@ struct arm_smmu_domain {
struct iommu_domain domain;
 };
 
+static inline struct arm_smmu_domain *to_smmu_domain(struct iommu_domain *dom)
+{
+   return container_of(dom, struct arm_smmu_domain, domain);
+}
+
 struct arm_smmu_master_cfg {
struct arm_smmu_device  *smmu;
s16 smendx[];
@@ -442,6 +447,7 @@ struct arm_smmu_impl {
int (*alloc_context_bank)(struct arm_smmu_domain *smmu_domain,
  struct arm_smmu_device *smmu,
  struct device *dev, int start);
+   int (*inherit_mappings)(struct arm_smmu_device *smmu);
 };
 
 #define INVALID_SMENDX -1
-- 
2.28.0

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v16 14/20] iommu/arm-smmu: Prepare for the adreno-smmu implementation

2020-09-04 Thread Bjorn Andersson
On Tue 01 Sep 11:46 CDT 2020, Rob Clark wrote:

> From: Jordan Crouse 
> 
> Do a bit of prep work to add the upcoming adreno-smmu implementation.
> 
> Add an hook to allow the implementation to choose which context banks
> to allocate.
> 
> Move some of the common structs to arm-smmu.h in anticipation of them
> being used by the implementations and update some of the existing hooks
> to pass more information that the implementation will need.
> 
> These modifications will be used by the upcoming Adreno SMMU
> implementation to identify the GPU device and properly configure it
> for pagetable switching.
> 
> Co-developed-by: Rob Clark 
> Signed-off-by: Jordan Crouse 
> Signed-off-by: Rob Clark 

As I built the handoff support on top of this patch I ended up
reworking the alloc_context_bank() prototype to something I found a
little bit cleaner.

So perhaps you would be interested in squashing
https://lore.kernel.org/linux-arm-msm/20200904155513.282067-2-bjorn.anders...@linaro.org/
into this patch?

Otherwise, feel free to add my:

Reviewed-by: Bjorn Andersson 

Regards,
Bjorn

> ---
>  drivers/iommu/arm/arm-smmu/arm-smmu-impl.c |  2 +-
>  drivers/iommu/arm/arm-smmu/arm-smmu.c  | 69 ++
>  drivers/iommu/arm/arm-smmu/arm-smmu.h  | 51 +++-
>  3 files changed, 68 insertions(+), 54 deletions(-)
> 
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c 
> b/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c
> index a9861dcd0884..88f17cc33023 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c
> @@ -69,7 +69,7 @@ static int cavium_cfg_probe(struct arm_smmu_device *smmu)
>  }
>  
>  static int cavium_init_context(struct arm_smmu_domain *smmu_domain,
> - struct io_pgtable_cfg *pgtbl_cfg)
> + struct io_pgtable_cfg *pgtbl_cfg, struct device *dev)
>  {
>   struct cavium_smmu *cs = container_of(smmu_domain->smmu,
> struct cavium_smmu, smmu);
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c 
> b/drivers/iommu/arm/arm-smmu/arm-smmu.c
> index 8e884e58f208..68b7b9e6140e 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
> @@ -65,41 +65,10 @@ module_param(disable_bypass, bool, S_IRUGO);
>  MODULE_PARM_DESC(disable_bypass,
>   "Disable bypass streams such that incoming transactions from devices 
> that are not attached to an iommu domain will report an abort back to the 
> device and will not be allowed to pass through the SMMU.");
>  
> -struct arm_smmu_s2cr {
> - struct iommu_group  *group;
> - int count;
> - enum arm_smmu_s2cr_type type;
> - enum arm_smmu_s2cr_privcfg  privcfg;
> - u8  cbndx;
> -};
> -
>  #define s2cr_init_val (struct arm_smmu_s2cr){
> \
>   .type = disable_bypass ? S2CR_TYPE_FAULT : S2CR_TYPE_BYPASS,\
>  }
>  
> -struct arm_smmu_smr {
> - u16 mask;
> - u16 id;
> - boolvalid;
> -};
> -
> -struct arm_smmu_cb {
> - u64 ttbr[2];
> - u32 tcr[2];
> - u32 mair[2];
> - struct arm_smmu_cfg *cfg;
> -};
> -
> -struct arm_smmu_master_cfg {
> - struct arm_smmu_device  *smmu;
> - s16 smendx[];
> -};
> -#define INVALID_SMENDX   -1
> -#define cfg_smendx(cfg, fw, i) \
> - (i >= fw->num_ids ? INVALID_SMENDX : cfg->smendx[i])
> -#define for_each_cfg_sme(cfg, fw, i, idx) \
> - for (i = 0; idx = cfg_smendx(cfg, fw, i), i < fw->num_ids; ++i)
> -
>  static bool using_legacy_binding, using_generic_binding;
>  
>  static inline int arm_smmu_rpm_get(struct arm_smmu_device *smmu)
> @@ -234,19 +203,6 @@ static int arm_smmu_register_legacy_master(struct device 
> *dev,
>  }
>  #endif /* CONFIG_ARM_SMMU_LEGACY_DT_BINDINGS */
>  
> -static int __arm_smmu_alloc_bitmap(unsigned long *map, int start, int end)
> -{
> - int idx;
> -
> - do {
> - idx = find_next_zero_bit(map, end, start);
> - if (idx == end)
> - return -ENOSPC;
> - } while (test_and_set_bit(idx, map));
> -
> - return idx;
> -}
> -
>  static void __arm_smmu_free_bitmap(unsigned long *map, int idx)
>  {
>   clear_bit(idx, map);
> @@ -578,7 +534,7 @@ static void arm_smmu_init_context_bank(struct 
> arm_smmu_domain *

[PATCH v3 3/8] iommu/arm-smmu: Consult context bank allocator for identify domains

2020-09-04 Thread Bjorn Andersson
For implementations of the ARM SMMU where stream mappings of bypass type
are prohibited identity domains can be implemented by using context
banks with translation disabled.

Postpone the decision to skip allocating a context bank until the
implementation specific context bank allocator has been consulted and if
it decides to use a context bank for the identity map, don't enable
translation (i.e. omit ARM_SMMU_SCTLR_M).

Signed-off-by: Bjorn Andersson 
---

Changes since v2:
- Tie this to alloc_context_bank rather than carrying a Qualcomm specific quirk
  in the generic code.

 drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c |  4 
 drivers/iommu/arm/arm-smmu/arm-smmu.c  | 23 +++---
 drivers/iommu/arm/arm-smmu/arm-smmu.h  |  3 +++
 3 files changed, 23 insertions(+), 7 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c 
b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
index 0663d7d26908..229fc8ff8cea 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
@@ -94,8 +94,12 @@ static int qcom_adreno_smmu_alloc_context_bank(struct 
arm_smmu_domain *smmu_doma
   struct arm_smmu_device *smmu,
   struct device *dev, int start)
 {
+   struct iommu_domain *domain = _domain->domain;
int count;
 
+   if (domain->type == IOMMU_DOMAIN_IDENTITY)
+   return ARM_SMMU_CBNDX_BYPASS;
+
/*
 * Assign context bank 0 to the GPU device so the GPU hardware can
 * switch pagetables
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c 
b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index add2e1807e21..eb5c6ca5c138 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -611,7 +611,9 @@ void arm_smmu_write_context_bank(struct arm_smmu_device 
*smmu, int idx)
 
/* SCTLR */
reg = ARM_SMMU_SCTLR_CFIE | ARM_SMMU_SCTLR_CFRE | ARM_SMMU_SCTLR_AFE |
- ARM_SMMU_SCTLR_TRE | ARM_SMMU_SCTLR_M;
+ ARM_SMMU_SCTLR_TRE;
+   if (cfg->m)
+   reg |= ARM_SMMU_SCTLR_M;
if (stage1)
reg |= ARM_SMMU_SCTLR_S1_ASIDPNE;
if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
@@ -627,9 +629,14 @@ static int arm_smmu_alloc_context_bank(struct 
arm_smmu_domain *smmu_domain,
   struct arm_smmu_device *smmu,
   struct device *dev, unsigned int start)
 {
+   struct iommu_domain *domain = _domain->domain;
+
if (smmu->impl && smmu->impl->alloc_context_bank)
return smmu->impl->alloc_context_bank(smmu_domain, smmu, dev, 
start);
 
+   if (domain->type == IOMMU_DOMAIN_IDENTITY)
+   return ARM_SMMU_CBNDX_BYPASS;
+
return __arm_smmu_alloc_bitmap(smmu->context_map, start, 
smmu->num_context_banks);
 }
 
@@ -653,12 +660,6 @@ static int arm_smmu_init_domain_context(struct 
iommu_domain *domain,
if (smmu_domain->smmu)
goto out_unlock;
 
-   if (domain->type == IOMMU_DOMAIN_IDENTITY) {
-   smmu_domain->stage = ARM_SMMU_DOMAIN_BYPASS;
-   smmu_domain->smmu = smmu;
-   goto out_unlock;
-   }
-
/*
 * Mapping the requested stage onto what we support is surprisingly
 * complicated, mainly because the spec allows S1+S2 SMMUs without
@@ -757,6 +758,10 @@ static int arm_smmu_init_domain_context(struct 
iommu_domain *domain,
ret = arm_smmu_alloc_context_bank(smmu_domain, smmu, dev, start);
if (ret < 0) {
goto out_unlock;
+   } else if (ret == ARM_SMMU_CBNDX_BYPASS) {
+   smmu_domain->stage = ARM_SMMU_DOMAIN_BYPASS;
+   smmu_domain->smmu = smmu;
+   goto out_unlock;
}
 
smmu_domain->smmu = smmu;
@@ -813,6 +818,10 @@ static int arm_smmu_init_domain_context(struct 
iommu_domain *domain,
 
domain->geometry.force_aperture = true;
 
+   /* Enable translation for non-identity context banks */
+   if (domain->type != IOMMU_DOMAIN_IDENTITY)
+   cfg->m = true;
+
/* Initialise the context bank with our page table cfg */
arm_smmu_init_context_bank(smmu_domain, _cfg);
arm_smmu_write_context_bank(smmu, cfg->cbndx);
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.h 
b/drivers/iommu/arm/arm-smmu/arm-smmu.h
index ddf2ca4c923d..235d9a3a6ab6 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.h
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.h
@@ -243,6 +243,8 @@ enum arm_smmu_cbar_type {
 #define TLB_LOOP_TIMEOUT   100 /* 1s! */
 #define TLB_SPIN_COUNT 10
 
+#define ARM_SMMU_CBNDX_BYPASS  0x
+
 /* Shared driver definitions */
 enum arm_smmu_arch_version {
ARM_SMMU_V1,
@@ -346,6 +348,7 @@ struct arm_smmu_cfg 

[PATCH v3 2/8] iommu/arm-smmu: Delay modifying domain during init

2020-09-04 Thread Bjorn Andersson
Delay modifications to the domain during arm_smmu_init_domain_context()
until we've allocated a context bank. This will allow us to postpone the
special handling of identity domains until the platform specific context
bank allocator has been executed, in a later patch.

Signed-off-by: Bjorn Andersson 
---

Changes since v2:
- New patch to allow us to rely on the impl specific alloc_context_bank().

 drivers/iommu/arm/arm-smmu/arm-smmu.c | 40 +++
 1 file changed, 23 insertions(+), 17 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c 
b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index e19d7bdc7674..add2e1807e21 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -645,6 +645,9 @@ static int arm_smmu_init_domain_context(struct iommu_domain 
*domain,
struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
struct arm_smmu_cfg *cfg = _domain->cfg;
irqreturn_t (*context_fault)(int irq, void *dev);
+   struct arm_smmu_cfg new_cfg = *cfg;
+   enum arm_smmu_domain_stage new_stage = smmu_domain->stage;
+   const struct iommu_flush_ops *flush_ops;
 
mutex_lock(_domain->init_mutex);
if (smmu_domain->smmu)
@@ -675,9 +678,9 @@ static int arm_smmu_init_domain_context(struct iommu_domain 
*domain,
 * Note that you can't actually request stage-2 mappings.
 */
if (!(smmu->features & ARM_SMMU_FEAT_TRANS_S1))
-   smmu_domain->stage = ARM_SMMU_DOMAIN_S2;
+   new_stage = ARM_SMMU_DOMAIN_S2;
if (!(smmu->features & ARM_SMMU_FEAT_TRANS_S2))
-   smmu_domain->stage = ARM_SMMU_DOMAIN_S1;
+   new_stage = ARM_SMMU_DOMAIN_S1;
 
/*
 * Choosing a suitable context format is even more fiddly. Until we
@@ -688,32 +691,32 @@ static int arm_smmu_init_domain_context(struct 
iommu_domain *domain,
 * support to be a superset of AArch32 support...
 */
if (smmu->features & ARM_SMMU_FEAT_FMT_AARCH32_L)
-   cfg->fmt = ARM_SMMU_CTX_FMT_AARCH32_L;
+   new_cfg.fmt = ARM_SMMU_CTX_FMT_AARCH32_L;
if (IS_ENABLED(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) &&
!IS_ENABLED(CONFIG_64BIT) && !IS_ENABLED(CONFIG_ARM_LPAE) &&
(smmu->features & ARM_SMMU_FEAT_FMT_AARCH32_S) &&
-   (smmu_domain->stage == ARM_SMMU_DOMAIN_S1))
-   cfg->fmt = ARM_SMMU_CTX_FMT_AARCH32_S;
-   if ((IS_ENABLED(CONFIG_64BIT) || cfg->fmt == ARM_SMMU_CTX_FMT_NONE) &&
+   (new_stage == ARM_SMMU_DOMAIN_S1))
+   new_cfg.fmt = ARM_SMMU_CTX_FMT_AARCH32_S;
+   if ((IS_ENABLED(CONFIG_64BIT) || new_cfg.fmt == ARM_SMMU_CTX_FMT_NONE) 
&&
(smmu->features & (ARM_SMMU_FEAT_FMT_AARCH64_64K |
   ARM_SMMU_FEAT_FMT_AARCH64_16K |
   ARM_SMMU_FEAT_FMT_AARCH64_4K)))
-   cfg->fmt = ARM_SMMU_CTX_FMT_AARCH64;
+   new_cfg.fmt = ARM_SMMU_CTX_FMT_AARCH64;
 
-   if (cfg->fmt == ARM_SMMU_CTX_FMT_NONE) {
+   if (new_cfg.fmt == ARM_SMMU_CTX_FMT_NONE) {
ret = -EINVAL;
goto out_unlock;
}
 
-   switch (smmu_domain->stage) {
+   switch (new_stage) {
case ARM_SMMU_DOMAIN_S1:
-   cfg->cbar = CBAR_TYPE_S1_TRANS_S2_BYPASS;
+   new_cfg.cbar = CBAR_TYPE_S1_TRANS_S2_BYPASS;
start = smmu->num_s2_context_banks;
ias = smmu->va_size;
oas = smmu->ipa_size;
-   if (cfg->fmt == ARM_SMMU_CTX_FMT_AARCH64) {
+   if (new_cfg.fmt == ARM_SMMU_CTX_FMT_AARCH64) {
fmt = ARM_64_LPAE_S1;
-   } else if (cfg->fmt == ARM_SMMU_CTX_FMT_AARCH32_L) {
+   } else if (new_cfg.fmt == ARM_SMMU_CTX_FMT_AARCH32_L) {
fmt = ARM_32_LPAE_S1;
ias = min(ias, 32UL);
oas = min(oas, 40UL);
@@ -722,7 +725,7 @@ static int arm_smmu_init_domain_context(struct iommu_domain 
*domain,
ias = min(ias, 32UL);
oas = min(oas, 32UL);
}
-   smmu_domain->flush_ops = _smmu_s1_tlb_ops;
+   flush_ops = _smmu_s1_tlb_ops;
break;
case ARM_SMMU_DOMAIN_NESTED:
/*
@@ -730,11 +733,11 @@ static int arm_smmu_init_domain_context(struct 
iommu_domain *domain,
 * involved.
 */
case ARM_SMMU_DOMAIN_S2:
-   cfg->cbar = CBAR_TYPE_S2_TRANS;
+   new_cfg.cbar = CBAR_TYPE_S2_TRANS;
start = 0;
ias = smmu->ipa_size;
oas = smmu->pa_size;
-   if (cfg->fmt == ARM_SMMU_CTX_FMT_AARCH64) {
+   if (new

[PATCH v3 8/8] iommu/arm-smmu-qcom: Setup identity domain for boot mappings

2020-09-04 Thread Bjorn Andersson
With many Qualcomm platforms not having functional S2CR BYPASS a
temporary IOMMU domain, without translation, needs to be allocated in
order to allow these memory transactions.

Unfortunately the boot loader uses the first few context banks, so
rather than overwriting a active bank the last context bank is used and
streams are diverted here during initialization.

This also performs the readback of SMR registers for the Qualcomm
platform, to trigger the mechanism.

This is based on prior work by Thierry Reding and Laurentiu Tudor.

Signed-off-by: Bjorn Andersson 
---

Changes since v2:
- Combined from pieces spread between the Qualcomm impl and generic code in v2.
- Moved to use the newly introduced inherit_mapping op.

 drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 33 ++
 1 file changed, 33 insertions(+)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c 
b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
index 70a1eaa52e14..a54302190932 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
@@ -12,6 +12,7 @@
 struct qcom_smmu {
struct arm_smmu_device smmu;
bool bypass_broken;
+   struct iommu_domain *identity;
 };
 
 static struct qcom_smmu *to_qcom_smmu(struct arm_smmu_device *smmu)
@@ -228,6 +229,37 @@ static int qcom_smmu_cfg_probe(struct arm_smmu_device 
*smmu)
return 0;
 }
 
+static int qcom_smmu_inherit_mappings(struct arm_smmu_device *smmu)
+{
+   struct qcom_smmu *qsmmu = to_qcom_smmu(smmu);
+   int cbndx;
+   u32 smr;
+   int i;
+
+   qsmmu->identity = arm_smmu_alloc_identity_domain(smmu);
+   if (IS_ERR(qsmmu->identity))
+   return PTR_ERR(qsmmu->identity);
+
+   cbndx = to_smmu_domain(qsmmu->identity)->cfg.cbndx;
+
+   for (i = 0; i < smmu->num_mapping_groups; i++) {
+   smr = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_SMR(i));
+
+   if (FIELD_GET(ARM_SMMU_SMR_VALID, smr)) {
+   smmu->smrs[i].id = FIELD_GET(ARM_SMMU_SMR_ID, smr);
+   smmu->smrs[i].mask = FIELD_GET(ARM_SMMU_SMR_MASK, smr);
+   smmu->smrs[i].valid = true;
+
+   smmu->s2crs[i].type = S2CR_TYPE_TRANS;
+   smmu->s2crs[i].privcfg = S2CR_PRIVCFG_DEFAULT;
+   smmu->s2crs[i].cbndx = cbndx;
+   smmu->s2crs[i].count++;
+   }
+   }
+
+   return 0;
+}
+
 static int qcom_smmu_def_domain_type(struct device *dev)
 {
const struct of_device_id *match =
@@ -270,6 +302,7 @@ static const struct arm_smmu_impl qcom_smmu_impl = {
.cfg_probe = qcom_smmu_cfg_probe,
.def_domain_type = qcom_smmu_def_domain_type,
.reset = qcom_smmu500_reset,
+   .inherit_mappings = qcom_smmu_inherit_mappings,
 };
 
 static const struct arm_smmu_impl qcom_adreno_smmu_impl = {
-- 
2.28.0

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v3 0/8] iommu/arm-smmu: Support maintaining bootloader mappings

2020-09-04 Thread Bjorn Andersson
Based on previous attempts and discussions this is the latest attempt at
inheriting stream mappings set up by the bootloader, for e.g. boot splash or
efifb.

Per Will's request this builds on the work by Jordan and Rob for the Adreno
SMMU support. It applies cleanly ontop of v16 of their series, which can be
found at
https://lore.kernel.org/linux-arm-msm/20200901164707.2645413-1-robdcl...@gmail.com/

Bjorn Andersson (8):
  iommu/arm-smmu: Refactor context bank allocation
  iommu/arm-smmu: Delay modifying domain during init
  iommu/arm-smmu: Consult context bank allocator for identify domains
  iommu/arm-smmu-qcom: Emulate bypass by using context banks
  iommu/arm-smmu-qcom: Consistently initialize stream mappings
  iommu/arm-smmu: Add impl hook for inherit boot mappings
  iommu/arm-smmu: Provide helper for allocating identity domain
  iommu/arm-smmu-qcom: Setup identity domain for boot mappings

 drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 111 ++-
 drivers/iommu/arm/arm-smmu/arm-smmu.c  | 122 ++---
 drivers/iommu/arm/arm-smmu/arm-smmu.h  |  14 ++-
 3 files changed, 205 insertions(+), 42 deletions(-)

-- 
2.28.0

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 1/3] iommu: amd: Fix kerneldoc

2020-09-04 Thread Bjorn Andersson
On Tue 28 Jul 12:08 CDT 2020, Krzysztof Kozlowski wrote:

> Fix W=1 compile warnings (invalid kerneldoc):
> 
> drivers/iommu/amd/init.c:1586: warning: Function parameter or member 
> 'ivrs' not described in 'get_highest_supported_ivhd_type'
> drivers/iommu/amd/init.c:1938: warning: Function parameter or member 
> 'iommu' not described in 'iommu_update_intcapxt'
> 

Reviewed-by: Bjorn Andersson 

> Signed-off-by: Krzysztof Kozlowski 
> ---
>  drivers/iommu/amd/init.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c
> index 958050c213f9..4a37169b1b1b 100644
> --- a/drivers/iommu/amd/init.c
> +++ b/drivers/iommu/amd/init.c
> @@ -1578,7 +1578,7 @@ static int __init init_iommu_one(struct amd_iommu 
> *iommu, struct ivhd_header *h)
>  
>  /**
>   * get_highest_supported_ivhd_type - Look up the appropriate IVHD type
> - * @ivrs  Pointer to the IVRS header
> + * @ivrs: Pointer to the IVRS header
>   *
>   * This function search through all IVDB of the maximum supported IVHD
>   */
> @@ -1929,7 +1929,7 @@ static int iommu_setup_msi(struct amd_iommu *iommu)
>  #define XT_INT_VEC(x)(((x) & 0xFFULL) << 32)
>  #define XT_INT_DEST_HI(x)x) >> 24) & 0xFFULL) << 56)
>  
> -/**
> +/*
>   * Setup the IntCapXT registers with interrupt routing information
>   * based on the PCI MSI capability block registers, accessed via
>   * MMIO MSI address low/hi and MSI data registers.
> -- 
> 2.17.1
> 
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 2/3] iommu: intel: Drop kerneldoc marker from regular comment

2020-09-04 Thread Bjorn Andersson
On Tue 28 Jul 12:08 CDT 2020, Krzysztof Kozlowski wrote:

> Fix W=1 compile warnings (invalid kerneldoc):
> 
> drivers/iommu/intel/dmar.c:389: warning: Function parameter or member 
> 'header' not described in 'dmar_parse_one_drhd'
> 

Reviewed-by: Bjorn Andersson 

> Signed-off-by: Krzysztof Kozlowski 
> ---
>  drivers/iommu/intel/dmar.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/iommu/intel/dmar.c b/drivers/iommu/intel/dmar.c
> index 93e6345f3414..ba47edf03941 100644
> --- a/drivers/iommu/intel/dmar.c
> +++ b/drivers/iommu/intel/dmar.c
> @@ -380,7 +380,7 @@ dmar_find_dmaru(struct acpi_dmar_hardware_unit *drhd)
>   return NULL;
>  }
>  
> -/**
> +/*
>   * dmar_parse_one_drhd - parses exactly one DMA remapping hardware definition
>   * structure which uniquely represent one DMA remapping hardware unit
>   * present in the platform
> -- 
> 2.17.1
> 
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 3/3] iommu: qcom: Drop of_match_ptr to fix -Wunused-const-variable

2020-09-04 Thread Bjorn Andersson
On Tue 28 Jul 12:08 CDT 2020, Krzysztof Kozlowski wrote:

> The of_device_id is included unconditionally by of.h header and used
> in the driver as well.  Remove of_match_ptr to fix W=1 compile test
> warning with !CONFIG_OF:
> 
> drivers/iommu/qcom_iommu.c:910:34: warning: 'qcom_iommu_of_match' defined 
> but not used [-Wunused-const-variable=]
>   910 | static const struct of_device_id qcom_iommu_of_match[] = {
> 

Reviewed-by: Bjorn Andersson 

> Signed-off-by: Krzysztof Kozlowski 
> ---
>  drivers/iommu/qcom_iommu.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/iommu/qcom_iommu.c b/drivers/iommu/qcom_iommu.c
> index af6bec3ace00..9535a6af7553 100644
> --- a/drivers/iommu/qcom_iommu.c
> +++ b/drivers/iommu/qcom_iommu.c
> @@ -752,7 +752,7 @@ static const struct of_device_id ctx_of_match[] = {
>  static struct platform_driver qcom_iommu_ctx_driver = {
>   .driver = {
>   .name   = "qcom-iommu-ctx",
> - .of_match_table = of_match_ptr(ctx_of_match),
> + .of_match_table = ctx_of_match,
>   },
>   .probe  = qcom_iommu_ctx_probe,
>   .remove = qcom_iommu_ctx_remove,
> @@ -915,7 +915,7 @@ static const struct of_device_id qcom_iommu_of_match[] = {
>  static struct platform_driver qcom_iommu_driver = {
>   .driver = {
>   .name   = "qcom-iommu",
> - .of_match_table = of_match_ptr(qcom_iommu_of_match),
> + .of_match_table = qcom_iommu_of_match,
>   .pm = _iommu_pm_ops,
>   },
>   .probe  = qcom_iommu_device_probe,
> -- 
> 2.17.1
> 
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 01/19] drm/msm: remove dangling submitqueue references

2020-08-31 Thread Bjorn Andersson
On Tue 01 Sep 03:42 UTC 2020, Rob Clark wrote:

> On Mon, Aug 31, 2020 at 7:35 PM Bjorn Andersson
>  wrote:
> >
> > On Fri 14 Aug 02:40 UTC 2020, Rob Clark wrote:
> >
> > > From: Rob Clark 
> > >
> > > Currently it doesn't matter, since we free the ctx immediately.  But
> > > when we start refcnt'ing the ctx, we don't want old dangling list
> > > entries to hang around.
> > >
> > > Signed-off-by: Rob Clark 
> > > ---
> > >  drivers/gpu/drm/msm/msm_submitqueue.c | 4 +++-
> > >  1 file changed, 3 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/drivers/gpu/drm/msm/msm_submitqueue.c 
> > > b/drivers/gpu/drm/msm/msm_submitqueue.c
> > > index a1d94be7883a..90c9d84e6155 100644
> > > --- a/drivers/gpu/drm/msm/msm_submitqueue.c
> > > +++ b/drivers/gpu/drm/msm/msm_submitqueue.c
> > > @@ -49,8 +49,10 @@ void msm_submitqueue_close(struct msm_file_private 
> > > *ctx)
> > >* No lock needed in close and there won't
> > >* be any more user ioctls coming our way
> > >*/
> > > - list_for_each_entry_safe(entry, tmp, >submitqueues, node)
> > > + list_for_each_entry_safe(entry, tmp, >submitqueues, node) {
> > > + list_del(>node);
> >
> > If you refcount ctx, what does that do for the entries in the submit
> > queue?
> >
> > "entry" here is kref'ed, but you're popping it off the list regardless
> > of the put ends up freeing the object or not - which afaict would mean
> > leaking the object.
> >
> 
> What ends up happening is the submit has reference to submit-queue,
> which has reference to the ctx.. the submitqueue could be alive still
> pending in-flight submits (in a later patch), but dead from the PoV of
> userspace interface.
> 
> We aren't relying (or at least aren't in the end, and I *think* I
> didn't miss anything in the middle) relying on ctx->submitqueues list
> to clean anything up in the end, just track what is still a valid
> submitqueue from userspace PoV
> 

Looks reasonable, thanks for the explanation.

> BR,
> -R
> 
> >
> > On the other hand, with the current implementation an object with higher
> > refcount with adjacent objects of single refcount would end up with
> > dangling pointers after the put. So in itself this change seems like a
> > net gain, but I'm wondering about the plan described in the commit
> > message.
> >
> > Regards,
> > Bjorn
> >
> > >   msm_submitqueue_put(entry);
> > > + }
> > >  }
> > >
> > >  int msm_submitqueue_create(struct drm_device *drm, struct 
> > > msm_file_private *ctx,
> > > --
> > > 2.26.2
> > >
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 01/19] drm/msm: remove dangling submitqueue references

2020-08-31 Thread Bjorn Andersson
On Fri 14 Aug 02:40 UTC 2020, Rob Clark wrote:

> From: Rob Clark 
> 
> Currently it doesn't matter, since we free the ctx immediately.  But
> when we start refcnt'ing the ctx, we don't want old dangling list
> entries to hang around.
> 
> Signed-off-by: Rob Clark 

Reviewed-by: Bjorn Andersson 

> ---
>  drivers/gpu/drm/msm/msm_submitqueue.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/msm/msm_submitqueue.c 
> b/drivers/gpu/drm/msm/msm_submitqueue.c
> index a1d94be7883a..90c9d84e6155 100644
> --- a/drivers/gpu/drm/msm/msm_submitqueue.c
> +++ b/drivers/gpu/drm/msm/msm_submitqueue.c
> @@ -49,8 +49,10 @@ void msm_submitqueue_close(struct msm_file_private *ctx)
>* No lock needed in close and there won't
>* be any more user ioctls coming our way
>*/
> - list_for_each_entry_safe(entry, tmp, >submitqueues, node)
> + list_for_each_entry_safe(entry, tmp, >submitqueues, node) {
> + list_del(>node);
>   msm_submitqueue_put(entry);
> + }
>  }
>  
>  int msm_submitqueue_create(struct drm_device *drm, struct msm_file_private 
> *ctx,
> -- 
> 2.26.2
> 
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 19/19] drm/msm: show process names in gem_describe

2020-08-31 Thread Bjorn Andersson
On Thu 13 Aug 21:41 CDT 2020, Rob Clark wrote:

> From: Rob Clark 
> 
> In $debugfs/gem we already show any vma(s) associated with an object.
> Also show process names if the vma's address space is a per-process
> address space.
> 

Reviewed-by: Bjorn Andersson 

> Signed-off-by: Rob Clark 
> ---
>  drivers/gpu/drm/msm/msm_drv.c |  2 +-
>  drivers/gpu/drm/msm/msm_gem.c | 25 +
>  drivers/gpu/drm/msm/msm_gem.h |  5 +
>  drivers/gpu/drm/msm/msm_gem_vma.c |  1 +
>  drivers/gpu/drm/msm/msm_gpu.c |  8 +---
>  drivers/gpu/drm/msm/msm_gpu.h |  2 +-
>  6 files changed, 34 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
> index 8e70d220bba8..8d5c4f98c332 100644
> --- a/drivers/gpu/drm/msm/msm_drv.c
> +++ b/drivers/gpu/drm/msm/msm_drv.c
> @@ -597,7 +597,7 @@ static int context_init(struct drm_device *dev, struct 
> drm_file *file)
>   kref_init(>ref);
>   msm_submitqueue_init(dev, ctx);
>  
> - ctx->aspace = msm_gpu_create_private_address_space(priv->gpu);
> + ctx->aspace = msm_gpu_create_private_address_space(priv->gpu, current);
>   file->driver_priv = ctx;
>  
>   return 0;
> diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c
> index 3cb7aeb93fd3..76a6c5271e57 100644
> --- a/drivers/gpu/drm/msm/msm_gem.c
> +++ b/drivers/gpu/drm/msm/msm_gem.c
> @@ -842,11 +842,28 @@ void msm_gem_describe(struct drm_gem_object *obj, 
> struct seq_file *m)
>  
>   seq_puts(m, "  vmas:");
>  
> - list_for_each_entry(vma, _obj->vmas, list)
> - seq_printf(m, " [%s: %08llx,%s,inuse=%d]",
> - vma->aspace != NULL ? vma->aspace->name : NULL,
> - vma->iova, vma->mapped ? "mapped" : "unmapped",
> + list_for_each_entry(vma, _obj->vmas, list) {
> + const char *name, *comm;
> + if (vma->aspace) {
> + struct msm_gem_address_space *aspace = 
> vma->aspace;
> + struct task_struct *task =
> + get_pid_task(aspace->pid, PIDTYPE_PID);
> + if (task) {
> + comm = kstrdup(task->comm, GFP_KERNEL);
> + } else {
> + comm = NULL;
> + }
> + name = aspace->name;
> + } else {
> + name = comm = NULL;
> + }
> + seq_printf(m, " [%s%s%s: aspace=%p, 
> %08llx,%s,inuse=%d]",
> + name, comm ? ":" : "", comm ? comm : "",
> + vma->aspace, vma->iova,
> + vma->mapped ? "mapped" : "unmapped",
>   vma->inuse);
> + kfree(comm);
> + }
>  
>   seq_puts(m, "\n");
>   }
> diff --git a/drivers/gpu/drm/msm/msm_gem.h b/drivers/gpu/drm/msm/msm_gem.h
> index 9c573c4269cb..7b1c7a5f8eef 100644
> --- a/drivers/gpu/drm/msm/msm_gem.h
> +++ b/drivers/gpu/drm/msm/msm_gem.h
> @@ -24,6 +24,11 @@ struct msm_gem_address_space {
>   spinlock_t lock; /* Protects drm_mm node allocation/removal */
>   struct msm_mmu *mmu;
>   struct kref kref;
> +
> + /* For address spaces associated with a specific process, this
> +  * will be non-NULL:
> +  */
> + struct pid *pid;
>  };
>  
>  struct msm_gem_vma {
> diff --git a/drivers/gpu/drm/msm/msm_gem_vma.c 
> b/drivers/gpu/drm/msm/msm_gem_vma.c
> index 29cc1305cf37..80a8a266d68f 100644
> --- a/drivers/gpu/drm/msm/msm_gem_vma.c
> +++ b/drivers/gpu/drm/msm/msm_gem_vma.c
> @@ -17,6 +17,7 @@ msm_gem_address_space_destroy(struct kref *kref)
>   drm_mm_takedown(>mm);
>   if (aspace->mmu)
>   aspace->mmu->funcs->destroy(aspace->mmu);
> + put_pid(aspace->pid);
>   kfree(aspace);
>  }
>  
> diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c
> index 951850804d77..ac8961187a73 100644
> --- a/drivers/gpu/drm/msm/msm_gpu.c
> +++ b/drivers/gpu/drm/msm/msm_gpu.c
> @@ -825,10 +825,9 @@ static int get_clocks(struct platform_device *pdev, 
> struct msm_gpu *gpu)
>  
>  /* Return a new address space for a msm_drm_private instance */
>  struct msm_gem_addres

Re: [PATCH 18/19] iommu/arm-smmu: add a way for implementations to influence SCTLR

2020-08-31 Thread Bjorn Andersson
On Thu 13 Aug 21:41 CDT 2020, Rob Clark wrote:

> From: Rob Clark 
> 
> For the Adreno GPU's SMMU, we want SCTLR.HUPCF set to ensure that
> pending translations are not terminated on iova fault.  Otherwise
> a terminated CP read could hang the GPU by returning invalid
> command-stream data.
> 

Reviewed-by: Bjorn Andersson 

> Signed-off-by: Rob Clark 
> ---
>  drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 6 ++
>  drivers/iommu/arm/arm-smmu/arm-smmu.c  | 3 +++
>  drivers/iommu/arm/arm-smmu/arm-smmu.h  | 3 +++
>  3 files changed, 12 insertions(+)
> 
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c 
> b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> index 5640d9960610..2aa6249050ff 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> @@ -127,6 +127,12 @@ static int qcom_adreno_smmu_init_context(struct 
> arm_smmu_domain *smmu_domain,
>   (smmu_domain->cfg.fmt == ARM_SMMU_CTX_FMT_AARCH64))
>   pgtbl_cfg->quirks |= IO_PGTABLE_QUIRK_ARM_TTBR1;
>  
> + /*
> +  * On the GPU device we want to process subsequent transactions after a
> +  * fault to keep the GPU from hanging
> +  */
> + smmu_domain->cfg.sctlr_set |= ARM_SMMU_SCTLR_HUPCF;
> +
>   /*
>* Initialize private interface with GPU:
>*/
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c 
> b/drivers/iommu/arm/arm-smmu/arm-smmu.c
> index e63a480d7f71..bbec5793faf8 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
> @@ -617,6 +617,9 @@ void arm_smmu_write_context_bank(struct arm_smmu_device 
> *smmu, int idx)
>   if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
>   reg |= ARM_SMMU_SCTLR_E;
>  
> + reg |= cfg->sctlr_set;
> + reg &= ~cfg->sctlr_clr;
> +
>   arm_smmu_cb_write(smmu, idx, ARM_SMMU_CB_SCTLR, reg);
>  }
>  
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.h 
> b/drivers/iommu/arm/arm-smmu/arm-smmu.h
> index cd75a33967bb..2df3a70a8a41 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu.h
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.h
> @@ -144,6 +144,7 @@ enum arm_smmu_cbar_type {
>  #define ARM_SMMU_CB_SCTLR0x0
>  #define ARM_SMMU_SCTLR_S1_ASIDPNEBIT(12)
>  #define ARM_SMMU_SCTLR_CFCFG BIT(7)
> +#define ARM_SMMU_SCTLR_HUPCF BIT(8)
>  #define ARM_SMMU_SCTLR_CFIE  BIT(6)
>  #define ARM_SMMU_SCTLR_CFRE  BIT(5)
>  #define ARM_SMMU_SCTLR_E BIT(4)
> @@ -341,6 +342,8 @@ struct arm_smmu_cfg {
>   u16 asid;
>   u16 vmid;
>   };
> + u32 sctlr_set;/* extra bits to set in 
> SCTLR */
> + u32 sctlr_clr;/* bits to mask in SCTLR 
> */
>   enum arm_smmu_cbar_type cbar;
>   enum arm_smmu_context_fmt   fmt;
>  };
> -- 
> 2.26.2
> 
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 15/19] drm/msm: Add support for private address space instances

2020-08-31 Thread Bjorn Andersson
On Thu 13 Aug 21:41 CDT 2020, Rob Clark wrote:

> From: Jordan Crouse 
> 
> Add support for allocating private address space instances. Targets that
> support per-context pagetables should implement their own function to
> allocate private address spaces.
> 
> The default will return a pointer to the global address space.
> 

Reviewed-by: Bjorn Andersson 

> Signed-off-by: Jordan Crouse 
> Signed-off-by: Rob Clark 
> ---
>  drivers/gpu/drm/msm/msm_drv.c | 13 +++--
>  drivers/gpu/drm/msm/msm_drv.h |  5 +
>  drivers/gpu/drm/msm/msm_gem_vma.c |  9 +
>  drivers/gpu/drm/msm/msm_gpu.c | 22 ++
>  drivers/gpu/drm/msm/msm_gpu.h |  5 +
>  5 files changed, 48 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
> index 01845a3b8d52..8e70d220bba8 100644
> --- a/drivers/gpu/drm/msm/msm_drv.c
> +++ b/drivers/gpu/drm/msm/msm_drv.c
> @@ -597,7 +597,7 @@ static int context_init(struct drm_device *dev, struct 
> drm_file *file)
>   kref_init(>ref);
>   msm_submitqueue_init(dev, ctx);
>  
> - ctx->aspace = priv->gpu ? priv->gpu->aspace : NULL;
> + ctx->aspace = msm_gpu_create_private_address_space(priv->gpu);
>   file->driver_priv = ctx;
>  
>   return 0;
> @@ -780,18 +780,19 @@ static int msm_ioctl_gem_cpu_fini(struct drm_device 
> *dev, void *data,
>  }
>  
>  static int msm_ioctl_gem_info_iova(struct drm_device *dev,
> - struct drm_gem_object *obj, uint64_t *iova)
> + struct drm_file *file, struct drm_gem_object *obj,
> + uint64_t *iova)
>  {
> - struct msm_drm_private *priv = dev->dev_private;
> + struct msm_file_private *ctx = file->driver_priv;
>  
> - if (!priv->gpu)
> + if (!ctx->aspace)
>   return -EINVAL;
>  
>   /*
>* Don't pin the memory here - just get an address so that userspace can
>* be productive
>*/
> - return msm_gem_get_iova(obj, priv->gpu->aspace, iova);
> + return msm_gem_get_iova(obj, ctx->aspace, iova);
>  }
>  
>  static int msm_ioctl_gem_info(struct drm_device *dev, void *data,
> @@ -830,7 +831,7 @@ static int msm_ioctl_gem_info(struct drm_device *dev, 
> void *data,
>   args->value = msm_gem_mmap_offset(obj);
>   break;
>   case MSM_INFO_GET_IOVA:
> - ret = msm_ioctl_gem_info_iova(dev, obj, >value);
> + ret = msm_ioctl_gem_info_iova(dev, file, obj, >value);
>   break;
>   case MSM_INFO_SET_NAME:
>   /* length check should leave room for terminating null: */
> diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
> index 4561bfb5e745..2ca9c3c03845 100644
> --- a/drivers/gpu/drm/msm/msm_drv.h
> +++ b/drivers/gpu/drm/msm/msm_drv.h
> @@ -249,6 +249,10 @@ int msm_gem_map_vma(struct msm_gem_address_space *aspace,
>  void msm_gem_close_vma(struct msm_gem_address_space *aspace,
>   struct msm_gem_vma *vma);
>  
> +
> +struct msm_gem_address_space *
> +msm_gem_address_space_get(struct msm_gem_address_space *aspace);
> +
>  void msm_gem_address_space_put(struct msm_gem_address_space *aspace);
>  
>  struct msm_gem_address_space *
> @@ -434,6 +438,7 @@ static inline void __msm_file_private_destroy(struct kref 
> *kref)
>   struct msm_file_private *ctx = container_of(kref,
>   struct msm_file_private, ref);
>  
> + msm_gem_address_space_put(ctx->aspace);
>   kfree(ctx);
>  }
>  
> diff --git a/drivers/gpu/drm/msm/msm_gem_vma.c 
> b/drivers/gpu/drm/msm/msm_gem_vma.c
> index 5f6a11211b64..29cc1305cf37 100644
> --- a/drivers/gpu/drm/msm/msm_gem_vma.c
> +++ b/drivers/gpu/drm/msm/msm_gem_vma.c
> @@ -27,6 +27,15 @@ void msm_gem_address_space_put(struct 
> msm_gem_address_space *aspace)
>   kref_put(>kref, msm_gem_address_space_destroy);
>  }
>  
> +struct msm_gem_address_space *
> +msm_gem_address_space_get(struct msm_gem_address_space *aspace)
> +{
> + if (!IS_ERR_OR_NULL(aspace))
> + kref_get(>kref);
> +
> + return aspace;
> +}
> +
>  /* Actually unmap memory for the vma */
>  void msm_gem_purge_vma(struct msm_gem_address_space *aspace,
>   struct msm_gem_vma *vma)
> diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c
> index e1a3cbe25a0c..951850804d77 100644
> --- a/drivers/gpu/drm/msm/msm_gpu.c
> +++ b/drivers/gpu/drm/msm/msm_gpu.c
> @@ -823,6 +823,28 @@ static int get_clocks(struct platform_device *pdev, 
> struct msm_gpu *gpu)
>   return 0;
>  }

Re: [PATCH 14/19] drm/msm: Add support to create a local pagetable

2020-08-31 Thread Bjorn Andersson
On Thu 13 Aug 21:41 CDT 2020, Rob Clark wrote:

> From: Jordan Crouse 
> 
> Add support to create a io-pgtable for use by targets that support
> per-instance pagetables. In order to support per-instance pagetables the
> GPU SMMU device needs to have the qcom,adreno-smmu compatible string and
> split pagetables enabled.
> 

Reviewed-by: Bjorn Andersson 

> Signed-off-by: Jordan Crouse 
> Signed-off-by: Rob Clark 
> ---
>  drivers/gpu/drm/msm/msm_gpummu.c |   2 +-
>  drivers/gpu/drm/msm/msm_iommu.c  | 199 ++-
>  drivers/gpu/drm/msm/msm_mmu.h|  16 ++-
>  3 files changed, 214 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/msm_gpummu.c 
> b/drivers/gpu/drm/msm/msm_gpummu.c
> index 310a31b05faa..aab121f4beb7 100644
> --- a/drivers/gpu/drm/msm/msm_gpummu.c
> +++ b/drivers/gpu/drm/msm/msm_gpummu.c
> @@ -102,7 +102,7 @@ struct msm_mmu *msm_gpummu_new(struct device *dev, struct 
> msm_gpu *gpu)
>   }
>  
>   gpummu->gpu = gpu;
> - msm_mmu_init(>base, dev, );
> + msm_mmu_init(>base, dev, , MSM_MMU_GPUMMU);
>  
>   return >base;
>  }
> diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c
> index 1b6635504069..697cc0a059d6 100644
> --- a/drivers/gpu/drm/msm/msm_iommu.c
> +++ b/drivers/gpu/drm/msm/msm_iommu.c
> @@ -4,15 +4,210 @@
>   * Author: Rob Clark 
>   */
>  
> +#include 
> +#include 
>  #include "msm_drv.h"
>  #include "msm_mmu.h"
>  
>  struct msm_iommu {
>   struct msm_mmu base;
>   struct iommu_domain *domain;
> + atomic_t pagetables;
>  };
> +
>  #define to_msm_iommu(x) container_of(x, struct msm_iommu, base)
>  
> +struct msm_iommu_pagetable {
> + struct msm_mmu base;
> + struct msm_mmu *parent;
> + struct io_pgtable_ops *pgtbl_ops;
> + phys_addr_t ttbr;
> + u32 asid;
> +};
> +static struct msm_iommu_pagetable *to_pagetable(struct msm_mmu *mmu)
> +{
> + return container_of(mmu, struct msm_iommu_pagetable, base);
> +}
> +
> +static int msm_iommu_pagetable_unmap(struct msm_mmu *mmu, u64 iova,
> + size_t size)
> +{
> + struct msm_iommu_pagetable *pagetable = to_pagetable(mmu);
> + struct io_pgtable_ops *ops = pagetable->pgtbl_ops;
> + size_t unmapped = 0;
> +
> + /* Unmap the block one page at a time */
> + while (size) {
> + unmapped += ops->unmap(ops, iova, 4096, NULL);
> + iova += 4096;
> + size -= 4096;
> + }
> +
> + iommu_flush_tlb_all(to_msm_iommu(pagetable->parent)->domain);
> +
> + return (unmapped == size) ? 0 : -EINVAL;
> +}
> +
> +static int msm_iommu_pagetable_map(struct msm_mmu *mmu, u64 iova,
> + struct sg_table *sgt, size_t len, int prot)
> +{
> + struct msm_iommu_pagetable *pagetable = to_pagetable(mmu);
> + struct io_pgtable_ops *ops = pagetable->pgtbl_ops;
> + struct scatterlist *sg;
> + size_t mapped = 0;
> + u64 addr = iova;
> + unsigned int i;
> +
> + for_each_sg(sgt->sgl, sg, sgt->nents, i) {
> + size_t size = sg->length;
> + phys_addr_t phys = sg_phys(sg);
> +
> + /* Map the block one page at a time */
> + while (size) {
> + if (ops->map(ops, addr, phys, 4096, prot, GFP_KERNEL)) {
> + msm_iommu_pagetable_unmap(mmu, iova, mapped);
> + return -EINVAL;
> + }
> +
> + phys += 4096;
> + addr += 4096;
> + size -= 4096;
> + mapped += 4096;
> + }
> + }
> +
> + return 0;
> +}
> +
> +static void msm_iommu_pagetable_destroy(struct msm_mmu *mmu)
> +{
> + struct msm_iommu_pagetable *pagetable = to_pagetable(mmu);
> + struct msm_iommu *iommu = to_msm_iommu(pagetable->parent);
> + struct adreno_smmu_priv *adreno_smmu =
> + dev_get_drvdata(pagetable->parent->dev);
> +
> + /*
> +  * If this is the last attached pagetable for the parent,
> +  * disable TTBR0 in the arm-smmu driver
> +  */
> + if (atomic_dec_return(>pagetables) == 0)
> + adreno_smmu->set_ttbr0_cfg(adreno_smmu->cookie, NULL);
> +
> + free_io_pgtable_ops(pagetable->pgtbl_ops);
> + kfree(pagetable);
> +}
> +
> +int msm_iommu_pagetable_params(struct msm_mmu *mmu,
> + phys_addr_t *ttbr, int *asid)
> +{
> + struct msm_iommu_pagetable *pagetable;
> +
> + if (mmu->type != 

Re: [PATCH 12/19] drm/msm: Drop context arg to gpu->submit()

2020-08-31 Thread Bjorn Andersson
On Thu 13 Aug 21:41 CDT 2020, Rob Clark wrote:

> From: Jordan Crouse 
> 
> Now that we can get the ctx from the submitqueue, the extra arg is
> redundant.
> 

Reviewed-by: Bjorn Andersson 

> Signed-off-by: Jordan Crouse 
> [split out of previous patch to reduce churny noise]
> Signed-off-by: Rob Clark 
> ---
>  drivers/gpu/drm/msm/adreno/a5xx_gpu.c   | 12 +---
>  drivers/gpu/drm/msm/adreno/a6xx_gpu.c   |  5 ++---
>  drivers/gpu/drm/msm/adreno/adreno_gpu.c |  5 ++---
>  drivers/gpu/drm/msm/adreno/adreno_gpu.h |  3 +--
>  drivers/gpu/drm/msm/msm_gem_submit.c|  2 +-
>  drivers/gpu/drm/msm/msm_gpu.c   |  9 -
>  drivers/gpu/drm/msm/msm_gpu.h   |  6 ++
>  7 files changed, 17 insertions(+), 25 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c 
> b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
> index 9e63a190642c..eff2439ea57b 100644
> --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
> +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
> @@ -43,8 +43,7 @@ static void a5xx_flush(struct msm_gpu *gpu, struct 
> msm_ringbuffer *ring)
>   gpu_write(gpu, REG_A5XX_CP_RB_WPTR, wptr);
>  }
>  
> -static void a5xx_submit_in_rb(struct msm_gpu *gpu, struct msm_gem_submit 
> *submit,
> - struct msm_file_private *ctx)
> +static void a5xx_submit_in_rb(struct msm_gpu *gpu, struct msm_gem_submit 
> *submit)
>  {
>   struct msm_drm_private *priv = gpu->dev->dev_private;
>   struct msm_ringbuffer *ring = submit->ring;
> @@ -57,7 +56,7 @@ static void a5xx_submit_in_rb(struct msm_gpu *gpu, struct 
> msm_gem_submit *submit
>   case MSM_SUBMIT_CMD_IB_TARGET_BUF:
>   break;
>   case MSM_SUBMIT_CMD_CTX_RESTORE_BUF:
> - if (priv->lastctx == ctx)
> + if (priv->lastctx == submit->queue->ctx)
>   break;
>   /* fall-thru */
>   case MSM_SUBMIT_CMD_BUF:
> @@ -103,8 +102,7 @@ static void a5xx_submit_in_rb(struct msm_gpu *gpu, struct 
> msm_gem_submit *submit
>   msm_gpu_retire(gpu);
>  }
>  
> -static void a5xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit,
> - struct msm_file_private *ctx)
> +static void a5xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
>  {
>   struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
>   struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);
> @@ -114,7 +112,7 @@ static void a5xx_submit(struct msm_gpu *gpu, struct 
> msm_gem_submit *submit,
>  
>   if (IS_ENABLED(CONFIG_DRM_MSM_GPU_SUDO) && submit->in_rb) {
>   priv->lastctx = NULL;
> - a5xx_submit_in_rb(gpu, submit, ctx);
> + a5xx_submit_in_rb(gpu, submit);
>   return;
>   }
>  
> @@ -148,7 +146,7 @@ static void a5xx_submit(struct msm_gpu *gpu, struct 
> msm_gem_submit *submit,
>   case MSM_SUBMIT_CMD_IB_TARGET_BUF:
>   break;
>   case MSM_SUBMIT_CMD_CTX_RESTORE_BUF:
> - if (priv->lastctx == ctx)
> + if (priv->lastctx == submit->queue->ctx)
>   break;
>   /* fall-thru */
>   case MSM_SUBMIT_CMD_BUF:
> diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c 
> b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> index c5a3e4d4c007..5eabb0109577 100644
> --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> @@ -81,8 +81,7 @@ static void get_stats_counter(struct msm_ringbuffer *ring, 
> u32 counter,
>   OUT_RING(ring, upper_32_bits(iova));
>  }
>  
> -static void a6xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit,
> - struct msm_file_private *ctx)
> +static void a6xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
>  {
>   unsigned int index = submit->seqno % MSM_GPU_SUBMIT_STATS_COUNT;
>   struct msm_drm_private *priv = gpu->dev->dev_private;
> @@ -115,7 +114,7 @@ static void a6xx_submit(struct msm_gpu *gpu, struct 
> msm_gem_submit *submit,
>   case MSM_SUBMIT_CMD_IB_TARGET_BUF:
>   break;
>   case MSM_SUBMIT_CMD_CTX_RESTORE_BUF:
> - if (priv->lastctx == ctx)
> + if (priv->lastctx == submit->queue->ctx)
>   break;
>   /* fall-thru */
>   case MSM_SUBMIT_CMD_BUF:
> diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c 
> b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
> index d2dbb6968cba..533a34b4cce2 100644
> --- a/drivers/gpu/drm/m

Re: [PATCH 13/19] drm/msm: Set the global virtual address range from the IOMMU domain

2020-08-31 Thread Bjorn Andersson
On Thu 13 Aug 21:41 CDT 2020, Rob Clark wrote:

> From: Jordan Crouse 
> 
> Use the aperture settings from the IOMMU domain to set up the virtual
> address range for the GPU. This allows us to transparently deal with
> IOMMU side features (like split pagetables).
> 

Reviewed-by: Bjorn Andersson 

> Signed-off-by: Jordan Crouse 
> Signed-off-by: Rob Clark 
> ---
>  drivers/gpu/drm/msm/adreno/adreno_gpu.c | 13 +++--
>  drivers/gpu/drm/msm/msm_iommu.c |  7 +++
>  2 files changed, 18 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c 
> b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
> index 533a34b4cce2..34e6242c1767 100644
> --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
> +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
> @@ -192,9 +192,18 @@ adreno_iommu_create_address_space(struct msm_gpu *gpu,
>   struct iommu_domain *iommu = iommu_domain_alloc(_bus_type);
>   struct msm_mmu *mmu = msm_iommu_new(>dev, iommu);
>   struct msm_gem_address_space *aspace;
> + u64 start, size;
>  
> - aspace = msm_gem_address_space_create(mmu, "gpu", SZ_16M,
> - 0x - SZ_16M);
> + /*
> +  * Use the aperture start or SZ_16M, whichever is greater. This will
> +  * ensure that we align with the allocated pagetable range while still
> +  * allowing room in the lower 32 bits for GMEM and whatnot
> +  */
> + start = max_t(u64, SZ_16M, iommu->geometry.aperture_start);
> + size = iommu->geometry.aperture_end - start + 1;
> +
> + aspace = msm_gem_address_space_create(mmu, "gpu",
> + start & GENMASK(48, 0), size);
>  
>   if (IS_ERR(aspace) && !IS_ERR(mmu))
>   mmu->funcs->destroy(mmu);
> diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c
> index 3a381a9674c9..1b6635504069 100644
> --- a/drivers/gpu/drm/msm/msm_iommu.c
> +++ b/drivers/gpu/drm/msm/msm_iommu.c
> @@ -36,6 +36,10 @@ static int msm_iommu_map(struct msm_mmu *mmu, uint64_t 
> iova,
>   struct msm_iommu *iommu = to_msm_iommu(mmu);
>   size_t ret;
>  
> + /* The arm-smmu driver expects the addresses to be sign extended */
> + if (iova & BIT_ULL(48))
> + iova |= GENMASK_ULL(63, 49);
> +
>   ret = iommu_map_sg(iommu->domain, iova, sgt->sgl, sgt->nents, prot);
>   WARN_ON(!ret);
>  
> @@ -46,6 +50,9 @@ static int msm_iommu_unmap(struct msm_mmu *mmu, uint64_t 
> iova, size_t len)
>  {
>   struct msm_iommu *iommu = to_msm_iommu(mmu);
>  
> + if (iova & BIT_ULL(48))
> + iova |= GENMASK_ULL(63, 49);
> +
>   iommu_unmap(iommu->domain, iova, len);
>  
>   return 0;
> -- 
> 2.26.2
> 
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 11/19] drm/msm: Add a context pointer to the submitqueue

2020-08-31 Thread Bjorn Andersson
On Thu 13 Aug 21:41 CDT 2020, Rob Clark wrote:

> From: Jordan Crouse 
> 
> Each submitqueue is attached to a context. Add a pointer to the
> context to the submitqueue at create time and refcount it so
> that it stays around through the life of the queue.
> 

Reviewed-by: Bjorn Andersson 


> Co-developed-by: Rob Clark 
> Signed-off-by: Jordan Crouse 
> Signed-off-by: Rob Clark 
> ---
>  drivers/gpu/drm/msm/msm_drv.c |  3 ++-
>  drivers/gpu/drm/msm/msm_drv.h | 20 
>  drivers/gpu/drm/msm/msm_gem.h |  1 +
>  drivers/gpu/drm/msm/msm_gem_submit.c  |  6 +++---
>  drivers/gpu/drm/msm/msm_gpu.h |  1 +
>  drivers/gpu/drm/msm/msm_submitqueue.c |  3 +++
>  6 files changed, 30 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
> index 7d641c7e3514..01845a3b8d52 100644
> --- a/drivers/gpu/drm/msm/msm_drv.c
> +++ b/drivers/gpu/drm/msm/msm_drv.c
> @@ -594,6 +594,7 @@ static int context_init(struct drm_device *dev, struct 
> drm_file *file)
>   if (!ctx)
>   return -ENOMEM;
>  
> + kref_init(>ref);
>   msm_submitqueue_init(dev, ctx);
>  
>   ctx->aspace = priv->gpu ? priv->gpu->aspace : NULL;
> @@ -615,7 +616,7 @@ static int msm_open(struct drm_device *dev, struct 
> drm_file *file)
>  static void context_close(struct msm_file_private *ctx)
>  {
>   msm_submitqueue_close(ctx);
> - kfree(ctx);
> + msm_file_private_put(ctx);
>  }
>  
>  static void msm_postclose(struct drm_device *dev, struct drm_file *file)
> diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
> index af259b0573ea..4561bfb5e745 100644
> --- a/drivers/gpu/drm/msm/msm_drv.h
> +++ b/drivers/gpu/drm/msm/msm_drv.h
> @@ -57,6 +57,7 @@ struct msm_file_private {
>   struct list_head submitqueues;
>   int queueid;
>   struct msm_gem_address_space *aspace;
> + struct kref ref;
>  };
>  
>  enum msm_mdp_plane_property {
> @@ -428,6 +429,25 @@ void msm_submitqueue_close(struct msm_file_private *ctx);
>  
>  void msm_submitqueue_destroy(struct kref *kref);
>  
> +static inline void __msm_file_private_destroy(struct kref *kref)
> +{
> + struct msm_file_private *ctx = container_of(kref,
> + struct msm_file_private, ref);
> +
> + kfree(ctx);
> +}
> +
> +static inline void msm_file_private_put(struct msm_file_private *ctx)
> +{
> + kref_put(>ref, __msm_file_private_destroy);
> +}
> +
> +static inline struct msm_file_private *msm_file_private_get(
> + struct msm_file_private *ctx)
> +{
> + kref_get(>ref);
> + return ctx;
> +}
>  
>  #define DBG(fmt, ...) DRM_DEBUG_DRIVER(fmt"\n", ##__VA_ARGS__)
>  #define VERB(fmt, ...) if (0) DRM_DEBUG_DRIVER(fmt"\n", ##__VA_ARGS__)
> diff --git a/drivers/gpu/drm/msm/msm_gem.h b/drivers/gpu/drm/msm/msm_gem.h
> index 972490b14ba5..9c573c4269cb 100644
> --- a/drivers/gpu/drm/msm/msm_gem.h
> +++ b/drivers/gpu/drm/msm/msm_gem.h
> @@ -142,6 +142,7 @@ struct msm_gem_submit {
>   bool valid; /* true if no cmdstream patching needed */
>   bool in_rb; /* "sudo" mode, copy cmds into RB */
>   struct msm_ringbuffer *ring;
> + struct msm_file_private *ctx;
>   unsigned int nr_cmds;
>   unsigned int nr_bos;
>   u32 ident; /* A "identifier" for the submit for logging */
> diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c 
> b/drivers/gpu/drm/msm/msm_gem_submit.c
> index 8cb9aa15ff90..1464b04d25d3 100644
> --- a/drivers/gpu/drm/msm/msm_gem_submit.c
> +++ b/drivers/gpu/drm/msm/msm_gem_submit.c
> @@ -27,7 +27,7 @@
>  #define BO_PINNED   0x2000
>  
>  static struct msm_gem_submit *submit_create(struct drm_device *dev,
> - struct msm_gpu *gpu, struct msm_gem_address_space *aspace,
> + struct msm_gpu *gpu,
>   struct msm_gpu_submitqueue *queue, uint32_t nr_bos,
>   uint32_t nr_cmds)
>  {
> @@ -43,7 +43,7 @@ static struct msm_gem_submit *submit_create(struct 
> drm_device *dev,
>   return NULL;
>  
>   submit->dev = dev;
> - submit->aspace = aspace;
> + submit->aspace = queue->ctx->aspace;
>   submit->gpu = gpu;
>   submit->fence = NULL;
>   submit->cmd = (void *)>bos[nr_bos];
> @@ -677,7 +677,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void 
> *data,
>   }
>   }
>  
> - submit = submit_create(dev, gpu, ctx->aspace, queue, args->nr_bos,
> + submit = submit_create(dev, gpu, queue, args->nr_bos,
>  

Re: [PATCH 09/19] iommu/arm-smmu-qcom: Add implementation for the adreno GPU SMMU

2020-08-31 Thread Bjorn Andersson
On Thu 13 Aug 21:41 CDT 2020, Rob Clark wrote:

> From: Jordan Crouse 
> 
> Add a special implementation for the SMMU attached to most Adreno GPU
> target triggered from the qcom,adreno-smmu compatible string.
> 
> The new Adreno SMMU implementation will enable split pagetables
> (TTBR1) for the domain attached to the GPU device (SID 0) and
> hard code it context bank 0 so the GPU hardware can implement
> per-instance pagetables.
> 

Reviewed-by: Bjorn Andersson 

> Co-developed-by: Rob Clark 
> Signed-off-by: Jordan Crouse 
> Signed-off-by: Rob Clark 
> ---
>  drivers/iommu/arm/arm-smmu/arm-smmu-impl.c |   3 +
>  drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 149 -
>  drivers/iommu/arm/arm-smmu/arm-smmu.h  |   1 +
>  3 files changed, 151 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c 
> b/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c
> index 88f17cc33023..d199b4bff15d 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c
> @@ -223,6 +223,9 @@ struct arm_smmu_device *arm_smmu_impl_init(struct 
> arm_smmu_device *smmu)
>   of_device_is_compatible(np, "qcom,sm8250-smmu-500"))
>   return qcom_smmu_impl_init(smmu);
>  
> + if (of_device_is_compatible(smmu->dev->of_node, "qcom,adreno-smmu"))
> + return qcom_adreno_smmu_impl_init(smmu);
> +
>   if (of_device_is_compatible(np, "marvell,ap806-smmu-500"))
>   smmu->impl = _mmu500_impl;
>  
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c 
> b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> index be4318044f96..5640d9960610 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> @@ -3,6 +3,7 @@
>   * Copyright (c) 2019, The Linux Foundation. All rights reserved.
>   */
>  
> +#include 
>  #include 
>  #include 
>  
> @@ -12,6 +13,132 @@ struct qcom_smmu {
>   struct arm_smmu_device smmu;
>  };
>  
> +#define QCOM_ADRENO_SMMU_GPU_SID 0
> +
> +static bool qcom_adreno_smmu_is_gpu_device(struct device *dev)
> +{
> + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
> + int i;
> +
> + /*
> +  * The GPU will always use SID 0 so that is a handy way to uniquely
> +  * identify it and configure it for per-instance pagetables
> +  */
> + for (i = 0; i < fwspec->num_ids; i++) {
> + u16 sid = FIELD_GET(ARM_SMMU_SMR_ID, fwspec->ids[i]);
> +
> + if (sid == QCOM_ADRENO_SMMU_GPU_SID)
> + return true;
> + }
> +
> + return false;
> +}
> +
> +static const struct io_pgtable_cfg *qcom_adreno_smmu_get_ttbr1_cfg(
> + const void *cookie)
> +{
> + struct arm_smmu_domain *smmu_domain = (void *)cookie;
> + struct io_pgtable *pgtable =
> + io_pgtable_ops_to_pgtable(smmu_domain->pgtbl_ops);
> + return >cfg;
> +}
> +
> +/*
> + * Local implementation to configure TTBR0 with the specified pagetable 
> config.
> + * The GPU driver will call this to enable TTBR0 when per-instance pagetables
> + * are active
> + */
> +
> +static int qcom_adreno_smmu_set_ttbr0_cfg(const void *cookie,
> + const struct io_pgtable_cfg *pgtbl_cfg)
> +{
> + struct arm_smmu_domain *smmu_domain = (void *)cookie;
> + struct io_pgtable *pgtable = 
> io_pgtable_ops_to_pgtable(smmu_domain->pgtbl_ops);
> + struct arm_smmu_cfg *cfg = _domain->cfg;
> + struct arm_smmu_cb *cb = _domain->smmu->cbs[cfg->cbndx];
> +
> + /* The domain must have split pagetables already enabled */
> + if (cb->tcr[0] & ARM_SMMU_TCR_EPD1)
> + return -EINVAL;
> +
> + /* If the pagetable config is NULL, disable TTBR0 */
> + if (!pgtbl_cfg) {
> + /* Do nothing if it is already disabled */
> + if ((cb->tcr[0] & ARM_SMMU_TCR_EPD0))
> + return -EINVAL;
> +
> + /* Set TCR to the original configuration */
> + cb->tcr[0] = arm_smmu_lpae_tcr(>cfg);
> + cb->ttbr[0] = FIELD_PREP(ARM_SMMU_TTBRn_ASID, cb->cfg->asid);
> + } else {
> + u32 tcr = cb->tcr[0];
> +
> + /* Don't call this again if TTBR0 is already enabled */
> + if (!(cb->tcr[0] & ARM_SMMU_TCR_EPD0))
> + return -EINVAL;
> +
> + tcr |= arm_smmu_lpae_tcr(pgtbl_cfg);
> + tcr &= ~(ARM_SMMU_TCR_EPD0 | ARM_SMMU_TCR_EPD1);
> +
> + cb->t

Re: [PATCH 10/19] dt-bindings: arm-smmu: Add compatible string for Adreno GPU SMMU

2020-08-31 Thread Bjorn Andersson
On Thu 13 Aug 21:41 CDT 2020, Rob Clark wrote:

> From: Jordan Crouse 
> 
> Every Qcom Adreno GPU has an embedded SMMU for its own use. These
> devices depend on unique features such as split pagetables,
> different stall/halt requirements and other settings. Identify them
> with a compatible string so that they can be identified in the
> arm-smmu implementation specific code.
> 

Reviewed-by: Bjorn Andersson 

> Signed-off-by: Jordan Crouse 
> Reviewed-by: Rob Herring 
> Signed-off-by: Rob Clark 
> ---
>  Documentation/devicetree/bindings/iommu/arm,smmu.yaml | 4 
>  1 file changed, 4 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml 
> b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
> index 503160a7b9a0..5ec5d0d691f6 100644
> --- a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
> +++ b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
> @@ -40,6 +40,10 @@ properties:
>- qcom,sm8150-smmu-500
>- qcom,sm8250-smmu-500
>- const: arm,mmu-500
> +  - description: Qcom Adreno GPUs implementing "arm,smmu-v2"
> +items:
> +  - const: qcom,adreno-smmu
> +  - const: qcom,smmu-v2
>- description: Marvell SoCs implementing "arm,mmu-500"
>  items:
>- const: marvell,ap806-smmu-500
> -- 
> 2.26.2
> 
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 07/19] drm/msm: set adreno_smmu as gpu's drvdata

2020-08-31 Thread Bjorn Andersson
On Thu 13 Aug 21:41 CDT 2020, Rob Clark wrote:

> From: Rob Clark 
> 
> This will be populated by adreno-smmu, to provide a way for coordinating
> enabling/disabling TTBR0 translation.
> 

Reviewed-by: Bjorn Andersson 

> Signed-off-by: Rob Clark 
> ---
>  drivers/gpu/drm/msm/adreno/adreno_device.c | 2 --
>  drivers/gpu/drm/msm/msm_gpu.c  | 2 +-
>  drivers/gpu/drm/msm/msm_gpu.h  | 6 +-
>  3 files changed, 6 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c 
> b/drivers/gpu/drm/msm/adreno/adreno_device.c
> index 26664e1b30c0..58e03b20e1c7 100644
> --- a/drivers/gpu/drm/msm/adreno/adreno_device.c
> +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c
> @@ -417,8 +417,6 @@ static int adreno_bind(struct device *dev, struct device 
> *master, void *data)
>   return PTR_ERR(gpu);
>   }
>  
> - dev_set_drvdata(dev, gpu);
> -
>   return 0;
>  }
>  
> diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c
> index 6aa9e04e52e7..806eb0957280 100644
> --- a/drivers/gpu/drm/msm/msm_gpu.c
> +++ b/drivers/gpu/drm/msm/msm_gpu.c
> @@ -892,7 +892,7 @@ int msm_gpu_init(struct drm_device *drm, struct 
> platform_device *pdev,
>   gpu->gpu_cx = NULL;
>  
>   gpu->pdev = pdev;
> - platform_set_drvdata(pdev, gpu);
> + platform_set_drvdata(pdev, >adreno_smmu);
>  
>   msm_devfreq_init(gpu);
>  
> diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h
> index 8bda7beaed4b..f91b141add75 100644
> --- a/drivers/gpu/drm/msm/msm_gpu.h
> +++ b/drivers/gpu/drm/msm/msm_gpu.h
> @@ -7,6 +7,7 @@
>  #ifndef __MSM_GPU_H__
>  #define __MSM_GPU_H__
>  
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -73,6 +74,8 @@ struct msm_gpu {
>   struct platform_device *pdev;
>   const struct msm_gpu_funcs *funcs;
>  
> + struct adreno_smmu_priv adreno_smmu;
> +
>   /* performance counters (hw & sw): */
>   spinlock_t perf_lock;
>   bool perfcntr_active;
> @@ -143,7 +146,8 @@ struct msm_gpu {
>  
>  static inline struct msm_gpu *dev_to_gpu(struct device *dev)
>  {
> - return dev_get_drvdata(dev);
> + struct adreno_smmu_priv *adreno_smmu = dev_get_drvdata(dev);
> + return container_of(adreno_smmu, struct msm_gpu, adreno_smmu);
>  }
>  
>  /* It turns out that all targets use the same ringbuffer size */
> -- 
> 2.26.2
> 
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 08/19] iommu/arm-smmu: constify some helpers

2020-08-31 Thread Bjorn Andersson
On Thu 13 Aug 21:41 CDT 2020, Rob Clark wrote:

> From: Rob Clark 
> 
> Sprinkle a few `const`s where helpers don't need write access.
> 

Reviewed-by: Bjorn Andersson 

> Signed-off-by: Rob Clark 
> ---
>  drivers/iommu/arm/arm-smmu/arm-smmu.h | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.h 
> b/drivers/iommu/arm/arm-smmu/arm-smmu.h
> index 59ff3fc5c6c8..27c8fc50 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu.h
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.h
> @@ -377,7 +377,7 @@ struct arm_smmu_master_cfg {
>   s16 smendx[];
>  };
>  
> -static inline u32 arm_smmu_lpae_tcr(struct io_pgtable_cfg *cfg)
> +static inline u32 arm_smmu_lpae_tcr(const struct io_pgtable_cfg *cfg)
>  {
>   u32 tcr = FIELD_PREP(ARM_SMMU_TCR_TG0, cfg->arm_lpae_s1_cfg.tcr.tg) |
>   FIELD_PREP(ARM_SMMU_TCR_SH0, cfg->arm_lpae_s1_cfg.tcr.sh) |
> @@ -398,13 +398,13 @@ static inline u32 arm_smmu_lpae_tcr(struct 
> io_pgtable_cfg *cfg)
>   return tcr;
>  }
>  
> -static inline u32 arm_smmu_lpae_tcr2(struct io_pgtable_cfg *cfg)
> +static inline u32 arm_smmu_lpae_tcr2(const struct io_pgtable_cfg *cfg)
>  {
>   return FIELD_PREP(ARM_SMMU_TCR2_PASIZE, cfg->arm_lpae_s1_cfg.tcr.ips) |
>  FIELD_PREP(ARM_SMMU_TCR2_SEP, ARM_SMMU_TCR2_SEP_UPSTREAM);
>  }
>  
> -static inline u32 arm_smmu_lpae_vtcr(struct io_pgtable_cfg *cfg)
> +static inline u32 arm_smmu_lpae_vtcr(const struct io_pgtable_cfg *cfg)
>  {
>   return ARM_SMMU_VTCR_RES1 |
>  FIELD_PREP(ARM_SMMU_VTCR_PS, cfg->arm_lpae_s2_cfg.vtcr.ps) |
> -- 
> 2.26.2
> 
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 06/19] drm/msm/gpu: add dev_to_gpu() helper

2020-08-31 Thread Bjorn Andersson
On Thu 13 Aug 21:41 CDT 2020, Rob Clark wrote:

> From: Rob Clark 
> 
> In a later patch, the drvdata will not directly be 'struct msm_gpu *',
> so add a helper to reduce the churn.
> 
> Signed-off-by: Rob Clark 
> ---
>  drivers/gpu/drm/msm/adreno/adreno_device.c | 10 --
>  drivers/gpu/drm/msm/msm_gpu.c  |  6 +++---
>  drivers/gpu/drm/msm/msm_gpu.h  |  5 +
>  3 files changed, 12 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c 
> b/drivers/gpu/drm/msm/adreno/adreno_device.c
> index 9eeb46bf2a5d..26664e1b30c0 100644
> --- a/drivers/gpu/drm/msm/adreno/adreno_device.c
> +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c
> @@ -282,7 +282,7 @@ struct msm_gpu *adreno_load_gpu(struct drm_device *dev)
>   int ret;
>  
>   if (pdev)
> - gpu = platform_get_drvdata(pdev);
> + gpu = dev_to_gpu(>dev);
>  
>   if (!gpu) {
>   dev_err_once(dev->dev, "no GPU device was found\n");
> @@ -425,7 +425,7 @@ static int adreno_bind(struct device *dev, struct device 
> *master, void *data)
>  static void adreno_unbind(struct device *dev, struct device *master,
>   void *data)
>  {
> - struct msm_gpu *gpu = dev_get_drvdata(dev);
> + struct msm_gpu *gpu = dev_to_gpu(dev);
>  
>   pm_runtime_force_suspend(dev);
>   gpu->funcs->destroy(gpu);
> @@ -490,16 +490,14 @@ static const struct of_device_id dt_match[] = {
>  #ifdef CONFIG_PM
>  static int adreno_resume(struct device *dev)
>  {
> - struct platform_device *pdev = to_platform_device(dev);
> - struct msm_gpu *gpu = platform_get_drvdata(pdev);
> + struct msm_gpu *gpu = dev_to_gpu(dev);
>  
>   return gpu->funcs->pm_resume(gpu);
>  }
>  
>  static int adreno_suspend(struct device *dev)
>  {
> - struct platform_device *pdev = to_platform_device(dev);
> - struct msm_gpu *gpu = platform_get_drvdata(pdev);
> + struct msm_gpu *gpu = dev_to_gpu(dev);
>  
>   return gpu->funcs->pm_suspend(gpu);
>  }
> diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c
> index d5645472b25d..6aa9e04e52e7 100644
> --- a/drivers/gpu/drm/msm/msm_gpu.c
> +++ b/drivers/gpu/drm/msm/msm_gpu.c
> @@ -24,7 +24,7 @@
>  static int msm_devfreq_target(struct device *dev, unsigned long *freq,
>   u32 flags)
>  {
> - struct msm_gpu *gpu = platform_get_drvdata(to_platform_device(dev));
> + struct msm_gpu *gpu = dev_to_gpu(dev);
>   struct dev_pm_opp *opp;
>  
>   opp = devfreq_recommended_opp(dev, freq, flags);
> @@ -45,7 +45,7 @@ static int msm_devfreq_target(struct device *dev, unsigned 
> long *freq,
>  static int msm_devfreq_get_dev_status(struct device *dev,
>   struct devfreq_dev_status *status)
>  {
> - struct msm_gpu *gpu = platform_get_drvdata(to_platform_device(dev));
> + struct msm_gpu *gpu = dev_to_gpu(dev);
>   ktime_t time;
>  
>   if (gpu->funcs->gpu_get_freq)
> @@ -64,7 +64,7 @@ static int msm_devfreq_get_dev_status(struct device *dev,
>  
>  static int msm_devfreq_get_cur_freq(struct device *dev, unsigned long *freq)
>  {
> - struct msm_gpu *gpu = platform_get_drvdata(to_platform_device(dev));
> + struct msm_gpu *gpu = dev_to_gpu(dev);
>  
>   if (gpu->funcs->gpu_get_freq)
>   *freq = gpu->funcs->gpu_get_freq(gpu);
> diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h
> index 0db117a7339b..8bda7beaed4b 100644
> --- a/drivers/gpu/drm/msm/msm_gpu.h
> +++ b/drivers/gpu/drm/msm/msm_gpu.h
> @@ -141,6 +141,11 @@ struct msm_gpu {
>   struct msm_gpu_state *crashstate;
>  };
>  
> +static inline struct msm_gpu *dev_to_gpu(struct device *dev)

That's a fairly generic name for a driver-global helper :)

Reviewed-by: Bjorn Andersson 

Regards,
Bjorn

> +{
> + return dev_get_drvdata(dev);
> +}
> +
>  /* It turns out that all targets use the same ringbuffer size */
>  #define MSM_GPU_RINGBUFFER_SZ SZ_32K
>  #define MSM_GPU_RINGBUFFER_BLKSIZE 32
> -- 
> 2.26.2
> 
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 05/19] iommu: add private interface for adreno-smmu

2020-08-31 Thread Bjorn Andersson
On Thu 13 Aug 21:41 CDT 2020, Rob Clark wrote:

> From: Rob Clark 
> 
> This interface will be used for drm/msm to coordinate with the
> qcom_adreno_smmu_impl to enable/disable TTBR0 translation.
> 
> Once TTBR0 translation is enabled, the GPU's CP (Command Processor)
> will directly switch TTBR0 pgtables (and do the necessary TLB inv)
> synchronized to the GPU's operation.  But help from the SMMU driver
> is needed to initially bootstrap TTBR0 translation, which cannot be
> done from the GPU.
> 
> Since this is a very special case, a private interface is used to
> avoid adding highly driver specific things to the public iommu
> interface.
> 
> Signed-off-by: Rob Clark 

Reviewed-by: Bjorn Andersson 

> ---
>  include/linux/adreno-smmu-priv.h | 36 
>  1 file changed, 36 insertions(+)
>  create mode 100644 include/linux/adreno-smmu-priv.h
> 
> diff --git a/include/linux/adreno-smmu-priv.h 
> b/include/linux/adreno-smmu-priv.h
> new file mode 100644
> index ..a889f28afb42
> --- /dev/null
> +++ b/include/linux/adreno-smmu-priv.h
> @@ -0,0 +1,36 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (C) 2020 Google, Inc
> + */
> +
> +#ifndef __ADRENO_SMMU_PRIV_H
> +#define __ADRENO_SMMU_PRIV_H
> +
> +#include 
> +
> +/**
> + * struct adreno_smmu_priv - private interface between adreno-smmu and GPU
> + *
> + * @cookie:An opque token provided by adreno-smmu and passed
> + * back into the callbacks
> + * @get_ttbr1_cfg: Get the TTBR1 config for the GPUs context-bank
> + * @set_ttbr0_cfg: Set the TTBR0 config for the GPUs context bank.  A
> + * NULL config disables TTBR0 translation, otherwise
> + * TTBR0 translation is enabled with the specified cfg
> + *
> + * The GPU driver (drm/msm) and adreno-smmu work together for controlling
> + * the GPU's SMMU instance.  This is by necessity, as the GPU is directly
> + * updating the SMMU for context switches, while on the other hand we do
> + * not want to duplicate all of the initial setup logic from arm-smmu.
> + *
> + * This private interface is used for the two drivers to coordinate.  The
> + * cookie and callback functions are populated when the GPU driver attaches
> + * it's domain.
> + */
> +struct adreno_smmu_priv {
> +const void *cookie;
> +const struct io_pgtable_cfg *(*get_ttbr1_cfg)(const void *cookie);
> +int (*set_ttbr0_cfg)(const void *cookie, const struct io_pgtable_cfg 
> *cfg);
> +};
> +
> +#endif /* __ADRENO_SMMU_PRIV_H */
> \ No newline at end of file
> -- 
> 2.26.2
> 
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 03/19] iommu/arm-smmu: Add support for split pagetables

2020-08-31 Thread Bjorn Andersson
On Thu 13 Aug 21:40 CDT 2020, Rob Clark wrote:

> From: Jordan Crouse 
> 
> Enable TTBR1 for a context bank if IO_PGTABLE_QUIRK_ARM_TTBR1 is selected
> by the io-pgtable configuration.
> 
> Signed-off-by: Jordan Crouse 
> Signed-off-by: Rob Clark 
> ---
>  drivers/iommu/arm/arm-smmu/arm-smmu.c | 21 -
>  drivers/iommu/arm/arm-smmu/arm-smmu.h | 25 +++--
>  2 files changed, 35 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c 
> b/drivers/iommu/arm/arm-smmu/arm-smmu.c
> index 37d8d49299b4..976d43a7f2ff 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
> @@ -552,11 +552,15 @@ static void arm_smmu_init_context_bank(struct 
> arm_smmu_domain *smmu_domain,
>   cb->ttbr[0] = pgtbl_cfg->arm_v7s_cfg.ttbr;
>   cb->ttbr[1] = 0;
>   } else {
> - cb->ttbr[0] = pgtbl_cfg->arm_lpae_s1_cfg.ttbr;
> - cb->ttbr[0] |= FIELD_PREP(ARM_SMMU_TTBRn_ASID,
> -   cfg->asid);
> + cb->ttbr[0] = FIELD_PREP(ARM_SMMU_TTBRn_ASID,
> + cfg->asid);
>   cb->ttbr[1] = FIELD_PREP(ARM_SMMU_TTBRn_ASID,
> -  cfg->asid);
> +     cfg->asid);

The old indentation seems more appropriate.

Apart from that this looks sensible.

Reviewed-by: Bjorn Andersson 

Regards,
Bjorn

> +
> + if (pgtbl_cfg->quirks & IO_PGTABLE_QUIRK_ARM_TTBR1)
> + cb->ttbr[1] |= pgtbl_cfg->arm_lpae_s1_cfg.ttbr;
> + else
> + cb->ttbr[0] |= pgtbl_cfg->arm_lpae_s1_cfg.ttbr;
>   }
>   } else {
>   cb->ttbr[0] = pgtbl_cfg->arm_lpae_s2_cfg.vttbr;
> @@ -822,7 +826,14 @@ static int arm_smmu_init_domain_context(struct 
> iommu_domain *domain,
>  
>   /* Update the domain's page sizes to reflect the page table format */
>   domain->pgsize_bitmap = pgtbl_cfg.pgsize_bitmap;
> - domain->geometry.aperture_end = (1UL << ias) - 1;
> +
> + if (pgtbl_cfg.quirks & IO_PGTABLE_QUIRK_ARM_TTBR1) {
> + domain->geometry.aperture_start = ~0UL << ias;
> + domain->geometry.aperture_end = ~0UL;
> + } else {
> + domain->geometry.aperture_end = (1UL << ias) - 1;
> + }
> +
>   domain->geometry.force_aperture = true;
>  
>   /* Initialise the context bank with our page table cfg */
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.h 
> b/drivers/iommu/arm/arm-smmu/arm-smmu.h
> index 83294516ac08..f3e456893f28 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu.h
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.h
> @@ -169,10 +169,12 @@ enum arm_smmu_cbar_type {
>  #define ARM_SMMU_CB_TCR  0x30
>  #define ARM_SMMU_TCR_EAE BIT(31)
>  #define ARM_SMMU_TCR_EPD1BIT(23)
> +#define ARM_SMMU_TCR_A1  BIT(22)
>  #define ARM_SMMU_TCR_TG0 GENMASK(15, 14)
>  #define ARM_SMMU_TCR_SH0 GENMASK(13, 12)
>  #define ARM_SMMU_TCR_ORGN0   GENMASK(11, 10)
>  #define ARM_SMMU_TCR_IRGN0   GENMASK(9, 8)
> +#define ARM_SMMU_TCR_EPD0BIT(7)
>  #define ARM_SMMU_TCR_T0SZGENMASK(5, 0)
>  
>  #define ARM_SMMU_VTCR_RES1   BIT(31)
> @@ -350,12 +352,23 @@ struct arm_smmu_domain {
>  
>  static inline u32 arm_smmu_lpae_tcr(struct io_pgtable_cfg *cfg)
>  {
> - return ARM_SMMU_TCR_EPD1 |
> -FIELD_PREP(ARM_SMMU_TCR_TG0, cfg->arm_lpae_s1_cfg.tcr.tg) |
> -FIELD_PREP(ARM_SMMU_TCR_SH0, cfg->arm_lpae_s1_cfg.tcr.sh) |
> -FIELD_PREP(ARM_SMMU_TCR_ORGN0, cfg->arm_lpae_s1_cfg.tcr.orgn) |
> -FIELD_PREP(ARM_SMMU_TCR_IRGN0, cfg->arm_lpae_s1_cfg.tcr.irgn) |
> -FIELD_PREP(ARM_SMMU_TCR_T0SZ, cfg->arm_lpae_s1_cfg.tcr.tsz);
> + u32 tcr = FIELD_PREP(ARM_SMMU_TCR_TG0, cfg->arm_lpae_s1_cfg.tcr.tg) |
> + FIELD_PREP(ARM_SMMU_TCR_SH0, cfg->arm_lpae_s1_cfg.tcr.sh) |
> + FIELD_PREP(ARM_SMMU_TCR_ORGN0, cfg->arm_lpae_s1_cfg.tcr.orgn) |
> + FIELD_PREP(ARM_SMMU_TCR_IRGN0, cfg->arm_lpae_s1_cfg.tcr.irgn) |
> + FIELD_PREP(ARM_SMMU_TCR_T0SZ, cfg->arm_lpae_s1_cfg.tcr.tsz);
> +
> +   /*
> + * When TTBR1 is selected shift the TCR fields by 16 bits and disable
> + * translation in TTBR0
> + */
> + if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_TT

Re: [PATCH 02/19] iommu/arm-smmu: Pass io-pgtable config to implementation specific function

2020-08-31 Thread Bjorn Andersson
On Thu 13 Aug 21:40 CDT 2020, Rob Clark wrote:

> From: Jordan Crouse 
> 
> Construct the io-pgtable config before calling the implementation specific
> init_context function and pass it so the implementation specific function
> can get a chance to change it before the io-pgtable is created.
> 
> Signed-off-by: Jordan Crouse 
> Signed-off-by: Rob Clark 

Reviewed-by: Bjorn Andersson 

Regards,
Bjorn

> ---
>  drivers/iommu/arm/arm-smmu/arm-smmu-impl.c |  3 ++-
>  drivers/iommu/arm/arm-smmu/arm-smmu.c  | 11 ++-
>  drivers/iommu/arm/arm-smmu/arm-smmu.h  |  3 ++-
>  3 files changed, 10 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c 
> b/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c
> index f4ff124a1967..a9861dcd0884 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c
> @@ -68,7 +68,8 @@ static int cavium_cfg_probe(struct arm_smmu_device *smmu)
>   return 0;
>  }
>  
> -static int cavium_init_context(struct arm_smmu_domain *smmu_domain)
> +static int cavium_init_context(struct arm_smmu_domain *smmu_domain,
> + struct io_pgtable_cfg *pgtbl_cfg)
>  {
>   struct cavium_smmu *cs = container_of(smmu_domain->smmu,
> struct cavium_smmu, smmu);
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c 
> b/drivers/iommu/arm/arm-smmu/arm-smmu.c
> index 09c42af9f31e..37d8d49299b4 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
> @@ -795,11 +795,6 @@ static int arm_smmu_init_domain_context(struct 
> iommu_domain *domain,
>   cfg->asid = cfg->cbndx;
>  
>   smmu_domain->smmu = smmu;
> - if (smmu->impl && smmu->impl->init_context) {
> - ret = smmu->impl->init_context(smmu_domain);
> - if (ret)
> - goto out_unlock;
> - }
>  
>   pgtbl_cfg = (struct io_pgtable_cfg) {
>   .pgsize_bitmap  = smmu->pgsize_bitmap,
> @@ -810,6 +805,12 @@ static int arm_smmu_init_domain_context(struct 
> iommu_domain *domain,
>   .iommu_dev  = smmu->dev,
>   };
>  
> + if (smmu->impl && smmu->impl->init_context) {
> + ret = smmu->impl->init_context(smmu_domain, _cfg);
> + if (ret)
> + goto out_clear_smmu;
> + }
> +
>   if (smmu_domain->non_strict)
>   pgtbl_cfg.quirks |= IO_PGTABLE_QUIRK_NON_STRICT;
>  
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.h 
> b/drivers/iommu/arm/arm-smmu/arm-smmu.h
> index d890a4a968e8..83294516ac08 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu.h
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.h
> @@ -386,7 +386,8 @@ struct arm_smmu_impl {
>   u64 val);
>   int (*cfg_probe)(struct arm_smmu_device *smmu);
>   int (*reset)(struct arm_smmu_device *smmu);
> - int (*init_context)(struct arm_smmu_domain *smmu_domain);
> + int (*init_context)(struct arm_smmu_domain *smmu_domain,
> + struct io_pgtable_cfg *cfg);
>   void (*tlb_sync)(struct arm_smmu_device *smmu, int page, int sync,
>int status);
>   int (*def_domain_type)(struct device *dev);
> -- 
> 2.26.2
> 
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 01/19] drm/msm: remove dangling submitqueue references

2020-08-31 Thread Bjorn Andersson
On Fri 14 Aug 02:40 UTC 2020, Rob Clark wrote:

> From: Rob Clark 
> 
> Currently it doesn't matter, since we free the ctx immediately.  But
> when we start refcnt'ing the ctx, we don't want old dangling list
> entries to hang around.
> 
> Signed-off-by: Rob Clark 
> ---
>  drivers/gpu/drm/msm/msm_submitqueue.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/msm/msm_submitqueue.c 
> b/drivers/gpu/drm/msm/msm_submitqueue.c
> index a1d94be7883a..90c9d84e6155 100644
> --- a/drivers/gpu/drm/msm/msm_submitqueue.c
> +++ b/drivers/gpu/drm/msm/msm_submitqueue.c
> @@ -49,8 +49,10 @@ void msm_submitqueue_close(struct msm_file_private *ctx)
>* No lock needed in close and there won't
>* be any more user ioctls coming our way
>*/
> - list_for_each_entry_safe(entry, tmp, >submitqueues, node)
> + list_for_each_entry_safe(entry, tmp, >submitqueues, node) {
> + list_del(>node);

If you refcount ctx, what does that do for the entries in the submit
queue?

"entry" here is kref'ed, but you're popping it off the list regardless
of the put ends up freeing the object or not - which afaict would mean
leaking the object.


On the other hand, with the current implementation an object with higher
refcount with adjacent objects of single refcount would end up with
dangling pointers after the put. So in itself this change seems like a
net gain, but I'm wondering about the plan described in the commit
message.

Regards,
Bjorn

>   msm_submitqueue_put(entry);
> + }
>  }
>  
>  int msm_submitqueue_create(struct drm_device *drm, struct msm_file_private 
> *ctx,
> -- 
> 2.26.2
> 
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 1/1] iommu/arm-smmu: Implement qcom,skip-init

2020-07-30 Thread Bjorn Andersson
On Wed 22 Jul 13:11 PDT 2020, Konrad Dybcio wrote:

> >Is the problem on SDM630 that when you write to SMR/S2CR the device
> >reboots? Or that when you start writing out the context bank
> >configuration that trips the display and the device reboots?
> 
> I added some debug prints and the phone hangs after reaching the
> seventh CB (with i=6) at
> 
> arm_smmu_cb_write(smmu, i, ARM_SMMU_CB_FSR, ARM_SMMU_FSR_FAULT);
> 
> line in arm_smmu_device_reset.
> 

Sounds like things are progressing nicely for a while there, presumably
until the next time the display is being refreshed.

Would you be willing to try out the following work in progress:
https://lore.kernel.org/linux-arm-msm/20200717001619.325317-1-bjorn.anders...@linaro.org/

You need to adjust drivers/iommu/arm-smmu-impl.c so that
arm_smmu_impl_init() will invoke qcom_smmu_impl_init() as it spots your
apps smmu.

Regards,
Bjorn
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v10 04/13] iommu/arm-smmu-qcom: Add implementation for the adreno GPU SMMU

2020-07-27 Thread Bjorn Andersson
On Mon 20 Jul 08:40 PDT 2020, Jordan Crouse wrote:
> diff --git a/drivers/iommu/arm-smmu-qcom.c b/drivers/iommu/arm-smmu-qcom.c
[..]
> +static int qcom_adreno_smmu_alloc_context_bank(struct arm_smmu_domain 
> *smmu_domain,
> + struct device *dev, int start, int count)
> +{
> + struct arm_smmu_device *smmu = smmu_domain->smmu;
> +
> + /*
> +  * Assign context bank 0 to the GPU device so the GPU hardware can
> +  * switch pagetables
> +  */
> + if (qcom_adreno_smmu_is_gpu_device(dev)) {
> + if (start > 0 || test_bit(0, smmu->context_map))
> + return -ENOSPC;
> +
> + set_bit(0, smmu->context_map);
> + return 0;
> + }
> +
> + return __arm_smmu_alloc_bitmap(smmu->context_map, start, count);

If we end up here before the GPU device shows up this is going to
steal the first context bank, causing the subsequent allocation for the
GPU to always fail.

As such I think it would be appropriate for you to adjust "start" to
never be 0 here. And I think it would be appropriate to write this
function as:

if (gpu) {
start = 0;
count = 1;
} else {
if (start == 0)
start = 1;
}

return __arm_smmu_alloc_bitmap(smmu->context_map, start, count);

Regards,
Bjorn
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 1/1] iommu/arm-smmu: Implement qcom,skip-init

2020-07-21 Thread Bjorn Andersson
On Tue 21 Jul 09:20 PDT 2020, Konrad Dybcio wrote:

> >The current
> >focus has been on moving more of the SMMU specific bits into the 
> >arm-smmu-qcom
> >implementation [1] and I think that is the right way to go.
> 
> Pardon if I overlooked something obvious, but I can't seem to find a
> clean way for implementing qcom,skip-init in arm-smmu-qcom, as neither
> the arm_smmu_test_smr_masks nor the probe function seem to be
> alterable with arm_smmu_impl. I'm open to your ideas guys.
> 

Is the problem on SDM630 that when you write to SMR/S2CR the device
reboots? Or that when you start writing out the context bank
configuration that trips the display and the device reboots?

Regards,
Bjorn
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v2 5/5] iommu/arm-smmu: Setup identity domain for boot mappings

2020-07-16 Thread Bjorn Andersson
With many Qualcomm platforms not having functional S2CR BYPASS a
temporary IOMMU domain, without translation, needs to be allocated in
order to allow these memory transactions.

Unfortunately the boot loader uses the first few context banks, so
rather than overwriting a active bank the last context bank is used and
streams are diverted here during initialization.

This also performs the readback of SMR registers for the Qualcomm
platform, to trigger the mechanism.

This is based on prior work by Thierry Reding and Laurentiu Tudor.

Tested-by: John Stultz 
Tested-by: Vinod Koul 
Signed-off-by: Bjorn Andersson 
---

Changes since v1:
- Rebased to avoid conflict
- Picked up tested-by

 drivers/iommu/arm-smmu-qcom.c | 11 +
 drivers/iommu/arm-smmu.c  | 79 +--
 drivers/iommu/arm-smmu.h  |  3 ++
 3 files changed, 89 insertions(+), 4 deletions(-)

diff --git a/drivers/iommu/arm-smmu-qcom.c b/drivers/iommu/arm-smmu-qcom.c
index 10eb024981d1..147af11049eb 100644
--- a/drivers/iommu/arm-smmu-qcom.c
+++ b/drivers/iommu/arm-smmu-qcom.c
@@ -26,6 +26,7 @@ static const struct of_device_id qcom_smmu_client_of_match[] 
__maybe_unused = {
 static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu)
 {
unsigned int last_s2cr = ARM_SMMU_GR0_S2CR(smmu->num_mapping_groups - 
1);
+   u32 smr;
u32 reg;
int i;
 
@@ -56,6 +57,16 @@ static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu)
}
}
 
+   for (i = 0; i < smmu->num_mapping_groups; i++) {
+   smr = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_SMR(i));
+
+   if (FIELD_GET(ARM_SMMU_SMR_VALID, smr)) {
+   smmu->smrs[i].id = FIELD_GET(ARM_SMMU_SMR_ID, smr);
+   smmu->smrs[i].mask = FIELD_GET(ARM_SMMU_SMR_MASK, smr);
+   smmu->smrs[i].valid = true;
+   }
+   }
+
return 0;
 }
 
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 08a650fe02e3..69bd8ee03516 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -652,7 +652,8 @@ static void arm_smmu_write_context_bank(struct 
arm_smmu_device *smmu, int idx)
 }
 
 static int arm_smmu_init_domain_context(struct iommu_domain *domain,
-   struct arm_smmu_device *smmu)
+   struct arm_smmu_device *smmu,
+   bool boot_domain)
 {
int irq, start, ret = 0;
unsigned long ias, oas;
@@ -770,6 +771,15 @@ static int arm_smmu_init_domain_context(struct 
iommu_domain *domain,
ret = -EINVAL;
goto out_unlock;
}
+
+   /*
+* Use the last context bank for identity mappings during boot, to
+* avoid overwriting in-use bank configuration while we're setting up
+* the new mappings.
+*/
+   if (boot_domain)
+   start = smmu->num_context_banks - 1;
+
ret = __arm_smmu_alloc_bitmap(smmu->context_map, start,
  smmu->num_context_banks);
if (ret < 0)
@@ -1149,7 +1159,10 @@ static int arm_smmu_attach_dev(struct iommu_domain 
*domain, struct device *dev)
struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
struct arm_smmu_master_cfg *cfg;
struct arm_smmu_device *smmu;
+   bool free_identity_domain = false;
+   int idx;
int ret;
+   int i;
 
if (!fwspec || fwspec->ops != _smmu_ops) {
dev_err(dev, "cannot attach to SMMU, is it on the same bus?\n");
@@ -1174,7 +1187,7 @@ static int arm_smmu_attach_dev(struct iommu_domain 
*domain, struct device *dev)
return ret;
 
/* Ensure that the domain is finalised */
-   ret = arm_smmu_init_domain_context(domain, smmu);
+   ret = arm_smmu_init_domain_context(domain, smmu, false);
if (ret < 0)
goto rpm_put;
 
@@ -1190,9 +1203,33 @@ static int arm_smmu_attach_dev(struct iommu_domain 
*domain, struct device *dev)
goto rpm_put;
}
 
+   /* Decrement use counter for any references to the identity domain */
+   mutex_lock(>stream_map_mutex);
+   if (smmu->identity) {
+   struct arm_smmu_domain *identity = 
to_smmu_domain(smmu->identity);
+
+   for_each_cfg_sme(cfg, fwspec, i, idx) {
+   if (smmu->s2crs[idx].cbndx == identity->cfg.cbndx) {
+   smmu->num_identity_masters--;
+   if (smmu->num_identity_masters == 0)
+   free_identity_domain = true;
+   }
+   }
+   }
+   mutex_unlock(>stream_map_mutex);
+
/* Looks ok, so add the device to the domain */
ret = arm_smmu_domain_add_master(smmu_domain, cfg, fwspec);
 
+   /*
+ 

[PATCH v2 2/5] iommu/arm-smmu: Emulate bypass by using context banks

2020-07-16 Thread Bjorn Andersson
Some firmware found on various Qualcomm platforms traps writes to S2CR
of type BYPASS and writes FAULT into the register. This prevents us from
marking the streams for the display controller as BYPASS to allow
continued scanout of the screen through the initialization of the ARM
SMMU.

This adds a Qualcomm specific cfg_probe function, which probes the
behavior of the S2CR registers and if found faulty enables the related
quirk. Based on this quirk context banks are allocated for IDENTITY
domains as well, but with ARM_SMMU_SCTLR_M omitted.

The result is valid stream mappings, without translation.

Tested-by: John Stultz 
Tested-by: Vinod Koul 
Signed-off-by: Bjorn Andersson 
---

Changes since v1:
- Picked up tested-by

 drivers/iommu/arm-smmu-qcom.c | 21 +
 drivers/iommu/arm-smmu.c  | 14 --
 drivers/iommu/arm-smmu.h  |  3 +++
 3 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/arm-smmu-qcom.c b/drivers/iommu/arm-smmu-qcom.c
index be4318044f96..d95a5ee8c83c 100644
--- a/drivers/iommu/arm-smmu-qcom.c
+++ b/drivers/iommu/arm-smmu-qcom.c
@@ -23,6 +23,26 @@ static const struct of_device_id qcom_smmu_client_of_match[] 
__maybe_unused = {
{ }
 };
 
+static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu)
+{
+   unsigned int last_s2cr = ARM_SMMU_GR0_S2CR(smmu->num_mapping_groups - 
1);
+   u32 reg;
+
+   /*
+* With some firmware writes to S2CR of type FAULT are ignored, and
+* writing BYPASS will end up as FAULT in the register. Perform a write
+* to S2CR to detect if this is the case with the current firmware.
+*/
+   arm_smmu_gr0_write(smmu, last_s2cr, FIELD_PREP(ARM_SMMU_S2CR_TYPE, 
S2CR_TYPE_BYPASS) |
+   FIELD_PREP(ARM_SMMU_S2CR_CBNDX, 
0xff) |
+   FIELD_PREP(ARM_SMMU_S2CR_PRIVCFG, 
S2CR_PRIVCFG_DEFAULT));
+   reg = arm_smmu_gr0_read(smmu, last_s2cr);
+   if (FIELD_GET(ARM_SMMU_S2CR_TYPE, reg) != S2CR_TYPE_BYPASS)
+   smmu->qcom_bypass_quirk = true;
+
+   return 0;
+}
+
 static int qcom_smmu_def_domain_type(struct device *dev)
 {
const struct of_device_id *match =
@@ -61,6 +81,7 @@ static int qcom_smmu500_reset(struct arm_smmu_device *smmu)
 }
 
 static const struct arm_smmu_impl qcom_smmu_impl = {
+   .cfg_probe = qcom_smmu_cfg_probe,
.def_domain_type = qcom_smmu_def_domain_type,
.reset = qcom_smmu500_reset,
 };
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index fb85e716ae9a..5d5fe6741ed4 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -654,7 +654,9 @@ static void arm_smmu_write_context_bank(struct 
arm_smmu_device *smmu, int idx)
 
/* SCTLR */
reg = ARM_SMMU_SCTLR_CFIE | ARM_SMMU_SCTLR_CFRE | ARM_SMMU_SCTLR_AFE |
- ARM_SMMU_SCTLR_TRE | ARM_SMMU_SCTLR_M;
+ ARM_SMMU_SCTLR_TRE;
+   if (cfg->m)
+   reg |= ARM_SMMU_SCTLR_M;
if (stage1)
reg |= ARM_SMMU_SCTLR_S1_ASIDPNE;
if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
@@ -678,7 +680,11 @@ static int arm_smmu_init_domain_context(struct 
iommu_domain *domain,
if (smmu_domain->smmu)
goto out_unlock;
 
-   if (domain->type == IOMMU_DOMAIN_IDENTITY) {
+   /*
+* Nothing to do for IDENTITY domains,unless disabled context banks are
+* used to emulate bypass mappings on Qualcomm platforms.
+*/
+   if (domain->type == IOMMU_DOMAIN_IDENTITY && !smmu->qcom_bypass_quirk) {
smmu_domain->stage = ARM_SMMU_DOMAIN_BYPASS;
smmu_domain->smmu = smmu;
goto out_unlock;
@@ -826,6 +832,10 @@ static int arm_smmu_init_domain_context(struct 
iommu_domain *domain,
domain->geometry.aperture_end = (1UL << ias) - 1;
domain->geometry.force_aperture = true;
 
+   /* Enable translation for non-identity context banks */
+   if (domain->type != IOMMU_DOMAIN_IDENTITY)
+   cfg->m = true;
+
/* Initialise the context bank with our page table cfg */
arm_smmu_init_context_bank(smmu_domain, _cfg);
arm_smmu_write_context_bank(smmu, cfg->cbndx);
diff --git a/drivers/iommu/arm-smmu.h b/drivers/iommu/arm-smmu.h
index d172c024be61..a71d193073e4 100644
--- a/drivers/iommu/arm-smmu.h
+++ b/drivers/iommu/arm-smmu.h
@@ -305,6 +305,8 @@ struct arm_smmu_device {
 
/* IOMMU core code handle */
struct iommu_device iommu;
+
+   boolqcom_bypass_quirk;
 };
 
 enum arm_smmu_context_fmt {
@@ -323,6 +325,7 @@ struct arm_smmu_cfg {
};
enum arm_smmu_cbar_type cbar;
enum arm_smmu_context_fmt   fmt;
+   boolm;
 };
 #define ARM_SMMU_INVALID_IRPTNDX   0xff
 
-- 
2.26.2


[PATCH v2 1/5] iommu/arm-smmu: Make all valid stream mappings BYPASS

2020-07-16 Thread Bjorn Andersson
Turn all stream mappings marked as valid into BYPASS. This allows the
platform specific implementation to configure stream mappings to match
the boot loader's configuration for e.g. display to continue to function
through the reset of the SMMU.

Tested-by: John Stultz 
Tested-by: Vinod Koul 
Suggested-by: Robin Murphy 
Signed-off-by: Bjorn Andersson 
---

Changes since v1:
- Mark arm_smmu_setup_identity() static
- Picked up tested-by tags

 drivers/iommu/arm-smmu.c | 20 
 1 file changed, 20 insertions(+)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 243bc4cb2705..fb85e716ae9a 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -1924,6 +1924,22 @@ static int arm_smmu_device_cfg_probe(struct 
arm_smmu_device *smmu)
return 0;
 }
 
+static int arm_smmu_setup_identity(struct arm_smmu_device *smmu)
+{
+   int i;
+
+   for (i = 0; i < smmu->num_mapping_groups; i++) {
+   if (smmu->smrs[i].valid) {
+   smmu->s2crs[i].type = S2CR_TYPE_BYPASS;
+   smmu->s2crs[i].privcfg = S2CR_PRIVCFG_DEFAULT;
+   smmu->s2crs[i].cbndx = 0xff;
+   smmu->s2crs[i].count++;
+   }
+   }
+
+   return 0;
+}
+
 struct arm_smmu_match_data {
enum arm_smmu_arch_version version;
enum arm_smmu_implementation model;
@@ -2181,6 +2197,10 @@ static int arm_smmu_device_probe(struct platform_device 
*pdev)
if (err)
return err;
 
+   err = arm_smmu_setup_identity(smmu);
+   if (err)
+   return err;
+
if (smmu->version == ARM_SMMU_V2) {
if (smmu->num_context_banks > smmu->num_context_irqs) {
dev_err(dev,
-- 
2.26.2

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v2 4/5] iommu/arm-smmu-qcom: Consistently initialize stream mappings

2020-07-16 Thread Bjorn Andersson
Firmware that traps writes to S2CR to translate BYPASS into FAULT also
ignores writes of type FAULT. As such booting with "disable_bypass" set
will result in all S2CR registers left as configured by the bootloader.

This has been seen to result in indeterministic results, as these
mappings might linger and reference context banks that Linux is
reconfiguring.

Use the fact that BYPASS writes result in FAULT type to force all stream
mappings to FAULT.

Tested-by: John Stultz 
Tested-by: Vinod Koul 
Signed-off-by: Bjorn Andersson 
---

Changes since v1:
- Fixed subject spelling mistake
- Picked up tested-by

 drivers/iommu/arm-smmu-qcom.c | 18 +-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/arm-smmu-qcom.c b/drivers/iommu/arm-smmu-qcom.c
index d95a5ee8c83c..10eb024981d1 100644
--- a/drivers/iommu/arm-smmu-qcom.c
+++ b/drivers/iommu/arm-smmu-qcom.c
@@ -27,6 +27,7 @@ static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu)
 {
unsigned int last_s2cr = ARM_SMMU_GR0_S2CR(smmu->num_mapping_groups - 
1);
u32 reg;
+   int i;
 
/*
 * With some firmware writes to S2CR of type FAULT are ignored, and
@@ -37,9 +38,24 @@ static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu)
FIELD_PREP(ARM_SMMU_S2CR_CBNDX, 
0xff) |
FIELD_PREP(ARM_SMMU_S2CR_PRIVCFG, 
S2CR_PRIVCFG_DEFAULT));
reg = arm_smmu_gr0_read(smmu, last_s2cr);
-   if (FIELD_GET(ARM_SMMU_S2CR_TYPE, reg) != S2CR_TYPE_BYPASS)
+   if (FIELD_GET(ARM_SMMU_S2CR_TYPE, reg) != S2CR_TYPE_BYPASS) {
smmu->qcom_bypass_quirk = true;
 
+   /*
+* With firmware ignoring writes of type FAULT, booting the
+* Linux kernel with disable_bypass disabled (i.e. "enable
+* bypass") the initialization during probe will leave mappings
+* in an inconsistent state. Avoid this by configuring all
+* S2CRs to BYPASS.
+*/
+   for (i = 0; i < smmu->num_mapping_groups; i++) {
+   smmu->s2crs[i].type = S2CR_TYPE_BYPASS;
+   smmu->s2crs[i].privcfg = S2CR_PRIVCFG_DEFAULT;
+   smmu->s2crs[i].cbndx = 0xff;
+   smmu->s2crs[i].count = 0;
+   }
+   }
+
return 0;
 }
 
-- 
2.26.2

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v2 3/5] iommu/arm-smmu: Move SMR and S2CR definitions to header file

2020-07-16 Thread Bjorn Andersson
Expose the SMR and S2CR structs in the header file, to allow platform
specific implementations to populate/initialize the smrs and s2cr
arrays.

Tested-by: John Stultz 
Tested-by: Vinod Koul 
Signed-off-by: Bjorn Andersson 
---

Changes since v1:
- Picked up tested-by

 drivers/iommu/arm-smmu.c | 14 --
 drivers/iommu/arm-smmu.h | 15 +++
 2 files changed, 15 insertions(+), 14 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 5d5fe6741ed4..08a650fe02e3 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -68,24 +68,10 @@ module_param(disable_bypass, bool, S_IRUGO);
 MODULE_PARM_DESC(disable_bypass,
"Disable bypass streams such that incoming transactions from devices 
that are not attached to an iommu domain will report an abort back to the 
device and will not be allowed to pass through the SMMU.");
 
-struct arm_smmu_s2cr {
-   struct iommu_group  *group;
-   int count;
-   enum arm_smmu_s2cr_type type;
-   enum arm_smmu_s2cr_privcfg  privcfg;
-   u8  cbndx;
-};
-
 #define s2cr_init_val (struct arm_smmu_s2cr){  \
.type = disable_bypass ? S2CR_TYPE_FAULT : S2CR_TYPE_BYPASS,\
 }
 
-struct arm_smmu_smr {
-   u16 mask;
-   u16 id;
-   boolvalid;
-};
-
 struct arm_smmu_cb {
u64 ttbr[2];
u32 tcr[2];
diff --git a/drivers/iommu/arm-smmu.h b/drivers/iommu/arm-smmu.h
index a71d193073e4..bcd160d01c53 100644
--- a/drivers/iommu/arm-smmu.h
+++ b/drivers/iommu/arm-smmu.h
@@ -251,6 +251,21 @@ enum arm_smmu_implementation {
QCOM_SMMUV2,
 };
 
+struct arm_smmu_s2cr {
+   struct iommu_group  *group;
+   int count;
+   enum arm_smmu_s2cr_type type;
+   enum arm_smmu_s2cr_privcfg  privcfg;
+   u8  cbndx;
+};
+
+struct arm_smmu_smr {
+   u16 mask;
+   u16 id;
+   boolvalid;
+   boolpinned;
+};
+
 struct arm_smmu_device {
struct device   *dev;
 
-- 
2.26.2

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v2 0/5] iommu/arm-smmu: Support maintaining bootloader mappings

2020-07-16 Thread Bjorn Andersson
Based on previous attempts and discussions this is the latest attempt at
inheriting stream mappings set up by the bootloader, for e.g. boot splash or
efifb.

The first patch is an implementation of Robin's suggestion that we should just
mark the relevant stream mappings as BYPASS. Relying on something else to set
up the stream mappings wanted - e.g. by reading it back in platform specific
implementation code.

The series then tackles the problem seen in most versions of Qualcomm firmware,
that the hypervisor intercepts BYPASS writes and turn them into FAULTs. It does
this by allocating context banks for identity domains as well, with translation
disabled.

Lastly it amends the stream mapping initialization code to allocate a specific
identity domain that is used for any mappings inherited from the bootloader, if
above Qualcomm quirk is required.


The series has been tested and shown to allow booting SDM845, SDM850, SM8150,
SM8250 with boot splash screen setup by the bootloader. Specifically it also
allows the Lenovo Yoga C630 to boot with SMMU and efifb enabled.

Bjorn Andersson (5):
  iommu/arm-smmu: Make all valid stream mappings BYPASS
  iommu/arm-smmu: Emulate bypass by using context banks
  iommu/arm-smmu: Move SMR and S2CR definitions to header file
  iommu/arm-smmu-qcom: Consistently initialize stream mappings
  iommu/arm-smmu: Setup identity domain for boot mappings

 drivers/iommu/arm-smmu-qcom.c |  48 +
 drivers/iommu/arm-smmu.c  | 123 +-
 drivers/iommu/arm-smmu.h  |  21 ++
 3 files changed, 174 insertions(+), 18 deletions(-)

-- 
2.26.2

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 5/5] iommu/arm-smmu: Setup identity domain for boot mappings

2020-07-09 Thread Bjorn Andersson
On Thu 09 Jul 08:50 PDT 2020, Laurentiu Tudor wrote:

> 
> 
> On 7/9/2020 8:01 AM, Bjorn Andersson wrote:
> > With many Qualcomm platforms not having functional S2CR BYPASS a
> > temporary IOMMU domain, without translation, needs to be allocated in
> > order to allow these memory transactions.
> > 
> > Unfortunately the boot loader uses the first few context banks, so
> > rather than overwriting a active bank the last context bank is used and
> > streams are diverted here during initialization.
> > 
> > This also performs the readback of SMR registers for the Qualcomm
> > platform, to trigger the mechanism.
> > 
> > This is based on prior work by Thierry Reding and Laurentiu Tudor.
> > 
> > Signed-off-by: Bjorn Andersson 
> > ---
> >  drivers/iommu/arm-smmu-qcom.c | 11 +
> >  drivers/iommu/arm-smmu.c  | 80 +--
> >  drivers/iommu/arm-smmu.h  |  3 ++
> >  3 files changed, 90 insertions(+), 4 deletions(-)
> > 
> > diff --git a/drivers/iommu/arm-smmu-qcom.c b/drivers/iommu/arm-smmu-qcom.c
> > index 86b1917459a4..397df27c1d69 100644
> > --- a/drivers/iommu/arm-smmu-qcom.c
> > +++ b/drivers/iommu/arm-smmu-qcom.c
> > @@ -26,6 +26,7 @@ static const struct of_device_id 
> > qcom_smmu_client_of_match[] = {
> >  static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu)
> >  {
> > unsigned int last_s2cr = ARM_SMMU_GR0_S2CR(smmu->num_mapping_groups - 
> > 1);
> > +   u32 smr;
> > u32 reg;
> > int i;
> >  
> > @@ -56,6 +57,16 @@ static int qcom_smmu_cfg_probe(struct arm_smmu_device 
> > *smmu)
> > }
> > }
> >  
> > +   for (i = 0; i < smmu->num_mapping_groups; i++) {
> > +   smr = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_SMR(i));
> > +
> > +   if (FIELD_GET(ARM_SMMU_SMR_VALID, smr)) {
> > +   smmu->smrs[i].id = FIELD_GET(ARM_SMMU_SMR_ID, smr);
> > +   smmu->smrs[i].mask = FIELD_GET(ARM_SMMU_SMR_MASK, smr);
> > +   smmu->smrs[i].valid = true;
> > +   }
> > +   }
> > +
> > return 0;
> >  }
> >  
> > diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
> > index e2d6c0aaf1ea..a7cb27c1a49e 100644
> > --- a/drivers/iommu/arm-smmu.c
> > +++ b/drivers/iommu/arm-smmu.c
> > @@ -652,7 +652,8 @@ static void arm_smmu_write_context_bank(struct 
> > arm_smmu_device *smmu, int idx)
> >  }
> >  
> >  static int arm_smmu_init_domain_context(struct iommu_domain *domain,
> > -   struct arm_smmu_device *smmu)
> > +   struct arm_smmu_device *smmu,
> > +   bool boot_domain)
> >  {
> > int irq, start, ret = 0;
> > unsigned long ias, oas;
> > @@ -770,6 +771,15 @@ static int arm_smmu_init_domain_context(struct 
> > iommu_domain *domain,
> > ret = -EINVAL;
> > goto out_unlock;
> > }
> > +
> > +   /*
> > +* Use the last context bank for identity mappings during boot, to
> > +* avoid overwriting in-use bank configuration while we're setting up
> > +* the new mappings.
> > +*/
> > +   if (boot_domain)
> > +   start = smmu->num_context_banks - 1;
> > +
> > ret = __arm_smmu_alloc_bitmap(smmu->context_map, start,
> >   smmu->num_context_banks);
> > if (ret < 0)
> > @@ -1149,7 +1159,10 @@ static int arm_smmu_attach_dev(struct iommu_domain 
> > *domain, struct device *dev)
> > struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
> > struct arm_smmu_master_cfg *cfg;
> > struct arm_smmu_device *smmu;
> > +   bool free_identity_domain = false;
> > +   int idx;
> > int ret;
> > +   int i;
> >  
> > if (!fwspec || fwspec->ops != _smmu_ops) {
> > dev_err(dev, "cannot attach to SMMU, is it on the same bus?\n");
> > @@ -1174,7 +1187,7 @@ static int arm_smmu_attach_dev(struct iommu_domain 
> > *domain, struct device *dev)
> > return ret;
> >  
> > /* Ensure that the domain is finalised */
> > -   ret = arm_smmu_init_domain_context(domain, smmu);
> > +   ret = arm_smmu_init_domain_context(domain, smmu, false);
> > if (ret < 0)
> > goto rpm_put;
> >  
> > @@ -1190,9 +1203,34 @@ static int arm_smmu_attach_dev(struct iommu_domain 
> > *domain, struct devi

Re: [PATCH 2/5] iommu/arm-smmu: Emulate bypass by using context banks

2020-07-09 Thread Bjorn Andersson
On Thu 09 Jul 11:55 PDT 2020, Rob Clark wrote:

> On Thu, Jul 9, 2020 at 9:56 AM Rob Clark  wrote:
> >
> > On Thu, Jul 9, 2020 at 9:48 AM Bjorn Andersson
> >  wrote:
> > >
> > > On Thu 09 Jul 09:17 PDT 2020, Rob Clark wrote:
> > >
> > > > On Wed, Jul 8, 2020 at 10:01 PM Bjorn Andersson
> > > >  wrote:
> > > [..]
> > > > > @@ -678,7 +680,11 @@ static int arm_smmu_init_domain_context(struct 
> > > > > iommu_domain *domain,
> > > > > if (smmu_domain->smmu)
> > > > > goto out_unlock;
> > > > >
> > > > > -   if (domain->type == IOMMU_DOMAIN_IDENTITY) {
> > > > > +   /*
> > > > > +* Nothing to do for IDENTITY domains,unless disabled context 
> > > > > banks are
> > > > > +* used to emulate bypass mappings on Qualcomm platforms.
> > > > > +*/
> > > > > +   if (domain->type == IOMMU_DOMAIN_IDENTITY && 
> > > > > !smmu->qcom_bypass_quirk) {
> > > >
> > > > maybe I'm overlooking something, but I think this would put us back to
> > > > allocating pgtables (and making iommu->map/unmap() no longer no-ops),
> > > > which I don't think we want
> > > >
> > >
> > > You're right, we are allocating page tables for these contexts and
> > > map/unmap would modify the page tables. But afaict traversal is never
> > > performed, given that the banks are never enabled.
> > >
> > > But as drivers probe properly, or the direct mapped drivers sets up
> > > their iommu domains explicitly with translation this would not be used.
> > >
> > > So afaict we're just wasting some memory - for the gain of not
> > > overcomplicating this function.
> >
> > the problem is that it makes dma_map/unmap less of a no-op than it
> > should be (for the case where the driver is explicitly managing it's
> > own domain)..  I was hoping to get rid of the hacks to use dma_sync go
> > back to dma_map/unmap for cache cleaning
> 
> That said, it seems to cause less explosions than before.. either that
> or I'm not trying hard enough.  Still, I think it would probably
> result in unnecessary tlb inv's.
> 
> Previously, *somehow* we seemed to end up with dma_map/unmap trying to
> modify the domain that we had attached.
> 

I might need some help to really understand the plumbing here, but this
is what I read from the code and can see in my debugging...


The display device will upon creation be allocated a default_domain, of
type IOMMU_DOMAIN_IDENTITY - per the qcom-impl. Then you then allocate a
new iommu domain on the platform bus in the display driver and attach
this to the device. This will result in the group's domain being of type
IOMMU_DOMAIN_UNMANAGED.

But when you then invoke dma_map_single() on the display device, the map
operation will acquire the iommu_group's default_domain (not domain) and
as such attempt to map stuff on the IDENTITY domain.

__iommu_map() will however reject this, given that the type does not
have __IOMMU_DOMAIN_PAGING set. Afaict, this would happen regardless of
this patch actually setting up a page table for the default_domain or
not.


So, afaict, you can't use dma_map_single()/dma_unmap() to operate your
page table on a lately attached iommu domain.

This would also imply that the display device consumes two context
banks, which worries me more than the waste of page tables etc.

Regards,
Bjorn

> BR,
> -R
> 
> > BR,
> > -R
> >
> >
> > >
> > > Regards,
> > > Bjorn
> > >
> > > > BR,
> > > > -R
> > > >
> > > > > smmu_domain->stage = ARM_SMMU_DOMAIN_BYPASS;
> > > > > smmu_domain->smmu = smmu;
> > > > > goto out_unlock;
> > > > > @@ -826,6 +832,10 @@ static int arm_smmu_init_domain_context(struct 
> > > > > iommu_domain *domain,
> > > > > domain->geometry.aperture_end = (1UL << ias) - 1;
> > > > > domain->geometry.force_aperture = true;
> > > > >
> > > > > +   /* Enable translation for non-identity context banks */
> > > > > +   if (domain->type != IOMMU_DOMAIN_IDENTITY)
> > > > > +   cfg->m = true;
> > > > > +
> > > > > /* Initialise the context bank with our page table cfg */
> > > > > arm_smmu_init_context_bank(smmu_domain, _cfg);
> > &g

Re: [PATCH 2/5] iommu/arm-smmu: Emulate bypass by using context banks

2020-07-09 Thread Bjorn Andersson
On Thu 09 Jul 09:17 PDT 2020, Rob Clark wrote:

> On Wed, Jul 8, 2020 at 10:01 PM Bjorn Andersson
>  wrote:
[..]
> > @@ -678,7 +680,11 @@ static int arm_smmu_init_domain_context(struct 
> > iommu_domain *domain,
> > if (smmu_domain->smmu)
> > goto out_unlock;
> >
> > -   if (domain->type == IOMMU_DOMAIN_IDENTITY) {
> > +   /*
> > +* Nothing to do for IDENTITY domains,unless disabled context banks 
> > are
> > +* used to emulate bypass mappings on Qualcomm platforms.
> > +*/
> > +   if (domain->type == IOMMU_DOMAIN_IDENTITY && 
> > !smmu->qcom_bypass_quirk) {
> 
> maybe I'm overlooking something, but I think this would put us back to
> allocating pgtables (and making iommu->map/unmap() no longer no-ops),
> which I don't think we want
> 

You're right, we are allocating page tables for these contexts and
map/unmap would modify the page tables. But afaict traversal is never
performed, given that the banks are never enabled.

But as drivers probe properly, or the direct mapped drivers sets up
their iommu domains explicitly with translation this would not be used.

So afaict we're just wasting some memory - for the gain of not
overcomplicating this function.

Regards,
Bjorn

> BR,
> -R
> 
> > smmu_domain->stage = ARM_SMMU_DOMAIN_BYPASS;
> > smmu_domain->smmu = smmu;
> > goto out_unlock;
> > @@ -826,6 +832,10 @@ static int arm_smmu_init_domain_context(struct 
> > iommu_domain *domain,
> > domain->geometry.aperture_end = (1UL << ias) - 1;
> > domain->geometry.force_aperture = true;
> >
> > +   /* Enable translation for non-identity context banks */
> > +   if (domain->type != IOMMU_DOMAIN_IDENTITY)
> > +   cfg->m = true;
> > +
> > /* Initialise the context bank with our page table cfg */
> > arm_smmu_init_context_bank(smmu_domain, _cfg);
> > arm_smmu_write_context_bank(smmu, cfg->cbndx);
> > diff --git a/drivers/iommu/arm-smmu.h b/drivers/iommu/arm-smmu.h
> > index d172c024be61..a71d193073e4 100644
> > --- a/drivers/iommu/arm-smmu.h
> > +++ b/drivers/iommu/arm-smmu.h
> > @@ -305,6 +305,8 @@ struct arm_smmu_device {
> >
> > /* IOMMU core code handle */
> > struct iommu_device iommu;
> > +
> > +   boolqcom_bypass_quirk;
> >  };
> >
> >  enum arm_smmu_context_fmt {
> > @@ -323,6 +325,7 @@ struct arm_smmu_cfg {
> > };
> > enum arm_smmu_cbar_type cbar;
> > enum arm_smmu_context_fmt   fmt;
> > +   boolm;
> >  };
> >  #define ARM_SMMU_INVALID_IRPTNDX   0xff
> >
> > --
> > 2.26.2
> >
> > ___
> > iommu mailing list
> > iommu@lists.linux-foundation.org
> > https://lists.linuxfoundation.org/mailman/listinfo/iommu
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 4/5] iommu/arm-smmu-qcom: Consstently initialize stream mappings

2020-07-08 Thread Bjorn Andersson
Firmware that traps writes to S2CR to translate BYPASS into FAULT also
ignores writes of type FAULT. As such booting with "disable_bypass" set
will result in all S2CR registers left as configured by the bootloader.

This has been seen to result in indeterministic results, as these
mappings might linger and reference context banks that Linux is
reconfiguring.

Use the fact that BYPASS writes result in FAULT type to force all stream
mappings to FAULT.

Signed-off-by: Bjorn Andersson 
---
 drivers/iommu/arm-smmu-qcom.c | 18 +-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/arm-smmu-qcom.c b/drivers/iommu/arm-smmu-qcom.c
index e8a36054e912..86b1917459a4 100644
--- a/drivers/iommu/arm-smmu-qcom.c
+++ b/drivers/iommu/arm-smmu-qcom.c
@@ -27,6 +27,7 @@ static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu)
 {
unsigned int last_s2cr = ARM_SMMU_GR0_S2CR(smmu->num_mapping_groups - 
1);
u32 reg;
+   int i;
 
/*
 * With some firmware writes to S2CR of type FAULT are ignored, and
@@ -37,9 +38,24 @@ static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu)
FIELD_PREP(ARM_SMMU_S2CR_CBNDX, 
0xff) |
FIELD_PREP(ARM_SMMU_S2CR_PRIVCFG, 
S2CR_PRIVCFG_DEFAULT));
reg = arm_smmu_gr0_read(smmu, last_s2cr);
-   if (FIELD_GET(ARM_SMMU_S2CR_TYPE, reg) != S2CR_TYPE_BYPASS)
+   if (FIELD_GET(ARM_SMMU_S2CR_TYPE, reg) != S2CR_TYPE_BYPASS) {
smmu->qcom_bypass_quirk = true;
 
+   /*
+* With firmware ignoring writes of type FAULT, booting the
+* Linux kernel with disable_bypass disabled (i.e. "enable
+* bypass") the initialization during probe will leave mappings
+* in an inconsistent state. Avoid this by configuring all
+* S2CRs to BYPASS.
+*/
+   for (i = 0; i < smmu->num_mapping_groups; i++) {
+   smmu->s2crs[i].type = S2CR_TYPE_BYPASS;
+   smmu->s2crs[i].privcfg = S2CR_PRIVCFG_DEFAULT;
+   smmu->s2crs[i].cbndx = 0xff;
+   smmu->s2crs[i].count = 0;
+   }
+   }
+
return 0;
 }
 
-- 
2.26.2

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 3/5] iommu/arm-smmu: Move SMR and S2CR definitions to header file

2020-07-08 Thread Bjorn Andersson
Expose the SMR and S2CR structs in the header file, to allow platform
specific implementations to populate/initialize the smrs and s2cr
arrays.

Signed-off-by: Bjorn Andersson 
---
 drivers/iommu/arm-smmu.c | 14 --
 drivers/iommu/arm-smmu.h | 15 +++
 2 files changed, 15 insertions(+), 14 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index f33eda3117fa..e2d6c0aaf1ea 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -68,24 +68,10 @@ module_param(disable_bypass, bool, S_IRUGO);
 MODULE_PARM_DESC(disable_bypass,
"Disable bypass streams such that incoming transactions from devices 
that are not attached to an iommu domain will report an abort back to the 
device and will not be allowed to pass through the SMMU.");
 
-struct arm_smmu_s2cr {
-   struct iommu_group  *group;
-   int count;
-   enum arm_smmu_s2cr_type type;
-   enum arm_smmu_s2cr_privcfg  privcfg;
-   u8  cbndx;
-};
-
 #define s2cr_init_val (struct arm_smmu_s2cr){  \
.type = disable_bypass ? S2CR_TYPE_FAULT : S2CR_TYPE_BYPASS,\
 }
 
-struct arm_smmu_smr {
-   u16 mask;
-   u16 id;
-   boolvalid;
-};
-
 struct arm_smmu_cb {
u64 ttbr[2];
u32 tcr[2];
diff --git a/drivers/iommu/arm-smmu.h b/drivers/iommu/arm-smmu.h
index a71d193073e4..bcd160d01c53 100644
--- a/drivers/iommu/arm-smmu.h
+++ b/drivers/iommu/arm-smmu.h
@@ -251,6 +251,21 @@ enum arm_smmu_implementation {
QCOM_SMMUV2,
 };
 
+struct arm_smmu_s2cr {
+   struct iommu_group  *group;
+   int count;
+   enum arm_smmu_s2cr_type type;
+   enum arm_smmu_s2cr_privcfg  privcfg;
+   u8  cbndx;
+};
+
+struct arm_smmu_smr {
+   u16 mask;
+   u16 id;
+   boolvalid;
+   boolpinned;
+};
+
 struct arm_smmu_device {
struct device   *dev;
 
-- 
2.26.2

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


  1   2   >