RE: [PATCH] dma-mapping: benchmark: Extract a common header file for map_benchmark definition

2022-02-10 Thread Song Bao Hua (Barry Song) via iommu



> -Original Message-
> From: tiantao (H)
> Sent: Friday, February 11, 2022 4:15 PM
> To: Song Bao Hua (Barry Song) ; sh...@kernel.org;
> chenxiang (M) 
> Cc: iommu@lists.linux-foundation.org; linux-kselft...@vger.kernel.org;
> linux...@openeuler.org
> Subject: [PATCH] dma-mapping: benchmark: Extract a common header file for
> map_benchmark definition
> 
> kernel/dma/map_benchmark.c and selftests/dma/dma_map_benchmark.c
> have duplicate map_benchmark definitions, which tends to lead to
> inconsistent changes to map_benchmark on both sides, extract a
> common header file to avoid this problem.
> 
> Signed-off-by: Tian Tao 

+To: Christoph

Looks like a right cleanup. This will help decrease the maintain
overhead in the future. Other similar selftests tools are also
doing this.

Acked-by: Barry Song 

> ---
>  kernel/dma/map_benchmark.c| 24 +-
>  kernel/dma/map_benchmark.h| 31 +++
>  .../testing/selftests/dma/dma_map_benchmark.c | 25 +--
>  3 files changed, 33 insertions(+), 47 deletions(-)
>  create mode 100644 kernel/dma/map_benchmark.h
> 
> diff --git a/kernel/dma/map_benchmark.c b/kernel/dma/map_benchmark.c
> index 9b9af1bd6be3..c05f4e242991 100644
> --- a/kernel/dma/map_benchmark.c
> +++ b/kernel/dma/map_benchmark.c
> @@ -18,29 +18,7 @@
>  #include 
>  #include 
> 
> -#define DMA_MAP_BENCHMARK_IOWR('d', 1, struct map_benchmark)
> -#define DMA_MAP_MAX_THREADS  1024
> -#define DMA_MAP_MAX_SECONDS  300
> -#define DMA_MAP_MAX_TRANS_DELAY  (10 * NSEC_PER_MSEC)
> -
> -#define DMA_MAP_BIDIRECTIONAL0
> -#define DMA_MAP_TO_DEVICE1
> -#define DMA_MAP_FROM_DEVICE  2
> -
> -struct map_benchmark {
> - __u64 avg_map_100ns; /* average map latency in 100ns */
> - __u64 map_stddev; /* standard deviation of map latency */
> - __u64 avg_unmap_100ns; /* as above */
> - __u64 unmap_stddev;
> - __u32 threads; /* how many threads will do map/unmap in parallel */
> - __u32 seconds; /* how long the test will last */
> - __s32 node; /* which numa node this benchmark will run on */
> - __u32 dma_bits; /* DMA addressing capability */
> - __u32 dma_dir; /* DMA data direction */
> - __u32 dma_trans_ns; /* time for DMA transmission in ns */
> - __u32 granule;  /* how many PAGE_SIZE will do map/unmap once a time */
> - __u8 expansion[76]; /* For future use */
> -};
> +#include "map_benchmark.h"
> 
>  struct map_benchmark_data {
>   struct map_benchmark bparam;
> diff --git a/kernel/dma/map_benchmark.h b/kernel/dma/map_benchmark.h
> new file mode 100644
> index ..62674c83bde4
> --- /dev/null
> +++ b/kernel/dma/map_benchmark.h
> @@ -0,0 +1,31 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Copyright (C) 2022 HiSilicon Limited.
> + */
> +
> +#ifndef _KERNEL_DMA_BENCHMARK_H
> +#define _KERNEL_DMA_BENCHMARK_H
> +
> +#define DMA_MAP_BENCHMARK   _IOWR('d', 1, struct map_benchmark)
> +#define DMA_MAP_MAX_THREADS 1024
> +#define DMA_MAP_MAX_SECONDS 300
> +#define DMA_MAP_MAX_TRANS_DELAY (10 * NSEC_PER_MSEC)
> +
> +#define DMA_MAP_BIDIRECTIONAL   0
> +#define DMA_MAP_TO_DEVICE   1
> +#define DMA_MAP_FROM_DEVICE 2
> +
> +struct map_benchmark {
> + __u64 avg_map_100ns; /* average map latency in 100ns */
> + __u64 map_stddev; /* standard deviation of map latency */
> + __u64 avg_unmap_100ns; /* as above */
> + __u64 unmap_stddev;
> + __u32 threads; /* how many threads will do map/unmap in parallel */
> + __u32 seconds; /* how long the test will last */
> + __s32 node; /* which numa node this benchmark will run on */
> + __u32 dma_bits; /* DMA addressing capability */
> + __u32 dma_dir; /* DMA data direction */
> + __u32 dma_trans_ns; /* time for DMA transmission in ns */
> + __u32 granule;  /* how many PAGE_SIZE will do map/unmap once a time */
> +};
> +#endif /* _KERNEL_DMA_BENCHMARK_H */
> diff --git a/tools/testing/selftests/dma/dma_map_benchmark.c
> b/tools/testing/selftests/dma/dma_map_benchmark.c
> index 485dff51bad2..33bf073071aa 100644
> --- a/tools/testing/selftests/dma/dma_map_benchmark.c
> +++ b/tools/testing/selftests/dma/dma_map_benchmark.c
> @@ -11,39 +11,16 @@
>  #include 
>  #include 
>  #include 
> +#include "../../../../kernel/dma/map_benchmark.h"
> 
>  #define NSEC_PER_MSEC100L
> 
> -#define DMA_MAP_BENCHMARK_IOWR('d', 1, struct map_benchmark)
> -#define DMA_MAP_MAX_THREADS  1024
> -#define DMA_MAP_MAX_SECONDS 300
> -#define DMA_MAP_MAX_TRANS_DELAY  (10 * NSEC_PER_MSEC)
> -
> -#define DMA_MAP_BIDIRECTIONAL0
> -#define DMA_MAP_TO_DEVICE1
> -#define DMA_MAP_FROM_DEVICE  2
> -
>  static char *directions[] = {
>   "BIDIRECTIONAL",
>   "TO_DEVICE",
>   "FROM_DEVICE",
>  };
> 
> -struct map_benchmark {
> - __u64 avg_map_100ns; /* average map latency in 100ns */
> - __u64 map_stddev; /* standard deviation of map latency */
> -   

[PATCH] dma-mapping: benchmark: Extract a common header file for map_benchmark definition

2022-02-10 Thread Tian Tao via iommu
kernel/dma/map_benchmark.c and selftests/dma/dma_map_benchmark.c
have duplicate map_benchmark definitions, which tends to lead to
inconsistent changes to map_benchmark on both sides, extract a
common header file to avoid this problem.

Signed-off-by: Tian Tao 
---
 kernel/dma/map_benchmark.c| 24 +-
 kernel/dma/map_benchmark.h| 31 +++
 .../testing/selftests/dma/dma_map_benchmark.c | 25 +--
 3 files changed, 33 insertions(+), 47 deletions(-)
 create mode 100644 kernel/dma/map_benchmark.h

diff --git a/kernel/dma/map_benchmark.c b/kernel/dma/map_benchmark.c
index 9b9af1bd6be3..c05f4e242991 100644
--- a/kernel/dma/map_benchmark.c
+++ b/kernel/dma/map_benchmark.c
@@ -18,29 +18,7 @@
 #include 
 #include 
 
-#define DMA_MAP_BENCHMARK  _IOWR('d', 1, struct map_benchmark)
-#define DMA_MAP_MAX_THREADS1024
-#define DMA_MAP_MAX_SECONDS300
-#define DMA_MAP_MAX_TRANS_DELAY(10 * NSEC_PER_MSEC)
-
-#define DMA_MAP_BIDIRECTIONAL  0
-#define DMA_MAP_TO_DEVICE  1
-#define DMA_MAP_FROM_DEVICE2
-
-struct map_benchmark {
-   __u64 avg_map_100ns; /* average map latency in 100ns */
-   __u64 map_stddev; /* standard deviation of map latency */
-   __u64 avg_unmap_100ns; /* as above */
-   __u64 unmap_stddev;
-   __u32 threads; /* how many threads will do map/unmap in parallel */
-   __u32 seconds; /* how long the test will last */
-   __s32 node; /* which numa node this benchmark will run on */
-   __u32 dma_bits; /* DMA addressing capability */
-   __u32 dma_dir; /* DMA data direction */
-   __u32 dma_trans_ns; /* time for DMA transmission in ns */
-   __u32 granule;  /* how many PAGE_SIZE will do map/unmap once a time */
-   __u8 expansion[76]; /* For future use */
-};
+#include "map_benchmark.h"
 
 struct map_benchmark_data {
struct map_benchmark bparam;
diff --git a/kernel/dma/map_benchmark.h b/kernel/dma/map_benchmark.h
new file mode 100644
index ..62674c83bde4
--- /dev/null
+++ b/kernel/dma/map_benchmark.h
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2022 HiSilicon Limited.
+ */
+
+#ifndef _KERNEL_DMA_BENCHMARK_H
+#define _KERNEL_DMA_BENCHMARK_H
+
+#define DMA_MAP_BENCHMARK   _IOWR('d', 1, struct map_benchmark)
+#define DMA_MAP_MAX_THREADS 1024
+#define DMA_MAP_MAX_SECONDS 300
+#define DMA_MAP_MAX_TRANS_DELAY (10 * NSEC_PER_MSEC)
+
+#define DMA_MAP_BIDIRECTIONAL   0
+#define DMA_MAP_TO_DEVICE   1
+#define DMA_MAP_FROM_DEVICE 2
+
+struct map_benchmark {
+   __u64 avg_map_100ns; /* average map latency in 100ns */
+   __u64 map_stddev; /* standard deviation of map latency */
+   __u64 avg_unmap_100ns; /* as above */
+   __u64 unmap_stddev;
+   __u32 threads; /* how many threads will do map/unmap in parallel */
+   __u32 seconds; /* how long the test will last */
+   __s32 node; /* which numa node this benchmark will run on */
+   __u32 dma_bits; /* DMA addressing capability */
+   __u32 dma_dir; /* DMA data direction */
+   __u32 dma_trans_ns; /* time for DMA transmission in ns */
+   __u32 granule;  /* how many PAGE_SIZE will do map/unmap once a time */
+};
+#endif /* _KERNEL_DMA_BENCHMARK_H */
diff --git a/tools/testing/selftests/dma/dma_map_benchmark.c 
b/tools/testing/selftests/dma/dma_map_benchmark.c
index 485dff51bad2..33bf073071aa 100644
--- a/tools/testing/selftests/dma/dma_map_benchmark.c
+++ b/tools/testing/selftests/dma/dma_map_benchmark.c
@@ -11,39 +11,16 @@
 #include 
 #include 
 #include 
+#include "../../../../kernel/dma/map_benchmark.h"
 
 #define NSEC_PER_MSEC  100L
 
-#define DMA_MAP_BENCHMARK  _IOWR('d', 1, struct map_benchmark)
-#define DMA_MAP_MAX_THREADS1024
-#define DMA_MAP_MAX_SECONDS 300
-#define DMA_MAP_MAX_TRANS_DELAY(10 * NSEC_PER_MSEC)
-
-#define DMA_MAP_BIDIRECTIONAL  0
-#define DMA_MAP_TO_DEVICE  1
-#define DMA_MAP_FROM_DEVICE2
-
 static char *directions[] = {
"BIDIRECTIONAL",
"TO_DEVICE",
"FROM_DEVICE",
 };
 
-struct map_benchmark {
-   __u64 avg_map_100ns; /* average map latency in 100ns */
-   __u64 map_stddev; /* standard deviation of map latency */
-   __u64 avg_unmap_100ns; /* as above */
-   __u64 unmap_stddev;
-   __u32 threads; /* how many threads will do map/unmap in parallel */
-   __u32 seconds; /* how long the test will last */
-   __s32 node; /* which numa node this benchmark will run on */
-   __u32 dma_bits; /* DMA addressing capability */
-   __u32 dma_dir; /* DMA data direction */
-   __u32 dma_trans_ns; /* time for DMA transmission in ns */
-   __u32 granule; /* how many PAGE_SIZE will do map/unmap once a time */
-   __u8 expansion[76]; /* For future use */
-};
-
 int main(int argc, char **argv)
 {
struct map_benchmark map;
-- 
2.33.0

___

[PATCH 2/2] iommu/vt-d: Remove unnecessary exported symbol

2022-02-10 Thread Lu Baolu
The exported symbol intel_iommu_gfx_mapped is not used anywhere in the
tree. Remove it to avoid dead code.

Signed-off-by: Lu Baolu 
---
 include/linux/intel-iommu.h | 1 -
 drivers/iommu/intel/iommu.c | 6 --
 2 files changed, 7 deletions(-)

diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h
index 2f8a4517c929..b8b8be58cb6b 100644
--- a/include/linux/intel-iommu.h
+++ b/include/linux/intel-iommu.h
@@ -789,7 +789,6 @@ extern int iommu_calculate_agaw(struct intel_iommu *iommu);
 extern int iommu_calculate_max_sagaw(struct intel_iommu *iommu);
 extern int dmar_disabled;
 extern int intel_iommu_enabled;
-extern int intel_iommu_gfx_mapped;
 #else
 static inline int iommu_calculate_agaw(struct intel_iommu *iommu)
 {
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index 4b06f2f365bd..88a53140c7f1 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -311,9 +311,6 @@ static int iommu_skip_te_disable;
 #define IDENTMAP_GFX   2
 #define IDENTMAP_AZALIA4
 
-int intel_iommu_gfx_mapped;
-EXPORT_SYMBOL_GPL(intel_iommu_gfx_mapped);
-
 static DEFINE_XARRAY_ALLOC(device_domain_array);
 
 /* Convert device source ID into the index of device_domain_array. */
@@ -4070,9 +4067,6 @@ int __init intel_iommu_init(void)
if (list_empty(_satc_units))
pr_info("No SATC found\n");
 
-   if (dmar_map_gfx)
-   intel_iommu_gfx_mapped = 1;
-
init_no_remapping_devices();
 
ret = init_dmars();
-- 
2.25.1

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


[PATCH 1/2] agp/intel: Use per device iommu check

2022-02-10 Thread Lu Baolu
The IOMMU subsystem has already provided an interface to query whether
the IOMMU hardware is enabled for a specific device. This changes the
check from Intel specific intel_iommu_gfx_mapped (globally exported by
the Intel IOMMU driver) to probing the presence of IOMMU on a specific
device using the generic device_iommu_mapped().

This follows commit cca084692394a ("drm/i915: Use per device iommu check")
which converted drm/i915 driver to use device_iommu_mapped().

Signed-off-by: Lu Baolu 
---
 drivers/char/agp/intel-gtt.c | 17 +++--
 1 file changed, 7 insertions(+), 10 deletions(-)

diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c
index c53cc9868cd8..9631cbc7002e 100644
--- a/drivers/char/agp/intel-gtt.c
+++ b/drivers/char/agp/intel-gtt.c
@@ -20,7 +20,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
 #include "agp.h"
@@ -573,18 +573,15 @@ static void intel_gtt_cleanup(void)
  */
 static inline int needs_ilk_vtd_wa(void)
 {
-#ifdef CONFIG_INTEL_IOMMU
const unsigned short gpu_devid = intel_private.pcidev->device;
 
-   /* Query intel_iommu to see if we need the workaround. Presumably that
-* was loaded first.
+   /*
+* Query iommu subsystem to see if we need the workaround. Presumably
+* that was loaded first.
 */
-   if ((gpu_devid == PCI_DEVICE_ID_INTEL_IRONLAKE_D_IG ||
-gpu_devid == PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG) &&
-intel_iommu_gfx_mapped)
-   return 1;
-#endif
-   return 0;
+   return ((gpu_devid == PCI_DEVICE_ID_INTEL_IRONLAKE_D_IG ||
+gpu_devid == PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG) &&
+   device_iommu_mapped(_private.pcidev->dev));
 }
 
 static bool intel_gtt_can_wc(void)
-- 
2.25.1

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


[PATCH 0/2] Replace intel_iommu_gfx_mapped with device_iommu_mapped()

2022-02-10 Thread Lu Baolu
Hi,

This follows commit cca084692394a ("drm/i915: Use per device iommu check")
to convert intel_iommu_gfx_mapped use in agp/intel to device_iommu_mapped().
With this changed, the export intel_iommu_gfx_mapped could be removed.

Best regards,
baolu

Lu Baolu (2):
  agp/intel: Use per device iommu check
  iommu/vt-d: Remove unnecessary exported symbol

 include/linux/intel-iommu.h  |  1 -
 drivers/char/agp/intel-gtt.c | 17 +++--
 drivers/iommu/intel/iommu.c  |  6 --
 3 files changed, 7 insertions(+), 17 deletions(-)

-- 
2.25.1

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


[PATCH] iommu/vt-d: Fix list_add double add when enabling VMD and scalable mode

2022-02-10 Thread Adrian Huang
From: Adrian Huang 

When enabling VMD and IOMMU scalable mode, the following kernel panic
call trace/kernel log is shown in Eagle Stream platform (Sapphire Rapids
CPU) during booting:

pci :59:00.5: Adding to iommu group 42
...
vmd :59:00.5: PCI host bridge to bus 1:80
pci 1:80:01.0: [8086:352a] type 01 class 0x060400
pci 1:80:01.0: reg 0x10: [mem 0x-0x0001 64bit]
pci 1:80:01.0: enabling Extended Tags
pci 1:80:01.0: PME# supported from D0 D3hot D3cold
pci 1:80:01.0: DMAR: Setup RID2PASID failed
pci 1:80:01.0: Failed to add to iommu group 42: -16
pci 1:80:03.0: [8086:352b] type 01 class 0x060400
pci 1:80:03.0: reg 0x10: [mem 0x-0x0001 64bit]
pci 1:80:03.0: enabling Extended Tags
pci 1:80:03.0: PME# supported from D0 D3hot D3cold
list_add double add: new=ff4d61160b74b8a0, prev=ff4d611d8e245c10, 
next=ff4d61160b74b8a0.
[ cut here ]
kernel BUG at lib/list_debug.c:29!
invalid opcode:  [#1] PREEMPT SMP NOPTI
CPU: 0 PID: 7 Comm: kworker/0:1 Not tainted 5.17.0-rc3+ #7
Hardware name: Lenovo ThinkSystem SR650V3/SB27A86647, BIOS ESE101Y-1.00 
01/13/2022
Workqueue: events work_for_cpu_fn
RIP: 0010:__list_add_valid.cold+0x26/0x3f
Code: 9a 4a ab ff 4c 89 c1 48 c7 c7 40 0c d9 9e e8 b9 b1 fe ff 0f 0b 48 89 f2 
4c 89 c1 48 89 fe 48 c7 c7 f0 0c d9 9e e8 a2 b1 fe ff <0f> 0b 48 89 d1 4c 89 c6 
4c 89 ca 48 c7 c7 98 0c d9 9e e8 8b b1 fe
RSP: :ff5ad434865b3a40 EFLAGS: 00010246
RAX: 0058 RBX: ff4d61160b74b880 RCX: ff4d61255e1fffa8
RDX:  RSI: fffe RDI: 9fd34f20
RBP: ff4d611d8e245c00 R08:  R09: ff5ad434865b3888
R10: ff5ad434865b3880 R11: ff4d61257fdc6fe8 R12: ff4d61160b74b8a0
R13: ff4d61160b74b8a0 R14: ff4d611d8e245c10 R15: ff4d611d8001ba70
FS:  () GS:ff4d611d5ea0() knlGS:
CS:  0010 DS:  ES:  CR0: 80050033
CR2: ff4d611fa1401000 CR3: 000aa0210001 CR4: 00771ef0
DR0:  DR1:  DR2: 
DR3:  DR6: fffe07f0 DR7: 0400
PKRU: 5554
Call Trace:
 
 intel_pasid_alloc_table+0x9c/0x1d0
 dmar_insert_one_dev_info+0x423/0x540
 ? device_to_iommu+0x12d/0x2f0
 intel_iommu_attach_device+0x116/0x290
 __iommu_attach_device+0x1a/0x90
 iommu_group_add_device+0x190/0x2c0
 __iommu_probe_device+0x13e/0x250
 iommu_probe_device+0x24/0x150
 iommu_bus_notifier+0x69/0x90
 blocking_notifier_call_chain+0x5a/0x80
 device_add+0x3db/0x7b0
 ? arch_memremap_can_ram_remap+0x19/0x50
 ? memremap+0x75/0x140
 pci_device_add+0x193/0x1d0
 pci_scan_single_device+0xb9/0xf0
 pci_scan_slot+0x4c/0x110
 pci_scan_child_bus_extend+0x3a/0x290
 vmd_enable_domain.constprop.0+0x63e/0x820
 vmd_probe+0x163/0x190
 local_pci_probe+0x42/0x80
 work_for_cpu_fn+0x13/0x20
 process_one_work+0x1e2/0x3b0
 worker_thread+0x1c4/0x3a0
 ? rescuer_thread+0x370/0x370
 kthread+0xc7/0xf0
 ? kthread_complete_and_exit+0x20/0x20
 ret_from_fork+0x1f/0x30
 
Modules linked in:
---[ end trace  ]---
...
Kernel panic - not syncing: Fatal exception
Kernel Offset: 0x1ca0 from 0x8100 (relocation range: 
0x8000-0xbfff)
---[ end Kernel panic - not syncing: Fatal exception ]---

The following 'lspci' output shows devices '1:80:*' are subdevices of
the VMD device :59:00.5:

  $ lspci
  ...
  :59:00.5 RAID bus controller: Intel Corporation Volume Management Device 
NVMe RAID Controller (rev 20)
  ...
  1:80:01.0 PCI bridge: Intel Corporation Device 352a (rev 03)
  1:80:03.0 PCI bridge: Intel Corporation Device 352b (rev 03)
  1:80:05.0 PCI bridge: Intel Corporation Device 352c (rev 03)
  1:80:07.0 PCI bridge: Intel Corporation Device 352d (rev 03)
  1:81:00.0 Non-Volatile memory controller: Intel Corporation NVMe 
Datacenter SSD [3DNAND, Beta Rock Controller]
  1:82:00.0 Non-Volatile memory controller: Intel Corporation NVMe 
Datacenter SSD [3DNAND, Beta Rock Controller]

The symptom 'list_add double add' is caused by the following failure
message:

  pci 1:80:01.0: DMAR: Setup RID2PASID failed
  pci 1:80:01.0: Failed to add to iommu group 42: -16
  pci 1:80:03.0: [8086:352b] type 01 class 0x060400

Device 1:80:01.0 is the subdevice of the VMD device :59:00.5,
so invoking intel_pasid_alloc_table() gets the pasid_table of the VMD
device :59:00.5. Here is call path:

  intel_pasid_alloc_table
pci_for_each_dma_alias
 get_alias_pasid_table
   search_pasid_table

pci_real_dma_dev() in pci_for_each_dma_alias() gets the real dma device
which is the VMD device :59:00.5. However, pte of the VMD device
:59:00.5 has been configured during this message "pci :59:00.5:
Adding to iommu group 42". So, the status -EBUSY is returned when
configuring pasid entry for device 1:80:01.0.

It then invokes dmar_remove_one_dev_info() to release
'struct device_domain_info *' from 

Re: [PATCH] iommu: Remove trivial ops->capable implementations

2022-02-10 Thread Lu Baolu

On 2/10/22 8:29 PM, Robin Murphy wrote:

Implementing ops->capable to always return false is pointless since it's
the default behaviour anyway. Clean up the unnecessary implementations.

Signed-off-by: Robin Murphy 
---

Spinning this out of my bus ops stuff (currently 30 patches and
counting...) since it would be better off alongside Baolu's cleanup
series to avoid conflicts, and I want to depend on those patches for
dev_iommu_ops() anyway.

  drivers/iommu/msm_iommu.c  | 6 --
  drivers/iommu/tegra-gart.c | 6 --
  drivers/iommu/tegra-smmu.c | 6 --
  3 files changed, 18 deletions(-)

diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c
index 06bde6b66732..22061ddbd5df 100644
--- a/drivers/iommu/msm_iommu.c
+++ b/drivers/iommu/msm_iommu.c
@@ -558,11 +558,6 @@ static phys_addr_t msm_iommu_iova_to_phys(struct 
iommu_domain *domain,
return ret;
  }
  
-static bool msm_iommu_capable(enum iommu_cap cap)

-{
-   return false;
-}
-
  static void print_ctx_regs(void __iomem *base, int ctx)
  {
unsigned int fsr = GET_FSR(base, ctx);
@@ -672,7 +667,6 @@ irqreturn_t msm_iommu_fault_handler(int irq, void *dev_id)
  }
  
  static struct iommu_ops msm_iommu_ops = {

-   .capable = msm_iommu_capable,
.domain_alloc = msm_iommu_domain_alloc,
.domain_free = msm_iommu_domain_free,
.attach_dev = msm_iommu_attach_dev,
diff --git a/drivers/iommu/tegra-gart.c b/drivers/iommu/tegra-gart.c
index 6a358f92c7e5..bbd287d19324 100644
--- a/drivers/iommu/tegra-gart.c
+++ b/drivers/iommu/tegra-gart.c
@@ -238,11 +238,6 @@ static phys_addr_t gart_iommu_iova_to_phys(struct 
iommu_domain *domain,
return pte & GART_PAGE_MASK;
  }
  
-static bool gart_iommu_capable(enum iommu_cap cap)

-{
-   return false;
-}
-
  static struct iommu_device *gart_iommu_probe_device(struct device *dev)
  {
if (!dev_iommu_fwspec_get(dev))
@@ -276,7 +271,6 @@ static void gart_iommu_sync(struct iommu_domain *domain,
  }
  
  static const struct iommu_ops gart_iommu_ops = {

-   .capable= gart_iommu_capable,
.domain_alloc   = gart_iommu_domain_alloc,
.domain_free= gart_iommu_domain_free,
.attach_dev = gart_iommu_attach_dev,
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index e900e3c46903..43df44f918a1 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -272,11 +272,6 @@ static void tegra_smmu_free_asid(struct tegra_smmu *smmu, 
unsigned int id)
clear_bit(id, smmu->asids);
  }
  
-static bool tegra_smmu_capable(enum iommu_cap cap)

-{
-   return false;
-}
-
  static struct iommu_domain *tegra_smmu_domain_alloc(unsigned type)
  {
struct tegra_smmu_as *as;
@@ -967,7 +962,6 @@ static int tegra_smmu_of_xlate(struct device *dev,
  }
  
  static const struct iommu_ops tegra_smmu_ops = {

-   .capable = tegra_smmu_capable,
.domain_alloc = tegra_smmu_domain_alloc,
.domain_free = tegra_smmu_domain_free,
.attach_dev = tegra_smmu_attach_dev,


Looks good to me.

Reviewed-by: Lu Baolu 

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


Re: Error when running fio against nvme-of rdma target (mlx5 driver)

2022-02-10 Thread Martin Oliveira
On 2/9/22 1:41 AM, Chaitanya Kulkarni wrote:
> On 2/8/22 6:50 PM, Martin Oliveira wrote:
> > Hello,
> >
> > We have been hitting an error when running IO over our nvme-of setup, using 
> > the mlx5 driver and we are wondering if anyone has seen anything 
> > similar/has any suggestions.
> >
> > Both initiator and target are AMD EPYC 7502 machines connected over RDMA 
> > using a Mellanox MT28908. Target has 12 NVMe SSDs which are exposed as a 
> > single NVMe fabrics device, one physical SSD per namespace.
> >
> 
> Thanks for reporting this, if you can bisect the problem on your setup
> it will help others to help you better.
> 
> -ck

Hi Chaitanya,

I went back to a kernel as old as 4.15 and the problem was still there, so I 
don't know of a good commit to start from.

I also learned that I can reproduce this with as little as 3 cards and I 
updated the firmware on the Mellanox cards to the latest version.

I'd be happy to try any tests if someone has any suggestions.

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


Re: [PATCH v4 05/11] iommu/sva: Assign a PASID to mm on PASID allocation and free it on mm exit

2022-02-10 Thread Fenghua Yu
Hi, Tony,

On Thu, Feb 10, 2022 at 10:31:42AM -0800, Fenghua Yu wrote:
> 
> On Thu, Feb 10, 2022 at 09:24:50AM -0800, Luck, Tony wrote:
> > On Thu, Feb 10, 2022 at 08:27:50AM -0800, Fenghua Yu wrote:
> > > Hi, Jacob,
> > > 
> > > On Wed, Feb 09, 2022 at 07:16:14PM -0800, Jacob Pan wrote:
> > > > Hi Fenghua,
> > > > 
> > > > On Mon,  7 Feb 2022 15:02:48 -0800, Fenghua Yu  
> > > > wrote:
> > > > 
> > > > > @@ -1047,8 +1040,6 @@ struct iommu_sva *intel_svm_bind(struct device
> > > > > *dev, struct mm_struct *mm, void }
> > > > >  
> > > > >   sva = intel_svm_bind_mm(iommu, dev, mm, flags);
> > > > > - if (IS_ERR_OR_NULL(sva))
> > > > > - intel_svm_free_pasid(mm);
> > > > If bind fails, the PASID has no IOMMU nor CPU context. It should be 
> > > > safe to
> > > > free here.
> > > 
> > > The PASID can not be freed even if bind fails. The PASID allocated earlier
> > > (either in this thread or in another thread) might be populated to other
> > > threads already and being used now.
> > > 
> > > Without freeing the PASID on bind failure, the worst case is the PASID 
> > > might
> > > not be used in the process (and will be freed on process exit anyway).
> > > 
> > > This all matches with the PASID life time described in the commit message.
> > 
> > But what does this mean for the user that failed that intel_svm_bind_mm()?
> > 
> 
> That means the user may have a PASID but there is no PASID entry for the
> device. Then ENQCMD cannot be executed successfully.
> 
> > Here's a scenario:
> > 
> > Process sets up to use PASID capable device #1. Everything works,
> > so the process has mm->pasid, and the IOMMU has the tables to map
> > virtual addresses coming from device #1 using that PASID.
> > 
> > Now the same process asks to start using PASID capable device #2,
> > but there is a failure at intel_svm_bind_mm().
> > 
> > Fenghua is right that we shouldn't free the PASID. It is in use
> > by at least one thread of the process to access device #1.
> > 
> > But what happens with device #2? Does the caller of intel_svm_bind()
> > do the right thing with the IS_ERR_OR_NULL return value to let the
> > user know that device #2 isn't accessible?
> 
> A driver caller of intel_svm_bind() should handle this failure, i.e. fail
> the binding and let the user know the failure.
> 
> Even if the driver doesn't do the right thing to handle the failure,
> intel_svm_bind() doesn't set up a PASID entry for device #2.
> 
> One example is IDXD driver. User calls open()->IDXD driver idxd_cdev_open()
> ->intel_svm_bind()->intel_svm_bind_mm(). idxd_cdev_open() gets failed "sva"
> and passes the PTR_ERR(sva) to the user and the user cannot open the device.
> Due to the failure, no PASID entry is set up for the device.
> 
> Even if the user ignores the open() failure and tries to run ENQCMD on
> device #2, a PASID table fault will be generated due to no PASID entry
> for the device and the ENQCMD execution will fail.

Plus, the above behavior of handling intel_svm_bind_mm() failure is expected
right behavior and the current series doesn't need to be changed.

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


Re: [PATCH v2 1/5] dt-bindings: reserved-memory: Document memory region specifier

2022-02-10 Thread Janne Grunau
On 2022-02-09 17:31:16 +0100, Thierry Reding wrote:
> On Sun, Feb 06, 2022 at 11:27:00PM +0100, Janne Grunau wrote:
> > On 2021-09-15 17:19:39 +0200, Thierry Reding wrote:
> > > On Tue, Sep 07, 2021 at 07:44:44PM +0200, Thierry Reding wrote:
> > > > On Tue, Sep 07, 2021 at 10:33:24AM -0500, Rob Herring wrote:
> > > > > On Fri, Sep 3, 2021 at 10:36 AM Thierry Reding 
> > > > >  wrote:
> > > > > >
> > > > > > On Fri, Sep 03, 2021 at 09:36:33AM -0500, Rob Herring wrote:
> > > > > > > On Fri, Sep 3, 2021 at 8:52 AM Thierry Reding 
> > > > > > >  wrote:
> > > > > > > >
> > > > > > > > On Fri, Sep 03, 2021 at 08:20:55AM -0500, Rob Herring wrote:
> > > > > > > > >
> > > > > > > > > Couldn't we keep this all in /reserved-memory? Just add an 
> > > > > > > > > iova
> > > > > > > > > version of reg. Perhaps abuse 'assigned-address' for this 
> > > > > > > > > purpose. The
> > > > > > > > > issue I see would be handling reserved iova areas without a 
> > > > > > > > > physical
> > > > > > > > > area. That can be handled with just a iova and no reg. We 
> > > > > > > > > already have
> > > > > > > > > a no reg case.
> > > > > > > >
> > > > > > > > I had thought about that initially. One thing I'm worried about 
> > > > > > > > is that
> > > > > > > > every child node in /reserved-memory will effectively cause the 
> > > > > > > > memory
> > > > > > > > that it described to be reserved. But we don't want that for 
> > > > > > > > regions
> > > > > > > > that are "virtual only" (i.e. IOMMU reservations).
> > > > > > >
> > > > > > > By virtual only, you mean no physical mapping, just a region of
> > > > > > > virtual space, right? For that we'd have no 'reg' and therefore no
> > > > > > > (physical) reservation by the OS. It's similar to non-static 
> > > > > > > regions.
> > > > > > > You need a specific handler for them. We'd probably want a 
> > > > > > > compatible
> > > > > > > as well for these virtual reservations.
> > > > > >
> > > > > > Yeah, these would be purely used for reserving regions in the IOVA 
> > > > > > so
> > > > > > that they won't be used by the IOVA allocator. Typically these 
> > > > > > would be
> > > > > > used for cases where those addresses have some special meaning.
> > > > > >
> > > > > > Do we want something like:
> > > > > >
> > > > > > compatible = "iommu-reserved";
> > > > > >
> > > > > > for these? Or would that need to be:
> > > > > >
> > > > > > compatible = "linux,iommu-reserved";
> > > > > >
> > > > > > ? There seems to be a mix of vendor-prefix vs. non-vendor-prefix
> > > > > > compatible strings in the reserved-memory DT bindings directory.
> > > > > 
> > > > > I would not use 'linux,' here.
> > > > > 
> > > > > >
> > > > > > On the other hand, do we actually need the compatible string? 
> > > > > > Because we
> > > > > > don't really want to associate much extra information with this 
> > > > > > like we
> > > > > > do for example with "shared-dma-pool". The logic to handle this 
> > > > > > would
> > > > > > all be within the IOMMU framework. All we really need is for the
> > > > > > standard reservation code to skip nodes that don't have a reg 
> > > > > > property
> > > > > > so we don't reserve memory for "virtual-only" allocations.
> > > > > 
> > > > > It doesn't hurt to have one and I can imagine we might want to iterate
> > > > > over all the nodes. It's slightly easier and more common to iterate
> > > > > over compatible nodes rather than nodes with some property.
> > > > > 
> > > > > > > Are these being global in DT going to be a problem? Presumably we 
> > > > > > > have
> > > > > > > a virtual space per IOMMU. We'd know which IOMMU based on a 
> > > > > > > device's
> > > > > > > 'iommus' and 'memory-region' properties, but within 
> > > > > > > /reserved-memory
> > > > > > > we wouldn't be able to distinguish overlapping addresses from 
> > > > > > > separate
> > > > > > > address spaces. Or we could have 2 different IOVAs for 1 physical
> > > > > > > space. That could be solved with something like this:
> > > > > > >
> > > > > > > iommu-addresses = <  >;
> > > > > >
> > > > > > The only case that would be problematic would be if we have 
> > > > > > overlapping
> > > > > > physical regions, because that will probably trip up the standard 
> > > > > > code.
> > > > > >
> > > > > > But this could also be worked around by looking at iommu-addresses. 
> > > > > > For
> > > > > > example, if we had something like this:
> > > > > >
> > > > > > reserved-memory {
> > > > > > fb_dc0: fb@8000 {
> > > > > > reg = <0x8000 0x0100>;
> > > > > > iommu-addresses = <0xa000 0x0100>;
> > > > > > };
> > > > > >
> > > > > > fb_dc1: fb@8000 {
> > > > > 
> > > > > You can't have 2 nodes with the same name (actually, you can, they
> > > > > just get merged together). Different names with the same unit-address
> > > > > is a dtc warning. I'd 

Re: [PATCH v4 05/11] iommu/sva: Assign a PASID to mm on PASID allocation and free it on mm exit

2022-02-10 Thread Fenghua Yu
On Thu, Feb 10, 2022 at 10:49:04AM -0800, Jacob Pan wrote:
> 
> On Wed, 9 Feb 2022 19:16:14 -0800, Jacob Pan
>  wrote:
> 
> > Hi Fenghua,
> > 
> > On Mon,  7 Feb 2022 15:02:48 -0800, Fenghua Yu 
> > wrote:
> > 
> > > @@ -1047,8 +1040,6 @@ struct iommu_sva *intel_svm_bind(struct device
> > > *dev, struct mm_struct *mm, void }
> > >  
> > >   sva = intel_svm_bind_mm(iommu, dev, mm, flags);
> > > - if (IS_ERR_OR_NULL(sva))
> > > - intel_svm_free_pasid(mm);  
> > If bind fails, the PASID has no IOMMU nor CPU context. It should be safe
> > to free here.
> > 
> Actually, here we cannot tell if the bind is the first of the mm so I think
> this is fine.
> 
> Reviewed-by: Jacob Pan 

Thank you very much for your review, Jacob!

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


Re: [PATCH v4 05/11] iommu/sva: Assign a PASID to mm on PASID allocation and free it on mm exit

2022-02-10 Thread Jacob Pan


On Wed, 9 Feb 2022 19:16:14 -0800, Jacob Pan
 wrote:

> Hi Fenghua,
> 
> On Mon,  7 Feb 2022 15:02:48 -0800, Fenghua Yu 
> wrote:
> 
> > @@ -1047,8 +1040,6 @@ struct iommu_sva *intel_svm_bind(struct device
> > *dev, struct mm_struct *mm, void }
> >  
> > sva = intel_svm_bind_mm(iommu, dev, mm, flags);
> > -   if (IS_ERR_OR_NULL(sva))
> > -   intel_svm_free_pasid(mm);  
> If bind fails, the PASID has no IOMMU nor CPU context. It should be safe
> to free here.
> 
Actually, here we cannot tell if the bind is the first of the mm so I think
this is fine.

Reviewed-by: Jacob Pan 

> Thanks,
> 
> Jacob


Thanks,

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


Re: [PATCH v4 05/11] iommu/sva: Assign a PASID to mm on PASID allocation and free it on mm exit

2022-02-10 Thread Fenghua Yu
Hi, Tony,

On Thu, Feb 10, 2022 at 09:24:50AM -0800, Luck, Tony wrote:
> On Thu, Feb 10, 2022 at 08:27:50AM -0800, Fenghua Yu wrote:
> > Hi, Jacob,
> > 
> > On Wed, Feb 09, 2022 at 07:16:14PM -0800, Jacob Pan wrote:
> > > Hi Fenghua,
> > > 
> > > On Mon,  7 Feb 2022 15:02:48 -0800, Fenghua Yu  
> > > wrote:
> > > 
> > > > @@ -1047,8 +1040,6 @@ struct iommu_sva *intel_svm_bind(struct device
> > > > *dev, struct mm_struct *mm, void }
> > > >  
> > > > sva = intel_svm_bind_mm(iommu, dev, mm, flags);
> > > > -   if (IS_ERR_OR_NULL(sva))
> > > > -   intel_svm_free_pasid(mm);
> > > If bind fails, the PASID has no IOMMU nor CPU context. It should be safe 
> > > to
> > > free here.
> > 
> > The PASID can not be freed even if bind fails. The PASID allocated earlier
> > (either in this thread or in another thread) might be populated to other
> > threads already and being used now.
> > 
> > Without freeing the PASID on bind failure, the worst case is the PASID might
> > not be used in the process (and will be freed on process exit anyway).
> > 
> > This all matches with the PASID life time described in the commit message.
> 
> But what does this mean for the user that failed that intel_svm_bind_mm()?
> 

That means the user may have a PASID but there is no PASID entry for the
device. Then ENQCMD cannot be executed successfully.

> Here's a scenario:
> 
> Process sets up to use PASID capable device #1. Everything works,
> so the process has mm->pasid, and the IOMMU has the tables to map
> virtual addresses coming from device #1 using that PASID.
> 
> Now the same process asks to start using PASID capable device #2,
> but there is a failure at intel_svm_bind_mm().
> 
> Fenghua is right that we shouldn't free the PASID. It is in use
> by at least one thread of the process to access device #1.
> 
> But what happens with device #2? Does the caller of intel_svm_bind()
> do the right thing with the IS_ERR_OR_NULL return value to let the
> user know that device #2 isn't accessible?

A driver caller of intel_svm_bind() should handle this failure, i.e. fail
the binding and let the user know the failure.

Even if the driver doesn't do the right thing to handle the failure,
intel_svm_bind() doesn't set up a PASID entry for device #2.

One example is IDXD driver. User calls open()->IDXD driver idxd_cdev_open()
->intel_svm_bind()->intel_svm_bind_mm(). idxd_cdev_open() gets failed "sva"
and passes the PTR_ERR(sva) to the user and the user cannot open the device.
Due to the failure, no PASID entry is set up for the device.

Even if the user ignores the open() failure and tries to run ENQCMD on
device #2, a PASID table fault will be generated due to no PASID entry
for the device and the ENQCMD execution will fail.

Thanks.

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


Re: [PATCH v4 05/11] iommu/sva: Assign a PASID to mm on PASID allocation and free it on mm exit

2022-02-10 Thread Luck, Tony
On Thu, Feb 10, 2022 at 08:27:50AM -0800, Fenghua Yu wrote:
> Hi, Jacob,
> 
> On Wed, Feb 09, 2022 at 07:16:14PM -0800, Jacob Pan wrote:
> > Hi Fenghua,
> > 
> > On Mon,  7 Feb 2022 15:02:48 -0800, Fenghua Yu  wrote:
> > 
> > > @@ -1047,8 +1040,6 @@ struct iommu_sva *intel_svm_bind(struct device
> > > *dev, struct mm_struct *mm, void }
> > >  
> > >   sva = intel_svm_bind_mm(iommu, dev, mm, flags);
> > > - if (IS_ERR_OR_NULL(sva))
> > > - intel_svm_free_pasid(mm);
> > If bind fails, the PASID has no IOMMU nor CPU context. It should be safe to
> > free here.
> 
> The PASID can not be freed even if bind fails. The PASID allocated earlier
> (either in this thread or in another thread) might be populated to other
> threads already and being used now.
> 
> Without freeing the PASID on bind failure, the worst case is the PASID might
> not be used in the process (and will be freed on process exit anyway).
> 
> This all matches with the PASID life time described in the commit message.

But what does this mean for the user that failed that intel_svm_bind_mm()?

Here's a scenario:

Process sets up to use PASID capable device #1. Everything works,
so the process has mm->pasid, and the IOMMU has the tables to map
virtual addresses coming from device #1 using that PASID.

Now the same process asks to start using PASID capable device #2,
but there is a failure at intel_svm_bind_mm().

Fenghua is right that we shouldn't free the PASID. It is in use
by at least one thread of the process to access device #1.

But what happens with device #2? Does the caller of intel_svm_bind()
do the right thing with the IS_ERR_OR_NULL return value to let the
user know that device #2 isn't accessible?

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


Re: [PATCH v4 05/11] iommu/sva: Assign a PASID to mm on PASID allocation and free it on mm exit

2022-02-10 Thread Fenghua Yu
Hi, Jacob,

On Wed, Feb 09, 2022 at 07:16:14PM -0800, Jacob Pan wrote:
> Hi Fenghua,
> 
> On Mon,  7 Feb 2022 15:02:48 -0800, Fenghua Yu  wrote:
> 
> > @@ -1047,8 +1040,6 @@ struct iommu_sva *intel_svm_bind(struct device
> > *dev, struct mm_struct *mm, void }
> >  
> > sva = intel_svm_bind_mm(iommu, dev, mm, flags);
> > -   if (IS_ERR_OR_NULL(sva))
> > -   intel_svm_free_pasid(mm);
> If bind fails, the PASID has no IOMMU nor CPU context. It should be safe to
> free here.

The PASID can not be freed even if bind fails. The PASID allocated earlier
(either in this thread or in another thread) might be populated to other
threads already and being used now.

Without freeing the PASID on bind failure, the worst case is the PASID might
not be used in the process (and will be freed on process exit anyway).

This all matches with the PASID life time described in the commit message.

Thanks.

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


[PATCH] iommu/amd: Fix I/O page table memory leak

2022-02-10 Thread Suravee Suthikulpanit via iommu
The current logic updates the I/O page table mode for the domain
before calling the logic to free memory used for the page table.
This results in IOMMU page table memory leak, and can be observed
when launching VM w/ pass-through devices.

Fix by freeing the memory used for page table before updating the mode.

Cc: Joerg Roedel 
Reported-by: Daniel Jordan 
Tested-by: Daniel Jordan 
Signed-off-by: Suravee Suthikulpanit 
Fixes: e42ba0633064 ("iommu/amd: Restructure code for freeing page table")
Link: https://lore.kernel.org/all/20220118194720.urjgi73b7c3tq...@oracle.com/
---
 drivers/iommu/amd/io_pgtable.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/iommu/amd/io_pgtable.c b/drivers/iommu/amd/io_pgtable.c
index b1bf4125b0f7..6608d1717574 100644
--- a/drivers/iommu/amd/io_pgtable.c
+++ b/drivers/iommu/amd/io_pgtable.c
@@ -492,18 +492,18 @@ static void v1_free_pgtable(struct io_pgtable *iop)
 
dom = container_of(pgtable, struct protection_domain, iop);
 
-   /* Update data structure */
-   amd_iommu_domain_clr_pt_root(dom);
-
-   /* Make changes visible to IOMMUs */
-   amd_iommu_domain_update(dom);
-
/* Page-table is not visible to IOMMU anymore, so free it */
BUG_ON(pgtable->mode < PAGE_MODE_NONE ||
   pgtable->mode > PAGE_MODE_6_LEVEL);
 
free_sub_pt(pgtable->root, pgtable->mode, );
 
+   /* Update data structure */
+   amd_iommu_domain_clr_pt_root(dom);
+
+   /* Make changes visible to IOMMUs */
+   amd_iommu_domain_update(dom);
+
put_pages_list();
 }
 
-- 
2.17.1

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


[PATCH] iommu/vt-d: Add missing "__init" for rmrr_sanity_check()

2022-02-10 Thread Marco Bonelli
rmrr_sanity_check() calls arch_rmrr_sanity_check(), which is marked as
"__init". Add the annotation for rmrr_sanity_check() too. This function is
currently only called from dmar_parse_one_rmrr() which is also "__init".

Signed-off-by: Marco Bonelli 
---
 drivers/iommu/intel/iommu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index 92fea3fbbb11..7a308fd8d4b9 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -3691,7 +3691,7 @@ static void __init init_iommu_pm_ops(void)
 static inline void init_iommu_pm_ops(void) {}
 #endif /* CONFIG_PM */
 
-static int rmrr_sanity_check(struct acpi_dmar_reserved_memory *rmrr)
+static int __init rmrr_sanity_check(struct acpi_dmar_reserved_memory *rmrr)
 {
if (!IS_ALIGNED(rmrr->base_address, PAGE_SIZE) ||
!IS_ALIGNED(rmrr->end_address + 1, PAGE_SIZE) ||
-- 
2.30.2

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


[PATCH] iommu: Remove trivial ops->capable implementations

2022-02-10 Thread Robin Murphy
Implementing ops->capable to always return false is pointless since it's
the default behaviour anyway. Clean up the unnecessary implementations.

Signed-off-by: Robin Murphy 
---

Spinning this out of my bus ops stuff (currently 30 patches and
counting...) since it would be better off alongside Baolu's cleanup
series to avoid conflicts, and I want to depend on those patches for
dev_iommu_ops() anyway.

 drivers/iommu/msm_iommu.c  | 6 --
 drivers/iommu/tegra-gart.c | 6 --
 drivers/iommu/tegra-smmu.c | 6 --
 3 files changed, 18 deletions(-)

diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c
index 06bde6b66732..22061ddbd5df 100644
--- a/drivers/iommu/msm_iommu.c
+++ b/drivers/iommu/msm_iommu.c
@@ -558,11 +558,6 @@ static phys_addr_t msm_iommu_iova_to_phys(struct 
iommu_domain *domain,
return ret;
 }
 
-static bool msm_iommu_capable(enum iommu_cap cap)
-{
-   return false;
-}
-
 static void print_ctx_regs(void __iomem *base, int ctx)
 {
unsigned int fsr = GET_FSR(base, ctx);
@@ -672,7 +667,6 @@ irqreturn_t msm_iommu_fault_handler(int irq, void *dev_id)
 }
 
 static struct iommu_ops msm_iommu_ops = {
-   .capable = msm_iommu_capable,
.domain_alloc = msm_iommu_domain_alloc,
.domain_free = msm_iommu_domain_free,
.attach_dev = msm_iommu_attach_dev,
diff --git a/drivers/iommu/tegra-gart.c b/drivers/iommu/tegra-gart.c
index 6a358f92c7e5..bbd287d19324 100644
--- a/drivers/iommu/tegra-gart.c
+++ b/drivers/iommu/tegra-gart.c
@@ -238,11 +238,6 @@ static phys_addr_t gart_iommu_iova_to_phys(struct 
iommu_domain *domain,
return pte & GART_PAGE_MASK;
 }
 
-static bool gart_iommu_capable(enum iommu_cap cap)
-{
-   return false;
-}
-
 static struct iommu_device *gart_iommu_probe_device(struct device *dev)
 {
if (!dev_iommu_fwspec_get(dev))
@@ -276,7 +271,6 @@ static void gart_iommu_sync(struct iommu_domain *domain,
 }
 
 static const struct iommu_ops gart_iommu_ops = {
-   .capable= gart_iommu_capable,
.domain_alloc   = gart_iommu_domain_alloc,
.domain_free= gart_iommu_domain_free,
.attach_dev = gart_iommu_attach_dev,
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index e900e3c46903..43df44f918a1 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -272,11 +272,6 @@ static void tegra_smmu_free_asid(struct tegra_smmu *smmu, 
unsigned int id)
clear_bit(id, smmu->asids);
 }
 
-static bool tegra_smmu_capable(enum iommu_cap cap)
-{
-   return false;
-}
-
 static struct iommu_domain *tegra_smmu_domain_alloc(unsigned type)
 {
struct tegra_smmu_as *as;
@@ -967,7 +962,6 @@ static int tegra_smmu_of_xlate(struct device *dev,
 }
 
 static const struct iommu_ops tegra_smmu_ops = {
-   .capable = tegra_smmu_capable,
.domain_alloc = tegra_smmu_domain_alloc,
.domain_free = tegra_smmu_domain_free,
.attach_dev = tegra_smmu_attach_dev,
-- 
2.28.0.dirty

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


Re: [PATCH] iommu: explicitly check for NULL in iommu_dma_get_resv_regions()

2022-02-10 Thread Robin Murphy

On 2022-02-09 14:09, Aleksandr Fedorov wrote:

iommu_dma_get_resv_regions() assumes that iommu_fwspec field for
corresponding device is set which is not always true.  Since
iommu_dma_get_resv_regions() seems to be a future-proof generic API
that can be used by any iommu driver, add an explicit check for NULL.


Except it's not a "generic" interface for drivers to call at random, 
it's a helper for retrieving common firmware-based information 
specifically for drivers already using the fwspec mechanism for common 
firmware bindings. If any driver calls this with a device *without* a 
valid fwnode, it deserves to crash because it's done something 
fundamentally wrong.


I concur that it's not exactly obvious that "non-IOMMU-specific" means 
"based on common firmware bindings, thus implying fwspec".


Robin.


Currently it can work by accident since compiler can eliminate
the 'iommu_fwspec' check altogether when CONFIG_ACPI_IORT=n, but
code elimination from optimizations is not reliable.

Signed-off-by: Aleksandr Fedorov 
---
A compilation failure has been observed on a gcc-compatible compiler based on 
EDG.

diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index d85d54f2b549..474b1b7211d7 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -382,10 +382,10 @@ void iommu_put_dma_cookie(struct iommu_domain *domain)
   */
  void iommu_dma_get_resv_regions(struct device *dev, struct list_head *list)
  {
+   struct iommu_fwspec *iommu_fwspec = dev_iommu_fwspec_get(dev);
  
-	if (!is_of_node(dev_iommu_fwspec_get(dev)->iommu_fwnode))

+   if (iommu_fwspec && !is_of_node(iommu_fwspec->iommu_fwnode))
iort_iommu_msi_get_resv_regions(dev, list);
-
  }
  EXPORT_SYMBOL(iommu_dma_get_resv_regions);
  
___

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

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