[PATCH v2 0/3] iommu/amd: I/O VA address limits

2020-06-30 Thread Sebastian Ott via iommu
The IVRS ACPI table specifies maximum address sizes for I/O virtual
addresses that can be handled by the IOMMUs in the system. Parse that
data from the IVRS header to provide aperture information for DMA
mappings and users of the iommu API.

Changes for V2:
 - use limits in iommu_setup_dma_ops()
 - rebased to current upstream

Sebastian Ott (3):
  iommu/amd: Parse supported address sizes from IVRS
  iommu/amd: Restrict aperture for domains to conform with IVRS
  iommu/amd: Actually enforce geometry aperture

 drivers/iommu/amd/amd_iommu_types.h |  3 +++
 drivers/iommu/amd/init.c| 26 ++
 drivers/iommu/amd/iommu.c   | 12 ++--
 3 files changed, 39 insertions(+), 2 deletions(-)

-- 
2.17.1




Amazon Development Center Germany GmbH
Krausenstr. 38
10117 Berlin
Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss
Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B
Sitz: Berlin
Ust-ID: DE 289 237 879



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


[PATCH v2 3/3] iommu/amd: Actually enforce geometry aperture

2020-06-30 Thread Sebastian Ott via iommu
Add a check to enforce that I/O virtual addresses picked by iommu API
users stay within the domains geometry aperture.

Signed-off-by: Sebastian Ott 
Cc: Benjamin Serebrin 
Cc: Filippo Sironi 

CR: https://code.amazon.com/reviews/CR-26408388
---
 drivers/iommu/amd/iommu.c | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
index b3f79820fd6d..bfa9c4a1fcf8 100644
--- a/drivers/iommu/amd/iommu.c
+++ b/drivers/iommu/amd/iommu.c
@@ -2159,11 +2159,13 @@ static struct iommu_device 
*amd_iommu_probe_device(struct device *dev)
 static void amd_iommu_probe_finalize(struct device *dev)
 {
struct iommu_domain *domain;
+   u64 base = IOVA_START_PFN << PAGE_SHIFT;
+   u64 size = amd_iommu_max_va - base;
 
/* Domains are initialized for this device - have a look what we ended 
up with */
domain = iommu_get_domain_for_dev(dev);
if (domain->type == IOMMU_DOMAIN_DMA)
-   iommu_setup_dma_ops(dev, IOVA_START_PFN << PAGE_SHIFT, 0);
+   iommu_setup_dma_ops(dev, base, size);
 }
 
 static void amd_iommu_release_device(struct device *dev)
@@ -2500,6 +2502,11 @@ static int amd_iommu_map(struct iommu_domain *dom, 
unsigned long iova,
if (pgtable.mode == PAGE_MODE_NONE)
return -EINVAL;
 
+   if (dom->geometry.force_aperture &&
+   (iova < dom->geometry.aperture_start ||
+iova + page_size - 1 > dom->geometry.aperture_end))
+   return -EINVAL;
+
if (iommu_prot & IOMMU_READ)
prot |= IOMMU_PROT_IR;
if (iommu_prot & IOMMU_WRITE)
-- 
2.17.1




Amazon Development Center Germany GmbH
Krausenstr. 38
10117 Berlin
Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss
Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B
Sitz: Berlin
Ust-ID: DE 289 237 879



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


[PATCH v2 1/3] iommu/amd: Parse supported address sizes from IVRS

2020-06-30 Thread Sebastian Ott via iommu
The IVRS ACPI table specifies maximum address sizes for i/o virtual
addresses that can be handled by the IOMMUs in the system.  Parse that
data from the IVRS header so that it can be considered in limiting the
IO aperture (in subsequent patches).

Based on prior work by Marius Hillenbrand.

Link: https://www.amd.com/system/files/TechDocs/48882_IOMMU_3.05_PUB.pdf

Signed-off-by: Sebastian Ott 
Cc: Benjamin Serebrin 
Cc: Filippo Sironi 

CR: https://code.amazon.com/reviews/CR-26408321
---
 drivers/iommu/amd/amd_iommu_types.h |  3 +++
 drivers/iommu/amd/init.c| 26 ++
 drivers/iommu/amd/iommu.c   |  1 +
 3 files changed, 30 insertions(+)

diff --git a/drivers/iommu/amd/amd_iommu_types.h 
b/drivers/iommu/amd/amd_iommu_types.h
index 30a5d412255a..0946638306d6 100644
--- a/drivers/iommu/amd/amd_iommu_types.h
+++ b/drivers/iommu/amd/amd_iommu_types.h
@@ -754,6 +754,9 @@ extern bool amd_iommu_force_isolation;
 /* Max levels of glxval supported */
 extern int amd_iommu_max_glx_val;
 
+/* Maximum virtual address supported */
+extern u64 amd_iommu_max_va;
+
 /*
  * This function flushes all internal caches of
  * the IOMMU used by this driver.
diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c
index 6ebd4825e320..ab9d226b4215 100644
--- a/drivers/iommu/amd/init.c
+++ b/drivers/iommu/amd/init.c
@@ -11,6 +11,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -39,6 +40,7 @@
  * definitions for the ACPI scanning code
  */
 #define IVRS_HEADER_LENGTH 48
+#define IVRS_HEADER_IVINFO_OFFSET 36
 
 #define ACPI_IVHD_TYPE_MAX_SUPPORTED   0x40
 #define ACPI_IVMD_TYPE_ALL  0x20
@@ -2490,6 +2492,27 @@ static void __init free_dma_resources(void)
free_unity_maps();
 }
 
+static void __init get_ivrs_ivinfo(struct acpi_table_header *ivrs)
+{
+   u32 *ivinfo = (u32 *)((u8 *)ivrs + IVRS_HEADER_IVINFO_OFFSET);
+   u8 va_size = FIELD_GET(GENMASK(21, 15), *ivinfo);
+   u8 valid_va_sizes[] = {32, 40, 48, 64};
+   int i;
+
+   for (i = 0; i < ARRAY_SIZE(valid_va_sizes); i++) {
+   if (va_size == valid_va_sizes[i]) {
+   amd_iommu_max_va = DMA_BIT_MASK(va_size);
+   break;
+   }
+   }
+
+   if (!amd_iommu_max_va) {
+   pr_warn("Invalid virtual address size %u in IVRS header, use 
most restrictive %u\n",
+   va_size, valid_va_sizes[0]);
+   amd_iommu_max_va = DMA_BIT_MASK(valid_va_sizes[0]);
+   }
+}
+
 /*
  * This is the hardware init function for AMD IOMMU in the system.
  * This function is called either from amd_iommu_init or from the interrupt
@@ -2544,6 +2567,9 @@ static int __init early_amd_iommu_init(void)
if (ret)
goto out;
 
+   get_ivrs_ivinfo(ivrs_base);
+   DUMP_printk("IVRS vasize=%llx\n", amd_iommu_max_va);
+
amd_iommu_target_ivhd_type = get_highest_supported_ivhd_type(ivrs_base);
DUMP_printk("Using IVHD type %#x\n", amd_iommu_target_ivhd_type);
 
diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
index 74cca1757172..acab35220d98 100644
--- a/drivers/iommu/amd/iommu.c
+++ b/drivers/iommu/amd/iommu.c
@@ -88,6 +88,7 @@ const struct iommu_ops amd_iommu_ops;
 
 static ATOMIC_NOTIFIER_HEAD(ppr_notifier);
 int amd_iommu_max_glx_val = -1;
+u64 amd_iommu_max_va;
 
 /*
  * general struct to manage commands send to an IOMMU
-- 
2.17.1




Amazon Development Center Germany GmbH
Krausenstr. 38
10117 Berlin
Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss
Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B
Sitz: Berlin
Ust-ID: DE 289 237 879



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


[PATCH v2 2/3] iommu/amd: Restrict aperture for domains to conform with IVRS

2020-06-30 Thread Sebastian Ott via iommu
The IVRS ACPI table specifies maximum address sizes for I/O virtual
addresses. When allocating new protection domains that perform
translation, propagate these limits as the domain's geometry / aperture.

Based on prior work by Marius Hillenbrand.

Signed-off-by: Sebastian Ott 
Cc: Benjamin Serebrin 
Cc: Filippo Sironi 

CR: https://code.amazon.com/reviews/CR-26408353
---
 drivers/iommu/amd/iommu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
index acab35220d98..b3f79820fd6d 100644
--- a/drivers/iommu/amd/iommu.c
+++ b/drivers/iommu/amd/iommu.c
@@ -2382,7 +2382,7 @@ static struct iommu_domain 
*amd_iommu_domain_alloc(unsigned type)
return NULL;
 
domain->domain.geometry.aperture_start = 0;
-   domain->domain.geometry.aperture_end   = ~0ULL;
+   domain->domain.geometry.aperture_end   = amd_iommu_max_va;
domain->domain.geometry.force_aperture = true;
 
if (type == IOMMU_DOMAIN_DMA &&
-- 
2.17.1




Amazon Development Center Germany GmbH
Krausenstr. 38
10117 Berlin
Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss
Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B
Sitz: Berlin
Ust-ID: DE 289 237 879



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


Re: [PATCH 0/3] iommu/amd: I/O VA address limits

2020-06-24 Thread Sebastian Ott via iommu

Hello Joerg,

On 2020-06-05 16:56, Sebastian Ott wrote:

The IVRS ACPI table specifies maximum address sizes for I/O virtual
addresses that can be handled by the IOMMUs in the system. Parse that
data from the IVRS header to provide aperture information for DMA
mappings and users of the iommu API.

Sebastian Ott (3):
   iommu/amd: Parse supported address sizes from IVRS
   iommu/amd: Restrict aperture for domains to conform with IVRS
   iommu/amd: Actually enforce geometry aperture

  drivers/iommu/amd_iommu.c   | 16 +++-
  drivers/iommu/amd_iommu_init.c  | 26 ++
  drivers/iommu/amd_iommu_types.h |  3 +++
  3 files changed, 40 insertions(+), 5 deletions(-)


Would you consider taking these patches for the next release?

Regards,
Sebastian




Amazon Development Center Germany GmbH
Krausenstr. 38
10117 Berlin
Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss
Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B
Sitz: Berlin
Ust-ID: DE 289 237 879


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


[PATCH 1/3] iommu/amd: Parse supported address sizes from IVRS

2020-06-05 Thread Sebastian Ott via iommu
The IVRS ACPI table specifies maximum address sizes for I/O virtual
addresses that can be handled by the IOMMUs in the system. Parse that
data from the IVRS header so that it can be considered in limiting the
I/O aperture.

Based on prior work by Marius Hillenbrand.

Link: https://www.amd.com/system/files/TechDocs/48882_IOMMU_3.05_PUB.pdf

Signed-off-by: Sebastian Ott 
---
 drivers/iommu/amd_iommu.c   |  1 +
 drivers/iommu/amd_iommu_init.c  | 26 ++
 drivers/iommu/amd_iommu_types.h |  3 +++
 3 files changed, 30 insertions(+)

diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index 2883ac389abb..fb4a44550c4a 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -88,6 +88,7 @@ const struct iommu_ops amd_iommu_ops;
 
 static ATOMIC_NOTIFIER_HEAD(ppr_notifier);
 int amd_iommu_max_glx_val = -1;
+u8 amd_iommu_ivrs_va_size;
 
 /*
  * general struct to manage commands send to an IOMMU
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
index 5b81fd16f5fa..3b07218e7000 100644
--- a/drivers/iommu/amd_iommu_init.c
+++ b/drivers/iommu/amd_iommu_init.c
@@ -11,6 +11,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -41,6 +42,7 @@
  * definitions for the ACPI scanning code
  */
 #define IVRS_HEADER_LENGTH 48
+#define IVRS_HEADER_IVINFO_OFFSET 36
 
 #define ACPI_IVHD_TYPE_MAX_SUPPORTED   0x40
 #define ACPI_IVMD_TYPE_ALL  0x20
@@ -2492,6 +2494,27 @@ static void __init free_dma_resources(void)
free_unity_maps();
 }
 
+static void __init get_ivrs_ivinfo(struct acpi_table_header *ivrs)
+{
+   u32 *ivinfo = (u32 *)((u8 *)ivrs + IVRS_HEADER_IVINFO_OFFSET);
+   u8 va_size = FIELD_GET(GENMASK(21, 15), *ivinfo);
+   u8 valid_va_sizes[] = {32, 40, 48, 64};
+   int i;
+
+   for (i = 0; i < ARRAY_SIZE(valid_va_sizes); i++) {
+   if (va_size == valid_va_sizes[i]) {
+   amd_iommu_ivrs_va_size = va_size;
+   break;
+   }
+   }
+
+   if (!amd_iommu_ivrs_va_size) {
+   pr_warn("Invalid virtual address size %u in IVRS header, use 
most restrictive %u\n",
+   va_size, valid_va_sizes[0]);
+   amd_iommu_ivrs_va_size = valid_va_sizes[0];
+   }
+}
+
 /*
  * This is the hardware init function for AMD IOMMU in the system.
  * This function is called either from amd_iommu_init or from the interrupt
@@ -2546,6 +2569,9 @@ static int __init early_amd_iommu_init(void)
if (ret)
goto out;
 
+   get_ivrs_ivinfo(ivrs_base);
+   DUMP_printk("IVRS vasize=%d\n", amd_iommu_ivrs_va_size);
+
amd_iommu_target_ivhd_type = get_highest_supported_ivhd_type(ivrs_base);
DUMP_printk("Using IVHD type %#x\n", amd_iommu_target_ivhd_type);
 
diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h
index 7a8fdec138bd..8141b2874170 100644
--- a/drivers/iommu/amd_iommu_types.h
+++ b/drivers/iommu/amd_iommu_types.h
@@ -755,6 +755,9 @@ extern bool amd_iommu_force_isolation;
 /* Max levels of glxval supported */
 extern int amd_iommu_max_glx_val;
 
+/* Maximum virtual address size supported */
+extern u8 amd_iommu_ivrs_va_size;
+
 /*
  * This function flushes all internal caches of
  * the IOMMU used by this driver.
-- 
2.17.1




Amazon Development Center Germany GmbH
Krausenstr. 38
10117 Berlin
Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss
Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B
Sitz: Berlin
Ust-ID: DE 289 237 879



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


[PATCH 0/3] iommu/amd: I/O VA address limits

2020-06-05 Thread Sebastian Ott via iommu
The IVRS ACPI table specifies maximum address sizes for I/O virtual
addresses that can be handled by the IOMMUs in the system. Parse that
data from the IVRS header to provide aperture information for DMA
mappings and users of the iommu API.

Sebastian Ott (3):
  iommu/amd: Parse supported address sizes from IVRS
  iommu/amd: Restrict aperture for domains to conform with IVRS
  iommu/amd: Actually enforce geometry aperture

 drivers/iommu/amd_iommu.c   | 16 +++-
 drivers/iommu/amd_iommu_init.c  | 26 ++
 drivers/iommu/amd_iommu_types.h |  3 +++
 3 files changed, 40 insertions(+), 5 deletions(-)

-- 
2.17.1




Amazon Development Center Germany GmbH
Krausenstr. 38
10117 Berlin
Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss
Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B
Sitz: Berlin
Ust-ID: DE 289 237 879



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


[PATCH 3/3] iommu/amd: Actually enforce geometry aperture

2020-06-05 Thread Sebastian Ott via iommu
Add a check to enforce that I/O virtual addresses picked by iommu API
users stay within the domains geometry aperture.

Signed-off-by: Sebastian Ott 
---
 drivers/iommu/amd_iommu.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index d2e79e27778e..6485e2081706 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -2618,6 +2618,11 @@ static int amd_iommu_map(struct iommu_domain *dom, 
unsigned long iova,
if (pgtable.mode == PAGE_MODE_NONE)
return -EINVAL;
 
+   if (dom->geometry.force_aperture &&
+   (iova < dom->geometry.aperture_start ||
+iova + page_size - 1 > dom->geometry.aperture_end))
+   return -EINVAL;
+
if (iommu_prot & IOMMU_READ)
prot |= IOMMU_PROT_IR;
if (iommu_prot & IOMMU_WRITE)
-- 
2.17.1




Amazon Development Center Germany GmbH
Krausenstr. 38
10117 Berlin
Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss
Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B
Sitz: Berlin
Ust-ID: DE 289 237 879



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


[PATCH 2/3] iommu/amd: Restrict aperture for domains to conform with IVRS

2020-06-05 Thread Sebastian Ott via iommu
The IVRS ACPI table specifies maximum address sizes for I/O virtual
addresses. When allocating new protection domains that perform
translation, propagate these limits as the domain's geometry / aperture.

Based on prior work by Marius Hillenbrand.

Signed-off-by: Sebastian Ott 
---
 drivers/iommu/amd_iommu.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index fb4a44550c4a..d2e79e27778e 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -2460,6 +2460,7 @@ static struct protection_domain 
*protection_domain_alloc(void)
 
 static struct iommu_domain *amd_iommu_domain_alloc(unsigned type)
 {
+   dma_addr_t max_va = DMA_BIT_MASK(amd_iommu_ivrs_va_size);
struct protection_domain *pdomain;
u64 *pt_root, root;
 
@@ -2477,11 +2478,6 @@ static struct iommu_domain 
*amd_iommu_domain_alloc(unsigned type)
 
root = amd_iommu_domain_encode_pgtable(pt_root, 
PAGE_MODE_3_LEVEL);
atomic64_set(>pt_root, root);
-
-   pdomain->domain.geometry.aperture_start = 0;
-   pdomain->domain.geometry.aperture_end   = ~0ULL;
-   pdomain->domain.geometry.force_aperture = true;
-
break;
case IOMMU_DOMAIN_DMA:
pdomain = dma_ops_domain_alloc();
@@ -2501,6 +2497,10 @@ static struct iommu_domain 
*amd_iommu_domain_alloc(unsigned type)
return NULL;
}
 
+   pdomain->domain.geometry.aperture_start = 0;
+   pdomain->domain.geometry.aperture_end   = max_va;
+   pdomain->domain.geometry.force_aperture = true;
+
return >domain;
 }
 
-- 
2.17.1




Amazon Development Center Germany GmbH
Krausenstr. 38
10117 Berlin
Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss
Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B
Sitz: Berlin
Ust-ID: DE 289 237 879



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


Re: [PATCH v2 0/3] iommu/amd: I/O VA address limits

2020-07-17 Thread Sebastian Ott via iommu

Hello Joerg,

On 2020-07-10 14:31, Joerg Roedel wrote:

On Wed, Jul 01, 2020 at 12:46:31AM +0200, Sebastian Ott wrote:

The IVRS ACPI table specifies maximum address sizes for I/O virtual
addresses that can be handled by the IOMMUs in the system. Parse that
data from the IVRS header to provide aperture information for DMA
mappings and users of the iommu API.

Changes for V2:
  - use limits in iommu_setup_dma_ops()
  - rebased to current upstream

Sebastian Ott (3):
   iommu/amd: Parse supported address sizes from IVRS
   iommu/amd: Restrict aperture for domains to conform with IVRS
   iommu/amd: Actually enforce geometry aperture

Thanks for the changes. May I ask what the reason for those changes are?
AFAIK all AMD IOMMU implementations (in hardware) support full 64bit
address spaces, and the IVRS table might actually be wrong, limiting the
address space in the worst case to only 32 bit.


It's not the IOMMU, but we've encountered devices that are capable of 
more than
32- but less than 64- bit IOVA, and there's no way to express that to 
the IOVA
allocator in the PCIe spec. Our solution was to have our platforms 
express an
IVRS entry that says the IOMMU is capable of 48-bit, which these devices 
can generate.
48 bits is plenty of address space in this generation for the 
application we have.


Sebastian




Amazon Development Center Germany GmbH
Krausenstr. 38
10117 Berlin
Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss
Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B
Sitz: Berlin
Ust-ID: DE 289 237 879


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