RE: [PATCH v2 04/10] iommu/arm-smmu: tegra: Detect number of instances at runtime

2021-04-20 Thread Krishna Reddy
>+static const struct arm_smmu_impl nvidia_smmu_single_impl = {
>+   .probe_finalize = nvidia_smmu_probe_finalize,
>+};

nvidia_smmu_probe_finalize is used before it is defined. It is defined in patch 
5.

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


Re: [RESEND v2] iommu/vt-d: Use passthrough mode for the Intel IPUs

2021-04-20 Thread Grant Grundler
On Tue, Apr 20, 2021 at 11:02 AM Sakari Ailus
 wrote:
>
> Hi Bingbu,
>
> Thanks for the patch.
>
> On Tue, Apr 20, 2021 at 10:48:33AM +0800, Bingbu Cao wrote:
> > Intel IPU(Image Processing Unit) has its own (IO)MMU hardware,
> > The IPU driver allocates its own page table that is not mapped
> > via the DMA, and thus the Intel IOMMU driver blocks access giving
> > this error:
>
> The page table should be mapped to the possible IOMMU using the DMA API.

I've made the same "observation": this patch is intentionally enables
using "intel_iommu=on" (IIRC) to strictly enforce "all" DMA
transactions (except the ones we explicitly allow to identity map).

The question is: Is the security of IPU MMU the same as the system
IOMMU for the few devices behind the IPU MMU?

If not, then we (Chrome OS) require child devices to be "mapped"
twice: once in IPU MMU and again in the system IOMMU. I believe
dma_ops can be nested though I can't confidently point at examples
(IDE drivers maybe?)  This adds some latency to each DMA transaction -
decades ago I've measured roughly 5% on Itanium and PA-RISC systems
from HP. Perhaps Intel can measure this penatly on current HW they are
shipping.

If yes, then I think the IPU driver just needs to be consistent about
it's use of DMA API for it's own house keeping: Either use DMA API for
all IPU DMA operations or use it for none. This is the current plan
for Chrome OS (I didn't make this decision and wasn't party to the
discussion).

The IPU driver requires it's child devices to use DMA API and provides
the dma_ops table for those devices - this use of dma_ops is seperate
from IPU page tables and other host memory transactions to manage the
IPU MMU page tables.

CAVEAT: I'm not an expert in IPU driver - I've been reviewing Intel
IPU code for chromium.org inclusion here:
https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/2787723
I have no illusions that I'm going to be an expert after staring at
28k lines of code less than 10h.

> > DMAR: DRHD: handling fault status reg 3
> > DMAR: [DMA Read] Request device [00:05.0] PASID 
> >   fault addr 76406000 [fault reason 06] PTE Read access is not set
> >
> > As IPU is not an external facing device which is not risky, so use
> > IOMMU passthrough mode for Intel IPUs.
>
> I think a factor here is that the page tables aren't accessible by the IPU
> firmware.

Correct. At least not accessible through the system IOMMU. This is why
Intel prefers the IPU to bypass the system IOMMU.

cheers,
grant

>
> >
> > Fixes: 26f5689592e2 ("media: staging/intel-ipu3: mmu: Implement driver")
> > Signed-off-by: Bingbu Cao 
> > ---
> >  drivers/iommu/intel/iommu.c | 29 +
> >  1 file changed, 29 insertions(+)
> >
> > diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
> > index ee0932307d64..7e2fbdae467e 100644
> > --- a/drivers/iommu/intel/iommu.c
> > +++ b/drivers/iommu/intel/iommu.c
> > @@ -55,6 +55,12 @@
> >  #define IS_GFX_DEVICE(pdev) ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY)
> >  #define IS_USB_DEVICE(pdev) ((pdev->class >> 8) == PCI_CLASS_SERIAL_USB)
> >  #define IS_ISA_DEVICE(pdev) ((pdev->class >> 8) == PCI_CLASS_BRIDGE_ISA)
> > +#define IS_INTEL_IPU(pdev) ((pdev)->vendor == PCI_VENDOR_ID_INTEL && \
> > + ((pdev)->device == 0x9a19 ||\
> > +  (pdev)->device == 0x9a39 ||\
> > +  (pdev)->device == 0x4e19 ||\
> > +  (pdev)->device == 0x465d ||\
> > +  (pdev)->device == 0x1919))
> >  #define IS_AZALIA(pdev) ((pdev)->vendor == 0x8086 && (pdev)->device == 
> > 0x3a3e)
> >
> >  #define IOAPIC_RANGE_START   (0xfee0)
> > @@ -360,6 +366,7 @@ int intel_iommu_enabled = 0;
> >  EXPORT_SYMBOL_GPL(intel_iommu_enabled);
> >
> >  static int dmar_map_gfx = 1;
> > +static int dmar_map_ipu = 1;
>
> This works as long as there's only one IPU. Same for graphics. But I guess
> this can be reworked in the future if the presumption changes.
>
> >  static int dmar_forcedac;
> >  static int intel_iommu_strict;
> >  static int intel_iommu_superpage = 1;
> > @@ -368,6 +375,7 @@ static int iommu_skip_te_disable;
> >
> >  #define IDENTMAP_GFX 2
> >  #define IDENTMAP_AZALIA  4
> > +#define IDENTMAP_IPU 8
> >
> >  int intel_iommu_gfx_mapped;
> >  EXPORT_SYMBOL_GPL(intel_iommu_gfx_mapped);
> > @@ -2839,6 +2847,9 @@ static int device_def_domain_type(struct device *dev)
> >
> >   if ((iommu_identity_mapping & IDENTMAP_GFX) && 
> > IS_GFX_DEVICE(pdev))
> >   return IOMMU_DOMAIN_IDENTITY;
> > +
> > + if ((iommu_identity_mapping & IDENTMAP_IPU) && 
> > IS_INTEL_IPU(pdev))
> > + return IOMMU_DOMAIN_IDENTITY;
> >   }
> >
> >   return 0;
> > @@ -3278,6 +3289,9 @@ static int __init init_dmars(void)
> >   if (!dmar_map_gfx)
> > 

[PATCH v2 09/10] arm64: tegra: Enable SMMU support on Tegra194

2021-04-20 Thread Thierry Reding
From: Thierry Reding 

Add the device tree node for the dual-SMMU found on Tegra194 and hook up
peripherals such as host1x, BPMP, HDA, SDMMC, EQOS and VIC.

Signed-off-by: Thierry Reding 
---
 arch/arm64/boot/dts/nvidia/tegra194.dtsi | 86 
 1 file changed, 86 insertions(+)

diff --git a/arch/arm64/boot/dts/nvidia/tegra194.dtsi 
b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
index 4d37ee0ea4d1..6ed296e27158 100644
--- a/arch/arm64/boot/dts/nvidia/tegra194.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
@@ -62,6 +62,7 @@ ethernet@249 {
interconnects = < TEGRA194_MEMORY_CLIENT_EQOSR >,
< TEGRA194_MEMORY_CLIENT_EQOSW >;
interconnect-names = "dma-mem", "write";
+   iommus = < TEGRA194_SID_EQOS>;
status = "disabled";
 
snps,write-requests = <1>;
@@ -733,6 +734,7 @@ sdmmc1: mmc@340 {
interconnects = < TEGRA194_MEMORY_CLIENT_SDMMCRA 
>,
< TEGRA194_MEMORY_CLIENT_SDMMCWA 
>;
interconnect-names = "dma-mem", "write";
+   iommus = < TEGRA194_SID_SDMMC1>;
nvidia,pad-autocal-pull-up-offset-3v3-timeout =
<0x07>;
nvidia,pad-autocal-pull-down-offset-3v3-timeout =
@@ -759,6 +761,7 @@ sdmmc3: mmc@344 {
interconnects = < TEGRA194_MEMORY_CLIENT_SDMMCR 
>,
< TEGRA194_MEMORY_CLIENT_SDMMCW 
>;
interconnect-names = "dma-mem", "write";
+   iommus = < TEGRA194_SID_SDMMC3>;
nvidia,pad-autocal-pull-up-offset-1v8 = <0x00>;
nvidia,pad-autocal-pull-down-offset-1v8 = <0x7a>;
nvidia,pad-autocal-pull-up-offset-3v3-timeout = <0x07>;
@@ -790,6 +793,7 @@ sdmmc4: mmc@346 {
interconnects = < TEGRA194_MEMORY_CLIENT_SDMMCRAB 
>,
< TEGRA194_MEMORY_CLIENT_SDMMCWAB 
>;
interconnect-names = "dma-mem", "write";
+   iommus = < TEGRA194_SID_SDMMC4>;
nvidia,pad-autocal-pull-up-offset-hs400 = <0x00>;
nvidia,pad-autocal-pull-down-offset-hs400 = <0x00>;
nvidia,pad-autocal-pull-up-offset-1v8-timeout = <0x0a>;
@@ -821,6 +825,7 @@ hda@351 {
interconnects = < TEGRA194_MEMORY_CLIENT_HDAR >,
< TEGRA194_MEMORY_CLIENT_HDAW >;
interconnect-names = "dma-mem", "write";
+   iommus = < TEGRA194_SID_HDA>;
status = "disabled";
};
 
@@ -1300,6 +1305,84 @@ pmc: pmc@c36 {
interrupt-controller;
};
 
+   smmu: iommu@1200 {
+   compatible = "nvidia,tegra194-smmu", "nvidia,smmu-500";
+   reg = <0x1200 0x80>,
+ <0x1100 0x80>;
+   interrupts = ,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+ 

[PATCH v2 10/10] arm64: tegra: Enable SMMU support for display on Tegra194

2021-04-20 Thread Thierry Reding
From: Thierry Reding 

The display controllers are attached to a separate ARM SMMU instance
that is dedicated to servicing isochronous memory clients. Add this ISO
instance of the ARM SMMU to device tree and attach all four display
controllers to it.

Signed-off-by: Thierry Reding 
---
 arch/arm64/boot/dts/nvidia/tegra194.dtsi | 80 
 1 file changed, 80 insertions(+)

diff --git a/arch/arm64/boot/dts/nvidia/tegra194.dtsi 
b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
index 6ed296e27158..00f8248f216e 100644
--- a/arch/arm64/boot/dts/nvidia/tegra194.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
@@ -1305,6 +1305,82 @@ pmc: pmc@c36 {
interrupt-controller;
};
 
+   smmu_iso: iommu@1000 {
+   compatible = "nvidia,tegra194-smmu", "nvidia,smmu-500";
+   reg = <0x1000 0x80>;
+   interrupts = ,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+;
+   stream-match-mask = <0x7f80>;
+   #global-interrupts = <1>;
+   #iommu-cells = <1>;
+
+   nvidia,memory-controller = <>;
+   status = "okay";
+   };
+
smmu: iommu@1200 {
compatible = "nvidia,tegra194-smmu", "nvidia,smmu-500";
reg = <0x1200 0x80>,
@@ -1441,6 +1517,7 @@ display@1520 {
interconnects = < 
TEGRA194_MEMORY_CLIENT_NVDISPLAYR >,
< 
TEGRA194_MEMORY_CLIENT_NVDISPLAYR1 >;
interconnect-names = "dma-mem", 
"read-1";
+   iommus = <_iso 
TEGRA194_SID_NVDISPLAY>;
 
nvidia,outputs = <   
>;
nvidia,head = <0>;
@@ -1459,6 +1536,7 @@ display@1521 {
interconnects = < 
TEGRA194_MEMORY_CLIENT_NVDISPLAYR >,
< 
TEGRA194_MEMORY_CLIENT_NVDISPLAYR1 >;
interconnect-names = "dma-mem", 
"read-1";
+   iommus = <_iso 
TEGRA194_SID_NVDISPLAY>;
 
nvidia,outputs = <   
>;
nvidia,head = <1>;
@@ -1477,6 +1555,7 @@ display@1522 {
 

[PATCH v2 08/10] arm64: tegra: Hook up memory controller to SMMU on Tegra186

2021-04-20 Thread Thierry Reding
From: Thierry Reding 

On Tegra186 and later, the memory controller needs to be programmed in
coordination with any of the ARM SMMU instances to configure the stream
ID used for each memory client.

To support this, add a phandle reference to the memory controller to the
SMMU device tree node.

Signed-off-by: Thierry Reding 
---
 arch/arm64/boot/dts/nvidia/tegra186.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/boot/dts/nvidia/tegra186.dtsi 
b/arch/arm64/boot/dts/nvidia/tegra186.dtsi
index a173f40256ae..d02f6bf3e2ca 100644
--- a/arch/arm64/boot/dts/nvidia/tegra186.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra186.dtsi
@@ -1152,6 +1152,8 @@ smmu: iommu@1200 {
stream-match-mask = <0x7f80>;
#global-interrupts = <1>;
#iommu-cells = <1>;
+
+   nvidia,memory-controller = <>;
};
 
host1x@13e0 {
-- 
2.30.2

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


[PATCH v2 07/10] arm64: tegra: Use correct compatible string for Tegra186 SMMU

2021-04-20 Thread Thierry Reding
From: Thierry Reding 

The SMMU found on Tegra186 requires interoperation with the memory
controller in order to program stream ID overrides. The generic ARM SMMU
500 compatible is therefore inaccurate. Replace it with a more correct,
SoC-specific compatible string.

Signed-off-by: Thierry Reding 
---
 arch/arm64/boot/dts/nvidia/tegra186.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/nvidia/tegra186.dtsi 
b/arch/arm64/boot/dts/nvidia/tegra186.dtsi
index 9f75bbf00cf7..a173f40256ae 100644
--- a/arch/arm64/boot/dts/nvidia/tegra186.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra186.dtsi
@@ -1082,7 +1082,7 @@ pci@3,0 {
};
 
smmu: iommu@1200 {
-   compatible = "arm,mmu-500";
+   compatible = "nvidia,tegra186-smmu", "nvidia,smmu-500";
reg = <0 0x1200 0 0x80>;
interrupts = ,
 ,
-- 
2.30.2

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


[PATCH v2 06/10] iommu/arm-smmu: Use Tegra implementation on Tegra186

2021-04-20 Thread Thierry Reding
From: Thierry Reding 

Tegra186 requires the same SID override programming as Tegra194 in order
to seamlessly transition from the firmware framebuffer to the Linux
framebuffer, so the Tegra implementation needs to be used on Tegra186
devices as well.

Signed-off-by: Thierry Reding 
---
 drivers/iommu/arm/arm-smmu/arm-smmu-impl.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c 
b/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c
index 136872e77195..9f465e146799 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c
@@ -211,7 +211,8 @@ struct arm_smmu_device *arm_smmu_impl_init(struct 
arm_smmu_device *smmu)
if (of_property_read_bool(np, "calxeda,smmu-secure-config-access"))
smmu->impl = _impl;
 
-   if (of_device_is_compatible(np, "nvidia,tegra194-smmu"))
+   if (of_device_is_compatible(np, "nvidia,tegra194-smmu") ||
+   of_device_is_compatible(np, "nvidia,tegra186-smmu"))
return nvidia_smmu_impl_init(smmu);
 
smmu = qcom_smmu_impl_init(smmu);
-- 
2.30.2

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


[PATCH v2 05/10] iommu/arm-smmu: tegra: Implement SID override programming

2021-04-20 Thread Thierry Reding
From: Thierry Reding 

The secure firmware keeps some SID override registers set as passthrough
in order to allow devices such as the display controller to operate with
no knowledge of SMMU translations until an operating system driver takes
over. This is needed in order to seamlessly transition from the firmware
framebuffer to the OS framebuffer.

Upon successfully attaching a device to the SMMU and in the process
creating identity mappings for memory regions that are being accessed,
the Tegra implementation will call into the memory controller driver to
program the override SIDs appropriately.

Signed-off-by: Thierry Reding 
---
 drivers/iommu/arm/arm-smmu/arm-smmu-nvidia.c | 32 ++--
 1 file changed, 29 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-nvidia.c 
b/drivers/iommu/arm/arm-smmu/arm-smmu-nvidia.c
index 0e547b29143d..01e9b50b10a1 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu-nvidia.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-nvidia.c
@@ -7,6 +7,8 @@
 #include 
 #include 
 
+#include 
+
 #include "arm-smmu.h"
 
 /*
@@ -15,10 +17,17 @@
  * interleaved IOVA accesses across them and translates accesses from
  * non-isochronous HW devices.
  * Third one is used for translating accesses from isochronous HW devices.
+ *
+ * In addition, the SMMU driver needs to coordinate with the memory controller
+ * driver to ensure that the right SID override is programmed for any given
+ * memory client. This is necessary to allow for use-case such as seamlessly
+ * handing over the display controller configuration from the firmware to the
+ * kernel.
+ *
  * This implementation supports programming of the two instances that must
- * be programmed identically.
- * The third instance usage is through standard arm-smmu driver itself and
- * is out of scope of this implementation.
+ * be programmed identically and takes care of invoking the memory controller
+ * driver for SID override programming after devices have been attached to an
+ * SMMU instance.
  */
 #define MAX_SMMU_INSTANCES 2
 
@@ -26,6 +35,7 @@ struct nvidia_smmu {
struct arm_smmu_device smmu;
void __iomem *bases[MAX_SMMU_INSTANCES];
unsigned int num_instances;
+   struct tegra_mc *mc;
 };
 
 static inline struct nvidia_smmu *to_nvidia_smmu(struct arm_smmu_device *smmu)
@@ -237,6 +247,17 @@ static irqreturn_t nvidia_smmu_context_fault(int irq, void 
*dev)
return ret;
 }
 
+static void nvidia_smmu_probe_finalize(struct arm_smmu_device *smmu, struct 
device *dev)
+{
+   struct nvidia_smmu *nvidia = to_nvidia_smmu(smmu);
+   int err;
+
+   err = tegra_mc_probe_device(nvidia->mc, dev);
+   if (err < 0)
+   dev_err(smmu->dev, "memory controller probe failed for %s: 
%d\n",
+   dev_name(dev), err);
+}
+
 static const struct arm_smmu_impl nvidia_smmu_impl = {
.read_reg = nvidia_smmu_read_reg,
.write_reg = nvidia_smmu_write_reg,
@@ -246,6 +267,7 @@ static const struct arm_smmu_impl nvidia_smmu_impl = {
.tlb_sync = nvidia_smmu_tlb_sync,
.global_fault = nvidia_smmu_global_fault,
.context_fault = nvidia_smmu_context_fault,
+   .probe_finalize = nvidia_smmu_probe_finalize,
 };
 
 static const struct arm_smmu_impl nvidia_smmu_single_impl = {
@@ -264,6 +286,10 @@ struct arm_smmu_device *nvidia_smmu_impl_init(struct 
arm_smmu_device *smmu)
if (!nvidia_smmu)
return ERR_PTR(-ENOMEM);
 
+   nvidia_smmu->mc = devm_tegra_memory_controller_get(dev);
+   if (IS_ERR(nvidia_smmu->mc))
+   return ERR_CAST(nvidia_smmu->mc);
+
/* Instance 0 is ioremapped by arm-smmu.c. */
nvidia_smmu->bases[0] = smmu->base;
nvidia_smmu->num_instances++;
-- 
2.30.2

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


[PATCH v2 04/10] iommu/arm-smmu: tegra: Detect number of instances at runtime

2021-04-20 Thread Thierry Reding
From: Thierry Reding 

Parse the reg property in device tree and detect the number of instances
represented by a device tree node. This is subsequently needed in order
to support single-instance SMMUs with the Tegra implementation because
additional programming is needed to properly configure the SID override
registers in the memory controller.

Signed-off-by: Thierry Reding 
---
Changes in v2:
- provide a separate implementation to simplify single instances
---
 drivers/iommu/arm/arm-smmu/arm-smmu-nvidia.c | 58 ++--
 1 file changed, 42 insertions(+), 16 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-nvidia.c 
b/drivers/iommu/arm/arm-smmu/arm-smmu-nvidia.c
index 29117444e5a0..0e547b29143d 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu-nvidia.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-nvidia.c
@@ -20,13 +20,19 @@
  * The third instance usage is through standard arm-smmu driver itself and
  * is out of scope of this implementation.
  */
-#define NUM_SMMU_INSTANCES 2
+#define MAX_SMMU_INSTANCES 2
 
 struct nvidia_smmu {
-   struct arm_smmu_device  smmu;
-   void __iomem*bases[NUM_SMMU_INSTANCES];
+   struct arm_smmu_device smmu;
+   void __iomem *bases[MAX_SMMU_INSTANCES];
+   unsigned int num_instances;
 };
 
+static inline struct nvidia_smmu *to_nvidia_smmu(struct arm_smmu_device *smmu)
+{
+   return container_of(smmu, struct nvidia_smmu, smmu);
+}
+
 static inline void __iomem *nvidia_smmu_page(struct arm_smmu_device *smmu,
 unsigned int inst, int page)
 {
@@ -47,9 +53,10 @@ static u32 nvidia_smmu_read_reg(struct arm_smmu_device *smmu,
 static void nvidia_smmu_write_reg(struct arm_smmu_device *smmu,
  int page, int offset, u32 val)
 {
+   struct nvidia_smmu *nvidia = to_nvidia_smmu(smmu);
unsigned int i;
 
-   for (i = 0; i < NUM_SMMU_INSTANCES; i++) {
+   for (i = 0; i < nvidia->num_instances; i++) {
void __iomem *reg = nvidia_smmu_page(smmu, i, page) + offset;
 
writel_relaxed(val, reg);
@@ -67,9 +74,10 @@ static u64 nvidia_smmu_read_reg64(struct arm_smmu_device 
*smmu,
 static void nvidia_smmu_write_reg64(struct arm_smmu_device *smmu,
int page, int offset, u64 val)
 {
+   struct nvidia_smmu *nvidia = to_nvidia_smmu(smmu);
unsigned int i;
 
-   for (i = 0; i < NUM_SMMU_INSTANCES; i++) {
+   for (i = 0; i < nvidia->num_instances; i++) {
void __iomem *reg = nvidia_smmu_page(smmu, i, page) + offset;
 
writeq_relaxed(val, reg);
@@ -79,6 +87,7 @@ static void nvidia_smmu_write_reg64(struct arm_smmu_device 
*smmu,
 static void nvidia_smmu_tlb_sync(struct arm_smmu_device *smmu, int page,
 int sync, int status)
 {
+   struct nvidia_smmu *nvidia = to_nvidia_smmu(smmu);
unsigned int delay;
 
arm_smmu_writel(smmu, page, sync, 0);
@@ -90,7 +99,7 @@ static void nvidia_smmu_tlb_sync(struct arm_smmu_device 
*smmu, int page,
u32 val = 0;
unsigned int i;
 
-   for (i = 0; i < NUM_SMMU_INSTANCES; i++) {
+   for (i = 0; i < nvidia->num_instances; i++) {
void __iomem *reg;
 
reg = nvidia_smmu_page(smmu, i, page) + status;
@@ -112,9 +121,10 @@ static void nvidia_smmu_tlb_sync(struct arm_smmu_device 
*smmu, int page,
 
 static int nvidia_smmu_reset(struct arm_smmu_device *smmu)
 {
+   struct nvidia_smmu *nvidia = to_nvidia_smmu(smmu);
unsigned int i;
 
-   for (i = 0; i < NUM_SMMU_INSTANCES; i++) {
+   for (i = 0; i < nvidia->num_instances; i++) {
u32 val;
void __iomem *reg = nvidia_smmu_page(smmu, i, ARM_SMMU_GR0) +
ARM_SMMU_GR0_sGFSR;
@@ -157,8 +167,9 @@ static irqreturn_t nvidia_smmu_global_fault(int irq, void 
*dev)
unsigned int inst;
irqreturn_t ret = IRQ_NONE;
struct arm_smmu_device *smmu = dev;
+   struct nvidia_smmu *nvidia = to_nvidia_smmu(smmu);
 
-   for (inst = 0; inst < NUM_SMMU_INSTANCES; inst++) {
+   for (inst = 0; inst < nvidia->num_instances; inst++) {
irqreturn_t irq_ret;
 
irq_ret = nvidia_smmu_global_fault_inst(irq, smmu, inst);
@@ -202,11 +213,13 @@ static irqreturn_t nvidia_smmu_context_fault(int irq, 
void *dev)
struct arm_smmu_device *smmu;
struct iommu_domain *domain = dev;
struct arm_smmu_domain *smmu_domain;
+   struct nvidia_smmu *nvidia;
 
smmu_domain = container_of(domain, struct arm_smmu_domain, domain);
smmu = smmu_domain->smmu;
+   nvidia = to_nvidia_smmu(smmu);
 
-   for (inst = 0; inst < NUM_SMMU_INSTANCES; inst++) {
+   for (inst = 0; inst < nvidia->num_instances; inst++) {

[PATCH v2 03/10] iommu/arm-smmu: Implement ->probe_finalize()

2021-04-20 Thread Thierry Reding
From: Thierry Reding 

Implement a ->probe_finalize() callback that can be used by vendor
implementations to perform extra programming necessary after devices
have been attached to the SMMU.

Signed-off-by: Thierry Reding 
---
Changes in v2:
-remove unnecessarily paranoid check
---
 drivers/iommu/arm/arm-smmu/arm-smmu.c | 13 +
 drivers/iommu/arm/arm-smmu/arm-smmu.h |  1 +
 2 files changed, 14 insertions(+)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c 
b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index 6f72c4d208ca..d20ce4d57df2 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -1450,6 +1450,18 @@ static void arm_smmu_release_device(struct device *dev)
iommu_fwspec_free(dev);
 }
 
+static void arm_smmu_probe_finalize(struct device *dev)
+{
+   struct arm_smmu_master_cfg *cfg;
+   struct arm_smmu_device *smmu;
+
+   cfg = dev_iommu_priv_get(dev);
+   smmu = cfg->smmu;
+
+   if (smmu->impl->probe_finalize)
+   smmu->impl->probe_finalize(smmu, dev);
+}
+
 static struct iommu_group *arm_smmu_device_group(struct device *dev)
 {
struct arm_smmu_master_cfg *cfg = dev_iommu_priv_get(dev);
@@ -1569,6 +1581,7 @@ static struct iommu_ops arm_smmu_ops = {
.iova_to_phys   = arm_smmu_iova_to_phys,
.probe_device   = arm_smmu_probe_device,
.release_device = arm_smmu_release_device,
+   .probe_finalize = arm_smmu_probe_finalize,
.device_group   = arm_smmu_device_group,
.enable_nesting = arm_smmu_enable_nesting,
.set_pgtable_quirks = arm_smmu_set_pgtable_quirks,
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.h 
b/drivers/iommu/arm/arm-smmu/arm-smmu.h
index c31a59d35c64..147c95e7c59c 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.h
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.h
@@ -439,6 +439,7 @@ struct arm_smmu_impl {
  struct device *dev, int start);
void (*write_s2cr)(struct arm_smmu_device *smmu, int idx);
void (*write_sctlr)(struct arm_smmu_device *smmu, int idx, u32 reg);
+   void (*probe_finalize)(struct arm_smmu_device *smmu, struct device 
*dev);
 };
 
 #define INVALID_SMENDX -1
-- 
2.30.2

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


[PATCH v2 02/10] dt-bindings: arm-smmu: Add Tegra186 compatible string

2021-04-20 Thread Thierry Reding
From: Thierry Reding 

The ARM SMMU instantiations found on Tegra186 and later need inter-
operation with the memory controller in order to correctly program
stream ID overrides.

Furthermore, on Tegra194 multiple instances of the SMMU can gang up
to achieve higher throughput. In order to do this, they have to be
programmed identically so that the memory controller can interleave
memory accesses between them.

Add the Tegra186 compatible string to make sure the interoperation
with the memory controller can be enabled on that SoC generation.

Signed-off-by: Thierry Reding 
---
 Documentation/devicetree/bindings/iommu/arm,smmu.yaml | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml 
b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
index 9d27aa5111d4..1181b590db71 100644
--- a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
+++ b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
@@ -54,8 +54,14 @@ properties:
   - const: arm,mmu-500
   - description: NVIDIA SoCs that program two ARM MMU-500s identically
 items:
+  - description: NVIDIA SoCs that require memory controller interaction
+  and may program multiple ARM MMU-500s identically with the memory
+  controller interleaving translations between multiple instances
+  for improved performance.
+items:
   - enum:
-  - nvidia,tegra194-smmu
+  - const: nvidia,tegra194-smmu
+  - const: nvidia,tegra186-smmu
   - const: nvidia,smmu-500
   - items:
   - const: arm,mmu-500
@@ -165,10 +171,11 @@ allOf:
   contains:
 enum:
   - nvidia,tegra194-smmu
+  - nvidia,tegra186-smmu
 then:
   properties:
 reg:
-  minItems: 2
+  minItems: 1
   maxItems: 2
 else:
   properties:
-- 
2.30.2

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


[PATCH v2 01/10] memory: tegra: Implement SID override programming

2021-04-20 Thread Thierry Reding
From: Thierry Reding 

Instead of programming all SID overrides during early boot, perform the
operation on-demand after the SMMU translations have been set up for a
device. This reuses data from device tree to match memory clients for a
device and programs the SID specified in device tree, which corresponds
to the SID used for the SMMU context banks for the device.

Signed-off-by: Thierry Reding 
---
 drivers/memory/tegra/mc.c   |  9 +
 drivers/memory/tegra/tegra186.c | 72 +
 include/soc/tegra/mc.h  |  3 ++
 3 files changed, 84 insertions(+)

diff --git a/drivers/memory/tegra/mc.c b/drivers/memory/tegra/mc.c
index c854639cf30c..bace5ecfe770 100644
--- a/drivers/memory/tegra/mc.c
+++ b/drivers/memory/tegra/mc.c
@@ -97,6 +97,15 @@ struct tegra_mc *devm_tegra_memory_controller_get(struct 
device *dev)
 }
 EXPORT_SYMBOL_GPL(devm_tegra_memory_controller_get);
 
+int tegra_mc_probe_device(struct tegra_mc *mc, struct device *dev)
+{
+   if (mc->soc->ops && mc->soc->ops->probe_device)
+   return mc->soc->ops->probe_device(mc, dev);
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(tegra_mc_probe_device);
+
 static int tegra_mc_block_dma_common(struct tegra_mc *mc,
 const struct tegra_mc_reset *rst)
 {
diff --git a/drivers/memory/tegra/tegra186.c b/drivers/memory/tegra/tegra186.c
index 1f87915ccd62..e65eac5764d4 100644
--- a/drivers/memory/tegra/tegra186.c
+++ b/drivers/memory/tegra/tegra186.c
@@ -4,6 +4,7 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -15,6 +16,10 @@
 #include 
 #endif
 
+#define MC_SID_STREAMID_OVERRIDE_MASK GENMASK(7, 0)
+#define MC_SID_STREAMID_SECURITY_WRITE_ACCESS_DISABLED BIT(16)
+#define MC_SID_STREAMID_SECURITY_OVERRIDE BIT(8)
+
 static void tegra186_mc_program_sid(struct tegra_mc *mc)
 {
unsigned int i;
@@ -66,10 +71,77 @@ static int tegra186_mc_resume(struct tegra_mc *mc)
return 0;
 }
 
+static void tegra186_mc_client_sid_override(struct tegra_mc *mc,
+   const struct tegra_mc_client 
*client,
+   unsigned int sid)
+{
+   u32 value, old;
+
+   value = readl(mc->regs + client->regs.sid.security);
+   if ((value & MC_SID_STREAMID_SECURITY_OVERRIDE) == 0) {
+   /*
+* If the secure firmware has locked this down the override
+* for this memory client, there's nothing we can do here.
+*/
+   if (value & MC_SID_STREAMID_SECURITY_WRITE_ACCESS_DISABLED)
+   return;
+
+   /*
+* Otherwise, try to set the override itself. Typically the
+* secure firmware will never have set this configuration.
+* Instead, it will either have disabled write access to
+* this field, or it will already have set an explicit
+* override itself.
+*/
+   WARN_ON((value & MC_SID_STREAMID_SECURITY_OVERRIDE) == 0);
+
+   value |= MC_SID_STREAMID_SECURITY_OVERRIDE;
+   writel(value, mc->regs + client->regs.sid.security);
+   }
+
+   value = readl(mc->regs + client->regs.sid.override);
+   old = value & MC_SID_STREAMID_OVERRIDE_MASK;
+
+   if (old != sid) {
+   dev_dbg(mc->dev, "overriding SID %x for %s with %x\n", old,
+   client->name, sid);
+   writel(sid, mc->regs + client->regs.sid.override);
+   }
+}
+
+static int tegra186_mc_probe_device(struct tegra_mc *mc, struct device *dev)
+{
+#if IS_ENABLED(CONFIG_IOMMU_API)
+   struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+   struct of_phandle_args args;
+   unsigned int i, index = 0;
+
+   while (!of_parse_phandle_with_args(dev->of_node, "interconnects", 
"#interconnect-cells",
+  index, )) {
+   if (args.np == mc->dev->of_node && args.args_count != 0) {
+   for (i = 0; i < mc->soc->num_clients; i++) {
+   const struct tegra_mc_client *client = 
>soc->clients[i];
+
+   if (client->id == args.args[0]) {
+   u32 sid = fwspec->ids[0] & 
MC_SID_STREAMID_OVERRIDE_MASK;
+
+   tegra186_mc_client_sid_override(mc, 
client, sid);
+   }
+   }
+   }
+
+   index++;
+   }
+#endif
+
+   return 0;
+}
+
 const struct tegra_mc_ops tegra186_mc_ops = {
.probe = tegra186_mc_probe,
.remove = tegra186_mc_remove,
.resume = tegra186_mc_resume,
+   .probe_device = tegra186_mc_probe_device,
 };
 
 #if defined(CONFIG_ARCH_TEGRA_186_SOC)
diff --git a/include/soc/tegra/mc.h b/include/soc/tegra/mc.h
index 1387747d574b..bbad6330008b 100644
--- a/include/soc/tegra/mc.h

[PATCH v2 00/10] arm64: tegra: Prevent early SMMU faults

2021-04-20 Thread Thierry Reding
From: Thierry Reding 

Hi,

this is a set of patches that is the result of earlier discussions
regarding early identity mappings that are needed to avoid SMMU faults
during early boot.

The goal here is to avoid early identity mappings altogether and instead
postpone the need for the identity mappings to when devices are attached
to the SMMU. This works by making the SMMU driver coordinate with the
memory controller driver on when to start enforcing SMMU translations.
This makes Tegra behave in a more standard way and pushes the code to
deal with the Tegra-specific programming into the NVIDIA SMMU
implementation.

Compared to the original version of these patches, I've split the
preparatory work into a separate patch series because it became very
large and will be mostly uninteresting for this audience.

Patch 1 provides a mechanism to program SID overrides at runtime. Patch
2 updates the ARM SMMU device tree bindings to include the Tegra186
compatible string as suggested by Robin during review.

Patches 3 and 4 create the fundamentals in the SMMU driver to support
this and also make this functionality available on Tegra186. Patch 5
hooks the ARM SMMU up to the memory controller so that the memory client
stream ID overrides can be programmed at the right time.

Patch 6 extends this mechanism to Tegra186 and patches 7-9 enable all of
this through device tree updates. Patch 10 is included here to show how
SMMU will be enabled for display controllers. However, it cannot be
applied yet because the code to create identity mappings for potentially
live framebuffers hasn't been merged yet.

The end result is that various peripherals will have SMMU enabled, while
the display controllers will keep using passthrough, as initially set up
by firmware. Once the device tree bindings have been accepted and the
SMMU driver has been updated to create identity mappings for the display
controllers, they can be hooked up to the SMMU and the code in this
series will automatically program the SID overrides to enable SMMU
translations at the right time.

Note that the series creates a compile time dependency between the
memory controller and IOMMU trees. If it helps I can provide a branch
for each tree, modelling the dependency, once the series has been
reviewed.

Changes in v2:
- split off the preparatory work into a separate series (that needs to
  be applied first)
- address review comments by Robin

Thierry

Thierry Reding (10):
  memory: tegra: Implement SID override programming
  dt-bindings: arm-smmu: Add Tegra186 compatible string
  iommu/arm-smmu: Implement ->probe_finalize()
  iommu/arm-smmu: tegra: Detect number of instances at runtime
  iommu/arm-smmu: tegra: Implement SID override programming
  iommu/arm-smmu: Use Tegra implementation on Tegra186
  arm64: tegra: Use correct compatible string for Tegra186 SMMU
  arm64: tegra: Hook up memory controller to SMMU on Tegra186
  arm64: tegra: Enable SMMU support on Tegra194
  arm64: tegra: Enable SMMU support for display on Tegra194

 .../devicetree/bindings/iommu/arm,smmu.yaml   |  11 +-
 arch/arm64/boot/dts/nvidia/tegra186.dtsi  |   4 +-
 arch/arm64/boot/dts/nvidia/tegra194.dtsi  | 166 ++
 drivers/iommu/arm/arm-smmu/arm-smmu-impl.c|   3 +-
 drivers/iommu/arm/arm-smmu/arm-smmu-nvidia.c  |  90 --
 drivers/iommu/arm/arm-smmu/arm-smmu.c |  13 ++
 drivers/iommu/arm/arm-smmu/arm-smmu.h |   1 +
 drivers/memory/tegra/mc.c |   9 +
 drivers/memory/tegra/tegra186.c   |  72 
 include/soc/tegra/mc.h|   3 +
 10 files changed, 349 insertions(+), 23 deletions(-)

-- 
2.30.2

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


Re: [PATCH] pci: Rename pci_dev->untrusted to pci_dev->external

2021-04-20 Thread Bjorn Helgaas
On Tue, Apr 20, 2021 at 07:10:06AM +0100, Christoph Hellwig wrote:
> On Mon, Apr 19, 2021 at 05:30:49PM -0700, Rajat Jain wrote:
> > The current flag name "untrusted" is not correct as it is populated
> > using the firmware property "external-facing" for the parent ports. In
> > other words, the firmware only says which ports are external facing, so
> > the field really identifies the devices as external (vs internal).
> > 
> > Only field renaming. No functional change intended.
> 
> I don't think this is a good idea.  First the field should have been
> added to the generic struct device as requested multiple times before.

Fair point.  There isn't anything PCI-specific about this idea.  The
ACPI "ExternalFacingPort" and DT "external-facing" are currently only
defined for PCI devices, but could be applied elsewhere.

> Right now this requires horrible hacks in the IOMMU code to get at the
> pci_dev, and also doesn't scale to various other potential users.

Agreed, this is definitely suboptimal.  Do you have other users in
mind?  Maybe they could help inform the plan.

> Second the untrusted is objectively a better name.  Because untrusted
> is how we treat the device, which is what mattes.  External is just
> how we come to that conclusion.

The decision to treat "external" as being "untrusted" is a little bit
of policy that the PCI core really doesn't care about, so I think it
does make some sense to let the places that *do* care decide what to
trust based on "external" and possibly other factors, e.g., whether
the device is a BMC or processes untrusted data, etc.

But I guess it makes sense to wait until we have a better motivation
before renaming it, since we don't gain any functionality here.

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


Re: [RESEND v2] iommu/vt-d: Use passthrough mode for the Intel IPUs

2021-04-20 Thread Andy Shevchenko
On Tue, Apr 20, 2021 at 05:37:27PM +0300, Sakari Ailus wrote:
> On Tue, Apr 20, 2021 at 02:55:33PM +0300, Andy Shevchenko wrote:
> > On Tue, Apr 20, 2021 at 01:56:40PM +0300, Sakari Ailus wrote:
> > > On Tue, Apr 20, 2021 at 06:34:26PM +0800, Bingbu Cao wrote:
> > > > On 4/20/21 6:20 PM, Andy Shevchenko wrote:
> > > > > On Tue, Apr 20, 2021 at 10:48:33AM +0800, Bingbu Cao wrote:
> > 
> > ...
> > 
> > > > > This misses the changelog from v1 followed by the explanation why 
> > > > > resent.
> > > > > 
> > > > I noticed there was a typo in the recipient list:
> > > > stable.vger.kernel.org -> sta...@vger.kernel.org
> > > > 
> > > > no code change for resent.
> > > 
> > > When you're submitting a patch and want it reach the stable kernels, 
> > > you'll
> > > need to add a Cc tag:
> > > 
> > >   Cc: sta...@vger.kernel.org
> > > 
> > > But not actually add the address to cc. I dropped stable@vger address from
> > > distribution.
> > 
> > Does it really matter?
> 
> Usually aligning what you're doing with
> Documentation/process/submitting-patches.rst is not a bad idea.

True, my point is that technically both ways will give the same result, no?

-- 
With Best Regards,
Andy Shevchenko


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


Re: [RESEND v2] iommu/vt-d: Use passthrough mode for the Intel IPUs

2021-04-20 Thread Sakari Ailus
On Tue, Apr 20, 2021 at 02:55:33PM +0300, Andy Shevchenko wrote:
> On Tue, Apr 20, 2021 at 01:56:40PM +0300, Sakari Ailus wrote:
> > On Tue, Apr 20, 2021 at 06:34:26PM +0800, Bingbu Cao wrote:
> > > On 4/20/21 6:20 PM, Andy Shevchenko wrote:
> > > > On Tue, Apr 20, 2021 at 10:48:33AM +0800, Bingbu Cao wrote:
> 
> ...
> 
> > > > This misses the changelog from v1 followed by the explanation why 
> > > > resent.
> > > > 
> > > I noticed there was a typo in the recipient list:
> > > stable.vger.kernel.org -> sta...@vger.kernel.org
> > > 
> > > no code change for resent.
> > 
> > When you're submitting a patch and want it reach the stable kernels, you'll
> > need to add a Cc tag:
> > 
> > Cc: sta...@vger.kernel.org
> > 
> > But not actually add the address to cc. I dropped stable@vger address from
> > distribution.
> 
> Does it really matter?

Usually aligning what you're doing with
Documentation/process/submitting-patches.rst is not a bad idea.

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


Re: [PATCH v3 10/10] iommu/arm-smmu: Reserve any RMR regions associated with a dev

2021-04-20 Thread kernel test robot
Hi Shameer,

I love your patch! Yet something to improve:

[auto build test ERROR on pm/linux-next]
[also build test ERROR on arm/for-next soc/for-next arm64/for-next/core 
linus/master v5.12-rc8]
[cannot apply to iommu/next xlnx/master next-20210420]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:
https://github.com/0day-ci/linux/commits/Shameer-Kolothum/ACPI-IORT-Support-for-IORT-RMR-node/20210420-173125
base:   https://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git 
linux-next
config: arm-randconfig-r023-20210420 (attached as .config)
compiler: clang version 13.0.0 (https://github.com/llvm/llvm-project 
ca8eef7e3da8f750d7c7aa004fe426d1d34787ea)
reproduce (this is a W=1 build):
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# install arm cross compiling tool for clang build
# apt-get install binutils-arm-linux-gnueabi
# 
https://github.com/0day-ci/linux/commit/ea2019c2969e4e8f6ec2b0dc2d492f0d05f36cd9
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review 
Shameer-Kolothum/ACPI-IORT-Support-for-IORT-RMR-node/20210420-173125
git checkout ea2019c2969e4e8f6ec2b0dc2d492f0d05f36cd9
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 ARCH=arm 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot 

All errors (new ones prefixed by >>):

   In file included from drivers/iommu/arm/arm-smmu/arm-smmu.c:24:
   include/linux/dma-iommu.h:94:71: warning: declaration of 'struct iommu_rmr' 
will not be visible outside of this function [-Wvisibility]
   static void iommu_dma_get_rmr_resv_regions(struct device *dev, struct 
iommu_rmr *rmr,
 ^
   include/linux/dma-iommu.h:100:1: error: expected identifier or '('
   {
   ^
>> drivers/iommu/arm/arm-smmu/arm-smmu.c:1622:39: error: incompatible pointer 
>> types passing 'struct iommu_rmr *' to parameter of type 'struct iommu_rmr *' 
>> [-Werror,-Wincompatible-pointer-types]
   iommu_dma_get_rmr_resv_regions(dev, rmr, head);
   ^~~
   include/linux/dma-iommu.h:94:82: note: passing argument to parameter 'rmr' 
here
   static void iommu_dma_get_rmr_resv_regions(struct device *dev, struct 
iommu_rmr *rmr,

^
   1 warning and 2 errors generated.


vim +1622 drivers/iommu/arm/arm-smmu/arm-smmu.c

  1609  
  1610  static void arm_smmu_rmr_get_resv_regions(struct device *dev,
  1611struct list_head *head)
  1612  {
  1613  struct arm_smmu_master_cfg *cfg = dev_iommu_priv_get(dev);
  1614  struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
  1615  struct arm_smmu_device *smmu = cfg->smmu;
  1616  struct iommu_rmr *rmr;
  1617  
  1618  list_for_each_entry(rmr, >rmr_list, list) {
  1619  if (!arm_smmu_dev_has_rmr(cfg, fwspec, rmr))
  1620  continue;
  1621  
> 1622  iommu_dma_get_rmr_resv_regions(dev, rmr, head);
  1623  }
  1624  }
  1625  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org


.config.gz
Description: application/gzip
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

Re: swiotlb cleanups v3

2021-04-20 Thread Tom Lendacky
On 4/20/21 4:23 AM, Christoph Hellwig wrote:
> On Sat, Apr 17, 2021 at 11:39:22AM -0500, Tom Lendacky wrote:
>> Somewhere between the 1st and 2nd patch, specifying a specific swiotlb
>> for an SEV guest is no longer honored. For example, if I start an SEV
>> guest with 16GB of memory and specify swiotlb=131072 I used to get a
>> 256MB SWIOTLB. However, after the 2nd patch, the swiotlb=131072 is no
>> longer honored and I get a 982MB SWIOTLB (as set via sev_setup_arch() in
>> arch/x86/mm/mem_encrypt.c).
>>
>> I can't be sure which patch caused the issue since an SEV guest fails to
>> boot with the 1st patch but can boot with the 2nd patch, at which point
>> the SWIOTLB comes in at 982MB (I haven't had a chance to debug it and so
>> I'm hoping you might be able to quickly spot what's going on).
> 
> Can you try this patch?

Thanks, Christoph. This works for honoring the command line value with SEV
guests.

There was still a reference to default_nslabs in setup_io_tlb_npages()
that I'm not sure how you want to handle. I just commented it out for now
to let the code compile to test the intent of the patch.

Thanks,
Tom

> 
> diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c
> index 0a5b6f7e75bce6..ac81ef97df32f5 100644
> --- a/kernel/dma/swiotlb.c
> +++ b/kernel/dma/swiotlb.c
> @@ -71,15 +71,17 @@ struct io_tlb_mem *io_tlb_default_mem;
>   */
>  static unsigned int max_segment;
>  
> -static unsigned long default_nslabs = IO_TLB_DEFAULT_SIZE >> IO_TLB_SHIFT;
> +static unsigned long swiotlb_cmdline_size;
>  
>  static int __init
>  setup_io_tlb_npages(char *str)
>  {
>   if (isdigit(*str)) {
>   /* avoid tail segment of size < IO_TLB_SEGSIZE */
> - default_nslabs =
> - ALIGN(simple_strtoul(str, , 0), IO_TLB_SEGSIZE);
> + unsigned long nslabs = simple_strtoul(str, , 0);
> +
> + swiotlb_cmdline_size =
> + ALIGN(nslabs, IO_TLB_SEGSIZE) << IO_TLB_SHIFT;
>   }
>   if (*str == ',')
>   ++str;
> @@ -108,7 +110,9 @@ void swiotlb_set_max_segment(unsigned int val)
>  
>  unsigned long swiotlb_size_or_default(void)
>  {
> - return default_nslabs << IO_TLB_SHIFT;
> + if (swiotlb_cmdline_size)
> + return swiotlb_cmdline_size;
> + return IO_TLB_DEFAULT_SIZE;
>  }
>  
>  void __init swiotlb_adjust_size(unsigned long size)
> @@ -118,9 +122,10 @@ void __init swiotlb_adjust_size(unsigned long size)
>* architectures such as those supporting memory encryption to
>* adjust/expand SWIOTLB size for their use.
>*/
> - size = ALIGN(size, IO_TLB_SIZE);
> - default_nslabs = ALIGN(size >> IO_TLB_SHIFT, IO_TLB_SEGSIZE);
> - pr_info("SWIOTLB bounce buffer size adjusted to %luMB", size >> 20);
> + if (!swiotlb_cmdline_size)
> + swiotlb_cmdline_size = ALIGN(size, IO_TLB_SIZE);
> + pr_info("SWIOTLB bounce buffer size adjusted to %luMB",
> + swiotlb_cmdline_size >> 20);
>  }
>  
>  void swiotlb_print_info(void)
> @@ -209,7 +214,7 @@ int __init swiotlb_init_with_tbl(char *tlb, unsigned long 
> nslabs, int verbose)
>  void  __init
>  swiotlb_init(int verbose)
>  {
> - size_t bytes = PAGE_ALIGN(default_nslabs << IO_TLB_SHIFT);
> + size_t bytes = PAGE_ALIGN(swiotlb_size_or_default());
>   void *tlb;
>  
>   if (swiotlb_force == SWIOTLB_NO_FORCE)
> @@ -219,7 +224,7 @@ swiotlb_init(int verbose)
>   tlb = memblock_alloc_low(bytes, PAGE_SIZE);
>   if (!tlb)
>   goto fail;
> - if (swiotlb_init_with_tbl(tlb, default_nslabs, verbose))
> + if (swiotlb_init_with_tbl(tlb, bytes >> IO_TLB_SHIFT, verbose))
>   goto fail_free_mem;
>   return;
>  
> 
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v3 02/10] iommu/dma: Introduce generic helper to retrieve RMR info

2021-04-20 Thread kernel test robot
Hi Shameer,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on pm/linux-next]
[also build test WARNING on arm/for-next soc/for-next arm64/for-next/core 
linus/master v5.12-rc8]
[cannot apply to iommu/next xlnx/master next-20210420]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:
https://github.com/0day-ci/linux/commits/Shameer-Kolothum/ACPI-IORT-Support-for-IORT-RMR-node/20210420-173125
base:   https://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git 
linux-next
config: x86_64-randconfig-a002-20210420 (attached as .config)
compiler: clang version 13.0.0 (https://github.com/llvm/llvm-project 
ca8eef7e3da8f750d7c7aa004fe426d1d34787ea)
reproduce (this is a W=1 build):
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# install x86_64 cross compiling tool for clang build
# apt-get install binutils-x86-64-linux-gnu
# 
https://github.com/0day-ci/linux/commit/c68d4ba37ecc2173a2dc418799e23a184685d681
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review 
Shameer-Kolothum/ACPI-IORT-Support-for-IORT-RMR-node/20210420-173125
git checkout c68d4ba37ecc2173a2dc418799e23a184685d681
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 
ARCH=x86_64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot 

All warnings (new ones prefixed by >>):

   In file included from drivers/iommu/arm/arm-smmu/qcom_iommu.c:13:
>> include/linux/dma-iommu.h:92:31: warning: declaration of 'struct 
>> fwnode_handle' will not be visible outside of this function [-Wvisibility]
   int iommu_dma_get_rmrs(struct fwnode_handle *iommu, struct list_head *list);
 ^
   include/linux/dma-iommu.h:93:1: error: expected identifier or '('
   {
   ^
   1 warning and 1 error generated.


vim +92 include/linux/dma-iommu.h

91  
  > 92  int iommu_dma_get_rmrs(struct fwnode_handle *iommu, struct list_head 
*list);
93  {
94  return 0;
95  }
96  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org


.config.gz
Description: application/gzip
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

Re: [PATCH v3 02/10] iommu/dma: Introduce generic helper to retrieve RMR info

2021-04-20 Thread kernel test robot
Hi Shameer,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on pm/linux-next]
[also build test ERROR on arm/for-next soc/for-next arm64/for-next/core 
linus/master v5.12-rc8]
[cannot apply to iommu/next xlnx/master next-20210420]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:
https://github.com/0day-ci/linux/commits/Shameer-Kolothum/ACPI-IORT-Support-for-IORT-RMR-node/20210420-173125
base:   https://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git 
linux-next
config: arm-randconfig-r023-20210420 (attached as .config)
compiler: clang version 13.0.0 (https://github.com/llvm/llvm-project 
ca8eef7e3da8f750d7c7aa004fe426d1d34787ea)
reproduce (this is a W=1 build):
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# install arm cross compiling tool for clang build
# apt-get install binutils-arm-linux-gnueabi
# 
https://github.com/0day-ci/linux/commit/c68d4ba37ecc2173a2dc418799e23a184685d681
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review 
Shameer-Kolothum/ACPI-IORT-Support-for-IORT-RMR-node/20210420-173125
git checkout c68d4ba37ecc2173a2dc418799e23a184685d681
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 ARCH=arm 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot 

All errors (new ones prefixed by >>):

   In file included from drivers/iommu/arm/arm-smmu/arm-smmu.c:24:
>> include/linux/dma-iommu.h:93:1: error: expected identifier or '('
   {
   ^
   1 error generated.


vim +93 include/linux/dma-iommu.h

91  
92  int iommu_dma_get_rmrs(struct fwnode_handle *iommu, struct list_head 
*list);
  > 93  {
94  return 0;
95  }
96  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org


.config.gz
Description: application/gzip
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

Re: [PATCH v3 04/10] iommu/dma: Add a helper function to reserve RMRs for IOMMU drivers

2021-04-20 Thread kernel test robot
Hi Shameer,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on pm/linux-next]
[also build test WARNING on arm/for-next soc/for-next arm64/for-next/core 
linus/master v5.12-rc8]
[cannot apply to iommu/next xlnx/master next-20210420]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:
https://github.com/0day-ci/linux/commits/Shameer-Kolothum/ACPI-IORT-Support-for-IORT-RMR-node/20210420-173125
base:   https://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git 
linux-next
config: m68k-randconfig-m031-20210420 (attached as .config)
compiler: m68k-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# 
https://github.com/0day-ci/linux/commit/2501962e423895e2e4f126ff5998b226f4803186
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review 
Shameer-Kolothum/ACPI-IORT-Support-for-IORT-RMR-node/20210420-173125
git checkout 2501962e423895e2e4f126ff5998b226f4803186
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross W=1 
ARCH=m68k 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot 

All warnings (new ones prefixed by >>):

   In file included from drivers/iommu/rockchip-iommu.c:13:
>> include/linux/dma-iommu.h:94:71: warning: 'struct iommu_rmr' declared inside 
>> parameter list will not be visible outside of this definition or declaration
  94 | static void iommu_dma_get_rmr_resv_regions(struct device *dev, 
struct iommu_rmr *rmr,
 |  
 ^
   include/linux/dma-iommu.h:100:1: error: expected identifier or '(' before 
'{' token
 100 | {
 | ^
   In file included from drivers/iommu/rockchip-iommu.c:13:
   include/linux/dma-iommu.h:94:13: warning: 'iommu_dma_get_rmr_resv_regions' 
defined but not used [-Wunused-function]
  94 | static void iommu_dma_get_rmr_resv_regions(struct device *dev, 
struct iommu_rmr *rmr,
 | ^~

Kconfig warnings: (for reference only)
   WARNING: unmet direct dependencies detected for ADI_AXI_ADC
   Depends on IIO && HAS_IOMEM && OF
   Selected by
   - AD9467 && IIO && SPI


vim +94 include/linux/dma-iommu.h

93  
  > 94  static void iommu_dma_get_rmr_resv_regions(struct device *dev, struct 
iommu_rmr *rmr,
95 struct list_head *list)
96  {
97  }
98  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org


.config.gz
Description: application/gzip
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

Re: [PATCH v3 02/10] iommu/dma: Introduce generic helper to retrieve RMR info

2021-04-20 Thread kernel test robot
Hi Shameer,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on pm/linux-next]
[also build test WARNING on arm/for-next soc/for-next arm64/for-next/core 
linus/master v5.12-rc8]
[cannot apply to iommu/next xlnx/master next-20210420]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:
https://github.com/0day-ci/linux/commits/Shameer-Kolothum/ACPI-IORT-Support-for-IORT-RMR-node/20210420-173125
base:   https://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git 
linux-next
config: arc-allyesconfig (attached as .config)
compiler: arceb-elf-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# 
https://github.com/0day-ci/linux/commit/c68d4ba37ecc2173a2dc418799e23a184685d681
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review 
Shameer-Kolothum/ACPI-IORT-Support-for-IORT-RMR-node/20210420-173125
git checkout c68d4ba37ecc2173a2dc418799e23a184685d681
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross W=1 
ARCH=arc 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot 

All warnings (new ones prefixed by >>):

   In file included from drivers/gpu/drm/exynos/exynos_drm_dma.c:7:
>> include/linux/dma-iommu.h:92:31: warning: 'struct fwnode_handle' declared 
>> inside parameter list will not be visible outside of this definition or 
>> declaration
  92 | int iommu_dma_get_rmrs(struct fwnode_handle *iommu, struct list_head 
*list);
 |   ^
   include/linux/dma-iommu.h:93:1: error: expected identifier or '(' before '{' 
token
  93 | {
 | ^


vim +92 include/linux/dma-iommu.h

91  
  > 92  int iommu_dma_get_rmrs(struct fwnode_handle *iommu, struct list_head 
*list);
93  {
94  return 0;
95  }
96  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org


.config.gz
Description: application/gzip
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

Re: [RFC v1 PATCH 1/3] drivers: soc: add support for soc_device_match returning -EPROBE_DEFER

2021-04-20 Thread Dan Carpenter
On Mon, Apr 19, 2021 at 10:20:13AM +0200, Geert Uytterhoeven wrote:
> Hi Alice,
> 
> CC Arnd (soc_device_match() author)
> 
> On Mon, Apr 19, 2021 at 6:28 AM Alice Guo (OSS)  wrote:
> > From: Alice Guo 
> >
> > In i.MX8M boards, the registration of SoC device is later than caam
> > driver which needs it. Caam driver needs soc_device_match to provide
> > -EPROBE_DEFER when no SoC device is registered and no
> > early_soc_dev_attr.
> 
> I'm wondering if this is really a good idea: soc_device_match() is a
> last-resort low-level check, and IMHO should be made available early on,
> so there is no need for -EPROBE_DEFER.
> 
> >
> > Signed-off-by: Alice Guo 
> 
> Thanks for your patch!
> 
> > --- a/drivers/base/soc.c
> > +++ b/drivers/base/soc.c
> > @@ -110,6 +110,7 @@ static void soc_release(struct device *dev)
> >  }
> >
> >  static struct soc_device_attribute *early_soc_dev_attr;
> > +static bool soc_dev_attr_init_done = false;
> 
> Do you need this variable?
> 
> >
> >  struct soc_device *soc_device_register(struct soc_device_attribute 
> > *soc_dev_attr)
> >  {
> > @@ -157,6 +158,7 @@ struct soc_device *soc_device_register(struct 
> > soc_device_attribute *soc_dev_attr
> > return ERR_PTR(ret);
> > }
> >
> > +   soc_dev_attr_init_done = true;
> > return soc_dev;
> >
> >  out3:
> > @@ -246,6 +248,9 @@ const struct soc_device_attribute *soc_device_match(
> > if (!matches)
> > return NULL;
> >
> > +   if (!soc_dev_attr_init_done && !early_soc_dev_attr)
> 
> if (!soc_bus_type.p && !early_soc_dev_attr)

There is one place checking this already.  We could wrap it in a helper
function:

static bool device_init_done(void)
{
return soc_bus_type.p ? true : false;
}

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


Re: [RESEND v2] iommu/vt-d: Use passthrough mode for the Intel IPUs

2021-04-20 Thread Andy Shevchenko
On Tue, Apr 20, 2021 at 01:56:40PM +0300, Sakari Ailus wrote:
> On Tue, Apr 20, 2021 at 06:34:26PM +0800, Bingbu Cao wrote:
> > On 4/20/21 6:20 PM, Andy Shevchenko wrote:
> > > On Tue, Apr 20, 2021 at 10:48:33AM +0800, Bingbu Cao wrote:

...

> > > This misses the changelog from v1 followed by the explanation why resent.
> > > 
> > I noticed there was a typo in the recipient list:
> > stable.vger.kernel.org -> sta...@vger.kernel.org
> > 
> > no code change for resent.
> 
> When you're submitting a patch and want it reach the stable kernels, you'll
> need to add a Cc tag:
> 
>   Cc: sta...@vger.kernel.org
> 
> But not actually add the address to cc. I dropped stable@vger address from
> distribution.

Does it really matter?

-- 
With Best Regards,
Andy Shevchenko


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


Re: [RESEND v2] iommu/vt-d: Use passthrough mode for the Intel IPUs

2021-04-20 Thread Bingbu Cao
Andy,

On 4/20/21 6:20 PM, Andy Shevchenko wrote:
> On Tue, Apr 20, 2021 at 10:48:33AM +0800, Bingbu Cao wrote:
>> Intel IPU(Image Processing Unit) has its own (IO)MMU hardware,
>> The IPU driver allocates its own page table that is not mapped
>> via the DMA, and thus the Intel IOMMU driver blocks access giving
>> this error:
>>
>> DMAR: DRHD: handling fault status reg 3
>> DMAR: [DMA Read] Request device [00:05.0] PASID 
>>   fault addr 76406000 [fault reason 06] PTE Read access is not set
>>
>> As IPU is not an external facing device which is not risky, so use
>> IOMMU passthrough mode for Intel IPUs.
>>
>> Fixes: 26f5689592e2 ("media: staging/intel-ipu3: mmu: Implement driver")
>> Signed-off-by: Bingbu Cao 
>> ---
>>  drivers/iommu/intel/iommu.c | 29 +
> 
> This misses the changelog from v1 followed by the explanation why resent.
> 
I noticed there was a typo in the recipient list:
stable.vger.kernel.org -> sta...@vger.kernel.org

no code change for resent.

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


Re: [RESEND v2] iommu/vt-d: Use passthrough mode for the Intel IPUs

2021-04-20 Thread Sakari Ailus
Hi Bingbu,

On Tue, Apr 20, 2021 at 06:34:26PM +0800, Bingbu Cao wrote:
> Andy,
> 
> On 4/20/21 6:20 PM, Andy Shevchenko wrote:
> > On Tue, Apr 20, 2021 at 10:48:33AM +0800, Bingbu Cao wrote:
> >> Intel IPU(Image Processing Unit) has its own (IO)MMU hardware,
> >> The IPU driver allocates its own page table that is not mapped
> >> via the DMA, and thus the Intel IOMMU driver blocks access giving
> >> this error:
> >>
> >> DMAR: DRHD: handling fault status reg 3
> >> DMAR: [DMA Read] Request device [00:05.0] PASID 
> >>   fault addr 76406000 [fault reason 06] PTE Read access is not set
> >>
> >> As IPU is not an external facing device which is not risky, so use
> >> IOMMU passthrough mode for Intel IPUs.
> >>
> >> Fixes: 26f5689592e2 ("media: staging/intel-ipu3: mmu: Implement driver")
> >> Signed-off-by: Bingbu Cao 
> >> ---
> >>  drivers/iommu/intel/iommu.c | 29 +
> > 
> > This misses the changelog from v1 followed by the explanation why resent.
> > 
> I noticed there was a typo in the recipient list:
> stable.vger.kernel.org -> sta...@vger.kernel.org
> 
> no code change for resent.

When you're submitting a patch and want it reach the stable kernels, you'll
need to add a Cc tag:

Cc: sta...@vger.kernel.org

But not actually add the address to cc. I dropped stable@vger address from
distribution.

Please change this for v3.

-- 
Kind regards,

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


Re: [RESEND v2] iommu/vt-d: Use passthrough mode for the Intel IPUs

2021-04-20 Thread Sakari Ailus
Hi Bingbu,

Thanks for the patch.

On Tue, Apr 20, 2021 at 10:48:33AM +0800, Bingbu Cao wrote:
> Intel IPU(Image Processing Unit) has its own (IO)MMU hardware,
> The IPU driver allocates its own page table that is not mapped
> via the DMA, and thus the Intel IOMMU driver blocks access giving
> this error:

The page table should be mapped to the possible IOMMU using the DMA API.

> 
> DMAR: DRHD: handling fault status reg 3
> DMAR: [DMA Read] Request device [00:05.0] PASID 
>   fault addr 76406000 [fault reason 06] PTE Read access is not set
> 
> As IPU is not an external facing device which is not risky, so use
> IOMMU passthrough mode for Intel IPUs.

I think a factor here is that the page tables aren't accessible by the IPU
firmware.

> 
> Fixes: 26f5689592e2 ("media: staging/intel-ipu3: mmu: Implement driver")
> Signed-off-by: Bingbu Cao 
> ---
>  drivers/iommu/intel/iommu.c | 29 +
>  1 file changed, 29 insertions(+)
> 
> diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
> index ee0932307d64..7e2fbdae467e 100644
> --- a/drivers/iommu/intel/iommu.c
> +++ b/drivers/iommu/intel/iommu.c
> @@ -55,6 +55,12 @@
>  #define IS_GFX_DEVICE(pdev) ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY)
>  #define IS_USB_DEVICE(pdev) ((pdev->class >> 8) == PCI_CLASS_SERIAL_USB)
>  #define IS_ISA_DEVICE(pdev) ((pdev->class >> 8) == PCI_CLASS_BRIDGE_ISA)
> +#define IS_INTEL_IPU(pdev) ((pdev)->vendor == PCI_VENDOR_ID_INTEL && \
> + ((pdev)->device == 0x9a19 ||\
> +  (pdev)->device == 0x9a39 ||\
> +  (pdev)->device == 0x4e19 ||\
> +  (pdev)->device == 0x465d ||\
> +  (pdev)->device == 0x1919))
>  #define IS_AZALIA(pdev) ((pdev)->vendor == 0x8086 && (pdev)->device == 
> 0x3a3e)
>  
>  #define IOAPIC_RANGE_START   (0xfee0)
> @@ -360,6 +366,7 @@ int intel_iommu_enabled = 0;
>  EXPORT_SYMBOL_GPL(intel_iommu_enabled);
>  
>  static int dmar_map_gfx = 1;
> +static int dmar_map_ipu = 1;

This works as long as there's only one IPU. Same for graphics. But I guess
this can be reworked in the future if the presumption changes.

>  static int dmar_forcedac;
>  static int intel_iommu_strict;
>  static int intel_iommu_superpage = 1;
> @@ -368,6 +375,7 @@ static int iommu_skip_te_disable;
>  
>  #define IDENTMAP_GFX 2
>  #define IDENTMAP_AZALIA  4
> +#define IDENTMAP_IPU 8
>  
>  int intel_iommu_gfx_mapped;
>  EXPORT_SYMBOL_GPL(intel_iommu_gfx_mapped);
> @@ -2839,6 +2847,9 @@ static int device_def_domain_type(struct device *dev)
>  
>   if ((iommu_identity_mapping & IDENTMAP_GFX) && 
> IS_GFX_DEVICE(pdev))
>   return IOMMU_DOMAIN_IDENTITY;
> +
> + if ((iommu_identity_mapping & IDENTMAP_IPU) && 
> IS_INTEL_IPU(pdev))
> + return IOMMU_DOMAIN_IDENTITY;
>   }
>  
>   return 0;
> @@ -3278,6 +3289,9 @@ static int __init init_dmars(void)
>   if (!dmar_map_gfx)
>   iommu_identity_mapping |= IDENTMAP_GFX;
>  
> + if (!dmar_map_ipu)
> + iommu_identity_mapping |= IDENTMAP_IPU;
> +
>   check_tylersburg_isoch();
>  
>   ret = si_domain_init(hw_pass_through);
> @@ -5622,6 +5636,18 @@ static void quirk_iommu_igfx(struct pci_dev *dev)
>   dmar_map_gfx = 0;
>  }
>  
> +static void quirk_iommu_ipu(struct pci_dev *dev)
> +{
> + if (!IS_INTEL_IPU(dev))
> + return;
> +
> + if (risky_device(dev))
> + return;
> +
> + pci_info(dev, "Passthrough IOMMU for integrated Intel IPU\n");
> + dmar_map_ipu = 0;
> +}
> +
>  /* G4x/GM45 integrated gfx dmar support is totally busted. */
>  DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_igfx);
>  DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e00, quirk_iommu_igfx);
> @@ -5657,6 +5683,9 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1632, 
> quirk_iommu_igfx);
>  DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x163A, quirk_iommu_igfx);
>  DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x163D, quirk_iommu_igfx);
>  
> +/* disable IPU dmar support */
> +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, quirk_iommu_ipu);
> +
>  static void quirk_iommu_rwbf(struct pci_dev *dev)
>  {
>   if (risky_device(dev))

-- 
Kind regards,

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


Re: [PATCH 2/2] iommu/amd: Remove performance counter pre-initialization test

2021-04-20 Thread Alexander Monakov
On Tue, 20 Apr 2021, Suthikulpanit, Suravee wrote:

> David / Joerg,
> 
> On 4/10/2021 5:03 PM, David Coe wrote:
> > 
> > The immediately obvious difference is the with the enormous count seen on
> > mem_dte_mis on the older Ryzen 2400G. Will do some RTFM but anyone
> > with comments and insight?
> > 
> > 841,689,151,202,939   amd_iommu_0/mem_dte_mis/  (33.44%)
> > 
> > Otherwise, all seems to running smoothly (especially for a distribution
> > still in β). Bravo and many thanks all!
> 
> The initial hypothesis is that the issue happens only when users specify more
> number of events than
> the available counters, which Perf will time-multiplex the events onto the
> counters.
> 
> Looking at the Perf and AMD IOMMU PMU multiplexing logic, it requires:
>  1. Stop the counter (i.e. set CSOURCE to zero to stop counting)
>  2. Save the counter value of the current event
>  3. Reload the counter value of the new event (previously saved)
>  4. Start the counter (i.e. set CSOURCE to count new events)
> 
> The problem here is that when the driver writes zero to CSOURCE register in
> step 1, this would enable power-gating,
> which prevents access to the counter and result in writing/reading value in
> step 2 and 3.
> 
> I have found a system that reproduced this case (w/ unusually large number of
> count), and debug the issue further.
> As a hack, I have tried skipping step 1, and it seems to eliminate this issue.
> However, this is logically incorrect,
> and might result in inaccurate data depending on the events.
> 
> Here are the options:
> 1. Continue to look for workaround for this issue.
> 2. Find a way to disable event time-multiplexing (e.g. only limit the number
> of counters to 8)
>if power gating is enabled on the platform.
> 3. Back to the original logic where we had the pre-init check of the counter
> vlues, which is still the safest choice
>at the moment unless

If the "power-gated" counter only ignores writes, but yields correct values on
reads, you don't need to change its value.

0. When initializing the counter, save its value as 'raw_counter_value'.

When switching:

1. Set CSOURCE to zero (pauses the counter).
2. Read current counter value ('new_value').
3. Add '(new_value - raw_counter_value) & mask' to the current event count;
   where 'mask' is '(1ULL << 48) - 1' to account for overflow correctly.
4. Assign 'raw_counter_value = new_value'.
5. Set CSOURCE to new configuration value.

Modifying the hardware counter value is only needed to get overflow interrupts,
but there's no code to handle them on Linux (since the interrupts are
asynchronous, and given the nature of the events, I don't see how it would be
useful).

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

Re: [RESEND v2] iommu/vt-d: Use passthrough mode for the Intel IPUs

2021-04-20 Thread Andy Shevchenko
On Tue, Apr 20, 2021 at 10:48:33AM +0800, Bingbu Cao wrote:
> Intel IPU(Image Processing Unit) has its own (IO)MMU hardware,
> The IPU driver allocates its own page table that is not mapped
> via the DMA, and thus the Intel IOMMU driver blocks access giving
> this error:
> 
> DMAR: DRHD: handling fault status reg 3
> DMAR: [DMA Read] Request device [00:05.0] PASID 
>   fault addr 76406000 [fault reason 06] PTE Read access is not set
> 
> As IPU is not an external facing device which is not risky, so use
> IOMMU passthrough mode for Intel IPUs.

I'm wondering if IPU MMU should be described properly in the DMAR table.

-- 
With Best Regards,
Andy Shevchenko


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


Re: [RESEND v2] iommu/vt-d: Use passthrough mode for the Intel IPUs

2021-04-20 Thread Andy Shevchenko
On Tue, Apr 20, 2021 at 10:48:33AM +0800, Bingbu Cao wrote:
> Intel IPU(Image Processing Unit) has its own (IO)MMU hardware,
> The IPU driver allocates its own page table that is not mapped
> via the DMA, and thus the Intel IOMMU driver blocks access giving
> this error:
> 
> DMAR: DRHD: handling fault status reg 3
> DMAR: [DMA Read] Request device [00:05.0] PASID 
>   fault addr 76406000 [fault reason 06] PTE Read access is not set
> 
> As IPU is not an external facing device which is not risky, so use
> IOMMU passthrough mode for Intel IPUs.
> 
> Fixes: 26f5689592e2 ("media: staging/intel-ipu3: mmu: Implement driver")
> Signed-off-by: Bingbu Cao 
> ---
>  drivers/iommu/intel/iommu.c | 29 +

This misses the changelog from v1 followed by the explanation why resent.

-- 
With Best Regards,
Andy Shevchenko


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


Re: [RFC v1 PATCH 3/3] driver: update all the code that use soc_device_match

2021-04-20 Thread Péter Ujfalusi
Hi Alice,

On 4/19/21 7:27 AM, Alice Guo (OSS) wrote:
> From: Alice Guo 
> 
> Update all the code that use soc_device_match because add support for
> soc_device_match returning -EPROBE_DEFER.
> 
> Signed-off-by: Alice Guo 
> ---
>  drivers/bus/ti-sysc.c |  2 +-
>  drivers/clk/renesas/r8a7795-cpg-mssr.c|  4 +++-
>  drivers/clk/renesas/rcar-gen2-cpg.c   |  2 +-
>  drivers/clk/renesas/rcar-gen3-cpg.c   |  2 +-
>  drivers/dma/fsl-dpaa2-qdma/dpaa2-qdma.c   |  7 ++-
>  drivers/dma/ti/k3-psil.c  |  3 +++
>  drivers/dma/ti/k3-udma.c  |  2 +-
>  drivers/gpu/drm/bridge/nwl-dsi.c  |  2 +-
>  drivers/gpu/drm/meson/meson_drv.c |  4 +++-
>  drivers/gpu/drm/omapdrm/dss/dispc.c   |  2 +-
>  drivers/gpu/drm/omapdrm/dss/dpi.c |  4 +++-
>  drivers/gpu/drm/omapdrm/dss/dsi.c |  3 +++
>  drivers/gpu/drm/omapdrm/dss/dss.c |  3 +++
>  drivers/gpu/drm/omapdrm/dss/hdmi4_core.c  |  3 +++
>  drivers/gpu/drm/omapdrm/dss/venc.c|  4 +++-
>  drivers/gpu/drm/omapdrm/omap_drv.c|  3 +++
>  drivers/gpu/drm/rcar-du/rcar_du_crtc.c|  4 +++-
>  drivers/gpu/drm/rcar-du/rcar_lvds.c   |  2 +-
>  drivers/gpu/drm/tidss/tidss_dispc.c   |  4 +++-
>  drivers/iommu/ipmmu-vmsa.c|  7 +--
>  drivers/media/platform/rcar-vin/rcar-core.c   |  2 +-
>  drivers/media/platform/rcar-vin/rcar-csi2.c   |  2 +-
>  drivers/media/platform/vsp1/vsp1_uif.c|  4 +++-
>  drivers/mmc/host/renesas_sdhi_core.c  |  2 +-
>  drivers/mmc/host/renesas_sdhi_internal_dmac.c |  2 +-
>  drivers/mmc/host/sdhci-of-esdhc.c | 21 ++-
>  drivers/mmc/host/sdhci-omap.c |  2 +-
>  drivers/mmc/host/sdhci_am654.c|  2 +-
>  drivers/net/ethernet/renesas/ravb_main.c  |  4 +++-
>  drivers/net/ethernet/ti/am65-cpsw-nuss.c  |  2 +-
>  drivers/net/ethernet/ti/cpsw.c|  2 +-
>  drivers/net/ethernet/ti/cpsw_new.c|  2 +-
>  drivers/phy/ti/phy-omap-usb2.c|  4 +++-
>  drivers/pinctrl/renesas/core.c|  2 +-
>  drivers/pinctrl/renesas/pfc-r8a7790.c |  5 -
>  drivers/pinctrl/renesas/pfc-r8a7794.c |  5 -
>  drivers/soc/fsl/dpio/dpio-driver.c| 13 
>  drivers/soc/renesas/r8a774c0-sysc.c   |  5 -
>  drivers/soc/renesas/r8a7795-sysc.c|  2 +-
>  drivers/soc/renesas/r8a77990-sysc.c   |  5 -
>  drivers/soc/ti/k3-ringacc.c   |  2 +-
>  drivers/staging/mt7621-pci/pci-mt7621.c   |  2 +-
>  drivers/thermal/rcar_gen3_thermal.c   |  4 +++-
>  drivers/thermal/ti-soc-thermal/ti-bandgap.c   | 10 +++--
>  drivers/usb/gadget/udc/renesas_usb3.c |  2 +-
>  drivers/usb/host/ehci-platform.c  |  4 +++-
>  drivers/usb/host/xhci-rcar.c  |  2 +-
>  drivers/watchdog/renesas_wdt.c|  2 +-
>  48 files changed, 131 insertions(+), 52 deletions(-)
> 

...

> diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c
> index 96ad21869ba7..50a4c8f0993d 100644
> --- a/drivers/dma/ti/k3-udma.c
> +++ b/drivers/dma/ti/k3-udma.c
> @@ -5188,7 +5188,7 @@ static int udma_probe(struct platform_device *pdev)
>   ud->match_data = match->data;
>  
>   soc = soc_device_match(k3_soc_devices);
> - if (!soc) {
> + if (!IS_ERR(soc) && !soc) {

this does not sound right...

if (!soc || IS_ERR(soc))
or
if (IS_ERR_OR_NULL(soc))
is even better.

>   dev_err(dev, "No compatible SoC found\n");
>   return -ENODEV;

There might be a clever macro for it, but:

return soc ? PTR_ERR(soc) : -ENODEV;

>   }

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

[PATCH v3 10/10] iommu/arm-smmu: Reserve any RMR regions associated with a dev

2021-04-20 Thread Shameer Kolothum
From: Jon Nettleton 

Get RMR regions associated with a dev reserved so that there is
a unity mapping for them in SMMU.

Signed-off-by: Jon Nettleton 
Signed-off-by: Shameer Kolothum 
---
 drivers/iommu/arm/arm-smmu/arm-smmu.c | 33 +++
 1 file changed, 33 insertions(+)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c 
b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index 4d2f91626d87..8cbe8b98e8f0 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -1591,6 +1591,38 @@ static int arm_smmu_of_xlate(struct device *dev, struct 
of_phandle_args *args)
return iommu_fwspec_add_ids(dev, , 1);
 }
 
+static bool arm_smmu_dev_has_rmr(struct arm_smmu_master_cfg *cfg,
+struct iommu_fwspec *fwspec,
+struct iommu_rmr *e)
+{
+   struct arm_smmu_device *smmu = cfg->smmu;
+   struct arm_smmu_smr *smrs = smmu->smrs;
+   int i, idx;
+
+   for_each_cfg_sme(cfg, fwspec, i, idx) {
+   if (e->sid == smrs[idx].id)
+   return true;
+   }
+
+   return false;
+}
+
+static void arm_smmu_rmr_get_resv_regions(struct device *dev,
+ struct list_head *head)
+{
+   struct arm_smmu_master_cfg *cfg = dev_iommu_priv_get(dev);
+   struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+   struct arm_smmu_device *smmu = cfg->smmu;
+   struct iommu_rmr *rmr;
+
+   list_for_each_entry(rmr, >rmr_list, list) {
+   if (!arm_smmu_dev_has_rmr(cfg, fwspec, rmr))
+   continue;
+
+   iommu_dma_get_rmr_resv_regions(dev, rmr, head);
+   }
+}
+
 static void arm_smmu_get_resv_regions(struct device *dev,
  struct list_head *head)
 {
@@ -1605,6 +1637,7 @@ static void arm_smmu_get_resv_regions(struct device *dev,
list_add_tail(>list, head);
 
iommu_dma_get_resv_regions(dev, head);
+   arm_smmu_rmr_get_resv_regions(dev, head);
 }
 
 static int arm_smmu_def_domain_type(struct device *dev)
-- 
2.17.1

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

[PATCH v3 09/10] iommu/arm-smmu: Get associated RMR info and install bypass SMR

2021-04-20 Thread Shameer Kolothum
From: Jon Nettleton 

Check if there is any RMR info associated with the devices behind
the SMMU and if any, install bypass SMRs for them. This is to
keep any ongoing traffic associated with these devices alive
when we enable/reset SMMU during probe().

Signed-off-by: Jon Nettleton 
Signed-off-by: Shameer Kolothum 
---
 drivers/iommu/arm/arm-smmu/arm-smmu.c | 42 +++
 drivers/iommu/arm/arm-smmu/arm-smmu.h |  2 ++
 2 files changed, 44 insertions(+)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c 
b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index d8c6bfde6a61..4d2f91626d87 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -2102,6 +2102,43 @@ err_reset_platform_ops: __maybe_unused;
return err;
 }
 
+static void arm_smmu_rmr_install_bypass_smr(struct arm_smmu_device *smmu)
+{
+   struct iommu_rmr *e;
+   int i, cnt = 0;
+   u32 smr;
+
+   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))
+   continue;
+
+   list_for_each_entry(e, >rmr_list, list) {
+   if (FIELD_GET(ARM_SMMU_SMR_ID, smr) != e->sid)
+   continue;
+
+   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;
+
+   cnt++;
+   }
+   }
+
+   dev_notice(smmu->dev, "\tpreserved %d boot mapping%s\n", cnt,
+  cnt == 1 ? "" : "s");
+}
+
+static int arm_smmu_get_rmr(struct arm_smmu_device *smmu)
+{
+   INIT_LIST_HEAD(>rmr_list);
+   return iommu_dma_get_rmrs(dev_fwnode(smmu->dev), >rmr_list);
+}
+
 static int arm_smmu_device_probe(struct platform_device *pdev)
 {
struct resource *res;
@@ -2231,6 +2268,11 @@ static int arm_smmu_device_probe(struct platform_device 
*pdev)
}
 
platform_set_drvdata(pdev, smmu);
+
+   /* Check for RMRs and install bypass SMRs if any */
+   if (!arm_smmu_get_rmr(smmu))
+   arm_smmu_rmr_install_bypass_smr(smmu);
+
arm_smmu_device_reset(smmu);
arm_smmu_test_smr_masks(smmu);
 
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.h 
b/drivers/iommu/arm/arm-smmu/arm-smmu.h
index d2a2d1bc58ba..ca9559eb8733 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.h
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.h
@@ -326,6 +326,8 @@ struct arm_smmu_device {
 
/* IOMMU core code handle */
struct iommu_device iommu;
+
+   struct list_headrmr_list;
 };
 
 enum arm_smmu_context_fmt {
-- 
2.17.1

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

[PATCH v3 08/10] iommu/arm-smmu-v3: Reserve any RMR regions associated with a dev

2021-04-20 Thread Shameer Kolothum
Get RMR regions associated with a dev reserved so that there is
a unity mapping for them in SMMU.

Signed-off-by: Shameer Kolothum 
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 29 +
 1 file changed, 29 insertions(+)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c 
b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 14e9c7034c04..8bacedf7bb34 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2531,6 +2531,34 @@ static int arm_smmu_of_xlate(struct device *dev, struct 
of_phandle_args *args)
return iommu_fwspec_add_ids(dev, args->args, 1);
 }
 
+static bool arm_smmu_dev_has_rmr(struct arm_smmu_master *master,
+struct iommu_rmr *e)
+{
+   int i;
+
+   for (i = 0; i < master->num_sids; i++) {
+   if (e->sid == master->sids[i])
+   return true;
+   }
+
+   return false;
+}
+
+static void arm_smmu_rmr_get_resv_regions(struct device *dev,
+ struct list_head *head)
+{
+   struct arm_smmu_master *master = dev_iommu_priv_get(dev);
+   struct arm_smmu_device *smmu = master->smmu;
+   struct iommu_rmr *rmr;
+
+   list_for_each_entry(rmr, >rmr_list, list) {
+   if (!arm_smmu_dev_has_rmr(master, rmr))
+   continue;
+
+   iommu_dma_get_rmr_resv_regions(dev, rmr, head);
+   }
+}
+
 static void arm_smmu_get_resv_regions(struct device *dev,
  struct list_head *head)
 {
@@ -2545,6 +2573,7 @@ static void arm_smmu_get_resv_regions(struct device *dev,
list_add_tail(>list, head);
 
iommu_dma_get_resv_regions(dev, head);
+   arm_smmu_rmr_get_resv_regions(dev, head);
 }
 
 static bool arm_smmu_dev_has_feature(struct device *dev,
-- 
2.17.1

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

[PATCH v3 07/10] iommu/arm-smmu-v3: Get associated RMR info and install bypass STE

2021-04-20 Thread Shameer Kolothum
Check if there is any RMR info associated with the devices behind
the SMMUv3 and if any, install bypass STEs for them. This is to
keep any ongoing traffic associated with these devices alive
when we enable/reset SMMUv3 during probe().

Signed-off-by: Shameer Kolothum 
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 35 +
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h |  2 ++
 2 files changed, 37 insertions(+)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c 
b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 190285812182..14e9c7034c04 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -3530,6 +3530,37 @@ static void __iomem *arm_smmu_ioremap(struct device 
*dev, resource_size_t start,
return devm_ioremap_resource(dev, );
 }
 
+static void arm_smmu_rmr_install_bypass_ste(struct arm_smmu_device *smmu)
+{
+   struct iommu_rmr *e;
+   int ret;
+
+   /*
+* Since, we don't have a mechanism to differentiate the RMR
+* SIDs that has an ongoing live stream, install bypass STEs
+* for all the reported ones. 
+*/
+   list_for_each_entry(e, >rmr_list, list) {
+   __le64 *step;
+
+   ret = arm_smmu_init_sid_strtab(smmu, e->sid);
+   if (ret) {
+   dev_err(smmu->dev, "RMR bypass(0x%x) failed\n",
+   e->sid);
+   continue;
+   }
+
+   step = arm_smmu_get_step_for_sid(smmu, e->sid);
+   arm_smmu_write_strtab_ent(NULL, e->sid, step, true);
+   }
+}
+
+static int arm_smmu_get_rmr(struct arm_smmu_device *smmu)
+{
+   INIT_LIST_HEAD(>rmr_list);
+   return iommu_dma_get_rmrs(dev_fwnode(smmu->dev), >rmr_list);
+}
+
 static int arm_smmu_device_probe(struct platform_device *pdev)
 {
int irq, ret;
@@ -3613,6 +3644,10 @@ static int arm_smmu_device_probe(struct platform_device 
*pdev)
/* Record our private device structure */
platform_set_drvdata(pdev, smmu);
 
+   /* Check for RMRs and install bypass STEs if any */
+   if (!arm_smmu_get_rmr(smmu))
+   arm_smmu_rmr_install_bypass_ste(smmu);
+
/* Reset the device */
ret = arm_smmu_device_reset(smmu, bypass);
if (ret)
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h 
b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
index f985817c967a..e210fa81538a 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -639,6 +639,8 @@ struct arm_smmu_device {
 
/* IOMMU core code handle */
struct iommu_device iommu;
+
+   struct list_headrmr_list;
 };
 
 /* SMMU private data for each master */
-- 
2.17.1

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

[PATCH v3 06/10] iommu/arm-smmu-v3: Add bypass flag to arm_smmu_write_strtab_ent()

2021-04-20 Thread Shameer Kolothum
By default, disable_bypass is set and any dev without an iommu domain
installs STE with CFG_ABORT during arm_smmu_init_bypass_stes(). Introduce
a "bypass" flag to arm_smmu_write_strtab_ent() so that we can force it to
install CFG_BYPASS STE for specific SIDs. This will be useful for RMR
related SIDs.

Signed-off-by: Shameer Kolothum 
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c 
b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 29da3b681621..190285812182 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -1176,7 +1176,7 @@ static void arm_smmu_sync_ste_for_sid(struct 
arm_smmu_device *smmu, u32 sid)
 }
 
 static void arm_smmu_write_strtab_ent(struct arm_smmu_master *master, u32 sid,
- __le64 *dst)
+ __le64 *dst, bool bypass)
 {
/*
 * This is hideously complicated, but we only really care about
@@ -1247,7 +1247,7 @@ static void arm_smmu_write_strtab_ent(struct 
arm_smmu_master *master, u32 sid,
 
/* Bypass/fault */
if (!smmu_domain || !(s1_cfg || s2_cfg)) {
-   if (!smmu_domain && disable_bypass)
+   if (!smmu_domain && disable_bypass && !bypass)
val |= FIELD_PREP(STRTAB_STE_0_CFG, 
STRTAB_STE_0_CFG_ABORT);
else
val |= FIELD_PREP(STRTAB_STE_0_CFG, 
STRTAB_STE_0_CFG_BYPASS);
@@ -1322,7 +1322,7 @@ static void arm_smmu_init_bypass_stes(__le64 *strtab, 
unsigned int nent)
unsigned int i;
 
for (i = 0; i < nent; ++i) {
-   arm_smmu_write_strtab_ent(NULL, -1, strtab);
+   arm_smmu_write_strtab_ent(NULL, -1, strtab, false);
strtab += STRTAB_STE_DWORDS;
}
 }
@@ -2076,7 +2076,7 @@ static void arm_smmu_install_ste_for_dev(struct 
arm_smmu_master *master)
if (j < i)
continue;
 
-   arm_smmu_write_strtab_ent(master, sid, step);
+   arm_smmu_write_strtab_ent(master, sid, step, false);
}
 }
 
-- 
2.17.1

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

[PATCH v3 05/10] iommu/arm-smmu-v3: Introduce strtab init helper

2021-04-20 Thread Shameer Kolothum
Introduce a helper to check the sid range and to init the l2 strtab
entries(bypass). This will be useful when we have to initialize the
l2 strtab with bypass for RMR SIDs.

Signed-off-by: Shameer Kolothum 
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 26 -
 1 file changed, 15 insertions(+), 11 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c 
b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 8594b4a83043..29da3b681621 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2347,6 +2347,19 @@ static bool arm_smmu_sid_in_range(struct arm_smmu_device 
*smmu, u32 sid)
 
 static struct iommu_ops arm_smmu_ops;
 
+static int arm_smmu_init_sid_strtab(struct arm_smmu_device *smmu, u32 sid)
+{
+   /* Check the SIDs are in range of the SMMU and our stream table */
+   if (!arm_smmu_sid_in_range(smmu, sid))
+   return -ERANGE;
+
+   /* Ensure l2 strtab is initialised */
+   if (smmu->features & ARM_SMMU_FEAT_2_LVL_STRTAB)
+   return arm_smmu_init_l2_strtab(smmu, sid);
+
+   return 0;
+}
+
 static struct iommu_device *arm_smmu_probe_device(struct device *dev)
 {
int i, ret;
@@ -2375,21 +2388,12 @@ static struct iommu_device 
*arm_smmu_probe_device(struct device *dev)
INIT_LIST_HEAD(>bonds);
dev_iommu_priv_set(dev, master);
 
-   /* Check the SIDs are in range of the SMMU and our stream table */
for (i = 0; i < master->num_sids; i++) {
u32 sid = master->sids[i];
 
-   if (!arm_smmu_sid_in_range(smmu, sid)) {
-   ret = -ERANGE;
+   ret = arm_smmu_init_sid_strtab(smmu, sid);
+   if (ret)
goto err_free_master;
-   }
-
-   /* Ensure l2 strtab is initialised */
-   if (smmu->features & ARM_SMMU_FEAT_2_LVL_STRTAB) {
-   ret = arm_smmu_init_l2_strtab(smmu, sid);
-   if (ret)
-   goto err_free_master;
-   }
}
 
master->ssid_bits = min(smmu->ssid_bits, fwspec->num_pasid_bits);
-- 
2.17.1

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


[PATCH v3 04/10] iommu/dma: Add a helper function to reserve RMRs for IOMMU drivers

2021-04-20 Thread Shameer Kolothum
IOMMU drivers can use this to implement their .get_resv_regions callback
for any RMR address regions specific to a device.

As per ACPI IORT E.b spec, a check is added to make sure OS has preserved
the PCIe configuration done by boot firmware.

Signed-off-by: Shameer Kolothum 
---
 drivers/iommu/dma-iommu.c | 35 +++
 include/linux/dma-iommu.h |  7 +++
 2 files changed, 42 insertions(+)

diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index a942cc04eee1..c624000bf230 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -191,6 +191,41 @@ void iommu_dma_get_resv_regions(struct device *dev, struct 
list_head *list)
 }
 EXPORT_SYMBOL(iommu_dma_get_resv_regions);
 
+void iommu_dma_get_rmr_resv_regions(struct device *dev, struct iommu_rmr *rmr,
+   struct list_head *list)
+{
+   int prot = IOMMU_READ | IOMMU_WRITE | IOMMU_NOEXEC | IOMMU_MMIO;
+   struct iommu_resv_region *region;
+   enum iommu_resv_type type;
+
+   /*
+* For ACPI, please make sure the OS has preserved the PCIe 
configuration
+* performed by the boot firmware(See IORT revision E.b).
+*/
+   if (!is_of_node(dev_iommu_fwspec_get(dev)->iommu_fwnode) &&
+   dev_is_pci(dev)) {
+   struct pci_dev *pdev = to_pci_dev(dev);
+   struct pci_host_bridge *host = pci_find_host_bridge(pdev->bus);
+
+   if (!host->preserve_config)
+   return;
+   }
+
+   if (rmr->flags & IOMMU_RMR_REMAP_PERMITTED)
+   type = IOMMU_RESV_DIRECT_RELAXABLE;
+   else
+   type = IOMMU_RESV_DIRECT;
+
+   region = iommu_alloc_resv_region(rmr->base_address,
+rmr->length, prot,
+type);
+   if (!region)
+   return;
+
+   list_add_tail(>list, list);
+}
+EXPORT_SYMBOL(iommu_dma_get_rmr_resv_regions);
+
 /**
  * iommu_dma_get_rmrs - Retrieve Reserved Memory Regions(RMRs) associated
  *  with a given IOMMU
diff --git a/include/linux/dma-iommu.h b/include/linux/dma-iommu.h
index beb84c4fe5b1..dbad5073c9e0 100644
--- a/include/linux/dma-iommu.h
+++ b/include/linux/dma-iommu.h
@@ -40,6 +40,8 @@ void iommu_dma_get_resv_regions(struct device *dev, struct 
list_head *list);
 void iommu_dma_free_cpu_cached_iovas(unsigned int cpu,
struct iommu_domain *domain);
 
+void iommu_dma_get_rmr_resv_regions(struct device *dev, struct iommu_rmr *rmr,
+   struct list_head *list);
 int iommu_dma_get_rmrs(struct fwnode_handle *iommu, struct list_head *list);
 struct iommu_rmr *iommu_dma_alloc_rmr(u64 base, u64 length, u32 sid, u32 
flags);
 
@@ -89,6 +91,11 @@ static inline void iommu_dma_free_cpu_cached_iovas(unsigned 
int cpu,
 {
 }
 
+static void iommu_dma_get_rmr_resv_regions(struct device *dev, struct 
iommu_rmr *rmr,
+  struct list_head *list)
+{
+}
+
 int iommu_dma_get_rmrs(struct fwnode_handle *iommu, struct list_head *list);
 {
return 0;
-- 
2.17.1

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


[PATCH v3 03/10] ACPI/IORT: Add a helper to retrieve RMR memory regions

2021-04-20 Thread Shameer Kolothum
Add a helper function that retrieves RMR memory descriptors
associated with a given IOMMU. This will be used by IOMMU
drivers to setup necessary mappings.

Now that we have this, invoke this from the generic helper
interface.

Signed-off-by: Shameer Kolothum 
---
 drivers/acpi/arm64/iort.c | 40 +++
 drivers/iommu/dma-iommu.c |  3 +++
 include/linux/acpi_iort.h |  7 +++
 3 files changed, 50 insertions(+)

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index bd96c5e3b36e..66e314b15692 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -12,6 +12,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -837,6 +838,43 @@ static inline int iort_add_device_replay(struct device 
*dev)
return err;
 }
 
+/**
+ * iort_iommu_get_rmrs - Helper to retrieve RMR info associated with IOMMU
+ * @iommu: fwnode for the IOMMU
+ * @head: RMR list head to be populated
+ *
+ * Returns: 0 on success, <0 failure
+ */
+int iort_iommu_get_rmrs(struct fwnode_handle *iommu_fwnode,
+   struct list_head *head)
+{
+   struct iort_rmr_entry *e;
+   struct acpi_iort_node *iommu;
+
+   iommu = iort_get_iort_node(iommu_fwnode);
+   if (!iommu)
+   return 0;
+
+   list_for_each_entry(e, _rmr_list, list) {
+   struct acpi_iort_rmr_desc *rmr_desc;
+   struct iommu_rmr *rmr;
+
+   if (e->smmu != iommu)
+   continue;
+
+   rmr_desc = e->rmr_desc;
+   rmr = iommu_dma_alloc_rmr(rmr_desc->base_address,
+ rmr_desc->length, e->sid,
+ e->flags);
+   if (!rmr)
+   return -ENOMEM;
+
+   list_add_tail(>list, head);
+   }
+
+   return 0;
+}
+
 /**
  * iort_iommu_msi_get_resv_regions - Reserved region driver helper
  * @dev: Device from iommu_get_resv_regions()
@@ -1107,6 +1145,8 @@ int iort_iommu_msi_get_resv_regions(struct device *dev, 
struct list_head *head)
 const struct iommu_ops *iort_iommu_configure_id(struct device *dev,
const u32 *input_id)
 { return NULL; }
+int iort_iommu_get_rmrs(struct fwnode_handle *fwnode, struct list_head *head)
+{ return 0; }
 #endif
 
 static int nc_dma_get_range(struct device *dev, u64 *size)
diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index 86a1e48b1fe8..a942cc04eee1 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -201,6 +201,9 @@ EXPORT_SYMBOL(iommu_dma_get_resv_regions);
 int iommu_dma_get_rmrs(struct fwnode_handle *iommu_fwnode,
   struct list_head *list)
 {
+   if (!is_of_node(iommu_fwnode))
+   return iort_iommu_get_rmrs(iommu_fwnode, list);
+
return 0;
 }
 EXPORT_SYMBOL(iommu_dma_get_rmrs);
diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
index 1a12baa58e40..e9f3bc2f4842 100644
--- a/include/linux/acpi_iort.h
+++ b/include/linux/acpi_iort.h
@@ -39,6 +39,8 @@ const struct iommu_ops *iort_iommu_configure_id(struct device 
*dev,
const u32 *id_in);
 int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head 
*head);
 phys_addr_t acpi_iort_dma_get_max_cpu_address(void);
+int iort_iommu_get_rmrs(struct fwnode_handle *iommu_fwnode,
+   struct list_head *list);
 #else
 static inline void acpi_iort_init(void) { }
 static inline u32 iort_msi_map_id(struct device *dev, u32 id)
@@ -59,6 +61,11 @@ int iort_iommu_msi_get_resv_regions(struct device *dev, 
struct list_head *head)
 
 static inline phys_addr_t acpi_iort_dma_get_max_cpu_address(void)
 { return PHYS_ADDR_MAX; }
+
+static inline
+int iort_iommu_get_rmrs(struct fwnode_handle *iommu_fwnode,
+   struct list_head *list)
+{ return 0; }
 #endif
 
 #endif /* __ACPI_IORT_H__ */
-- 
2.17.1

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


[PATCH v3 02/10] iommu/dma: Introduce generic helper to retrieve RMR info

2021-04-20 Thread Shameer Kolothum
Reserved Memory Regions(RMR) associated with an IOMMU may be
described either through ACPI tables or DT in systems with
devices that require a unity mapping or bypass for those
regions in IOMMU drivers.

Introduce a generic interface so that IOMMU drivers can retrieve
and set up necessary mappings.

Signed-off-by: Shameer Kolothum 
---
 drivers/iommu/dma-iommu.c | 33 +
 include/linux/dma-iommu.h |  8 
 include/linux/iommu.h | 19 +++
 3 files changed, 60 insertions(+)

diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index af765c813cc8..86a1e48b1fe8 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -191,6 +191,39 @@ void iommu_dma_get_resv_regions(struct device *dev, struct 
list_head *list)
 }
 EXPORT_SYMBOL(iommu_dma_get_resv_regions);
 
+/**
+ * iommu_dma_get_rmrs - Retrieve Reserved Memory Regions(RMRs) associated
+ *  with a given IOMMU
+ * @iommu_fwnode: fwnode associated with IOMMU
+ * @list: RMR list to be populated
+ *
+ */
+int iommu_dma_get_rmrs(struct fwnode_handle *iommu_fwnode,
+  struct list_head *list)
+{
+   return 0;
+}
+EXPORT_SYMBOL(iommu_dma_get_rmrs);
+
+struct iommu_rmr *iommu_dma_alloc_rmr(u64 base, u64 length, u32 sid,
+ u32 flags)
+{
+   struct iommu_rmr *rmr;
+
+   rmr = kzalloc(sizeof(*rmr), GFP_KERNEL);
+   if (!rmr)
+   return NULL;
+
+   INIT_LIST_HEAD(>list);
+   rmr->base_address = base;
+   rmr->length = length;
+   rmr->sid = sid;
+   rmr->flags = flags;
+
+   return rmr;
+}
+EXPORT_SYMBOL(iommu_dma_alloc_rmr);
+
 static int cookie_init_hw_msi_region(struct iommu_dma_cookie *cookie,
phys_addr_t start, phys_addr_t end)
 {
diff --git a/include/linux/dma-iommu.h b/include/linux/dma-iommu.h
index 706b68d1359b..beb84c4fe5b1 100644
--- a/include/linux/dma-iommu.h
+++ b/include/linux/dma-iommu.h
@@ -40,6 +40,9 @@ void iommu_dma_get_resv_regions(struct device *dev, struct 
list_head *list);
 void iommu_dma_free_cpu_cached_iovas(unsigned int cpu,
struct iommu_domain *domain);
 
+int iommu_dma_get_rmrs(struct fwnode_handle *iommu, struct list_head *list);
+struct iommu_rmr *iommu_dma_alloc_rmr(u64 base, u64 length, u32 sid, u32 
flags);
+
 #else /* CONFIG_IOMMU_DMA */
 
 struct iommu_domain;
@@ -86,5 +89,10 @@ static inline void iommu_dma_free_cpu_cached_iovas(unsigned 
int cpu,
 {
 }
 
+int iommu_dma_get_rmrs(struct fwnode_handle *iommu, struct list_head *list);
+{
+   return 0;
+}
+
 #endif /* CONFIG_IOMMU_DMA */
 #endif /* __DMA_IOMMU_H */
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 5e7fe519430a..fb8820c40144 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -595,6 +595,25 @@ struct iommu_sva {
struct device   *dev;
 };
 
+/**
+ * struct iommu_rmr - Reserved Memory Region details per IOMMU
+ * @list: Linked list pointers to hold RMR region info
+ * @base_address: base address of Reserved Memory Region
+ * @length: length of memory region
+ * @sid: associated stream id
+ * @flags: flags that apply to the RMR node
+ */
+struct iommu_rmr {
+   struct list_headlist;
+   phys_addr_t base_address;
+   u64 length;
+   u32 sid;
+   u32 flags;
+};
+
+/* RMR Remap permitted */
+#define IOMMU_RMR_REMAP_PERMITTED  (1 << 0)
+
 int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
  const struct iommu_ops *ops);
 void iommu_fwspec_free(struct device *dev);
-- 
2.17.1

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


[PATCH v3 01/10] ACPI/IORT: Add support for RMR node parsing

2021-04-20 Thread Shameer Kolothum
Add support for parsing RMR node information from ACPI.
Find associated stream id and smmu node info from the
RMR node and populate a linked list with RMR memory
descriptors.

Signed-off-by: Shameer Kolothum 
---
 drivers/acpi/arm64/iort.c | 104 +-
 1 file changed, 103 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index 2494138a6905..bd96c5e3b36e 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -40,6 +40,19 @@ struct iort_fwnode {
 static LIST_HEAD(iort_fwnode_list);
 static DEFINE_SPINLOCK(iort_fwnode_lock);
 
+/*
+ * One entry for IORT RMR.
+ */
+struct iort_rmr_entry {
+   struct list_head list;
+   u32 sid;
+   struct acpi_iort_node *smmu;
+   struct acpi_iort_rmr_desc *rmr_desc;
+   u32 flags;
+};
+
+static LIST_HEAD(iort_rmr_list); /* list of RMR regions from ACPI */
+
 /**
  * iort_set_fwnode() - Create iort_fwnode and use it to register
  *iommu data in the iort_fwnode_list
@@ -393,7 +406,8 @@ static struct acpi_iort_node *iort_node_get_id(struct 
acpi_iort_node *node,
if (node->type == ACPI_IORT_NODE_NAMED_COMPONENT ||
node->type == ACPI_IORT_NODE_PCI_ROOT_COMPLEX ||
node->type == ACPI_IORT_NODE_SMMU_V3 ||
-   node->type == ACPI_IORT_NODE_PMCG) {
+   node->type == ACPI_IORT_NODE_PMCG ||
+   node->type == ACPI_IORT_NODE_RMR) {
*id_out = map->output_base;
return parent;
}
@@ -1659,6 +1673,91 @@ static void __init iort_enable_acs(struct acpi_iort_node 
*iort_node)
 #else
 static inline void iort_enable_acs(struct acpi_iort_node *iort_node) { }
 #endif
+static int iort_rmr_desc_valid(struct acpi_iort_rmr_desc *desc, u32 count)
+{
+   int i, j;
+
+   for (i = 0; i < count; i++) {
+   u64 end, start = desc[i].base_address, length = desc[i].length;
+
+   if (!IS_ALIGNED(start, SZ_64K) || !IS_ALIGNED(length, SZ_64K))
+   return -EINVAL;
+
+   end = start + length - 1;
+
+   /* Check for address overlap */
+   for (j = i + 1; j < count; j++) {
+   u64 e_start = desc[j].base_address;
+   u64 e_end = e_start + desc[j].length - 1;
+
+   if (start <= e_end && end >= e_start)
+   return -EINVAL;
+   }
+   }
+
+   return 0;
+}
+
+static int __init iort_parse_rmr(struct acpi_iort_node *iort_node)
+{
+   struct acpi_iort_node *smmu;
+   struct iort_rmr_entry *e;
+   struct acpi_iort_rmr *rmr;
+   struct acpi_iort_rmr_desc *rmr_desc;
+   u32 map_count = iort_node->mapping_count;
+   u32  sid;
+   int i, ret = 0;
+
+   if (iort_node->type != ACPI_IORT_NODE_RMR)
+   return 0;
+
+   if (!iort_node->mapping_offset || map_count != 1) {
+   pr_err(FW_BUG "Invalid ID mapping, skipping RMR node %p\n",
+  iort_node);
+   return -EINVAL;
+   }
+
+   /* Retrieve associated smmu and stream id */
+   smmu = iort_node_get_id(iort_node, , 0);
+   if (!smmu) {
+   pr_err(FW_BUG "Invalid SMMU reference, skipping RMR node %p\n",
+  iort_node);
+   return -EINVAL;
+   }
+
+   /* Retrieve RMR data */
+   rmr = (struct acpi_iort_rmr *)iort_node->node_data;
+   if (!rmr->rmr_offset || !rmr->rmr_count) {
+   pr_err(FW_BUG "Invalid RMR descriptor array, skipping RMR node 
%p\n",
+  iort_node);
+   return -EINVAL;
+   }
+
+   rmr_desc = ACPI_ADD_PTR(struct acpi_iort_rmr_desc, iort_node,
+   rmr->rmr_offset);
+
+   ret = iort_rmr_desc_valid(rmr_desc, rmr->rmr_count);
+   if (ret) {
+   pr_err(FW_BUG "Invalid RMR descriptor[%d] for node %p, 
skipping...\n",
+  i, iort_node);
+   return ret;
+   }
+
+   for (i = 0; i < rmr->rmr_count; i++, rmr_desc++) {
+   e = kmalloc(sizeof(*e), GFP_KERNEL);
+   if (!e)
+   return -ENOMEM;
+
+   e->sid = sid;
+   e->smmu = smmu;
+   e->rmr_desc = rmr_desc;
+   e->flags = rmr->flags;
+
+   list_add_tail(>list, _rmr_list);
+   }
+
+   return 0;
+}
 
 static void __init iort_init_platform_devices(void)
 {
@@ -1688,6 +1787,9 @@ static void __init iort_init_platform_devices(void)
 
iort_enable_acs(iort_node);
 
+   if (iort_table->revision == 3)
+   iort_parse_rmr(iort_node);
+
ops = iort_get_dev_cfg(iort_node);
if (ops) {
fwnode = acpi_alloc_fwnode_static();
-- 
2.17.1


[PATCH v3 00/10] ACPI/IORT: Support for IORT RMR node

2021-04-20 Thread Shameer Kolothum
Hi,

RFC v2 --> v3
 -Dropped RFC tag as the ACPICA header changes are now ready to be
  part of 5.13[0]. But this series still has a dependency on that patch.
 -Added IORT E.b related changes(node flags, _DSM function 5 checks for
  PCIe).
 -Changed RMR to stream id mapping from M:N to M:1 as per the spec and
  discussion here[1].
 -Last two patches add support for SMMUv2(Thanks to Jon Nettleton!) 

Sanity tested on a HiSilicon D06. Further testing and feedback is greatly
appreciated.

The whole series can be found here,
https://github.com/hisilicon/kernel-dev/tree/private-v5.12-rc8-rmr-v3

Thanks,
Shameer

[0] 
https://lore.kernel.org/linux-acpi/20210406213028.718796-22-erik.kan...@intel.com/
[1] 
https://op-lists.linaro.org/pipermail/linaro-open-discussions/2021-April/000150.html

RFC v1 --> v2:
 - Added a generic interface for IOMMU drivers to retrieve all the 
   RMR info associated with a given IOMMU.
 - SMMUv3 driver gets the RMR list during probe() and installs
   bypass STEs for all the SIDs in the RMR list. This is to keep
   the ongoing traffic alive(if any) during SMMUv3 reset. This is
   based on the suggestions received for v1 to take care of the
   EFI framebuffer use case. Only sanity tested for now.
 - During the probe/attach device, SMMUv3 driver reserves any
   RMR region associated with the device such that there is a unity
   mapping for them in SMMU.
---    

From RFC v1:
-
The series adds support to IORT RMR nodes specified in IORT
Revision E -ARM DEN 0049E[0]. RMR nodes are used to describe memory
ranges that are used by endpoints and require a unity mapping
in SMMU.

We have faced issues with 3408iMR RAID controller cards which
fail to boot when SMMU is enabled. This is because these controllers
make use of host memory for various caching related purposes and when
SMMU is enabled the iMR firmware fails to access these memory regions
as there is no mapping for them. IORT RMR provides a way for UEFI to
describe and report these memory regions so that the kernel can make
a unity mapping for these in SMMU.

Tests:

With a UEFI, that reports the RMR for the dev,

[16F0h 5872   1] Type : 06
[16F1h 5873   2]   Length : 007C
[16F3h 5875   1] Revision : 00
[1038h 0056   2] Reserved : 
[1038h 0056   2]   Identifier : 
[16F8h 5880   4]Mapping Count : 0001
[16FCh 5884   4]   Mapping Offset : 0040

[1700h 5888   4]Number of RMR Descriptors : 0002
[1704h 5892   4]RMR Descriptor Offset : 0018

[1708h 5896   8]  Base Address of RMR : E640
[1710h 5904   8]Length of RMR : 0010
[1718h 5912   4] Reserved : 

[171Ch 5916   8]  Base Address of RMR : 27B0
[1724h 5924   8]Length of RMR : 00C0
[172Ch 5932   4] Reserved : 

[1730h 5936   4]   Input base : 
[1734h 5940   4] ID Count : 0001
[1738h 5944   4]  Output Base : 0003
[173Ch 5948   4] Output Reference : 0064
[1740h 5952   4]Flags (decoded below) : 0001
   Single Mapping : 1
...

Without the series the RAID controller initialization fails as
below,

...
[   12.631117] megaraid_sas :03:00.0: FW supports sync cache: Yes   
[   12.637360] megaraid_sas :03:00.0: megasas_disable_intr_fusion is called 
outbound_intr_mask:0x4009   
[   18.776377] megaraid_sas :03:00.0: Init cmd return status FAILED for 
SCSI host 0 

[   23.019383] megaraid_sas :03:00.0: Waiting for FW to come to ready state 
[  106.684281] megaraid_sas :03:00.0: FW in FAULT state, Fault code:0x1 
subcode:0x0 func:megasas_transition_to_ready
[  106.695186] megaraid_sas :03:00.0: System Register set:  
[  106.889787] megaraid_sas :03:00.0: Failed to transition controller to 
ready for scsi0.
   
[  106.910475] megaraid_sas :03:00.0: Failed from megasas_init_fw 6407  
estuary:/$

With the series, now the kernel has direct mapping for the dev as
below,

estuary:/$ cat /sys/kernel/iommu_groups/0/reserved_regions  
0x0800 0x080f msi   
0x27b0 0x286f direct
0xe640 0xe64f direct
estuary:/$


[   12.254318] megaraid_sas :03:00.0: megasas_disable_intr_fusion is called 
outbound_intr_mask:0x4009   
[   12.739089] 

Re: swiotlb cleanups v3

2021-04-20 Thread Christoph Hellwig
On Sat, Apr 17, 2021 at 11:39:22AM -0500, Tom Lendacky wrote:
> Somewhere between the 1st and 2nd patch, specifying a specific swiotlb
> for an SEV guest is no longer honored. For example, if I start an SEV
> guest with 16GB of memory and specify swiotlb=131072 I used to get a
> 256MB SWIOTLB. However, after the 2nd patch, the swiotlb=131072 is no
> longer honored and I get a 982MB SWIOTLB (as set via sev_setup_arch() in
> arch/x86/mm/mem_encrypt.c).
> 
> I can't be sure which patch caused the issue since an SEV guest fails to
> boot with the 1st patch but can boot with the 2nd patch, at which point
> the SWIOTLB comes in at 982MB (I haven't had a chance to debug it and so
> I'm hoping you might be able to quickly spot what's going on).

Can you try this patch?

diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c
index 0a5b6f7e75bce6..ac81ef97df32f5 100644
--- a/kernel/dma/swiotlb.c
+++ b/kernel/dma/swiotlb.c
@@ -71,15 +71,17 @@ struct io_tlb_mem *io_tlb_default_mem;
  */
 static unsigned int max_segment;
 
-static unsigned long default_nslabs = IO_TLB_DEFAULT_SIZE >> IO_TLB_SHIFT;
+static unsigned long swiotlb_cmdline_size;
 
 static int __init
 setup_io_tlb_npages(char *str)
 {
if (isdigit(*str)) {
/* avoid tail segment of size < IO_TLB_SEGSIZE */
-   default_nslabs =
-   ALIGN(simple_strtoul(str, , 0), IO_TLB_SEGSIZE);
+   unsigned long nslabs = simple_strtoul(str, , 0);
+
+   swiotlb_cmdline_size =
+   ALIGN(nslabs, IO_TLB_SEGSIZE) << IO_TLB_SHIFT;
}
if (*str == ',')
++str;
@@ -108,7 +110,9 @@ void swiotlb_set_max_segment(unsigned int val)
 
 unsigned long swiotlb_size_or_default(void)
 {
-   return default_nslabs << IO_TLB_SHIFT;
+   if (swiotlb_cmdline_size)
+   return swiotlb_cmdline_size;
+   return IO_TLB_DEFAULT_SIZE;
 }
 
 void __init swiotlb_adjust_size(unsigned long size)
@@ -118,9 +122,10 @@ void __init swiotlb_adjust_size(unsigned long size)
 * architectures such as those supporting memory encryption to
 * adjust/expand SWIOTLB size for their use.
 */
-   size = ALIGN(size, IO_TLB_SIZE);
-   default_nslabs = ALIGN(size >> IO_TLB_SHIFT, IO_TLB_SEGSIZE);
-   pr_info("SWIOTLB bounce buffer size adjusted to %luMB", size >> 20);
+   if (!swiotlb_cmdline_size)
+   swiotlb_cmdline_size = ALIGN(size, IO_TLB_SIZE);
+   pr_info("SWIOTLB bounce buffer size adjusted to %luMB",
+   swiotlb_cmdline_size >> 20);
 }
 
 void swiotlb_print_info(void)
@@ -209,7 +214,7 @@ int __init swiotlb_init_with_tbl(char *tlb, unsigned long 
nslabs, int verbose)
 void  __init
 swiotlb_init(int verbose)
 {
-   size_t bytes = PAGE_ALIGN(default_nslabs << IO_TLB_SHIFT);
+   size_t bytes = PAGE_ALIGN(swiotlb_size_or_default());
void *tlb;
 
if (swiotlb_force == SWIOTLB_NO_FORCE)
@@ -219,7 +224,7 @@ swiotlb_init(int verbose)
tlb = memblock_alloc_low(bytes, PAGE_SIZE);
if (!tlb)
goto fail;
-   if (swiotlb_init_with_tbl(tlb, default_nslabs, verbose))
+   if (swiotlb_init_with_tbl(tlb, bytes >> IO_TLB_SHIFT, verbose))
goto fail_free_mem;
return;
 
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [RFC v1 PATCH 3/3] driver: update all the code that use soc_device_match

2021-04-20 Thread Arnd Bergmann
On Tue, Apr 20, 2021 at 1:44 AM Dominique MARTINET
 wrote:
> Arnd Bergmann wrote on Mon, Apr 19, 2021 at 02:16:36PM +0200:
> > For built-in drivers, load order depends on the initcall level and
> > link order (how things are lined listed in the Makefile hierarchy).
> >
> > For loadable modules, this is up to user space in the end.
> >
> > Which of the drivers in this scenario are loadable modules?
>
> All the drivers involved in my case are built-in (nvmem, soc and final
> soc_device_match consumer e.g. caam_jr that crashes the kernel if soc is
> not identified properly).

Ok, in that case you may have a chance to just adapt the initcall
levels. This is somewhat fragile if someone else already relies
on a particular order, but it's an easy one-line change to change
a driver e.g. from module_init() or device_initcall() to arch_initcall().

> I frankly don't like the idea of moving nvmem/ above soc/ in
> drivers/Makefile as a "solution" to this (especially as there is one
> that seems to care about what soc they run on...), so I'll have a look
> at links first, hopefully that will work out.

Right, that would be way more fragile.

I think the main problem in this case is the caam driver that really
should not look into the particular SoC type or even machine
compatible string. This is something we can do as a last resort
for compatibility with busted devicetree files, but it appears that
this driver does it as the primary method for identifying different
hardware revisions. I would suggest fixing the binding so that
each SoC that includes one of these devices has a soc specific
compatible string associated with the device that the driver can
use as the primary way of identifying the device.

We probably need to keep the old logic around for old dtb files,
but there can at least be a comment next to that table that
discourages people from adding more entries there.

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


Re: [RFC v1 PATCH 3/3] driver: update all the code that use soc_device_match

2021-04-20 Thread Arnd Bergmann
On Tue, Apr 20, 2021 at 1:44 AM Dominique MARTINET
 wrote:
> Arnd Bergmann wrote on Mon, Apr 19, 2021 at 02:16:36PM +0200:
> > For built-in drivers, load order depends on the initcall level and
> > link order (how things are lined listed in the Makefile hierarchy).
> >
> > For loadable modules, this is up to user space in the end.
> >
> > Which of the drivers in this scenario are loadable modules?
>
> All the drivers involved in my case are built-in (nvmem, soc and final
> soc_device_match consumer e.g. caam_jr that crashes the kernel if soc is
> not identified properly).

Ok, in that case you may have a chance to just adapt the initcall
levels. This is somewhat fragile if someone else already relies
on a particular order, but it's an easy one-line change to change
a driver e.g. from module_init() or device_initcall() to arch_initcall().

> I frankly don't like the idea of moving nvmem/ above soc/ in
> drivers/Makefile as a "solution" to this (especially as there is one
> that seems to care about what soc they run on...), so I'll have a look
> at links first, hopefully that will work out.

Right, that would be way more fragile.

I think the main problem in this case is the caam driver that really
should not look into the particular SoC type or even machine
compatible string. This is something we can do as a last resort
for compatibility with busted devicetree files, but it appears that
this driver does it as the primary method for identifying different
hardware revisions. I would suggest fixing the binding so that
each SoC that includes one of these devices has a soc specific
compatible string associated with the device that the driver can
use as the primary way of identifying the device.

We probably need to keep the old logic around for old dtb files,
but there can at least be a comment next to that table that
discourages people from adding more entries there.

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


Re: [PATCH 2/2] iommu/amd: Remove performance counter pre-initialization test

2021-04-20 Thread Suthikulpanit, Suravee

David / Joerg,

On 4/10/2021 5:03 PM, David Coe wrote:


The immediately obvious difference is the with the enormous count seen on 
mem_dte_mis on the older Ryzen 2400G. Will do some RTFM but anyone with 
comments and insight?

841,689,151,202,939   amd_iommu_0/mem_dte_mis/  (33.44%)

Otherwise, all seems to running smoothly (especially for a distribution still 
in β). Bravo and many thanks all!


The initial hypothesis is that the issue happens only when users specify more 
number of events than
the available counters, which Perf will time-multiplex the events onto the 
counters.

Looking at the Perf and AMD IOMMU PMU multiplexing logic, it requires:
 1. Stop the counter (i.e. set CSOURCE to zero to stop counting)
 2. Save the counter value of the current event
 3. Reload the counter value of the new event (previously saved)
 4. Start the counter (i.e. set CSOURCE to count new events)

The problem here is that when the driver writes zero to CSOURCE register in 
step 1, this would enable power-gating,
which prevents access to the counter and result in writing/reading value in 
step 2 and 3.

I have found a system that reproduced this case (w/ unusually large number of 
count), and debug the issue further.
As a hack, I have tried skipping step 1, and it seems to eliminate this issue. 
However, this is logically incorrect,
and might result in inaccurate data depending on the events.

Here are the options:
1. Continue to look for workaround for this issue.
2. Find a way to disable event time-multiplexing (e.g. only limit the number of 
counters to 8)
   if power gating is enabled on the platform.
3. Back to the original logic where we had the pre-init check of the counter 
vlues, which is still the safest choice
   at the moment unless

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

Re: [PATCH v3 02/12] iommu: Add iommu_split_block interface

2021-04-20 Thread Lu Baolu

On 4/20/21 3:32 PM, Keqian Zhu wrote:

Hi Baolu,

Cheers for the your quick reply.

On 2021/4/20 10:09, Lu Baolu wrote:

Hi Keqian,

On 4/20/21 9:25 AM, Keqian Zhu wrote:

Hi Baolu,

On 2021/4/19 21:33, Lu Baolu wrote:

Hi Keqian,

On 2021/4/19 17:32, Keqian Zhu wrote:

+EXPORT_SYMBOL_GPL(iommu_split_block);

Do you really have any consumers of this interface other than the dirty
bit tracking? If not, I don't suggest to make this as a generic IOMMU
interface.

There is an implicit requirement for such interfaces. The
iommu_map/unmap(iova, size) shouldn't be called at the same time.
Currently there's no such sanity check in the iommu core. A poorly
written driver could mess up the kernel by misusing this interface.

Yes, I don't think up a scenario except dirty tracking.

Indeed, we'd better not make them as a generic interface.

Do you have any suggestion that underlying iommu drivers can share these code 
but
not make it as a generic iommu interface?

I have a not so good idea. Make the "split" interfaces as a static function, and
transfer the function pointer to start_dirty_log. But it looks weird and 
inflexible.


I understand splitting/merging super pages is an optimization, but not a
functional requirement. So is it possible to let the vendor iommu driver
decide whether splitting super pages when starting dirty bit tracking
and the opposite operation during when stopping it? The requirement for

Right. If I understand you correct, actually that is what this series does.


I mean to say no generic APIs, jut do it by the iommu subsystem itself.
It's totally transparent to the upper level, just like what map() does.
The upper layer doesn't care about either super page or small page is
in use when do a mapping, right?

If you want to consolidate some code, how about putting them in
start/stop_tracking()?


Yep, this reminds me. What we want to reuse is the logic of "chunk by chunk" in 
split().
We can implement switch_dirty_log to be "chunk by chunk" too (just the same as 
sync/clear),
then the vendor iommu driver can invoke it's own private implementation of 
split().
So we can completely remove split() in the IOMMU core layer.

example code logic

iommu.c:
switch_dirty_log(big range) {
 for_each_iommu_page(big range) {
   ops->switch_dirty_log(iommu_pgsize)
 }
}

vendor iommu driver:
switch_dirty_log(iommu_pgsize) {

 if (enable) {
 ops->split_block(iommu_pgsize)
 /* And other actions, such as enable hardware capability */
 } else {
 for_each_continuous_physical_address(iommu_pgsize)
 ops->merge_page()
 }
}

Besides, vendor iommu driver can invoke split() in clear_dirty_log instead of 
in switch_dirty_log.
The benefit is that we usually clear dirty log gradually during dirty tracking, 
then we can split
large page mapping gradually, which speedup start_dirty_log and make less side 
effect on DMA performance.

Does it looks good for you?


Yes. It's clearer now.



Thanks,
Keqian



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


Re: [PATCH v3 02/12] iommu: Add iommu_split_block interface

2021-04-20 Thread Keqian Zhu
Hi Baolu,

Cheers for the your quick reply.

On 2021/4/20 10:09, Lu Baolu wrote:
> Hi Keqian,
> 
> On 4/20/21 9:25 AM, Keqian Zhu wrote:
>> Hi Baolu,
>>
>> On 2021/4/19 21:33, Lu Baolu wrote:
>>> Hi Keqian,
>>>
>>> On 2021/4/19 17:32, Keqian Zhu wrote:
>> +EXPORT_SYMBOL_GPL(iommu_split_block);
> Do you really have any consumers of this interface other than the dirty
> bit tracking? If not, I don't suggest to make this as a generic IOMMU
> interface.
>
> There is an implicit requirement for such interfaces. The
> iommu_map/unmap(iova, size) shouldn't be called at the same time.
> Currently there's no such sanity check in the iommu core. A poorly
> written driver could mess up the kernel by misusing this interface.
 Yes, I don't think up a scenario except dirty tracking.

 Indeed, we'd better not make them as a generic interface.

 Do you have any suggestion that underlying iommu drivers can share these 
 code but
 not make it as a generic iommu interface?

 I have a not so good idea. Make the "split" interfaces as a static 
 function, and
 transfer the function pointer to start_dirty_log. But it looks weird and 
 inflexible.
>>>
>>> I understand splitting/merging super pages is an optimization, but not a
>>> functional requirement. So is it possible to let the vendor iommu driver
>>> decide whether splitting super pages when starting dirty bit tracking
>>> and the opposite operation during when stopping it? The requirement for
>> Right. If I understand you correct, actually that is what this series does.
> 
> I mean to say no generic APIs, jut do it by the iommu subsystem itself.
> It's totally transparent to the upper level, just like what map() does.
> The upper layer doesn't care about either super page or small page is
> in use when do a mapping, right?
> 
> If you want to consolidate some code, how about putting them in
> start/stop_tracking()?

Yep, this reminds me. What we want to reuse is the logic of "chunk by chunk" in 
split().
We can implement switch_dirty_log to be "chunk by chunk" too (just the same as 
sync/clear),
then the vendor iommu driver can invoke it's own private implementation of 
split().
So we can completely remove split() in the IOMMU core layer.

example code logic

iommu.c:
switch_dirty_log(big range) {
for_each_iommu_page(big range) {
  ops->switch_dirty_log(iommu_pgsize)
}
}

vendor iommu driver:
switch_dirty_log(iommu_pgsize) {

if (enable) {
ops->split_block(iommu_pgsize)
/* And other actions, such as enable hardware capability */
} else {
for_each_continuous_physical_address(iommu_pgsize)
ops->merge_page()
}
}

Besides, vendor iommu driver can invoke split() in clear_dirty_log instead of 
in switch_dirty_log.
The benefit is that we usually clear dirty log gradually during dirty tracking, 
then we can split
large page mapping gradually, which speedup start_dirty_log and make less side 
effect on DMA performance.

Does it looks good for you?

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


Re: [PATCH] pci: Rename pci_dev->untrusted to pci_dev->external

2021-04-20 Thread Christoph Hellwig
On Mon, Apr 19, 2021 at 05:30:49PM -0700, Rajat Jain wrote:
> The current flag name "untrusted" is not correct as it is populated
> using the firmware property "external-facing" for the parent ports. In
> other words, the firmware only says which ports are external facing, so
> the field really identifies the devices as external (vs internal).
> 
> Only field renaming. No functional change intended.

I don't think this is a good idea.  First the field should have been
added to the generic struct device as requested multiple times before.
Right now this requires horrible hacks in the IOMMU code to get at the
pci_dev, and also doesn't scale to various other potential users.

Second the untrusted is objectively a better name.  Because untrusted
is how we treat the device, which is what mattes.  External is just
how we come to that conclusion.
___
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-20 Thread Sai Prakash Ranjan

On 2021-04-19 20:08, 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.

Suggested-by: Akhil P Oommen 
Signed-off-by: Sai Prakash Ranjan 


Sorry for taking my time thinking about this.

Reviewed-by: Bjorn Andersson 



No worries, thanks Bjorn.

--
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


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

2021-04-20 Thread Sai Prakash Ranjan
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 
Reviewed-by: Bjorn Andersson 
Acked-by: Jordan Crouse 
---
 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


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

2021-04-20 Thread Sai Prakash Ranjan
Add compatible for SC7280 SMMU to use the Qualcomm Technologies, Inc.
specific implementation.

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


[PATCHv3 0/2] iommu/arm-smmu-qcom: Add SC7280 support

2021-04-20 Thread Sai Prakash Ranjan
Patch 1 adds the sc7280 smmu compatible.
Patch 2 moves the adreno smmu check before apss smmu to enable
adreno smmu specific implementation.

Note that dt-binding for sc7280 is already merged.

Changes in v3:
 * Collect acks and reviews
 * Rebase on top of for-joerg/arm-smmu/updates

Changes in v2:
 * Add a comment to make sure this order is not changed in future (Jordan)

Sai Prakash Ranjan (2):
  iommu/arm-smmu-qcom: Add SC7280 SMMU compatible
  iommu/arm-smmu-qcom: Move the adreno smmu specific impl earlier

 drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 14 +++---
 1 file changed, 11 insertions(+), 3 deletions(-)

-- 
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