[PATCH 9/9] iommu/vt-d: Avoid duplicate removing in __domain_mapping()

2021-10-13 Thread Lu Baolu
From: "Longpeng(Mike)" 

The __domain_mapping() always removes the pages in the range from
'iov_pfn' to 'end_pfn', but the 'end_pfn' is always the last pfn
of the range that the caller wants to map.

This would introduce too many duplicated removing and leads the
map operation take too long, for example:

  Map iova=0x10,nr_pages=0x7d61800
iov_pfn: 0x10, end_pfn: 0x7e617ff
iov_pfn: 0x14, end_pfn: 0x7e617ff
iov_pfn: 0x18, end_pfn: 0x7e617ff
iov_pfn: 0x1c, end_pfn: 0x7e617ff
iov_pfn: 0x20, end_pfn: 0x7e617ff
...
  it takes about 50ms in total.

We can reduce the cost by recalculate the 'end_pfn' and limit it
to the boundary of the end of this pte page.

  Map iova=0x10,nr_pages=0x7d61800
iov_pfn: 0x10, end_pfn: 0x13
iov_pfn: 0x14, end_pfn: 0x17
iov_pfn: 0x18, end_pfn: 0x1b
iov_pfn: 0x1c, end_pfn: 0x1f
iov_pfn: 0x20, end_pfn: 0x23
...
  it only need 9ms now.

This also removes a meaningless BUG_ON() in __domain_mapping().

Signed-off-by: Longpeng(Mike) 
Tested-by: Liujunjie 
Link: https://lore.kernel.org/r/20211008000433.1115-1-longpe...@huawei.com
Signed-off-by: Lu Baolu 
---
 include/linux/intel-iommu.h |  6 ++
 drivers/iommu/intel/iommu.c | 11 ++-
 2 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h
index 52481625838c..69230fd695ea 100644
--- a/include/linux/intel-iommu.h
+++ b/include/linux/intel-iommu.h
@@ -710,6 +710,12 @@ static inline bool first_pte_in_page(struct dma_pte *pte)
return IS_ALIGNED((unsigned long)pte, VTD_PAGE_SIZE);
 }
 
+static inline int nr_pte_to_next_page(struct dma_pte *pte)
+{
+   return first_pte_in_page(pte) ? BIT_ULL(VTD_STRIDE_SHIFT) :
+   (struct dma_pte *)ALIGN((unsigned long)pte, VTD_PAGE_SIZE) - 
pte;
+}
+
 extern struct dmar_drhd_unit * dmar_find_matched_drhd_unit(struct pci_dev 
*dev);
 extern int dmar_find_matched_atsr_unit(struct pci_dev *dev);
 
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index 16a35669a9d0..0bde0c8b4126 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -2479,12 +2479,17 @@ __domain_mapping(struct dmar_domain *domain, unsigned 
long iov_pfn,
return -ENOMEM;
first_pte = pte;
 
+   lvl_pages = lvl_to_nr_pages(largepage_lvl);
+
/* It is large page*/
if (largepage_lvl > 1) {
unsigned long end_pfn;
+   unsigned long pages_to_remove;
 
pteval |= DMA_PTE_LARGE_PAGE;
-   end_pfn = ((iov_pfn + nr_pages) & 
level_mask(largepage_lvl)) - 1;
+   pages_to_remove = min_t(unsigned long, nr_pages,
+   
nr_pte_to_next_page(pte) * lvl_pages);
+   end_pfn = iov_pfn + pages_to_remove - 1;
switch_to_super_page(domain, iov_pfn, end_pfn, 
largepage_lvl);
} else {
pteval &= ~(uint64_t)DMA_PTE_LARGE_PAGE;
@@ -2506,10 +2511,6 @@ __domain_mapping(struct dmar_domain *domain, unsigned 
long iov_pfn,
WARN_ON(1);
}
 
-   lvl_pages = lvl_to_nr_pages(largepage_lvl);
-
-   BUG_ON(nr_pages < lvl_pages);
-
nr_pages -= lvl_pages;
iov_pfn += lvl_pages;
phys_pfn += lvl_pages;
-- 
2.25.1

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


[PATCH 8/9] iommu/vt-d: Convert the return type of first_pte_in_page to bool

2021-10-13 Thread Lu Baolu
From: "Longpeng(Mike)" 

The first_pte_in_page() returns true or false, so let's convert its
return type to bool. In addition, use 'IS_ALIGNED' to make the
code more readable and neater.

Signed-off-by: Longpeng(Mike) 
Link: https://lore.kernel.org/r/20211008000433.1115-1-longpe...@huawei.com
Signed-off-by: Lu Baolu 
---
 include/linux/intel-iommu.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h
index 65b15af3cf1a..52481625838c 100644
--- a/include/linux/intel-iommu.h
+++ b/include/linux/intel-iommu.h
@@ -705,9 +705,9 @@ static inline bool dma_pte_superpage(struct dma_pte *pte)
return (pte->val & DMA_PTE_LARGE_PAGE);
 }
 
-static inline int first_pte_in_page(struct dma_pte *pte)
+static inline bool first_pte_in_page(struct dma_pte *pte)
 {
-   return !((unsigned long)pte & ~VTD_PAGE_MASK);
+   return IS_ALIGNED((unsigned long)pte, VTD_PAGE_SIZE);
 }
 
 extern struct dmar_drhd_unit * dmar_find_matched_drhd_unit(struct pci_dev 
*dev);
-- 
2.25.1

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


[PATCH 7/9] iommu/vt-d: Clean up unused PASID updating functions

2021-10-13 Thread Lu Baolu
From: Fenghua Yu 

update_pasid() and its call chain are currently unused in the tree because
Thomas disabled the ENQCMD feature. The feature will be re-enabled shortly
using a different approach and update_pasid() and its call chain will not
be used in the new approach.

Remove the useless functions.

Signed-off-by: Fenghua Yu 
Reviewed-by: Tony Luck 
Link: https://lore.kernel.org/r/20210920192349.2602141-1-fenghua...@intel.com
Signed-off-by: Lu Baolu 
---
 arch/x86/include/asm/fpu/api.h |  2 --
 drivers/iommu/intel/svm.c  | 24 +---
 2 files changed, 1 insertion(+), 25 deletions(-)

diff --git a/arch/x86/include/asm/fpu/api.h b/arch/x86/include/asm/fpu/api.h
index 23bef08a8388..ca4d0dee1ecd 100644
--- a/arch/x86/include/asm/fpu/api.h
+++ b/arch/x86/include/asm/fpu/api.h
@@ -106,6 +106,4 @@ extern int cpu_has_xfeatures(u64 xfeatures_mask, const char 
**feature_name);
  */
 #define PASID_DISABLED 0
 
-static inline void update_pasid(void) { }
-
 #endif /* _ASM_X86_FPU_API_H */
diff --git a/drivers/iommu/intel/svm.c b/drivers/iommu/intel/svm.c
index 0c228787704f..5b5d69b04fcc 100644
--- a/drivers/iommu/intel/svm.c
+++ b/drivers/iommu/intel/svm.c
@@ -505,21 +505,6 @@ int intel_svm_unbind_gpasid(struct device *dev, u32 pasid)
return ret;
 }
 
-static void _load_pasid(void *unused)
-{
-   update_pasid();
-}
-
-static void load_pasid(struct mm_struct *mm, u32 pasid)
-{
-   mutex_lock(>context.lock);
-
-   /* Update PASID MSR on all CPUs running the mm's tasks. */
-   on_each_cpu_mask(mm_cpumask(mm), _load_pasid, NULL, true);
-
-   mutex_unlock(>context.lock);
-}
-
 static int intel_svm_alloc_pasid(struct device *dev, struct mm_struct *mm,
 unsigned int flags)
 {
@@ -614,10 +599,6 @@ static struct iommu_sva *intel_svm_bind_mm(struct 
intel_iommu *iommu,
if (ret)
goto free_sdev;
 
-   /* The newly allocated pasid is loaded to the mm. */
-   if (!(flags & SVM_FLAG_SUPERVISOR_MODE) && list_empty(>devs))
-   load_pasid(mm, svm->pasid);
-
list_add_rcu(>list, >devs);
 success:
return >sva;
@@ -670,11 +651,8 @@ static int intel_svm_unbind_mm(struct device *dev, u32 
pasid)
kfree_rcu(sdev, rcu);
 
if (list_empty(>devs)) {
-   if (svm->notifier.ops) {
+   if (svm->notifier.ops)
mmu_notifier_unregister(>notifier, 
mm);
-   /* Clear mm's pasid. */
-   load_pasid(mm, PASID_DISABLED);
-   }
pasid_private_remove(svm->pasid);
/* We mandate that no page faults may be 
outstanding
 * for the PASID when intel_svm_unbind_mm() is 
called.
-- 
2.25.1

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


[PATCH 6/9] iommu/vt-d: Delete dev_has_feat callback

2021-10-13 Thread Lu Baolu
The commit 262948f8ba573 ("iommu: Delete iommu_dev_has_feature()") has
deleted the iommu_dev_has_feature() interface. Remove the dev_has_feat
callback to avoid dead code.

Signed-off-by: Lu Baolu 
Link: 
https://lore.kernel.org/r/20210929072030.1330225-1-baolu...@linux.intel.com
---
 drivers/iommu/intel/iommu.c | 59 -
 1 file changed, 5 insertions(+), 54 deletions(-)

diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index 1c26a7a012ce..16a35669a9d0 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -5511,62 +5511,14 @@ static int intel_iommu_disable_sva(struct device *dev)
return ret;
 }
 
-/*
- * A PCI express designated vendor specific extended capability is defined
- * in the section 3.7 of Intel scalable I/O virtualization technical spec
- * for system software and tools to detect endpoint devices supporting the
- * Intel scalable IO virtualization without host driver dependency.
- *
- * Returns the address of the matching extended capability structure within
- * the device's PCI configuration space or 0 if the device does not support
- * it.
- */
-static int siov_find_pci_dvsec(struct pci_dev *pdev)
-{
-   int pos;
-   u16 vendor, id;
-
-   pos = pci_find_next_ext_capability(pdev, 0, 0x23);
-   while (pos) {
-   pci_read_config_word(pdev, pos + 4, );
-   pci_read_config_word(pdev, pos + 8, );
-   if (vendor == PCI_VENDOR_ID_INTEL && id == 5)
-   return pos;
-
-   pos = pci_find_next_ext_capability(pdev, pos, 0x23);
-   }
-
-   return 0;
-}
-
-static bool
-intel_iommu_dev_has_feat(struct device *dev, enum iommu_dev_features feat)
+static int intel_iommu_enable_iopf(struct device *dev)
 {
struct device_domain_info *info = get_domain_info(dev);
 
-   if (feat == IOMMU_DEV_FEAT_AUX) {
-   int ret;
-
-   if (!dev_is_pci(dev) || dmar_disabled ||
-   !scalable_mode_support() || !pasid_mode_support())
-   return false;
-
-   ret = pci_pasid_features(to_pci_dev(dev));
-   if (ret < 0)
-   return false;
-
-   return !!siov_find_pci_dvsec(to_pci_dev(dev));
-   }
-
-   if (feat == IOMMU_DEV_FEAT_IOPF)
-   return info && info->pri_supported;
-
-   if (feat == IOMMU_DEV_FEAT_SVA)
-   return info && (info->iommu->flags & VTD_FLAG_SVM_CAPABLE) &&
-   info->pasid_supported && info->pri_supported &&
-   info->ats_supported;
+   if (info && info->pri_supported)
+   return 0;
 
-   return false;
+   return -ENODEV;
 }
 
 static int
@@ -5577,7 +5529,7 @@ intel_iommu_dev_enable_feat(struct device *dev, enum 
iommu_dev_features feat)
return intel_iommu_enable_auxd(dev);
 
case IOMMU_DEV_FEAT_IOPF:
-   return intel_iommu_dev_has_feat(dev, feat) ? 0 : -ENODEV;
+   return intel_iommu_enable_iopf(dev);
 
case IOMMU_DEV_FEAT_SVA:
return intel_iommu_enable_sva(dev);
@@ -5703,7 +5655,6 @@ const struct iommu_ops intel_iommu_ops = {
.get_resv_regions   = intel_iommu_get_resv_regions,
.put_resv_regions   = generic_iommu_put_resv_regions,
.device_group   = intel_iommu_device_group,
-   .dev_has_feat   = intel_iommu_dev_has_feat,
.dev_feat_enabled   = intel_iommu_dev_feat_enabled,
.dev_enable_feat= intel_iommu_dev_enable_feat,
.dev_disable_feat   = intel_iommu_dev_disable_feat,
-- 
2.25.1

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


[PATCH 5/9] iommu/vt-d: Use second level for GPA->HPA translation

2021-10-13 Thread Lu Baolu
The IOMMU VT-d implementation uses the first level for GPA->HPA translation
by default. Although both the first level and the second level could handle
the DMA translation, they're different in some way. For example, the second
level translation has separate controls for the Access/Dirty page tracking.
With the first level translation, there's no such control. On the other
hand, the second level translation has the page-level control for forcing
snoop, but the first level only has global control with pasid granularity.

This uses the second level for GPA->HPA translation so that we can provide
a consistent hardware interface for use cases like dirty page tracking for
live migration.

Signed-off-by: Lu Baolu 
Reviewed-by: Kevin Tian 
Link: https://lore.kernel.org/r/20210926114535.923263-1-baolu...@linux.intel.com
---
 drivers/iommu/intel/iommu.c | 15 ---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index ec9ceb2dcf57..1c26a7a012ce 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -1991,9 +1991,18 @@ static void free_dmar_iommu(struct intel_iommu *iommu)
  * Check and return whether first level is used by default for
  * DMA translation.
  */
-static bool first_level_by_default(void)
+static bool first_level_by_default(unsigned int type)
 {
-   return scalable_mode_support() && intel_cap_flts_sanity();
+   /* Only SL is available in legacy mode */
+   if (!scalable_mode_support())
+   return false;
+
+   /* Only level (either FL or SL) is available, just use it */
+   if (intel_cap_flts_sanity() ^ intel_cap_slts_sanity())
+   return intel_cap_flts_sanity();
+
+   /* Both levels are available, decide it based on domain type */
+   return type != IOMMU_DOMAIN_UNMANAGED;
 }
 
 static struct dmar_domain *alloc_domain(unsigned int type)
@@ -2006,7 +2015,7 @@ static struct dmar_domain *alloc_domain(unsigned int type)
 
memset(domain, 0, sizeof(*domain));
domain->nid = NUMA_NO_NODE;
-   if (first_level_by_default())
+   if (first_level_by_default(type))
domain->flags |= DOMAIN_FLAG_USE_FIRST_LEVEL;
domain->has_iotlb_device = false;
INIT_LIST_HEAD(>devices);
-- 
2.25.1

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


[PATCH 4/9] iommu/vt-d: Check FL and SL capability sanity in scalable mode

2021-10-13 Thread Lu Baolu
An iommu domain could be allocated and mapped before it's attached to any
device. This requires that in scalable mode, when the domain is allocated,
the format (FL or SL) of the page table must be determined. In order to
achieve this, the platform should support consistent SL or FL capabilities
on all IOMMU's. This adds a check for this and aborts IOMMU probing if it
doesn't meet this requirement.

Signed-off-by: Lu Baolu 
Reviewed-by: Kevin Tian 
Link: https://lore.kernel.org/r/20210926114535.923263-1-baolu...@linux.intel.com
---
 drivers/iommu/intel/cap_audit.h |  1 +
 drivers/iommu/intel/cap_audit.c | 13 +
 2 files changed, 14 insertions(+)

diff --git a/drivers/iommu/intel/cap_audit.h b/drivers/iommu/intel/cap_audit.h
index 74cfccae0e81..d07b75938961 100644
--- a/drivers/iommu/intel/cap_audit.h
+++ b/drivers/iommu/intel/cap_audit.h
@@ -111,6 +111,7 @@ bool intel_cap_smts_sanity(void);
 bool intel_cap_pasid_sanity(void);
 bool intel_cap_nest_sanity(void);
 bool intel_cap_flts_sanity(void);
+bool intel_cap_slts_sanity(void);
 
 static inline bool scalable_mode_support(void)
 {
diff --git a/drivers/iommu/intel/cap_audit.c b/drivers/iommu/intel/cap_audit.c
index b12e421a2f1a..b39d223926a4 100644
--- a/drivers/iommu/intel/cap_audit.c
+++ b/drivers/iommu/intel/cap_audit.c
@@ -163,6 +163,14 @@ static int cap_audit_static(struct intel_iommu *iommu, 
enum cap_audit_type type)
check_irq_capabilities(iommu, i);
}
 
+   /*
+* If the system is sane to support scalable mode, either SL or FL
+* should be sane.
+*/
+   if (intel_cap_smts_sanity() &&
+   !intel_cap_flts_sanity() && !intel_cap_slts_sanity())
+   return -EOPNOTSUPP;
+
 out:
rcu_read_unlock();
return 0;
@@ -203,3 +211,8 @@ bool intel_cap_flts_sanity(void)
 {
return ecap_flts(intel_iommu_ecap_sanity);
 }
+
+bool intel_cap_slts_sanity(void)
+{
+   return ecap_slts(intel_iommu_ecap_sanity);
+}
-- 
2.25.1

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


[PATCH 3/9] iommu/vt-d: Remove duplicate identity domain flag

2021-10-13 Thread Lu Baolu
The iommu_domain data structure already has the "type" field to keep the
type of a domain. It's unnecessary to have the DOMAIN_FLAG_STATIC_IDENTITY
flag in the vt-d implementation. This cleans it up with no functionality
change.

Signed-off-by: Lu Baolu 
Reviewed-by: Kevin Tian 
Link: https://lore.kernel.org/r/20210926114535.923263-1-baolu...@linux.intel.com
---
 include/linux/intel-iommu.h | 3 ---
 drivers/iommu/intel/iommu.c | 9 -
 2 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h
index 05a65eb155f7..65b15af3cf1a 100644
--- a/include/linux/intel-iommu.h
+++ b/include/linux/intel-iommu.h
@@ -517,9 +517,6 @@ struct context_entry {
u64 hi;
 };
 
-/* si_domain contains mulitple devices */
-#define DOMAIN_FLAG_STATIC_IDENTITYBIT(0)
-
 /*
  * When VT-d works in the scalable mode, it allows DMA translation to
  * happen through either first level or second level page table. This
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index abb258b1..ec9ceb2dcf57 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -528,7 +528,7 @@ static inline void free_devinfo_mem(void *vaddr)
 
 static inline int domain_type_is_si(struct dmar_domain *domain)
 {
-   return domain->flags & DOMAIN_FLAG_STATIC_IDENTITY;
+   return domain->domain.type == IOMMU_DOMAIN_IDENTITY;
 }
 
 static inline bool domain_use_first_level(struct dmar_domain *domain)
@@ -1996,7 +1996,7 @@ static bool first_level_by_default(void)
return scalable_mode_support() && intel_cap_flts_sanity();
 }
 
-static struct dmar_domain *alloc_domain(int flags)
+static struct dmar_domain *alloc_domain(unsigned int type)
 {
struct dmar_domain *domain;
 
@@ -2006,7 +2006,6 @@ static struct dmar_domain *alloc_domain(int flags)
 
memset(domain, 0, sizeof(*domain));
domain->nid = NUMA_NO_NODE;
-   domain->flags = flags;
if (first_level_by_default())
domain->flags |= DOMAIN_FLAG_USE_FIRST_LEVEL;
domain->has_iotlb_device = false;
@@ -2825,7 +2824,7 @@ static int __init si_domain_init(int hw)
struct device *dev;
int i, nid, ret;
 
-   si_domain = alloc_domain(DOMAIN_FLAG_STATIC_IDENTITY);
+   si_domain = alloc_domain(IOMMU_DOMAIN_IDENTITY);
if (!si_domain)
return -EFAULT;
 
@@ -4634,7 +4633,7 @@ static struct iommu_domain 
*intel_iommu_domain_alloc(unsigned type)
case IOMMU_DOMAIN_DMA:
case IOMMU_DOMAIN_DMA_FQ:
case IOMMU_DOMAIN_UNMANAGED:
-   dmar_domain = alloc_domain(0);
+   dmar_domain = alloc_domain(type);
if (!dmar_domain) {
pr_err("Can't allocate dmar_domain\n");
return NULL;
-- 
2.25.1

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


[PATCH 0/9] [PULL REQUEST] Intel IOMMU Updates for Linux v5.16

2021-10-13 Thread Lu Baolu
Hi Joerg,

The patches queued in this series are for v5.16. It includes:

 - Dump DMAR translation structure when DMA fault occurs.
 - An optimization in the page table manipulation code.
 - Use second level for GPA->HPA translation.
 - Various cleanups

Please pull.

Best regards,
Baolu

Fenghua Yu (1):
  iommu/vt-d: Clean up unused PASID updating functions

Kyung Min Park (1):
  iommu/vt-d: Dump DMAR translation structure when DMA fault occurs

Longpeng(Mike) (2):
  iommu/vt-d: Convert the return type of first_pte_in_page to bool
  iommu/vt-d: Avoid duplicate removing in __domain_mapping()

Lu Baolu (4):
  iommu/vt-d: Remove duplicate identity domain flag
  iommu/vt-d: Check FL and SL capability sanity in scalable mode
  iommu/vt-d: Use second level for GPA->HPA translation
  iommu/vt-d: Delete dev_has_feat callback

Tvrtko Ursulin (1):
  iommu/vt-d: Do not falsely log intel_iommu is unsupported kernel
option

 include/linux/dmar.h|   8 ++
 include/linux/intel-iommu.h |  13 +-
 arch/x86/include/asm/fpu/api.h  |   2 -
 drivers/iommu/intel/cap_audit.h |   1 +
 drivers/iommu/intel/cap_audit.c |  13 ++
 drivers/iommu/intel/dmar.c  |  10 +-
 drivers/iommu/intel/iommu.c | 213 ++--
 drivers/iommu/intel/svm.c   |  24 +---
 drivers/iommu/intel/Kconfig |   4 +
 9 files changed, 188 insertions(+), 100 deletions(-)

-- 
2.25.1

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


[PATCH 2/9] iommu/vt-d: Dump DMAR translation structure when DMA fault occurs

2021-10-13 Thread Lu Baolu
From: Kyung Min Park 

When the dmar translation fault happens, the kernel prints a single line
fault reason with corresponding hexadecimal code defined in the Intel VT-d
specification.

Currently, when user wants to debug the translation fault in detail,
debugfs is used for dumping the dmar_translation_struct, which is not
available when the kernel failed to boot.

Dump the DMAR translation structure, pagewalk the IO page table and print
the page table entry when the fault happens.

This takes effect only when CONFIG_DMAR_DEBUG is enabled.

Signed-off-by: Kyung Min Park 
Link: https://lore.kernel.org/r/20210815203845.31287-1-kyung.min.p...@intel.com
Signed-off-by: Lu Baolu 
---
 include/linux/dmar.h|   8 +++
 drivers/iommu/intel/dmar.c  |  10 +++-
 drivers/iommu/intel/iommu.c | 113 
 drivers/iommu/intel/Kconfig |   4 ++
 4 files changed, 133 insertions(+), 2 deletions(-)

diff --git a/include/linux/dmar.h b/include/linux/dmar.h
index e04436a7ff27..45e903d84733 100644
--- a/include/linux/dmar.h
+++ b/include/linux/dmar.h
@@ -131,6 +131,14 @@ static inline int dmar_res_noop(struct acpi_dmar_header 
*hdr, void *arg)
return 0;
 }
 
+#ifdef CONFIG_DMAR_DEBUG
+void dmar_fault_dump_ptes(struct intel_iommu *iommu, u16 source_id,
+ unsigned long long addr, u32 pasid);
+#else
+static inline void dmar_fault_dump_ptes(struct intel_iommu *iommu, u16 
source_id,
+   unsigned long long addr, u32 pasid) {}
+#endif
+
 #ifdef CONFIG_INTEL_IOMMU
 extern int iommu_detected, no_iommu;
 extern int intel_iommu_init(void);
diff --git a/drivers/iommu/intel/dmar.c b/drivers/iommu/intel/dmar.c
index b7708b93f3fa..915bff76fe96 100644
--- a/drivers/iommu/intel/dmar.c
+++ b/drivers/iommu/intel/dmar.c
@@ -1941,12 +1941,16 @@ static int dmar_fault_do_one(struct intel_iommu *iommu, 
int type,
 
reason = dmar_get_fault_reason(fault_reason, _type);
 
-   if (fault_type == INTR_REMAP)
+   if (fault_type == INTR_REMAP) {
pr_err("[INTR-REMAP] Request device [%02x:%02x.%d] fault index 
0x%llx [fault reason 0x%02x] %s\n",
   source_id >> 8, PCI_SLOT(source_id & 0xFF),
   PCI_FUNC(source_id & 0xFF), addr >> 48,
   fault_reason, reason);
-   else if (pasid == INVALID_IOASID)
+
+   return 0;
+   }
+
+   if (pasid == INVALID_IOASID)
pr_err("[%s NO_PASID] Request device [%02x:%02x.%d] fault addr 
0x%llx [fault reason 0x%02x] %s\n",
   type ? "DMA Read" : "DMA Write",
   source_id >> 8, PCI_SLOT(source_id & 0xFF),
@@ -1959,6 +1963,8 @@ static int dmar_fault_do_one(struct intel_iommu *iommu, 
int type,
   PCI_FUNC(source_id & 0xFF), addr,
   fault_reason, reason);
 
+   dmar_fault_dump_ptes(iommu, source_id, addr, pasid);
+
return 0;
 }
 
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index 9a356075d345..abb258b1 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -156,6 +156,8 @@ static struct intel_iommu **g_iommus;
 
 static void __init check_tylersburg_isoch(void);
 static int rwbf_quirk;
+static inline struct device_domain_info *
+dmar_search_domain_by_dev_info(int segment, int bus, int devfn);
 
 /*
  * set to 1 to panic kernel if can't successfully enable VT-d
@@ -996,6 +998,117 @@ static void free_context_table(struct intel_iommu *iommu)
spin_unlock_irqrestore(>lock, flags);
 }
 
+#ifdef CONFIG_DMAR_DEBUG
+static void pgtable_walk(struct intel_iommu *iommu, unsigned long pfn, u8 bus, 
u8 devfn)
+{
+   struct device_domain_info *info;
+   struct dma_pte *parent, *pte;
+   struct dmar_domain *domain;
+   int offset, level;
+
+   info = dmar_search_domain_by_dev_info(iommu->segment, bus, devfn);
+   if (!info || !info->domain) {
+   pr_info("device [%02x:%02x.%d] not probed\n",
+   bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
+   return;
+   }
+
+   domain = info->domain;
+   level = agaw_to_level(domain->agaw);
+   parent = domain->pgd;
+   if (!parent) {
+   pr_info("no page table setup\n");
+   return;
+   }
+
+   while (1) {
+   offset = pfn_level_offset(pfn, level);
+   pte = [offset];
+   if (!pte || (dma_pte_superpage(pte) || !dma_pte_present(pte))) {
+   pr_info("PTE not present at level %d\n", level);
+   break;
+   }
+
+   pr_info("pte level: %d, pte value: 0x%016llx\n", level, 
pte->val);
+
+   if (level == 1)
+   break;
+
+   parent = phys_to_virt(dma_pte_addr(pte));
+   level--;
+   }
+}
+
+void dmar_fault_dump_ptes(struct intel_iommu *iommu, u16 source_id,
+   

[PATCH 1/9] iommu/vt-d: Do not falsely log intel_iommu is unsupported kernel option

2021-10-13 Thread Lu Baolu
From: Tvrtko Ursulin 

Handling of intel_iommu kernel command line option should return "true" to
indicate option is valid and so avoid logging it as unknown by the core
parsing code.

Also log unknown sub-options at the notice level to let user know of
potential typos or similar.

Reported-by: Eero Tamminen 
Signed-off-by: Tvrtko Ursulin 
Link: 
https://lore.kernel.org/r/20210831112947.310080-1-tvrtko.ursu...@linux.intel.com
Signed-off-by: Lu Baolu 
---
 drivers/iommu/intel/iommu.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index d75f59ae28e6..9a356075d345 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -412,6 +412,7 @@ static int __init intel_iommu_setup(char *str)
 {
if (!str)
return -EINVAL;
+
while (*str) {
if (!strncmp(str, "on", 2)) {
dmar_disabled = 0;
@@ -441,13 +442,16 @@ static int __init intel_iommu_setup(char *str)
} else if (!strncmp(str, "tboot_noforce", 13)) {
pr_info("Intel-IOMMU: not forcing on after tboot. This 
could expose security risk for tboot\n");
intel_iommu_tboot_noforce = 1;
+   } else {
+   pr_notice("Unknown option - '%s'\n", str);
}
 
str += strcspn(str, ",");
while (*str == ',')
str++;
}
-   return 0;
+
+   return 1;
 }
 __setup("intel_iommu=", intel_iommu_setup);
 
-- 
2.25.1

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


RE: [PATCH 2/5] iommu/virtio: Support bypass domains

2021-10-13 Thread Tian, Kevin
> From: Tian, Kevin
> Sent: Thursday, October 14, 2021 11:25 AM
> 
> > From: Jean-Philippe Brucker 
> > Sent: Wednesday, October 13, 2021 8:11 PM
> >
> > The VIRTIO_IOMMU_F_BYPASS_CONFIG feature adds a new flag to the
> > ATTACH
> > request, that creates a bypass domain. Use it to enable identity
> > domains.
> >
> > When VIRTIO_IOMMU_F_BYPASS_CONFIG is not supported by the device,
> > we
> > currently fail attaching to an identity domain. Future patches will
> > instead create identity mappings in this case.
> >
> > Signed-off-by: Jean-Philippe Brucker 
> > ---
> >  drivers/iommu/virtio-iommu.c | 20 +++-
> >  1 file changed, 19 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c
> > index 80930ce04a16..ee8a7afd667b 100644
> > --- a/drivers/iommu/virtio-iommu.c
> > +++ b/drivers/iommu/virtio-iommu.c
> > @@ -71,6 +71,7 @@ struct viommu_domain {
> > struct rb_root_cached   mappings;
> >
> > unsigned long   nr_endpoints;
> > +   boolbypass;
> >  };
> >
> >  struct viommu_endpoint {
> > @@ -587,7 +588,9 @@ static struct iommu_domain
> > *viommu_domain_alloc(unsigned type)
> >  {
> > struct viommu_domain *vdomain;
> >
> > -   if (type != IOMMU_DOMAIN_UNMANAGED && type !=
> > IOMMU_DOMAIN_DMA)
> > +   if (type != IOMMU_DOMAIN_UNMANAGED &&
> > +   type != IOMMU_DOMAIN_DMA &&
> > +   type != IOMMU_DOMAIN_IDENTITY)
> > return NULL;
> >
> > vdomain = kzalloc(sizeof(*vdomain), GFP_KERNEL);
> > @@ -630,6 +633,17 @@ static int viommu_domain_finalise(struct
> > viommu_endpoint *vdev,
> > vdomain->map_flags  = viommu->map_flags;
> > vdomain->viommu = viommu;
> >
> > +   if (domain->type == IOMMU_DOMAIN_IDENTITY) {
> > +   if (!virtio_has_feature(viommu->vdev,
> > +   VIRTIO_IOMMU_F_BYPASS_CONFIG))
> > {
> > +   ida_free(>domain_ids, vdomain->id);
> > +   vdomain->viommu = 0;
> > +   return -EOPNOTSUPP;
> > +   }
> > +
> > +   vdomain->bypass = true;
> > +   }
> > +
> 
> move to the start of the function, then no need for above cleanup.
> 

forgot it as I see the reason now when looking at patch05
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


RE: [PATCH 2/5] iommu/virtio: Support bypass domains

2021-10-13 Thread Tian, Kevin
> From: Jean-Philippe Brucker 
> Sent: Wednesday, October 13, 2021 8:11 PM
> 
> The VIRTIO_IOMMU_F_BYPASS_CONFIG feature adds a new flag to the
> ATTACH
> request, that creates a bypass domain. Use it to enable identity
> domains.
> 
> When VIRTIO_IOMMU_F_BYPASS_CONFIG is not supported by the device,
> we
> currently fail attaching to an identity domain. Future patches will
> instead create identity mappings in this case.
> 
> Signed-off-by: Jean-Philippe Brucker 
> ---
>  drivers/iommu/virtio-iommu.c | 20 +++-
>  1 file changed, 19 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c
> index 80930ce04a16..ee8a7afd667b 100644
> --- a/drivers/iommu/virtio-iommu.c
> +++ b/drivers/iommu/virtio-iommu.c
> @@ -71,6 +71,7 @@ struct viommu_domain {
>   struct rb_root_cached   mappings;
> 
>   unsigned long   nr_endpoints;
> + boolbypass;
>  };
> 
>  struct viommu_endpoint {
> @@ -587,7 +588,9 @@ static struct iommu_domain
> *viommu_domain_alloc(unsigned type)
>  {
>   struct viommu_domain *vdomain;
> 
> - if (type != IOMMU_DOMAIN_UNMANAGED && type !=
> IOMMU_DOMAIN_DMA)
> + if (type != IOMMU_DOMAIN_UNMANAGED &&
> + type != IOMMU_DOMAIN_DMA &&
> + type != IOMMU_DOMAIN_IDENTITY)
>   return NULL;
> 
>   vdomain = kzalloc(sizeof(*vdomain), GFP_KERNEL);
> @@ -630,6 +633,17 @@ static int viommu_domain_finalise(struct
> viommu_endpoint *vdev,
>   vdomain->map_flags  = viommu->map_flags;
>   vdomain->viommu = viommu;
> 
> + if (domain->type == IOMMU_DOMAIN_IDENTITY) {
> + if (!virtio_has_feature(viommu->vdev,
> + VIRTIO_IOMMU_F_BYPASS_CONFIG))
> {
> + ida_free(>domain_ids, vdomain->id);
> + vdomain->viommu = 0;
> + return -EOPNOTSUPP;
> + }
> +
> + vdomain->bypass = true;
> + }
> +

move to the start of the function, then no need for above cleanup.

>   return 0;
>  }
> 
> @@ -691,6 +705,9 @@ static int viommu_attach_dev(struct iommu_domain
> *domain, struct device *dev)
>   .domain = cpu_to_le32(vdomain->id),
>   };
> 
> + if (vdomain->bypass)
> + req.flags |=
> cpu_to_le32(VIRTIO_IOMMU_ATTACH_F_BYPASS);
> +
>   for (i = 0; i < fwspec->num_ids; i++) {
>   req.endpoint = cpu_to_le32(fwspec->ids[i]);
> 
> @@ -1132,6 +1149,7 @@ static unsigned int features[] = {
>   VIRTIO_IOMMU_F_DOMAIN_RANGE,
>   VIRTIO_IOMMU_F_PROBE,
>   VIRTIO_IOMMU_F_MMIO,
> + VIRTIO_IOMMU_F_BYPASS_CONFIG,
>  };
> 
>  static struct virtio_device_id id_table[] = {
> --
> 2.33.0

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


Re: [PATCH] iommu/iova: Add support for IOVA max alignment tuning

2021-10-13 Thread kernel test robot
Hi Georgi,

I love your patch! Yet something to improve:

[auto build test ERROR on joro-iommu/next]
[also build test ERROR on hnaz-mm/master linus/master v5.15-rc5 next-20211013]
[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/Georgi-Djakov/iommu-iova-Add-support-for-IOVA-max-alignment-tuning/20211014-021248
base:   https://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git next
config: i386-randconfig-a003-20211013 (attached as .config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 
b6a8c695542b2987eb9a203d5663a0740cb4725f)
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/dc4cf3ea22a4c30a8a2c395e830ea37dd819
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review 
Georgi-Djakov/iommu-iova-Add-support-for-IOVA-max-alignment-tuning/20211014-021248
git checkout dc4cf3ea22a4c30a8a2c395e830ea37dd819
# save the attached .config to linux build tree
mkdir build_dir
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 
O=build_dir ARCH=i386 SHELL=/bin/bash drivers/iommu/

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

All error/warnings (new ones prefixed by >>):

>> drivers/iommu/iova.c:52:13: error: expected parameter declarator
   early_param("iommu.max_align_shift", iommu_set_def_max_align_shift);
   ^
>> drivers/iommu/iova.c:52:13: error: expected ')'
   drivers/iommu/iova.c:52:12: note: to match this '('
   early_param("iommu.max_align_shift", iommu_set_def_max_align_shift);
  ^
>> drivers/iommu/iova.c:52:1: warning: declaration specifier missing, 
>> defaulting to 'int'
   early_param("iommu.max_align_shift", iommu_set_def_max_align_shift);
   ^
   int
>> drivers/iommu/iova.c:52:12: error: this function declaration is not a 
>> prototype [-Werror,-Wstrict-prototypes]
   early_param("iommu.max_align_shift", iommu_set_def_max_align_shift);
  ^
 void
   1 warning and 3 errors generated.


vim +52 drivers/iommu/iova.c

40  
41  static int __init iommu_set_def_max_align_shift(char *str)
42  {
43  unsigned long max_align_shift;
44  
45  int ret = kstrtoul(str, 10, _align_shift);
46  
47  if (!ret)
48  iommu_max_align_shift = max_align_shift;
49  
50  return 0;
51  }
  > 52  early_param("iommu.max_align_shift", iommu_set_def_max_align_shift);
53  

---
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 0/5] iommu/virtio: Add identity domains

2021-10-13 Thread Tian, Kevin
> From: Jean-Philippe Brucker 
> Sent: Wednesday, October 13, 2021 8:11 PM
> 
> Support identity domains, allowing to only enable IOMMU protection for a
> subset of endpoints (those assigned to userspace, for example). Users
> may enable identity domains at compile time
> (CONFIG_IOMMU_DEFAULT_PASSTHROUGH), boot time
> (iommu.passthrough=1) or
> runtime (/sys/kernel/iommu_groups/*/type = identity).

Do we want to use consistent terms between spec (bypass domain) 
and code (identity domain)? 

> 
> Patches 1-2 support identity domains using the optional
> VIRTIO_IOMMU_F_BYPASS_CONFIG feature. The feature bit is not yet in the
> spec, see [1] for the latest proposal.
> 
> Patches 3-5 add a fallback to identity mappings, when the feature is not
> supported.
> 
> Note that this series doesn't touch the global bypass bit added by
> VIRTIO_IOMMU_F_BYPASS_CONFIG. All endpoints managed by the IOMMU
> should
> be attached to a domain, so global bypass isn't in use after endpoints

I saw a concept of deferred attach in iommu core. See iommu_is_
attach_deferred(). Currently this is vendor specific and I haven't
looked into the exact reason why some vendor sets it now. Just
be curious whether the same reason might be applied to virtio-iommu.

> are probed. Before that, the global bypass policy is decided by the
> hypervisor and firmware. So I don't think Linux needs to touch the

This reminds me one thing. The spec says that the global bypass
bit is sticky and not affected by reset. This implies that in the case
of rebooting the VM into a different OS, the previous OS actually
has the right to override this setting for the next OS. Is it a right
design? Even the firmware itself is unable to identify the original
setting enforced by the hypervisor after reboot. I feel the hypervisor
setting should be recovered after reset since it reflects the 
security measure enforced by the virtual platform?

> global bypass bit, but there are some patches available on my
> virtio-iommu/bypass branch [2] to test it.
> 
> QEMU patches are on my virtio-iommu/bypass branch [3] (and the list)
> 
> [1] https://www.mail-archive.com/virtio-dev@lists.oasis-
> open.org/msg07898.html
> [2] https://jpbrucker.net/git/linux/log/?h=virtio-iommu/bypass
> [3] https://jpbrucker.net/git/qemu/log/?h=virtio-iommu/bypass
> 
> Jean-Philippe Brucker (5):
>   iommu/virtio: Add definitions for VIRTIO_IOMMU_F_BYPASS_CONFIG
>   iommu/virtio: Support bypass domains
>   iommu/virtio: Sort reserved regions
>   iommu/virtio: Pass end address to viommu_add_mapping()
>   iommu/virtio: Support identity-mapped domains
> 
>  include/uapi/linux/virtio_iommu.h |   8 ++-
>  drivers/iommu/virtio-iommu.c  | 113 +-
>  2 files changed, 101 insertions(+), 20 deletions(-)
> 
> --
> 2.33.0

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


Re: [PATCH] iommu/arm: fix ARM_SMMU_QCOM compilation

2021-10-13 Thread Arnd Bergmann
On Wed, Oct 13, 2021 at 6:20 PM Will Deacon  wrote:
> On Wed, Oct 13, 2021 at 10:33:55AM +0200, Arnd Bergmann wrote:
> > On Wed, Oct 13, 2021 at 9:58 AM Will Deacon  wrote:
> > > On Tue, Oct 12, 2021 at 05:18:00PM +0200, Arnd Bergmann wrote:

> > I was hoping you and Joerg could just pick your preferred patch
> > into the iommu fixes tree for v5.15.
> >
> > I currently have nothing else pending for my asm-generic tree that
> > introduced the regression, but I can take it through there if that helps
> > you.
>
> I also don't have any fixes pending, and I don't see any in Joerg's tree so
> it's probably quickest if you send it on yourself. Is that ok?

Sure, no problem. I ended up adding it to the arm/fixes branch of the
soc tree, as I just merged some other fixes there, and it seems as good
as any of the other trees.

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


Re: [PATCH] iommu/iova: Add support for IOVA max alignment tuning

2021-10-13 Thread Robin Murphy

On 2021-10-13 19:11, Georgi Djakov wrote:

IOVAs are aligned to the smallest PAGE_SIZE order, where the requested
IOVA can fit. But this might not work for all use-cases. It can cause
IOVA fragmentation in some multimedia and 8K video use-cases that may
require larger buffers to be allocated and mapped.

When the above allocation pattern is used with the current alignment
scheme, the IOVA space could be quickly exhausted for 32bit devices.

In order to get better IOVA space utilization and reduce fragmentation,
a new kernel command line parameter is introduced to make the alignment
limit configurable by the user during boot.

Signed-off-by: Georgi Djakov 
---
  Documentation/admin-guide/kernel-parameters.txt |  8 
  drivers/iommu/iova.c| 26 -


I see no good reason for the IOVA layer to lie to its callers. If they 
don't need an aligned IOVA, they shouldn't ask for one in the first 
place. If callers still need some intermediate degree of alignment then 
the IOVA API might want to grow something more expressive than "bool 
size_aligned", but it should still be the callers' responsibility to 
pass an appropriate value.


Thanks,
Robin.


  2 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt 
b/Documentation/admin-guide/kernel-parameters.txt
index ad94a2aa9819..630246dc691f 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -2056,6 +2056,14 @@
  forcing Dual Address Cycle for PCI cards supporting
  greater than 32-bit addressing.
  
+	iommu.max_align_shift=

+   [ARM64, X86] Limit the alignment of IOVAs to a maximum
+   PAGE_SIZE order. Larger IOVAs will be aligned to this
+   specified order. The order is expressed as a power of
+   two multiplied by the PAGE_SIZE.
+   Format: { "4" | "5" | "6" | "7" | "8" | "9" }
+   Default: 9
+
iommu.strict=   [ARM64, X86] Configure TLB invalidation behaviour
Format: { "0" | "1" }
0 - Lazy mode.
diff --git a/drivers/iommu/iova.c b/drivers/iommu/iova.c
index 9e8bc802ac05..5a8c86871735 100644
--- a/drivers/iommu/iova.c
+++ b/drivers/iommu/iova.c
@@ -15,6 +15,9 @@
  /* The anchor node sits above the top of the usable address space */
  #define IOVA_ANCHOR   ~0UL
  
+#define IOMMU_DEFAULT_IOVA_MAX_ALIGN_SHIFT	9

+static unsigned long iommu_max_align_shift __read_mostly = 
IOMMU_DEFAULT_IOVA_MAX_ALIGN_SHIFT;
+
  static bool iova_rcache_insert(struct iova_domain *iovad,
   unsigned long pfn,
   unsigned long size);
@@ -27,6 +30,27 @@ static void free_iova_rcaches(struct iova_domain *iovad);
  static void fq_destroy_all_entries(struct iova_domain *iovad);
  static void fq_flush_timeout(struct timer_list *t);
  
+static unsigned long limit_align_shift(struct iova_domain *iovad, unsigned long shift)

+{
+   unsigned long max_align_shift;
+
+   max_align_shift = iommu_max_align_shift + PAGE_SHIFT - 
iova_shift(iovad);
+   return min_t(unsigned long, max_align_shift, shift);
+}
+
+static int __init iommu_set_def_max_align_shift(char *str)
+{
+   unsigned long max_align_shift;
+
+   int ret = kstrtoul(str, 10, _align_shift);
+
+   if (!ret)
+   iommu_max_align_shift = max_align_shift;
+
+   return 0;
+}
+early_param("iommu.max_align_shift", iommu_set_def_max_align_shift);
+
  static int iova_cpuhp_dead(unsigned int cpu, struct hlist_node *node)
  {
struct iova_domain *iovad;
@@ -242,7 +266,7 @@ static int __alloc_and_insert_iova_range(struct iova_domain 
*iovad,
unsigned long high_pfn = limit_pfn, low_pfn = iovad->start_pfn;
  
  	if (size_aligned)

-   align_mask <<= fls_long(size - 1);
+   align_mask <<= limit_align_shift(iovad, fls_long(size - 1));
  
  	/* Walk the tree backwards */

spin_lock_irqsave(>iova_rbtree_lock, flags);


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


[PATCH] iommu/iova: Add support for IOVA max alignment tuning

2021-10-13 Thread Georgi Djakov
IOVAs are aligned to the smallest PAGE_SIZE order, where the requested
IOVA can fit. But this might not work for all use-cases. It can cause
IOVA fragmentation in some multimedia and 8K video use-cases that may
require larger buffers to be allocated and mapped.

When the above allocation pattern is used with the current alignment
scheme, the IOVA space could be quickly exhausted for 32bit devices.

In order to get better IOVA space utilization and reduce fragmentation,
a new kernel command line parameter is introduced to make the alignment
limit configurable by the user during boot.

Signed-off-by: Georgi Djakov 
---
 Documentation/admin-guide/kernel-parameters.txt |  8 
 drivers/iommu/iova.c| 26 -
 2 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt 
b/Documentation/admin-guide/kernel-parameters.txt
index ad94a2aa9819..630246dc691f 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -2056,6 +2056,14 @@
  forcing Dual Address Cycle for PCI cards supporting
  greater than 32-bit addressing.
 
+   iommu.max_align_shift=
+   [ARM64, X86] Limit the alignment of IOVAs to a maximum
+   PAGE_SIZE order. Larger IOVAs will be aligned to this
+   specified order. The order is expressed as a power of
+   two multiplied by the PAGE_SIZE.
+   Format: { "4" | "5" | "6" | "7" | "8" | "9" }
+   Default: 9
+
iommu.strict=   [ARM64, X86] Configure TLB invalidation behaviour
Format: { "0" | "1" }
0 - Lazy mode.
diff --git a/drivers/iommu/iova.c b/drivers/iommu/iova.c
index 9e8bc802ac05..5a8c86871735 100644
--- a/drivers/iommu/iova.c
+++ b/drivers/iommu/iova.c
@@ -15,6 +15,9 @@
 /* The anchor node sits above the top of the usable address space */
 #define IOVA_ANCHOR~0UL
 
+#define IOMMU_DEFAULT_IOVA_MAX_ALIGN_SHIFT 9
+static unsigned long iommu_max_align_shift __read_mostly = 
IOMMU_DEFAULT_IOVA_MAX_ALIGN_SHIFT;
+
 static bool iova_rcache_insert(struct iova_domain *iovad,
   unsigned long pfn,
   unsigned long size);
@@ -27,6 +30,27 @@ static void free_iova_rcaches(struct iova_domain *iovad);
 static void fq_destroy_all_entries(struct iova_domain *iovad);
 static void fq_flush_timeout(struct timer_list *t);
 
+static unsigned long limit_align_shift(struct iova_domain *iovad, unsigned 
long shift)
+{
+   unsigned long max_align_shift;
+
+   max_align_shift = iommu_max_align_shift + PAGE_SHIFT - 
iova_shift(iovad);
+   return min_t(unsigned long, max_align_shift, shift);
+}
+
+static int __init iommu_set_def_max_align_shift(char *str)
+{
+   unsigned long max_align_shift;
+
+   int ret = kstrtoul(str, 10, _align_shift);
+
+   if (!ret)
+   iommu_max_align_shift = max_align_shift;
+
+   return 0;
+}
+early_param("iommu.max_align_shift", iommu_set_def_max_align_shift);
+
 static int iova_cpuhp_dead(unsigned int cpu, struct hlist_node *node)
 {
struct iova_domain *iovad;
@@ -242,7 +266,7 @@ static int __alloc_and_insert_iova_range(struct iova_domain 
*iovad,
unsigned long high_pfn = limit_pfn, low_pfn = iovad->start_pfn;
 
if (size_aligned)
-   align_mask <<= fls_long(size - 1);
+   align_mask <<= limit_align_shift(iovad, fls_long(size - 1));
 
/* Walk the tree backwards */
spin_lock_irqsave(>iova_rbtree_lock, flags);
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH RFC] virtio: wrap config->reset calls

2021-10-13 Thread Cristian Marussi
On Wed, Oct 13, 2021 at 06:55:31AM -0400, Michael S. Tsirkin wrote:
> This will enable cleanups down the road.
> The idea is to disable cbs, then add "flush_queued_cbs" callback
> as a parameter, this way drivers can flush any work
> queued after callbacks have been disabled.
> 
> Signed-off-by: Michael S. Tsirkin 
> ---
>  arch/um/drivers/virt-pci.c | 2 +-
>  drivers/block/virtio_blk.c | 4 ++--
>  drivers/bluetooth/virtio_bt.c  | 2 +-
>  drivers/char/hw_random/virtio-rng.c| 2 +-
>  drivers/char/virtio_console.c  | 4 ++--
>  drivers/crypto/virtio/virtio_crypto_core.c | 8 
>  drivers/firmware/arm_scmi/virtio.c | 2 +-
>  drivers/gpio/gpio-virtio.c | 2 +-
>  drivers/gpu/drm/virtio/virtgpu_kms.c   | 2 +-
>  drivers/i2c/busses/i2c-virtio.c| 2 +-
>  drivers/iommu/virtio-iommu.c   | 2 +-
>  drivers/net/caif/caif_virtio.c | 2 +-
>  drivers/net/virtio_net.c   | 4 ++--
>  drivers/net/wireless/mac80211_hwsim.c  | 2 +-
>  drivers/nvdimm/virtio_pmem.c   | 2 +-
>  drivers/rpmsg/virtio_rpmsg_bus.c   | 2 +-
>  drivers/scsi/virtio_scsi.c | 2 +-
>  drivers/virtio/virtio.c| 5 +
>  drivers/virtio/virtio_balloon.c| 2 +-
>  drivers/virtio/virtio_input.c  | 2 +-
>  drivers/virtio/virtio_mem.c| 2 +-
>  fs/fuse/virtio_fs.c| 4 ++--
>  include/linux/virtio.h | 1 +
>  net/9p/trans_virtio.c  | 2 +-
>  net/vmw_vsock/virtio_transport.c   | 4 ++--
>  sound/virtio/virtio_card.c | 4 ++--
>  26 files changed, 39 insertions(+), 33 deletions(-)
> 
[snip]
> diff --git a/drivers/firmware/arm_scmi/virtio.c 
> b/drivers/firmware/arm_scmi/virtio.c
> index 11e8efb71375..6b8d93fe8848 100644
> --- a/drivers/firmware/arm_scmi/virtio.c
> +++ b/drivers/firmware/arm_scmi/virtio.c
> @@ -452,7 +452,7 @@ static void scmi_vio_remove(struct virtio_device *vdev)
>* outstanding message on any vqueue to be ignored by complete_cb: now
>* we can just stop processing buffers and destroy the vqueues.
>*/
> - vdev->config->reset(vdev);
> + virtio_reset_device(vdev);
>   vdev->config->del_vqs(vdev);
>   /* Ensure scmi_vdev is visible as NULL */
>   smp_store_mb(scmi_vdev, NULL);


Reviewed-by: Cristian Marussi 

Thanks,
Cristian

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


Re: [PATCH RFC] virtio: wrap config->reset calls

2021-10-13 Thread Pankaj Gupta
> This will enable cleanups down the road.
> The idea is to disable cbs, then add "flush_queued_cbs" callback
> as a parameter, this way drivers can flush any work
> queued after callbacks have been disabled.
>
> Signed-off-by: Michael S. Tsirkin 
> ---
>  arch/um/drivers/virt-pci.c | 2 +-
>  drivers/block/virtio_blk.c | 4 ++--
>  drivers/bluetooth/virtio_bt.c  | 2 +-
>  drivers/char/hw_random/virtio-rng.c| 2 +-
>  drivers/char/virtio_console.c  | 4 ++--
>  drivers/crypto/virtio/virtio_crypto_core.c | 8 
>  drivers/firmware/arm_scmi/virtio.c | 2 +-
>  drivers/gpio/gpio-virtio.c | 2 +-
>  drivers/gpu/drm/virtio/virtgpu_kms.c   | 2 +-
>  drivers/i2c/busses/i2c-virtio.c| 2 +-
>  drivers/iommu/virtio-iommu.c   | 2 +-
>  drivers/net/caif/caif_virtio.c | 2 +-
>  drivers/net/virtio_net.c   | 4 ++--
>  drivers/net/wireless/mac80211_hwsim.c  | 2 +-
>  drivers/nvdimm/virtio_pmem.c   | 2 +-
>  drivers/rpmsg/virtio_rpmsg_bus.c   | 2 +-
>  drivers/scsi/virtio_scsi.c | 2 +-
>  drivers/virtio/virtio.c| 5 +
>  drivers/virtio/virtio_balloon.c| 2 +-
>  drivers/virtio/virtio_input.c  | 2 +-
>  drivers/virtio/virtio_mem.c| 2 +-
>  fs/fuse/virtio_fs.c| 4 ++--
>  include/linux/virtio.h | 1 +
>  net/9p/trans_virtio.c  | 2 +-
>  net/vmw_vsock/virtio_transport.c   | 4 ++--
>  sound/virtio/virtio_card.c | 4 ++--
>  26 files changed, 39 insertions(+), 33 deletions(-)
>
> diff --git a/arch/um/drivers/virt-pci.c b/arch/um/drivers/virt-pci.c
> index c08066633023..22c4d87c9c15 100644
> --- a/arch/um/drivers/virt-pci.c
> +++ b/arch/um/drivers/virt-pci.c
> @@ -616,7 +616,7 @@ static void um_pci_virtio_remove(struct virtio_device 
> *vdev)
> int i;
>
>  /* Stop all virtqueues */
> -vdev->config->reset(vdev);
> +virtio_reset_device(vdev);
>  vdev->config->del_vqs(vdev);
>
> device_set_wakeup_enable(>dev, false);
> diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
> index 303caf2d17d0..83d0af3fbf30 100644
> --- a/drivers/block/virtio_blk.c
> +++ b/drivers/block/virtio_blk.c
> @@ -910,7 +910,7 @@ static void virtblk_remove(struct virtio_device *vdev)
> mutex_lock(>vdev_mutex);
>
> /* Stop all the virtqueues. */
> -   vdev->config->reset(vdev);
> +   virtio_reset_device(vdev);
>
> /* Virtqueues are stopped, nothing can use vblk->vdev anymore. */
> vblk->vdev = NULL;
> @@ -929,7 +929,7 @@ static int virtblk_freeze(struct virtio_device *vdev)
> struct virtio_blk *vblk = vdev->priv;
>
> /* Ensure we don't receive any more interrupts */
> -   vdev->config->reset(vdev);
> +   virtio_reset_device(vdev);
>
> /* Make sure no work handler is accessing the device. */
> flush_work(>config_work);
> diff --git a/drivers/bluetooth/virtio_bt.c b/drivers/bluetooth/virtio_bt.c
> index 57908ce4fae8..24a9258962fa 100644
> --- a/drivers/bluetooth/virtio_bt.c
> +++ b/drivers/bluetooth/virtio_bt.c
> @@ -364,7 +364,7 @@ static void virtbt_remove(struct virtio_device *vdev)
> struct hci_dev *hdev = vbt->hdev;
>
> hci_unregister_dev(hdev);
> -   vdev->config->reset(vdev);
> +   virtio_reset_device(vdev);
>
> hci_free_dev(hdev);
> vbt->hdev = NULL;
> diff --git a/drivers/char/hw_random/virtio-rng.c 
> b/drivers/char/hw_random/virtio-rng.c
> index a90001e02bf7..95980489514b 100644
> --- a/drivers/char/hw_random/virtio-rng.c
> +++ b/drivers/char/hw_random/virtio-rng.c
> @@ -134,7 +134,7 @@ static void remove_common(struct virtio_device *vdev)
> vi->hwrng_removed = true;
> vi->data_avail = 0;
> complete(>have_data);
> -   vdev->config->reset(vdev);
> +   virtio_reset_device(vdev);
> vi->busy = false;
> if (vi->hwrng_register_done)
> hwrng_unregister(>hwrng);
> diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
> index 7eaf303a7a86..08bbd693436f 100644
> --- a/drivers/char/virtio_console.c
> +++ b/drivers/char/virtio_console.c
> @@ -1957,7 +1957,7 @@ static void virtcons_remove(struct virtio_device *vdev)
> spin_unlock_irq(_lock);
>
> /* Disable interrupts for vqs */
> -   vdev->config->reset(vdev);
> +   virtio_reset_device(vdev);
> /* Finish up work that's lined up */
> if (use_multiport(portdev))
> cancel_work_sync(>control_work);
> @@ -2139,7 +2139,7 @@ static int virtcons_freeze(struct virtio_device *vdev)
>
> portdev = vdev->priv;
>
> -   vdev->config->reset(vdev);
> +   virtio_reset_device(vdev);
>
> if (use_multiport(portdev))
> 

Re: [PATCH] iommu/arm: fix ARM_SMMU_QCOM compilation

2021-10-13 Thread Will Deacon
Hi Arnd,

On Wed, Oct 13, 2021 at 10:33:55AM +0200, Arnd Bergmann wrote:
> On Wed, Oct 13, 2021 at 9:58 AM Will Deacon  wrote:
> > On Tue, Oct 12, 2021 at 05:18:00PM +0200, Arnd Bergmann wrote:
> > > From: Arnd Bergmann 
> > >
> > > My previous bugfix ended up making things worse for the QCOM IOMMU
> > > driver when it forgot to add the Kconfig symbol that is getting used to
> > > control the compilation of the SMMU implementation specific code
> > > for Qualcomm.
> > >
> > > Fixes: 424953cf3c66 ("qcom_scm: hide Kconfig symbol")
> > > Reported-by: Daniel Lezcano 
> > > Reported-by: Dmitry Baryshkov 
> > > Reported-by: John Stultz 
> > > Link: 
> > > https://lore.kernel.org/lkml/20211010023350.978638-1-dmitry.barysh...@linaro.org/
> > > Signed-off-by: Arnd Bergmann 
> > > ---
> > > In case we want fix it this way after all, here is the patch
> > > I made. Either this one or Dmitry patch from the link above
> > > is required for v5.15
> > > ---
> > >  drivers/iommu/Kconfig | 8 
> > >  1 file changed, 8 insertions(+)
> > >
> > > diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
> > > index c5c71b7ab7e8..3eb68fa1b8cc 100644
> > > --- a/drivers/iommu/Kconfig
> > > +++ b/drivers/iommu/Kconfig
> > > @@ -355,6 +355,14 @@ config ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT
> > > 'arm-smmu.disable_bypass' will continue to override this
> > > config.
> > >
> > > +config ARM_SMMU_QCOM
> > > + def_tristate y
> > > + depends on ARM_SMMU && ARCH_QCOM
> > > + select QCOM_SCM
> > > + help
> > > +   When running on a Qualcomm platform that has the custom variant
> > > +   of the ARM SMMU, this needs to be built into the SMMU driver.
> > > +
> >
> > FWIW, I prefer this solution over changing the driver code, so:
> >
> > Acked-by: Will Deacon 
> >
> > I assume you'll be getting this fixed for 5.15?
> 
> I was hoping you and Joerg could just pick your preferred patch
> into the iommu fixes tree for v5.15.
> 
> I currently have nothing else pending for my asm-generic tree that
> introduced the regression, but I can take it through there if that helps
> you.

I also don't have any fixes pending, and I don't see any in Joerg's tree so
it's probably quickest if you send it on yourself. Is that ok?

Cheers,

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


Re: [PATCH RFC] virtio: wrap config->reset calls

2021-10-13 Thread David Hildenbrand
On 13.10.21 14:17, Michael S. Tsirkin wrote:
> On Wed, Oct 13, 2021 at 01:03:46PM +0200, David Hildenbrand wrote:
>> On 13.10.21 12:55, Michael S. Tsirkin wrote:
>>> This will enable cleanups down the road.
>>> The idea is to disable cbs, then add "flush_queued_cbs" callback
>>> as a parameter, this way drivers can flush any work
>>> queued after callbacks have been disabled.
>>>
>>> Signed-off-by: Michael S. Tsirkin 
>>> ---
>>>   arch/um/drivers/virt-pci.c | 2 +-
>>>   drivers/block/virtio_blk.c | 4 ++--
>>>   drivers/bluetooth/virtio_bt.c  | 2 +-
>>>   drivers/char/hw_random/virtio-rng.c| 2 +-
>>>   drivers/char/virtio_console.c  | 4 ++--
>>>   drivers/crypto/virtio/virtio_crypto_core.c | 8 
>>>   drivers/firmware/arm_scmi/virtio.c | 2 +-
>>>   drivers/gpio/gpio-virtio.c | 2 +-
>>>   drivers/gpu/drm/virtio/virtgpu_kms.c   | 2 +-
>>>   drivers/i2c/busses/i2c-virtio.c| 2 +-
>>>   drivers/iommu/virtio-iommu.c   | 2 +-
>>>   drivers/net/caif/caif_virtio.c | 2 +-
>>>   drivers/net/virtio_net.c   | 4 ++--
>>>   drivers/net/wireless/mac80211_hwsim.c  | 2 +-
>>>   drivers/nvdimm/virtio_pmem.c   | 2 +-
>>>   drivers/rpmsg/virtio_rpmsg_bus.c   | 2 +-
>>>   drivers/scsi/virtio_scsi.c | 2 +-
>>>   drivers/virtio/virtio.c| 5 +
>>>   drivers/virtio/virtio_balloon.c| 2 +-
>>>   drivers/virtio/virtio_input.c  | 2 +-
>>>   drivers/virtio/virtio_mem.c| 2 +-
>>>   fs/fuse/virtio_fs.c| 4 ++--
>>>   include/linux/virtio.h | 1 +
>>>   net/9p/trans_virtio.c  | 2 +-
>>>   net/vmw_vsock/virtio_transport.c   | 4 ++--
>>>   sound/virtio/virtio_card.c | 4 ++--
>>>   26 files changed, 39 insertions(+), 33 deletions(-)
>>>
>>> diff --git a/arch/um/drivers/virt-pci.c b/arch/um/drivers/virt-pci.c
>>> index c08066633023..22c4d87c9c15 100644
>>> --- a/arch/um/drivers/virt-pci.c
>>> +++ b/arch/um/drivers/virt-pci.c
>>> @@ -616,7 +616,7 @@ static void um_pci_virtio_remove(struct virtio_device 
>>> *vdev)
>>> int i;
>>>   /* Stop all virtqueues */
>>> -vdev->config->reset(vdev);
>>> +virtio_reset_device(vdev);
>>>   vdev->config->del_vqs(vdev);
>>
>> Nit: virtio_device_reset()?
>>
>> Because I see:
>>
>> int virtio_device_freeze(struct virtio_device *dev);
>> int virtio_device_restore(struct virtio_device *dev);
>> void virtio_device_ready(struct virtio_device *dev)
>>
>> But well, there is:
>> void virtio_break_device(struct virtio_device *dev);
> 
> Exactly. I don't know what's best, so I opted for plain english :)

Fair enough, LGTM

Reviewed-by: David Hildenbrand 


-- 
Thanks,

David / dhildenb

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


Re: [PATCH RFC] virtio: wrap config->reset calls

2021-10-13 Thread Mathieu Poirier
On Wed, Oct 13, 2021 at 06:55:31AM -0400, Michael S. Tsirkin wrote:
> This will enable cleanups down the road.
> The idea is to disable cbs, then add "flush_queued_cbs" callback
> as a parameter, this way drivers can flush any work
> queued after callbacks have been disabled.
> 
> Signed-off-by: Michael S. Tsirkin 
> ---
>  arch/um/drivers/virt-pci.c | 2 +-
>  drivers/block/virtio_blk.c | 4 ++--
>  drivers/bluetooth/virtio_bt.c  | 2 +-
>  drivers/char/hw_random/virtio-rng.c| 2 +-
>  drivers/char/virtio_console.c  | 4 ++--
>  drivers/crypto/virtio/virtio_crypto_core.c | 8 
>  drivers/firmware/arm_scmi/virtio.c | 2 +-
>  drivers/gpio/gpio-virtio.c | 2 +-
>  drivers/gpu/drm/virtio/virtgpu_kms.c   | 2 +-
>  drivers/i2c/busses/i2c-virtio.c| 2 +-
>  drivers/iommu/virtio-iommu.c   | 2 +-
>  drivers/net/caif/caif_virtio.c | 2 +-
>  drivers/net/virtio_net.c   | 4 ++--
>  drivers/net/wireless/mac80211_hwsim.c  | 2 +-
>  drivers/nvdimm/virtio_pmem.c   | 2 +-
>  drivers/rpmsg/virtio_rpmsg_bus.c   | 2 +-
>  drivers/scsi/virtio_scsi.c | 2 +-
>  drivers/virtio/virtio.c| 5 +
>  drivers/virtio/virtio_balloon.c| 2 +-
>  drivers/virtio/virtio_input.c  | 2 +-
>  drivers/virtio/virtio_mem.c| 2 +-
>  fs/fuse/virtio_fs.c| 4 ++--
>  include/linux/virtio.h | 1 +
>  net/9p/trans_virtio.c  | 2 +-
>  net/vmw_vsock/virtio_transport.c   | 4 ++--
>  sound/virtio/virtio_card.c | 4 ++--
>  26 files changed, 39 insertions(+), 33 deletions(-)
> 
>  static struct virtio_driver virtio_pmem_driver = {
> diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c 
> b/drivers/rpmsg/virtio_rpmsg_bus.c
> index 8e49a3bacfc7..6a11952822df 100644
> --- a/drivers/rpmsg/virtio_rpmsg_bus.c
> +++ b/drivers/rpmsg/virtio_rpmsg_bus.c
> @@ -1015,7 +1015,7 @@ static void rpmsg_remove(struct virtio_device *vdev)
>   size_t total_buf_space = vrp->num_bufs * vrp->buf_size;
>   int ret;
>  
> - vdev->config->reset(vdev);
> + virtio_reset_device(vdev);
> 

Reviewed-by: Mathieu Poirier 

>   ret = device_for_each_child(>dev, NULL, rpmsg_remove_device);
>   if (ret)
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH] iommu/dart: use kmemdup instead of kzalloc and memcpy

2021-10-13 Thread Alyssa Rosenzweig
Reviewed-by: Alyssa Rosenzweig 

On Wed, Oct 13, 2021 at 02:34:41AM -0400, Wan Jiabing wrote:
> Fix following coccicheck warning:
> drivers/iommu/apple-dart.c:704:20-27: WARNING opportunity for kmemdup
> 
> Signed-off-by: Wan Jiabing 
> ---
>  drivers/iommu/apple-dart.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/drivers/iommu/apple-dart.c b/drivers/iommu/apple-dart.c
> index 280ff8df728d..5eeb8d6b72e2 100644
> --- a/drivers/iommu/apple-dart.c
> +++ b/drivers/iommu/apple-dart.c
> @@ -701,13 +701,12 @@ static struct iommu_group 
> *apple_dart_device_group(struct device *dev)
>   if (!group)
>   goto out;
>  
> - group_master_cfg = kzalloc(sizeof(*group_master_cfg), GFP_KERNEL);
> + group_master_cfg = kmemdup(cfg, sizeof(*group_master_cfg), GFP_KERNEL);
>   if (!group_master_cfg) {
>   iommu_group_put(group);
>   goto out;
>   }
>  
> - memcpy(group_master_cfg, cfg, sizeof(*group_master_cfg));
>   iommu_group_set_iommudata(group, group_master_cfg,
>   apple_dart_release_group);
>  
> -- 
> 2.20.1
> 
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH RFC] virtio: wrap config->reset calls

2021-10-13 Thread Vivek Goyal
On Wed, Oct 13, 2021 at 06:55:31AM -0400, Michael S. Tsirkin wrote:
> This will enable cleanups down the road.
> The idea is to disable cbs, then add "flush_queued_cbs" callback
> as a parameter, this way drivers can flush any work
> queued after callbacks have been disabled.
> 
> Signed-off-by: Michael S. Tsirkin 
> ---
>  arch/um/drivers/virt-pci.c | 2 +-
>  drivers/block/virtio_blk.c | 4 ++--
>  drivers/bluetooth/virtio_bt.c  | 2 +-
>  drivers/char/hw_random/virtio-rng.c| 2 +-
>  drivers/char/virtio_console.c  | 4 ++--
>  drivers/crypto/virtio/virtio_crypto_core.c | 8 
>  drivers/firmware/arm_scmi/virtio.c | 2 +-
>  drivers/gpio/gpio-virtio.c | 2 +-
>  drivers/gpu/drm/virtio/virtgpu_kms.c   | 2 +-
>  drivers/i2c/busses/i2c-virtio.c| 2 +-
>  drivers/iommu/virtio-iommu.c   | 2 +-
>  drivers/net/caif/caif_virtio.c | 2 +-
>  drivers/net/virtio_net.c   | 4 ++--
>  drivers/net/wireless/mac80211_hwsim.c  | 2 +-
>  drivers/nvdimm/virtio_pmem.c   | 2 +-
>  drivers/rpmsg/virtio_rpmsg_bus.c   | 2 +-
>  drivers/scsi/virtio_scsi.c | 2 +-
>  drivers/virtio/virtio.c| 5 +
>  drivers/virtio/virtio_balloon.c| 2 +-
>  drivers/virtio/virtio_input.c  | 2 +-
>  drivers/virtio/virtio_mem.c| 2 +-
>  fs/fuse/virtio_fs.c| 4 ++--

fs/fuse/virtio_fs.c changes look good to me.

Reviewed-by: Vivek Goyal 

Vivek

[..]
> diff --git a/fs/fuse/virtio_fs.c b/fs/fuse/virtio_fs.c
> index 0ad89c6629d7..27c3b74070a2 100644
> --- a/fs/fuse/virtio_fs.c
> +++ b/fs/fuse/virtio_fs.c
> @@ -895,7 +895,7 @@ static int virtio_fs_probe(struct virtio_device *vdev)
>   return 0;
>  
>  out_vqs:
> - vdev->config->reset(vdev);
> + virtio_reset_device(vdev);
>   virtio_fs_cleanup_vqs(vdev, fs);
>   kfree(fs->vqs);
>  
> @@ -927,7 +927,7 @@ static void virtio_fs_remove(struct virtio_device *vdev)
>   list_del_init(>list);
>   virtio_fs_stop_all_queues(fs);
>   virtio_fs_drain_all_queues_locked(fs);
> - vdev->config->reset(vdev);
> + virtio_reset_device(vdev);
>   virtio_fs_cleanup_vqs(vdev, fs);
>  
>   vdev->priv = NULL;


Thanks
Vivek

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


[PATCH] iommu/dart: use kmemdup instead of kzalloc and memcpy

2021-10-13 Thread Wan Jiabing via iommu
Fix following coccicheck warning:
drivers/iommu/apple-dart.c:704:20-27: WARNING opportunity for kmemdup

Signed-off-by: Wan Jiabing 
---
 drivers/iommu/apple-dart.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/iommu/apple-dart.c b/drivers/iommu/apple-dart.c
index 280ff8df728d..5eeb8d6b72e2 100644
--- a/drivers/iommu/apple-dart.c
+++ b/drivers/iommu/apple-dart.c
@@ -701,13 +701,12 @@ static struct iommu_group *apple_dart_device_group(struct 
device *dev)
if (!group)
goto out;
 
-   group_master_cfg = kzalloc(sizeof(*group_master_cfg), GFP_KERNEL);
+   group_master_cfg = kmemdup(cfg, sizeof(*group_master_cfg), GFP_KERNEL);
if (!group_master_cfg) {
iommu_group_put(group);
goto out;
}
 
-   memcpy(group_master_cfg, cfg, sizeof(*group_master_cfg));
iommu_group_set_iommudata(group, group_master_cfg,
apple_dart_release_group);
 
-- 
2.20.1

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


[PATCH 5/5] iommu/virtio: Support identity-mapped domains

2021-10-13 Thread Jean-Philippe Brucker
Support identity domains for devices that do not offer the
VIRTIO_IOMMU_F_BYPASS_CONFIG feature, by creating 1:1 mappings between
the virtual and physical address space. Identity domains created this
way still perform noticeably better than DMA domains, because they don't
have the overhead of setting up and tearing down mappings at runtime.
The performance difference between this and bypass is minimal in
comparison.

It does not matter that the physical addresses in the identity mappings
do not all correspond to memory. By enabling passthrough we are trusting
the device driver and the device itself to only perform DMA to suitable
locations. In some cases it may even be desirable to perform DMA to MMIO
regions.

Signed-off-by: Jean-Philippe Brucker 
---
 drivers/iommu/virtio-iommu.c | 61 +---
 1 file changed, 57 insertions(+), 4 deletions(-)

diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c
index eceb9281c8c1..c9e8367d2962 100644
--- a/drivers/iommu/virtio-iommu.c
+++ b/drivers/iommu/virtio-iommu.c
@@ -375,6 +375,55 @@ static size_t viommu_del_mappings(struct viommu_domain 
*vdomain,
return unmapped;
 }
 
+/*
+ * Fill the domain with identity mappings, skipping the device's reserved
+ * regions.
+ */
+static int viommu_domain_map_identity(struct viommu_endpoint *vdev,
+ struct viommu_domain *vdomain)
+{
+   int ret;
+   struct iommu_resv_region *resv;
+   u64 iova = vdomain->domain.geometry.aperture_start;
+   u64 limit = vdomain->domain.geometry.aperture_end;
+   u32 flags = VIRTIO_IOMMU_MAP_F_READ | VIRTIO_IOMMU_MAP_F_WRITE;
+   unsigned long granule = 1UL << __ffs(vdomain->domain.pgsize_bitmap);
+
+   iova = ALIGN(iova, granule);
+   limit = ALIGN_DOWN(limit + 1, granule) - 1;
+
+   list_for_each_entry(resv, >resv_regions, list) {
+   u64 resv_start = ALIGN_DOWN(resv->start, granule);
+   u64 resv_end = ALIGN(resv->start + resv->length, granule) - 1;
+
+   if (resv_end < iova || resv_start > limit)
+   /* No overlap */
+   continue;
+
+   if (resv_start > iova) {
+   ret = viommu_add_mapping(vdomain, iova, resv_start - 1,
+(phys_addr_t)iova, flags);
+   if (ret)
+   goto err_unmap;
+   }
+
+   if (resv_end >= limit)
+   return 0;
+
+   iova = resv_end + 1;
+   }
+
+   ret = viommu_add_mapping(vdomain, iova, limit, (phys_addr_t)iova,
+flags);
+   if (ret)
+   goto err_unmap;
+   return 0;
+
+err_unmap:
+   viommu_del_mappings(vdomain, 0, iova);
+   return ret;
+}
+
 /*
  * viommu_replay_mappings - re-send MAP requests
  *
@@ -637,14 +686,18 @@ static int viommu_domain_finalise(struct viommu_endpoint 
*vdev,
vdomain->viommu = viommu;
 
if (domain->type == IOMMU_DOMAIN_IDENTITY) {
-   if (!virtio_has_feature(viommu->vdev,
-   VIRTIO_IOMMU_F_BYPASS_CONFIG)) {
+   if (virtio_has_feature(viommu->vdev,
+  VIRTIO_IOMMU_F_BYPASS_CONFIG)) {
+   vdomain->bypass = true;
+   return 0;
+   }
+
+   ret = viommu_domain_map_identity(vdev, vdomain);
+   if (ret) {
ida_free(>domain_ids, vdomain->id);
vdomain->viommu = 0;
return -EOPNOTSUPP;
}
-
-   vdomain->bypass = true;
}
 
return 0;
-- 
2.33.0

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


[PATCH 4/5] iommu/virtio: Pass end address to viommu_add_mapping()

2021-10-13 Thread Jean-Philippe Brucker
To support identity mappings, the virtio-iommu driver must be able to
represent full 64-bit ranges internally. Pass (start, end) instead of
(start, size) to viommu_add/del_mapping().

Clean comments. The one about the returned size was never true: when
sweeping the whole address space the returned size will most certainly
be smaller than 2^64.

Signed-off-by: Jean-Philippe Brucker 
---
 drivers/iommu/virtio-iommu.c | 31 +++
 1 file changed, 15 insertions(+), 16 deletions(-)

diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c
index d63ec4d11b00..eceb9281c8c1 100644
--- a/drivers/iommu/virtio-iommu.c
+++ b/drivers/iommu/virtio-iommu.c
@@ -311,8 +311,8 @@ static int viommu_send_req_sync(struct viommu_dev *viommu, 
void *buf,
  *
  * On success, return the new mapping. Otherwise return NULL.
  */
-static int viommu_add_mapping(struct viommu_domain *vdomain, unsigned long 
iova,
- phys_addr_t paddr, size_t size, u32 flags)
+static int viommu_add_mapping(struct viommu_domain *vdomain, u64 iova, u64 end,
+ phys_addr_t paddr, u32 flags)
 {
unsigned long irqflags;
struct viommu_mapping *mapping;
@@ -323,7 +323,7 @@ static int viommu_add_mapping(struct viommu_domain 
*vdomain, unsigned long iova,
 
mapping->paddr  = paddr;
mapping->iova.start = iova;
-   mapping->iova.last  = iova + size - 1;
+   mapping->iova.last  = end;
mapping->flags  = flags;
 
spin_lock_irqsave(>mappings_lock, irqflags);
@@ -338,26 +338,24 @@ static int viommu_add_mapping(struct viommu_domain 
*vdomain, unsigned long iova,
  *
  * @vdomain: the domain
  * @iova: start of the range
- * @size: size of the range. A size of 0 corresponds to the entire address
- * space.
+ * @end: end of the range
  *
- * On success, returns the number of unmapped bytes (>= size)
+ * On success, returns the number of unmapped bytes
  */
 static size_t viommu_del_mappings(struct viommu_domain *vdomain,
- unsigned long iova, size_t size)
+ u64 iova, u64 end)
 {
size_t unmapped = 0;
unsigned long flags;
-   unsigned long last = iova + size - 1;
struct viommu_mapping *mapping = NULL;
struct interval_tree_node *node, *next;
 
spin_lock_irqsave(>mappings_lock, flags);
-   next = interval_tree_iter_first(>mappings, iova, last);
+   next = interval_tree_iter_first(>mappings, iova, end);
while (next) {
node = next;
mapping = container_of(node, struct viommu_mapping, iova);
-   next = interval_tree_iter_next(node, iova, last);
+   next = interval_tree_iter_next(node, iova, end);
 
/* Trying to split a mapping? */
if (mapping->iova.start < iova)
@@ -656,8 +654,8 @@ static void viommu_domain_free(struct iommu_domain *domain)
 {
struct viommu_domain *vdomain = to_viommu_domain(domain);
 
-   /* Free all remaining mappings (size 2^64) */
-   viommu_del_mappings(vdomain, 0, 0);
+   /* Free all remaining mappings */
+   viommu_del_mappings(vdomain, 0, ULLONG_MAX);
 
if (vdomain->viommu)
ida_free(>viommu->domain_ids, vdomain->id);
@@ -742,6 +740,7 @@ static int viommu_map(struct iommu_domain *domain, unsigned 
long iova,
 {
int ret;
u32 flags;
+   u64 end = iova + size - 1;
struct virtio_iommu_req_map map;
struct viommu_domain *vdomain = to_viommu_domain(domain);
 
@@ -752,7 +751,7 @@ static int viommu_map(struct iommu_domain *domain, unsigned 
long iova,
if (flags & ~vdomain->map_flags)
return -EINVAL;
 
-   ret = viommu_add_mapping(vdomain, iova, paddr, size, flags);
+   ret = viommu_add_mapping(vdomain, iova, end, paddr, flags);
if (ret)
return ret;
 
@@ -761,7 +760,7 @@ static int viommu_map(struct iommu_domain *domain, unsigned 
long iova,
.domain = cpu_to_le32(vdomain->id),
.virt_start = cpu_to_le64(iova),
.phys_start = cpu_to_le64(paddr),
-   .virt_end   = cpu_to_le64(iova + size - 1),
+   .virt_end   = cpu_to_le64(end),
.flags  = cpu_to_le32(flags),
};
 
@@ -770,7 +769,7 @@ static int viommu_map(struct iommu_domain *domain, unsigned 
long iova,
 
ret = viommu_send_req_sync(vdomain->viommu, , sizeof(map));
if (ret)
-   viommu_del_mappings(vdomain, iova, size);
+   viommu_del_mappings(vdomain, iova, end);
 
return ret;
 }
@@ -783,7 +782,7 @@ static size_t viommu_unmap(struct iommu_domain *domain, 
unsigned long iova,
struct virtio_iommu_req_unmap unmap;
struct viommu_domain *vdomain = to_viommu_domain(domain);
 
-   unmapped = 

[PATCH 2/5] iommu/virtio: Support bypass domains

2021-10-13 Thread Jean-Philippe Brucker
The VIRTIO_IOMMU_F_BYPASS_CONFIG feature adds a new flag to the ATTACH
request, that creates a bypass domain. Use it to enable identity
domains.

When VIRTIO_IOMMU_F_BYPASS_CONFIG is not supported by the device, we
currently fail attaching to an identity domain. Future patches will
instead create identity mappings in this case.

Signed-off-by: Jean-Philippe Brucker 
---
 drivers/iommu/virtio-iommu.c | 20 +++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c
index 80930ce04a16..ee8a7afd667b 100644
--- a/drivers/iommu/virtio-iommu.c
+++ b/drivers/iommu/virtio-iommu.c
@@ -71,6 +71,7 @@ struct viommu_domain {
struct rb_root_cached   mappings;
 
unsigned long   nr_endpoints;
+   boolbypass;
 };
 
 struct viommu_endpoint {
@@ -587,7 +588,9 @@ static struct iommu_domain *viommu_domain_alloc(unsigned 
type)
 {
struct viommu_domain *vdomain;
 
-   if (type != IOMMU_DOMAIN_UNMANAGED && type != IOMMU_DOMAIN_DMA)
+   if (type != IOMMU_DOMAIN_UNMANAGED &&
+   type != IOMMU_DOMAIN_DMA &&
+   type != IOMMU_DOMAIN_IDENTITY)
return NULL;
 
vdomain = kzalloc(sizeof(*vdomain), GFP_KERNEL);
@@ -630,6 +633,17 @@ static int viommu_domain_finalise(struct viommu_endpoint 
*vdev,
vdomain->map_flags  = viommu->map_flags;
vdomain->viommu = viommu;
 
+   if (domain->type == IOMMU_DOMAIN_IDENTITY) {
+   if (!virtio_has_feature(viommu->vdev,
+   VIRTIO_IOMMU_F_BYPASS_CONFIG)) {
+   ida_free(>domain_ids, vdomain->id);
+   vdomain->viommu = 0;
+   return -EOPNOTSUPP;
+   }
+
+   vdomain->bypass = true;
+   }
+
return 0;
 }
 
@@ -691,6 +705,9 @@ static int viommu_attach_dev(struct iommu_domain *domain, 
struct device *dev)
.domain = cpu_to_le32(vdomain->id),
};
 
+   if (vdomain->bypass)
+   req.flags |= cpu_to_le32(VIRTIO_IOMMU_ATTACH_F_BYPASS);
+
for (i = 0; i < fwspec->num_ids; i++) {
req.endpoint = cpu_to_le32(fwspec->ids[i]);
 
@@ -1132,6 +1149,7 @@ static unsigned int features[] = {
VIRTIO_IOMMU_F_DOMAIN_RANGE,
VIRTIO_IOMMU_F_PROBE,
VIRTIO_IOMMU_F_MMIO,
+   VIRTIO_IOMMU_F_BYPASS_CONFIG,
 };
 
 static struct virtio_device_id id_table[] = {
-- 
2.33.0

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


[PATCH 1/5] iommu/virtio: Add definitions for VIRTIO_IOMMU_F_BYPASS_CONFIG

2021-10-13 Thread Jean-Philippe Brucker
Add definitions for the VIRTIO_IOMMU_F_BYPASS_CONFIG, which supersedes
VIRTIO_IOMMU_F_BYPASS.

Signed-off-by: Jean-Philippe Brucker 
---
 include/uapi/linux/virtio_iommu.h | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/include/uapi/linux/virtio_iommu.h 
b/include/uapi/linux/virtio_iommu.h
index 237e36a280cb..cafd8cf7febf 100644
--- a/include/uapi/linux/virtio_iommu.h
+++ b/include/uapi/linux/virtio_iommu.h
@@ -16,6 +16,7 @@
 #define VIRTIO_IOMMU_F_BYPASS  3
 #define VIRTIO_IOMMU_F_PROBE   4
 #define VIRTIO_IOMMU_F_MMIO5
+#define VIRTIO_IOMMU_F_BYPASS_CONFIG   6
 
 struct virtio_iommu_range_64 {
__le64  start;
@@ -36,6 +37,8 @@ struct virtio_iommu_config {
struct virtio_iommu_range_32domain_range;
/* Probe buffer size */
__le32  probe_size;
+   __u8bypass;
+   __u8reserved[7];
 };
 
 /* Request types */
@@ -66,11 +69,14 @@ struct virtio_iommu_req_tail {
__u8reserved[3];
 };
 
+#define VIRTIO_IOMMU_ATTACH_F_BYPASS   (1 << 0)
+
 struct virtio_iommu_req_attach {
struct virtio_iommu_req_headhead;
__le32  domain;
__le32  endpoint;
-   __u8reserved[8];
+   __le32  flags;
+   __u8reserved[4];
struct virtio_iommu_req_tailtail;
 };
 
-- 
2.33.0

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


[PATCH 0/5] iommu/virtio: Add identity domains

2021-10-13 Thread Jean-Philippe Brucker
Support identity domains, allowing to only enable IOMMU protection for a
subset of endpoints (those assigned to userspace, for example). Users
may enable identity domains at compile time
(CONFIG_IOMMU_DEFAULT_PASSTHROUGH), boot time (iommu.passthrough=1) or
runtime (/sys/kernel/iommu_groups/*/type = identity).

Patches 1-2 support identity domains using the optional
VIRTIO_IOMMU_F_BYPASS_CONFIG feature. The feature bit is not yet in the
spec, see [1] for the latest proposal.

Patches 3-5 add a fallback to identity mappings, when the feature is not
supported.

Note that this series doesn't touch the global bypass bit added by
VIRTIO_IOMMU_F_BYPASS_CONFIG. All endpoints managed by the IOMMU should
be attached to a domain, so global bypass isn't in use after endpoints
are probed. Before that, the global bypass policy is decided by the
hypervisor and firmware. So I don't think Linux needs to touch the
global bypass bit, but there are some patches available on my
virtio-iommu/bypass branch [2] to test it.

QEMU patches are on my virtio-iommu/bypass branch [3] (and the list)

[1] https://www.mail-archive.com/virtio-dev@lists.oasis-open.org/msg07898.html
[2] https://jpbrucker.net/git/linux/log/?h=virtio-iommu/bypass
[3] https://jpbrucker.net/git/qemu/log/?h=virtio-iommu/bypass

Jean-Philippe Brucker (5):
  iommu/virtio: Add definitions for VIRTIO_IOMMU_F_BYPASS_CONFIG
  iommu/virtio: Support bypass domains
  iommu/virtio: Sort reserved regions
  iommu/virtio: Pass end address to viommu_add_mapping()
  iommu/virtio: Support identity-mapped domains

 include/uapi/linux/virtio_iommu.h |   8 ++-
 drivers/iommu/virtio-iommu.c  | 113 +-
 2 files changed, 101 insertions(+), 20 deletions(-)

-- 
2.33.0

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


[PATCH 3/5] iommu/virtio: Sort reserved regions

2021-10-13 Thread Jean-Philippe Brucker
To ease identity mapping support, keep the list of reserved regions
sorted.

Signed-off-by: Jean-Philippe Brucker 
---
 drivers/iommu/virtio-iommu.c | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c
index ee8a7afd667b..d63ec4d11b00 100644
--- a/drivers/iommu/virtio-iommu.c
+++ b/drivers/iommu/virtio-iommu.c
@@ -423,7 +423,7 @@ static int viommu_add_resv_mem(struct viommu_endpoint *vdev,
size_t size;
u64 start64, end64;
phys_addr_t start, end;
-   struct iommu_resv_region *region = NULL;
+   struct iommu_resv_region *region = NULL, *next;
unsigned long prot = IOMMU_WRITE | IOMMU_NOEXEC | IOMMU_MMIO;
 
start = start64 = le64_to_cpu(mem->start);
@@ -454,7 +454,12 @@ static int viommu_add_resv_mem(struct viommu_endpoint 
*vdev,
if (!region)
return -ENOMEM;
 
-   list_add(>list, >resv_regions);
+   /* Keep the list sorted */
+   list_for_each_entry(next, >resv_regions, list) {
+   if (next->start > region->start)
+   break;
+   }
+   list_add_tail(>list, >list);
return 0;
 }
 
-- 
2.33.0

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


Re: [PATCH RFC] virtio: wrap config->reset calls

2021-10-13 Thread Michael S. Tsirkin
On Wed, Oct 13, 2021 at 01:03:46PM +0200, David Hildenbrand wrote:
> On 13.10.21 12:55, Michael S. Tsirkin wrote:
> > This will enable cleanups down the road.
> > The idea is to disable cbs, then add "flush_queued_cbs" callback
> > as a parameter, this way drivers can flush any work
> > queued after callbacks have been disabled.
> > 
> > Signed-off-by: Michael S. Tsirkin 
> > ---
> >   arch/um/drivers/virt-pci.c | 2 +-
> >   drivers/block/virtio_blk.c | 4 ++--
> >   drivers/bluetooth/virtio_bt.c  | 2 +-
> >   drivers/char/hw_random/virtio-rng.c| 2 +-
> >   drivers/char/virtio_console.c  | 4 ++--
> >   drivers/crypto/virtio/virtio_crypto_core.c | 8 
> >   drivers/firmware/arm_scmi/virtio.c | 2 +-
> >   drivers/gpio/gpio-virtio.c | 2 +-
> >   drivers/gpu/drm/virtio/virtgpu_kms.c   | 2 +-
> >   drivers/i2c/busses/i2c-virtio.c| 2 +-
> >   drivers/iommu/virtio-iommu.c   | 2 +-
> >   drivers/net/caif/caif_virtio.c | 2 +-
> >   drivers/net/virtio_net.c   | 4 ++--
> >   drivers/net/wireless/mac80211_hwsim.c  | 2 +-
> >   drivers/nvdimm/virtio_pmem.c   | 2 +-
> >   drivers/rpmsg/virtio_rpmsg_bus.c   | 2 +-
> >   drivers/scsi/virtio_scsi.c | 2 +-
> >   drivers/virtio/virtio.c| 5 +
> >   drivers/virtio/virtio_balloon.c| 2 +-
> >   drivers/virtio/virtio_input.c  | 2 +-
> >   drivers/virtio/virtio_mem.c| 2 +-
> >   fs/fuse/virtio_fs.c| 4 ++--
> >   include/linux/virtio.h | 1 +
> >   net/9p/trans_virtio.c  | 2 +-
> >   net/vmw_vsock/virtio_transport.c   | 4 ++--
> >   sound/virtio/virtio_card.c | 4 ++--
> >   26 files changed, 39 insertions(+), 33 deletions(-)
> > 
> > diff --git a/arch/um/drivers/virt-pci.c b/arch/um/drivers/virt-pci.c
> > index c08066633023..22c4d87c9c15 100644
> > --- a/arch/um/drivers/virt-pci.c
> > +++ b/arch/um/drivers/virt-pci.c
> > @@ -616,7 +616,7 @@ static void um_pci_virtio_remove(struct virtio_device 
> > *vdev)
> > int i;
> >   /* Stop all virtqueues */
> > -vdev->config->reset(vdev);
> > +virtio_reset_device(vdev);
> >   vdev->config->del_vqs(vdev);
> 
> Nit: virtio_device_reset()?
> 
> Because I see:
> 
> int virtio_device_freeze(struct virtio_device *dev);
> int virtio_device_restore(struct virtio_device *dev);
> void virtio_device_ready(struct virtio_device *dev)
> 
> But well, there is:
> void virtio_break_device(struct virtio_device *dev);

Exactly. I don't know what's best, so I opted for plain english :)


> -- 
> Thanks,
> 
> David / dhildenb

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


Re: [PATCH RFC] virtio: wrap config->reset calls

2021-10-13 Thread David Hildenbrand

On 13.10.21 12:55, Michael S. Tsirkin wrote:

This will enable cleanups down the road.
The idea is to disable cbs, then add "flush_queued_cbs" callback
as a parameter, this way drivers can flush any work
queued after callbacks have been disabled.

Signed-off-by: Michael S. Tsirkin 
---
  arch/um/drivers/virt-pci.c | 2 +-
  drivers/block/virtio_blk.c | 4 ++--
  drivers/bluetooth/virtio_bt.c  | 2 +-
  drivers/char/hw_random/virtio-rng.c| 2 +-
  drivers/char/virtio_console.c  | 4 ++--
  drivers/crypto/virtio/virtio_crypto_core.c | 8 
  drivers/firmware/arm_scmi/virtio.c | 2 +-
  drivers/gpio/gpio-virtio.c | 2 +-
  drivers/gpu/drm/virtio/virtgpu_kms.c   | 2 +-
  drivers/i2c/busses/i2c-virtio.c| 2 +-
  drivers/iommu/virtio-iommu.c   | 2 +-
  drivers/net/caif/caif_virtio.c | 2 +-
  drivers/net/virtio_net.c   | 4 ++--
  drivers/net/wireless/mac80211_hwsim.c  | 2 +-
  drivers/nvdimm/virtio_pmem.c   | 2 +-
  drivers/rpmsg/virtio_rpmsg_bus.c   | 2 +-
  drivers/scsi/virtio_scsi.c | 2 +-
  drivers/virtio/virtio.c| 5 +
  drivers/virtio/virtio_balloon.c| 2 +-
  drivers/virtio/virtio_input.c  | 2 +-
  drivers/virtio/virtio_mem.c| 2 +-
  fs/fuse/virtio_fs.c| 4 ++--
  include/linux/virtio.h | 1 +
  net/9p/trans_virtio.c  | 2 +-
  net/vmw_vsock/virtio_transport.c   | 4 ++--
  sound/virtio/virtio_card.c | 4 ++--
  26 files changed, 39 insertions(+), 33 deletions(-)

diff --git a/arch/um/drivers/virt-pci.c b/arch/um/drivers/virt-pci.c
index c08066633023..22c4d87c9c15 100644
--- a/arch/um/drivers/virt-pci.c
+++ b/arch/um/drivers/virt-pci.c
@@ -616,7 +616,7 @@ static void um_pci_virtio_remove(struct virtio_device *vdev)
int i;
  
  /* Stop all virtqueues */

-vdev->config->reset(vdev);
+virtio_reset_device(vdev);
  vdev->config->del_vqs(vdev);


Nit: virtio_device_reset()?

Because I see:

int virtio_device_freeze(struct virtio_device *dev);
int virtio_device_restore(struct virtio_device *dev);
void virtio_device_ready(struct virtio_device *dev)

But well, there is:
void virtio_break_device(struct virtio_device *dev);

--
Thanks,

David / dhildenb

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


Re: [PATCH RFC] virtio: wrap config->reset calls

2021-10-13 Thread Viresh Kumar
On 13-10-21, 06:55, Michael S. Tsirkin wrote:
> This will enable cleanups down the road.
> The idea is to disable cbs, then add "flush_queued_cbs" callback
> as a parameter, this way drivers can flush any work
> queued after callbacks have been disabled.
> 
> Signed-off-by: Michael S. Tsirkin 
> ---
>  drivers/gpio/gpio-virtio.c | 2 +-
>  drivers/i2c/busses/i2c-virtio.c| 2 +-

Reviewed-by: Viresh Kumar 

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


[PATCH RFC] virtio: wrap config->reset calls

2021-10-13 Thread Michael S. Tsirkin
This will enable cleanups down the road.
The idea is to disable cbs, then add "flush_queued_cbs" callback
as a parameter, this way drivers can flush any work
queued after callbacks have been disabled.

Signed-off-by: Michael S. Tsirkin 
---
 arch/um/drivers/virt-pci.c | 2 +-
 drivers/block/virtio_blk.c | 4 ++--
 drivers/bluetooth/virtio_bt.c  | 2 +-
 drivers/char/hw_random/virtio-rng.c| 2 +-
 drivers/char/virtio_console.c  | 4 ++--
 drivers/crypto/virtio/virtio_crypto_core.c | 8 
 drivers/firmware/arm_scmi/virtio.c | 2 +-
 drivers/gpio/gpio-virtio.c | 2 +-
 drivers/gpu/drm/virtio/virtgpu_kms.c   | 2 +-
 drivers/i2c/busses/i2c-virtio.c| 2 +-
 drivers/iommu/virtio-iommu.c   | 2 +-
 drivers/net/caif/caif_virtio.c | 2 +-
 drivers/net/virtio_net.c   | 4 ++--
 drivers/net/wireless/mac80211_hwsim.c  | 2 +-
 drivers/nvdimm/virtio_pmem.c   | 2 +-
 drivers/rpmsg/virtio_rpmsg_bus.c   | 2 +-
 drivers/scsi/virtio_scsi.c | 2 +-
 drivers/virtio/virtio.c| 5 +
 drivers/virtio/virtio_balloon.c| 2 +-
 drivers/virtio/virtio_input.c  | 2 +-
 drivers/virtio/virtio_mem.c| 2 +-
 fs/fuse/virtio_fs.c| 4 ++--
 include/linux/virtio.h | 1 +
 net/9p/trans_virtio.c  | 2 +-
 net/vmw_vsock/virtio_transport.c   | 4 ++--
 sound/virtio/virtio_card.c | 4 ++--
 26 files changed, 39 insertions(+), 33 deletions(-)

diff --git a/arch/um/drivers/virt-pci.c b/arch/um/drivers/virt-pci.c
index c08066633023..22c4d87c9c15 100644
--- a/arch/um/drivers/virt-pci.c
+++ b/arch/um/drivers/virt-pci.c
@@ -616,7 +616,7 @@ static void um_pci_virtio_remove(struct virtio_device *vdev)
int i;
 
 /* Stop all virtqueues */
-vdev->config->reset(vdev);
+virtio_reset_device(vdev);
 vdev->config->del_vqs(vdev);
 
device_set_wakeup_enable(>dev, false);
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index 303caf2d17d0..83d0af3fbf30 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -910,7 +910,7 @@ static void virtblk_remove(struct virtio_device *vdev)
mutex_lock(>vdev_mutex);
 
/* Stop all the virtqueues. */
-   vdev->config->reset(vdev);
+   virtio_reset_device(vdev);
 
/* Virtqueues are stopped, nothing can use vblk->vdev anymore. */
vblk->vdev = NULL;
@@ -929,7 +929,7 @@ static int virtblk_freeze(struct virtio_device *vdev)
struct virtio_blk *vblk = vdev->priv;
 
/* Ensure we don't receive any more interrupts */
-   vdev->config->reset(vdev);
+   virtio_reset_device(vdev);
 
/* Make sure no work handler is accessing the device. */
flush_work(>config_work);
diff --git a/drivers/bluetooth/virtio_bt.c b/drivers/bluetooth/virtio_bt.c
index 57908ce4fae8..24a9258962fa 100644
--- a/drivers/bluetooth/virtio_bt.c
+++ b/drivers/bluetooth/virtio_bt.c
@@ -364,7 +364,7 @@ static void virtbt_remove(struct virtio_device *vdev)
struct hci_dev *hdev = vbt->hdev;
 
hci_unregister_dev(hdev);
-   vdev->config->reset(vdev);
+   virtio_reset_device(vdev);
 
hci_free_dev(hdev);
vbt->hdev = NULL;
diff --git a/drivers/char/hw_random/virtio-rng.c 
b/drivers/char/hw_random/virtio-rng.c
index a90001e02bf7..95980489514b 100644
--- a/drivers/char/hw_random/virtio-rng.c
+++ b/drivers/char/hw_random/virtio-rng.c
@@ -134,7 +134,7 @@ static void remove_common(struct virtio_device *vdev)
vi->hwrng_removed = true;
vi->data_avail = 0;
complete(>have_data);
-   vdev->config->reset(vdev);
+   virtio_reset_device(vdev);
vi->busy = false;
if (vi->hwrng_register_done)
hwrng_unregister(>hwrng);
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
index 7eaf303a7a86..08bbd693436f 100644
--- a/drivers/char/virtio_console.c
+++ b/drivers/char/virtio_console.c
@@ -1957,7 +1957,7 @@ static void virtcons_remove(struct virtio_device *vdev)
spin_unlock_irq(_lock);
 
/* Disable interrupts for vqs */
-   vdev->config->reset(vdev);
+   virtio_reset_device(vdev);
/* Finish up work that's lined up */
if (use_multiport(portdev))
cancel_work_sync(>control_work);
@@ -2139,7 +2139,7 @@ static int virtcons_freeze(struct virtio_device *vdev)
 
portdev = vdev->priv;
 
-   vdev->config->reset(vdev);
+   virtio_reset_device(vdev);
 
if (use_multiport(portdev))
virtqueue_disable_cb(portdev->c_ivq);
diff --git a/drivers/crypto/virtio/virtio_crypto_core.c 
b/drivers/crypto/virtio/virtio_crypto_core.c
index e2375d992308..8e977b7627cb 100644
--- a/drivers/crypto/virtio/virtio_crypto_core.c
+++ 

Re: [PATCH] iommu/arm: fix ARM_SMMU_QCOM compilation

2021-10-13 Thread Arnd Bergmann
On Wed, Oct 13, 2021 at 9:58 AM Will Deacon  wrote:
> On Tue, Oct 12, 2021 at 05:18:00PM +0200, Arnd Bergmann wrote:
> > From: Arnd Bergmann 
> >
> > My previous bugfix ended up making things worse for the QCOM IOMMU
> > driver when it forgot to add the Kconfig symbol that is getting used to
> > control the compilation of the SMMU implementation specific code
> > for Qualcomm.
> >
> > Fixes: 424953cf3c66 ("qcom_scm: hide Kconfig symbol")
> > Reported-by: Daniel Lezcano 
> > Reported-by: Dmitry Baryshkov 
> > Reported-by: John Stultz 
> > Link: 
> > https://lore.kernel.org/lkml/20211010023350.978638-1-dmitry.barysh...@linaro.org/
> > Signed-off-by: Arnd Bergmann 
> > ---
> > In case we want fix it this way after all, here is the patch
> > I made. Either this one or Dmitry patch from the link above
> > is required for v5.15
> > ---
> >  drivers/iommu/Kconfig | 8 
> >  1 file changed, 8 insertions(+)
> >
> > diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
> > index c5c71b7ab7e8..3eb68fa1b8cc 100644
> > --- a/drivers/iommu/Kconfig
> > +++ b/drivers/iommu/Kconfig
> > @@ -355,6 +355,14 @@ config ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT
> > 'arm-smmu.disable_bypass' will continue to override this
> > config.
> >
> > +config ARM_SMMU_QCOM
> > + def_tristate y
> > + depends on ARM_SMMU && ARCH_QCOM
> > + select QCOM_SCM
> > + help
> > +   When running on a Qualcomm platform that has the custom variant
> > +   of the ARM SMMU, this needs to be built into the SMMU driver.
> > +
>
> FWIW, I prefer this solution over changing the driver code, so:
>
> Acked-by: Will Deacon 
>
> I assume you'll be getting this fixed for 5.15?

I was hoping you and Joerg could just pick your preferred patch
into the iommu fixes tree for v5.15.

I currently have nothing else pending for my asm-generic tree that
introduced the regression, but I can take it through there if that helps
you.

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


Re: [PATCH] iommu/arm: fix ARM_SMMU_QCOM compilation

2021-10-13 Thread Will Deacon
On Tue, Oct 12, 2021 at 05:18:00PM +0200, Arnd Bergmann wrote:
> From: Arnd Bergmann 
> 
> My previous bugfix ended up making things worse for the QCOM IOMMU
> driver when it forgot to add the Kconfig symbol that is getting used to
> control the compilation of the SMMU implementation specific code
> for Qualcomm.
> 
> Fixes: 424953cf3c66 ("qcom_scm: hide Kconfig symbol")
> Reported-by: Daniel Lezcano 
> Reported-by: Dmitry Baryshkov 
> Reported-by: John Stultz 
> Link: 
> https://lore.kernel.org/lkml/20211010023350.978638-1-dmitry.barysh...@linaro.org/
> Signed-off-by: Arnd Bergmann 
> ---
> In case we want fix it this way after all, here is the patch
> I made. Either this one or Dmitry patch from the link above
> is required for v5.15
> ---
>  drivers/iommu/Kconfig | 8 
>  1 file changed, 8 insertions(+)
> 
> diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
> index c5c71b7ab7e8..3eb68fa1b8cc 100644
> --- a/drivers/iommu/Kconfig
> +++ b/drivers/iommu/Kconfig
> @@ -355,6 +355,14 @@ config ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT
> 'arm-smmu.disable_bypass' will continue to override this
> config.
>  
> +config ARM_SMMU_QCOM
> + def_tristate y
> + depends on ARM_SMMU && ARCH_QCOM
> + select QCOM_SCM
> + help
> +   When running on a Qualcomm platform that has the custom variant
> +   of the ARM SMMU, this needs to be built into the SMMU driver.
> +

FWIW, I prefer this solution over changing the driver code, so:

Acked-by: Will Deacon 

I assume you'll be getting this fixed for 5.15?

Cheers,

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


RE: [RFC 11/20] iommu/iommufd: Add IOMMU_IOASID_ALLOC/FREE

2021-10-13 Thread Tian, Kevin
> From: Jean-Philippe Brucker 
> Sent: Tuesday, October 12, 2021 4:34 PM
> 
> On Mon, Oct 11, 2021 at 08:38:17PM -0300, Jason Gunthorpe wrote:
> > On Mon, Oct 11, 2021 at 09:49:57AM +0100, Jean-Philippe Brucker wrote:
> >
> > > Seems like we don't need the negotiation part?  The host kernel
> > > communicates available IOVA ranges to userspace including holes (patch
> > > 17), and userspace can check that the ranges it needs are within the IOVA
> > > space boundaries. That part is necessary for DPDK as well since it needs
> > > to know about holes in the IOVA space where DMA wouldn't work as
> expected
> > > (MSI doorbells for example).
> >
> > I haven't looked super closely at DPDK, but the other simple VFIO app
> > I am aware of struggled to properly implement this semantic (Indeed it
> > wasn't even clear to the author this was even needed).
> >
> > It requires interval tree logic inside the application which is not a
> > trivial algorithm to implement in C.
> >
> > I do wonder if the "simple" interface should have an option more like
> > the DMA API where userspace just asks to DMA map some user memory
> and
> > gets back the dma_addr_t to use. Kernel manages the allocation
> > space/etc.
> 
> Agreed, it's tempting to use IOVA = VA but the two spaces aren't
> necessarily compatible. An extension that plugs into the IOVA allocator
> could be useful to userspace drivers.
> 

Make sense. We can have a flag in IOMMUFD_MAP_DMA to tell whether
the user provides vaddr or expects the kernel to allocate and return.

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


RE: [RFC 11/20] iommu/iommufd: Add IOMMU_IOASID_ALLOC/FREE

2021-10-13 Thread Tian, Kevin
> From: Jean-Philippe Brucker 
> Sent: Monday, October 11, 2021 4:50 PM
> 
> On Mon, Oct 11, 2021 at 05:02:01PM +1100, David Gibson wrote:
> > qemu wants to emulate a PAPR vIOMMU, so it says (via interfaces yet to
> > be determined) that it needs an IOAS where things can be mapped in the
> > range 0..2GiB (for the 32-bit window) and 2^59..2^59+1TiB (for the
> > 64-bit window).
> >
> > Ideally the host /dev/iommu will say "ok!", since both those ranges
> > are within the 0..2^60 translated range of the host IOMMU, and don't
> > touch the IO hole.  When the guest calls the IO mapping hypercalls,
> > qemu translates those into DMA_MAP operations, and since they're all
> > within the previously verified windows, they should work fine.
> 
> Seems like we don't need the negotiation part?  The host kernel
> communicates available IOVA ranges to userspace including holes (patch
> 17), and userspace can check that the ranges it needs are within the IOVA
> space boundaries. That part is necessary for DPDK as well since it needs
> to know about holes in the IOVA space where DMA wouldn't work as
> expected
> (MSI doorbells for example). And there already is a negotiation happening,
> when the host kernel rejects MAP ioctl outside the advertised area.
> 

Agree. This can cover the ppc platforms with fixed reserved ranges.
It's meaningless to have user further tell kernel that it is only willing
to use a subset of advertised area. for ppc platforms with dynamic
reserved ranges which are claimed by user, we can leave it out of
the common set and handled in a different way, either leveraging
ioas nesting if applied or having ppc specific cmd.

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


RE: [RFC 11/20] iommu/iommufd: Add IOMMU_IOASID_ALLOC/FREE

2021-10-13 Thread Tian, Kevin
> From: David Gibson
> Sent: Friday, October 1, 2021 2:11 PM
> 
> On Sun, Sep 19, 2021 at 02:38:39PM +0800, Liu Yi L wrote:
> > This patch adds IOASID allocation/free interface per iommufd. When
> > allocating an IOASID, userspace is expected to specify the type and
> > format information for the target I/O page table.
> >
> > This RFC supports only one type (IOMMU_IOASID_TYPE_KERNEL_TYPE1V2),
> > implying a kernel-managed I/O page table with vfio type1v2 mapping
> > semantics. For this type the user should specify the addr_width of
> > the I/O address space and whether the I/O page table is created in
> > an iommu enfore_snoop format. enforce_snoop must be true at this point,
> > as the false setting requires additional contract with KVM on handling
> > WBINVD emulation, which can be added later.
> >
> > Userspace is expected to call IOMMU_CHECK_EXTENSION (see next patch)
> > for what formats can be specified when allocating an IOASID.
> >
> > Open:
> > - Devices on PPC platform currently use a different iommu driver in vfio.
> >   Per previous discussion they can also use vfio type1v2 as long as there
> >   is a way to claim a specific iova range from a system-wide address space.
> >   This requirement doesn't sound PPC specific, as addr_width for pci
> devices
> >   can be also represented by a range [0, 2^addr_width-1]. This RFC hasn't
> >   adopted this design yet. We hope to have formal alignment in v1
> discussion
> >   and then decide how to incorporate it in v2.
> 
> Ok, there are several things we need for ppc.  None of which are
> inherently ppc specific and some of which will I think be useful for
> most platforms.  So, starting from most general to most specific
> here's basically what's needed:
> 
> 1. We need to represent the fact that the IOMMU can only translate
>*some* IOVAs, not a full 64-bit range.  You have the addr_width
>already, but I'm entirely sure if the translatable range on ppc
>(or other platforms) is always a power-of-2 size.  It usually will
>be, of course, but I'm not sure that's a hard requirement.  So
>using a size/max rather than just a number of bits might be safer.
> 
>I think basically every platform will need this.  Most platforms
>don't actually implement full 64-bit translation in any case, but
>rather some smaller number of bits that fits their page table
>format.
> 
> 2. The translatable range of IOVAs may not begin at 0.  So we need to
>advertise to userspace what the base address is, as well as the
>size.  POWER's main IOVA range begins at 2^59 (at least on the
>models I know about).
> 
>I think a number of platforms are likely to want this, though I
>couldn't name them apart from POWER.  Putting the translated IOVA
>window at some huge address is a pretty obvious approach to making
>an IOMMU which can translate a wide address range without colliding
>with any legacy PCI addresses down low (the IOMMU can check if this
>transaction is for it by just looking at some high bits in the
>address).
> 
> 3. There might be multiple translatable ranges.  So, on POWER the
>IOMMU can typically translate IOVAs from 0..2GiB, and also from
>2^59..2^59+.  The two ranges have completely separate IO
>page tables, with (usually) different layouts.  (The low range will
>nearly always be a single-level page table with 4kiB or 64kiB
>entries, the high one will be multiple levels depending on the size
>of the range and pagesize).
> 
>This may be less common, but I suspect POWER won't be the only
>platform to do something like this.  As above, using a high range
>is a pretty obvious approach, but clearly won't handle older
>devices which can't do 64-bit DMA.  So adding a smaller range for
>those devices is again a pretty obvious solution.  Any platform
>with an "IO hole" can be treated as having two ranges, one below
>the hole and one above it (although in that case they may well not
>have separate page tables

1-3 are common on all platforms with fixed reserved ranges. Current
vfio already reports permitted iova ranges to user via VFIO_IOMMU_
TYPE1_INFO_CAP_IOVA_RANGE and the user is expected to construct
maps only in those ranges. iommufd can follow the same logic for the
baseline uAPI.

For above cases a [base, max] hint can be provided by the user per
Jason's recommendation. It is a hint as no additional restriction is
imposed, since the kernel only cares about no violation on permitted
ranges that it reports to the user. Underlying iommu driver may use 
this hint to optimize e.g. deciding how many levels are used for
the kernel-managed page table according to max addr.

> 
> 4. The translatable ranges might not be fixed.  On ppc that 0..2GiB
>and 2^59..whatever ranges are kernel conventions, not specified by
>the hardware or firmware.  When running as a guest (which is the
>normal case on POWER), there are explicit hypercalls for
>