[PATCH v2 3/3] iommu/vt-d: Fix ineffective devTLB invalidation for subdevices

2020-12-22 Thread Liu Yi L
iommu_flush_dev_iotlb() is called to invalidate caches on device. It only
loops the devices which are full-attached to the domain. For sub-devices,
this is ineffective. This results in invalid caching entries left on the
device. Fix it by adding loop for subdevices as well. Also, the domain->
has_iotlb_device needs to be updated when attaching to subdevices.

Fixes: 67b8e02b5e761 ("iommu/vt-d: Aux-domain specific domain attach/detach")
Signed-off-by: Liu Yi L 
---
 drivers/iommu/intel/iommu.c | 63 +++--
 1 file changed, 47 insertions(+), 16 deletions(-)

diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index acfe0a5b955e..e97c5ac1d7fc 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -726,6 +726,8 @@ static int domain_update_device_node(struct dmar_domain 
*domain)
return nid;
 }
 
+static void domain_update_iotlb(struct dmar_domain *domain);
+
 /* Some capabilities may be different across iommus */
 static void domain_update_iommu_cap(struct dmar_domain *domain)
 {
@@ -739,6 +741,8 @@ static void domain_update_iommu_cap(struct dmar_domain 
*domain)
 */
if (domain->nid == NUMA_NO_NODE)
domain->nid = domain_update_device_node(domain);
+
+   domain_update_iotlb(domain);
 }
 
 struct context_entry *iommu_context_addr(struct intel_iommu *iommu, u8 bus,
@@ -1459,6 +1463,18 @@ iommu_support_dev_iotlb (struct dmar_domain *domain, 
struct intel_iommu *iommu,
return NULL;
 }
 
+static bool dev_iotlb_enabled(struct device_domain_info *info)
+{
+   struct pci_dev *pdev;
+
+   if (!info->dev || !dev_is_pci(info->dev))
+   return false;
+
+   pdev = to_pci_dev(info->dev);
+
+   return !!pdev->ats_enabled;
+}
+
 static void domain_update_iotlb(struct dmar_domain *domain)
 {
struct device_domain_info *info;
@@ -1466,17 +1482,20 @@ static void domain_update_iotlb(struct dmar_domain 
*domain)
 
assert_spin_locked(_domain_lock);
 
-   list_for_each_entry(info, >devices, link) {
-   struct pci_dev *pdev;
-
-   if (!info->dev || !dev_is_pci(info->dev))
-   continue;
-
-   pdev = to_pci_dev(info->dev);
-   if (pdev->ats_enabled) {
+   list_for_each_entry(info, >devices, link)
+   if (dev_iotlb_enabled(info)) {
has_iotlb_device = true;
break;
}
+
+   if (!has_iotlb_device) {
+   struct subdev_domain_info *sinfo;
+
+   list_for_each_entry(sinfo, >subdevices, link_domain)
+   if (dev_iotlb_enabled(get_domain_info(sinfo->pdev))) {
+   has_iotlb_device = true;
+   break;
+   }
}
 
domain->has_iotlb_device = has_iotlb_device;
@@ -1557,25 +1576,37 @@ static void iommu_disable_dev_iotlb(struct 
device_domain_info *info)
 #endif
 }
 
+static void __iommu_flush_dev_iotlb(struct device_domain_info *info,
+   u64 addr, unsigned int mask)
+{
+   u16 sid, qdep;
+
+   if (!info || !info->ats_enabled)
+   return;
+
+   sid = info->bus << 8 | info->devfn;
+   qdep = info->ats_qdep;
+   qi_flush_dev_iotlb(info->iommu, sid, info->pfsid,
+  qdep, addr, mask);
+}
+
 static void iommu_flush_dev_iotlb(struct dmar_domain *domain,
  u64 addr, unsigned mask)
 {
-   u16 sid, qdep;
unsigned long flags;
struct device_domain_info *info;
+   struct subdev_domain_info *sinfo;
 
if (!domain->has_iotlb_device)
return;
 
spin_lock_irqsave(_domain_lock, flags);
-   list_for_each_entry(info, >devices, link) {
-   if (!info->ats_enabled)
-   continue;
+   list_for_each_entry(info, >devices, link)
+   __iommu_flush_dev_iotlb(info, addr, mask);
 
-   sid = info->bus << 8 | info->devfn;
-   qdep = info->ats_qdep;
-   qi_flush_dev_iotlb(info->iommu, sid, info->pfsid,
-   qdep, addr, mask);
+   list_for_each_entry(sinfo, >subdevices, link_domain) {
+   __iommu_flush_dev_iotlb(get_domain_info(sinfo->pdev),
+   addr, mask);
}
spin_unlock_irqrestore(_domain_lock, flags);
 }
-- 
2.25.1

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


[PATCH v2 2/3] iommu/vt-d: Track device aux-attach with subdevice_domain_info

2020-12-22 Thread Liu Yi L
In the existing code, loop all devices attached to a domain does not
include sub-devices attached via iommu_aux_attach_device().

This was found by when I'm working on the belwo patch, There is no
device in the domain->devices list, thus unable to get the cap and
ecap of iommu unit. But this domain actually has subdevice which is
attached via aux-manner. But it is tracked by domain. This patch is
going to fix it.

https://lore.kernel.org/kvm/1599734733-6431-17-git-send-email-yi.l@intel.com/

And this fix goes beyond the patch above, such sub-device tracking is
necessary for other cases. For example, flushing device_iotlb for a
domain which has sub-devices attached by auxiliary manner.

Co-developed-by: Xin Zeng 
Signed-off-by: Xin Zeng 
Signed-off-by: Liu Yi L 
---
 drivers/iommu/intel/iommu.c | 95 +++--
 include/linux/intel-iommu.h | 16 +--
 2 files changed, 82 insertions(+), 29 deletions(-)

diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index a49afa11673c..acfe0a5b955e 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -1881,6 +1881,7 @@ static struct dmar_domain *alloc_domain(int flags)
domain->flags |= DOMAIN_FLAG_USE_FIRST_LEVEL;
domain->has_iotlb_device = false;
INIT_LIST_HEAD(>devices);
+   INIT_LIST_HEAD(>subdevices);
 
return domain;
 }
@@ -2632,7 +2633,7 @@ static struct dmar_domain 
*dmar_insert_one_dev_info(struct intel_iommu *iommu,
info->iommu = iommu;
info->pasid_table = NULL;
info->auxd_enabled = 0;
-   INIT_LIST_HEAD(>auxiliary_domains);
+   INIT_LIST_HEAD(>subdevices);
 
if (dev && dev_is_pci(dev)) {
struct pci_dev *pdev = to_pci_dev(info->dev);
@@ -5172,33 +5173,61 @@ is_aux_domain(struct device *dev, struct iommu_domain 
*domain)
domain->type == IOMMU_DOMAIN_UNMANAGED;
 }
 
-static void auxiliary_link_device(struct dmar_domain *domain,
- struct device *dev)
+static inline struct subdev_domain_info *
+lookup_subdev_info(struct dmar_domain *domain, struct device *dev)
+{
+   struct subdev_domain_info *sinfo;
+
+   if (!list_empty(>subdevices)) {
+   list_for_each_entry(sinfo, >subdevices, link_domain) {
+   if (sinfo->pdev == dev)
+   return sinfo;
+   }
+   }
+
+   return NULL;
+}
+
+static int auxiliary_link_device(struct dmar_domain *domain,
+struct device *dev)
 {
struct device_domain_info *info = get_domain_info(dev);
+   struct subdev_domain_info *sinfo = lookup_subdev_info(domain, dev);
 
assert_spin_locked(_domain_lock);
if (WARN_ON(!info))
-   return;
+   return -EINVAL;
+
+   if (!sinfo) {
+   sinfo = kzalloc(sizeof(*sinfo), GFP_ATOMIC);
+   sinfo->domain = domain;
+   sinfo->pdev = dev;
+   list_add(>link_phys, >subdevices);
+   list_add(>link_domain, >subdevices);
+   }
 
-   domain->auxd_refcnt++;
-   list_add(>auxd, >auxiliary_domains);
+   return ++sinfo->users;
 }
 
-static void auxiliary_unlink_device(struct dmar_domain *domain,
-   struct device *dev)
+static int auxiliary_unlink_device(struct dmar_domain *domain,
+  struct device *dev)
 {
struct device_domain_info *info = get_domain_info(dev);
+   struct subdev_domain_info *sinfo = lookup_subdev_info(domain, dev);
+   int ret;
 
assert_spin_locked(_domain_lock);
-   if (WARN_ON(!info))
-   return;
+   if (WARN_ON(!info || !sinfo || sinfo->users <= 0))
+   return -EINVAL;
 
-   list_del(>auxd);
-   domain->auxd_refcnt--;
+   ret = --sinfo->users;
+   if (!ret) {
+   list_del(>link_phys);
+   list_del(>link_domain);
+   kfree(sinfo);
+   }
 
-   if (!domain->auxd_refcnt && domain->default_pasid > 0)
-   ioasid_free(domain->default_pasid);
+   return ret;
 }
 
 static int aux_domain_add_dev(struct dmar_domain *domain,
@@ -5227,6 +5256,19 @@ static int aux_domain_add_dev(struct dmar_domain *domain,
}
 
spin_lock_irqsave(_domain_lock, flags);
+   ret = auxiliary_link_device(domain, dev);
+   if (ret <= 0)
+   goto link_failed;
+
+   /*
+* Subdevices from the same physical device can be attached to the
+* same domain. For such cases, only the first subdevice attachment
+* needs to go through the full steps in this function. So if ret >
+* 1, just goto out.
+*/
+   if (ret > 1)
+   goto out;
+
/*
 * iommu->lock must be held to attach domain to iommu and setup the
 * pasid entry for second level translation.
@@ -5245,10 

[PATCH v2 1/3] iommu/vt-d: Move intel_iommu info from struct intel_svm to struct intel_svm_dev

2020-12-22 Thread Liu Yi L
Current struct intel_svm has a field to record the struct intel_iommu
pointer for a PASID bind. And struct intel_svm will be shared by all
the devices bind to the same process. The devices may be behind different
DMAR units. As the iommu driver code uses the intel_iommu pointer stored
in intel_svm struct to do cache invalidations, it may only flush the cache
on a single DMAR unit, for others, the cache invalidation is missed.

As intel_svm struct already has a device list, this patch just moves the
intel_iommu pointer to be a field of intel_svm_dev struct.

Fixes: 1c4f88b7f1f92 ("iommu/vt-d: Shared virtual address in scalable mode")
Cc: Lu Baolu 
Cc: Jacob Pan 
Cc: Raj Ashok 
Cc: David Woodhouse 
Reported-by: Guo Kaijie 
Reported-by: Xin Zeng 
Signed-off-by: Guo Kaijie 
Signed-off-by: Xin Zeng 
Signed-off-by: Liu Yi L 
Tested-by: Guo Kaijie 
---
 drivers/iommu/intel/svm.c   | 9 +
 include/linux/intel-iommu.h | 2 +-
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/iommu/intel/svm.c b/drivers/iommu/intel/svm.c
index 3242ebd0bca3..4a10c9ff368c 100644
--- a/drivers/iommu/intel/svm.c
+++ b/drivers/iommu/intel/svm.c
@@ -142,7 +142,7 @@ static void intel_flush_svm_range_dev (struct intel_svm 
*svm, struct intel_svm_d
}
desc.qw2 = 0;
desc.qw3 = 0;
-   qi_submit_sync(svm->iommu, , 1, 0);
+   qi_submit_sync(sdev->iommu, , 1, 0);
 
if (sdev->dev_iotlb) {
desc.qw0 = QI_DEV_EIOTLB_PASID(svm->pasid) |
@@ -166,7 +166,7 @@ static void intel_flush_svm_range_dev (struct intel_svm 
*svm, struct intel_svm_d
}
desc.qw2 = 0;
desc.qw3 = 0;
-   qi_submit_sync(svm->iommu, , 1, 0);
+   qi_submit_sync(sdev->iommu, , 1, 0);
}
 }
 
@@ -211,7 +211,7 @@ static void intel_mm_release(struct mmu_notifier *mn, 
struct mm_struct *mm)
 */
rcu_read_lock();
list_for_each_entry_rcu(sdev, >devs, list)
-   intel_pasid_tear_down_entry(svm->iommu, sdev->dev,
+   intel_pasid_tear_down_entry(sdev->iommu, sdev->dev,
svm->pasid, true);
rcu_read_unlock();
 
@@ -363,6 +363,7 @@ int intel_svm_bind_gpasid(struct iommu_domain *domain, 
struct device *dev,
}
sdev->dev = dev;
sdev->sid = PCI_DEVID(info->bus, info->devfn);
+   sdev->iommu = iommu;
 
/* Only count users if device has aux domains */
if (iommu_dev_feature_enabled(dev, IOMMU_DEV_FEAT_AUX))
@@ -546,6 +547,7 @@ intel_svm_bind_mm(struct device *dev, unsigned int flags,
goto out;
}
sdev->dev = dev;
+   sdev->iommu = iommu;
 
ret = intel_iommu_enable_pasid(iommu, dev);
if (ret) {
@@ -575,7 +577,6 @@ intel_svm_bind_mm(struct device *dev, unsigned int flags,
kfree(sdev);
goto out;
}
-   svm->iommu = iommu;
 
if (pasid_max > intel_pasid_max_id)
pasid_max = intel_pasid_max_id;
diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h
index d956987ed032..94522685a0d9 100644
--- a/include/linux/intel-iommu.h
+++ b/include/linux/intel-iommu.h
@@ -758,6 +758,7 @@ struct intel_svm_dev {
struct list_head list;
struct rcu_head rcu;
struct device *dev;
+   struct intel_iommu *iommu;
struct svm_dev_ops *ops;
struct iommu_sva sva;
u32 pasid;
@@ -771,7 +772,6 @@ struct intel_svm {
struct mmu_notifier notifier;
struct mm_struct *mm;
 
-   struct intel_iommu *iommu;
unsigned int flags;
u32 pasid;
int gpasid; /* In case that guest PASID is different from host PASID */
-- 
2.25.1

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


[PATCH v2 0/3] iommu/vt-d: Misc fixes on scalable mode

2020-12-22 Thread Liu Yi L
This patchset aims to fix a bug regards to native SVM usage, and
also several bugs around subdevice (attached to device via auxiliary
manner) tracking and ineffective device_tlb flush.

Liu Yi L (3):
  iommu/vt-d: Move intel_iommu info from struct intel_svm to struct
intel_svm_dev
  iommu/vt-d: Track device aux-attach with subdevice_domain_info
  iommu/vt-d: Fix ineffective devTLB invalidation for subdevices

 drivers/iommu/intel/iommu.c | 158 +++-
 drivers/iommu/intel/svm.c   |   9 +-
 include/linux/intel-iommu.h |  18 ++--
 3 files changed, 135 insertions(+), 50 deletions(-)

-- 
2.25.1

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


[PATCH] x86/iommu: Fix two minimal issues in check_iommu_entries()

2020-12-22 Thread Zhenzhong Duan
check_iommu_entries() checks for cyclic dependency in iommu entries
and fixes the cyclic dependency by setting x->depend to NULL. But
this repairing isn't correct if q is in front of p, there will be
"EXECUTION ORDER INVALID!" report following. Fix it by NULLing
whichever in the front.

The second issue is about the report of exectuion order reverse,
the order is reversed incorrectly in the report, fix it.

Signed-off-by: Zhenzhong Duan 
---
 arch/x86/kernel/pci-iommu_table.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kernel/pci-iommu_table.c 
b/arch/x86/kernel/pci-iommu_table.c
index 2e9006c..40c8249 100644
--- a/arch/x86/kernel/pci-iommu_table.c
+++ b/arch/x86/kernel/pci-iommu_table.c
@@ -60,7 +60,10 @@ void __init check_iommu_entries(struct iommu_table_entry 
*start,
printk(KERN_ERR "CYCLIC DEPENDENCY FOUND! %pS depends 
on %pS and vice-versa. BREAKING IT.\n",
   p->detect, q->detect);
/* Heavy handed way..*/
-   x->depend = NULL;
+   if (p > q)
+   q->depend = NULL;
+   else
+   p->depend = NULL;
}
}
 
@@ -68,7 +71,7 @@ void __init check_iommu_entries(struct iommu_table_entry 
*start,
q = find_dependents_of(p, finish, p);
if (q && q > p) {
printk(KERN_ERR "EXECUTION ORDER INVALID! %pS should be 
called before %pS!\n",
-  p->detect, q->detect);
+  q->detect, p->detect);
}
}
 }
-- 
1.8.3.1

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


RE: [PATCH 2/3] iommu/vt-d: Track device aux-attach with subdevice_domain_info.

2020-12-22 Thread Liu, Yi L
Hi Jacob,

> From: Jacob Pan 
> Sent: Wednesday, December 23, 2020 4:21 AM
>
> Hi Yi,
> 
> On Sun, 20 Dec 2020 08:03:51 +0800, Liu Yi L  wrote:
> 
> > In existing code, if wanting to loop all devices attached to a domain,
> > current code can only loop the devices which are attached to the domain
> > via normal manner. While for devices attached via auxiliary manner, this
> > is subdevice, they are not tracked in the domain. This patch adds struct
> How about "In the existing code, loop all devices attached to a domain does
> not include sub-devices attached via iommu_aux_attach_device()."

looks good. will refine accordingly. 

> 
> > subdevice_domain_info which is created per domain attachment via
> auxiliary
> > manner. So that such devices are also tracked in domain.
> >
> > This was found by when I'm working on the belwo patch, There is no device
> > in domain->devices, thus unable to get the cap and ecap of iommu unit. But
> > this domain actually has one sub-device which is attached via aux-manner.
> > This patch fixes the issue.
> >
> > https://lore.kernel.org/kvm/1599734733-6431-17-git-send-email-
> yi.l@intel.com/
> >
> > But looks like, it doesn't affect me only. Such auxiliary track should be
> > there for example if wanting to flush device_iotlb for a domain which has
> > devices attached by auxiliray manner, then this fix is also necessary.
> Perhaps:
> This fix goes beyond the patch above, such sub-device tracking is
> necessary for other cases. For example, flushing device_iotlb for a domain
> which has sub-devices attached by auxiliary manner.

yep. Baolu also suggested such refine. will tweak in next version.

Regards,
Yi Liu

> 
> > This issue will also be fixed by another patch in this series with some
> > additional changes based on the sudevice tracking framework introduced in
> > this patch.
> >
> > Co-developed-by: Xin Zeng 
> > Signed-off-by: Xin Zeng 
> > Co-developed-by: Liu Yi L 
> > Signed-off-by: Liu Yi L 
> > Co-developed-by: Lu Baolu 
> > Signed-off-by: Lu Baolu 
> > ---
> >  drivers/iommu/intel/iommu.c | 92 --
> ---
> >  include/linux/intel-iommu.h | 11 -
> >  2 files changed, 90 insertions(+), 13 deletions(-)
> >
> > diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
> > index a49afa11673c..4274b4acc325 100644
> > --- a/drivers/iommu/intel/iommu.c
> > +++ b/drivers/iommu/intel/iommu.c
> > @@ -1881,6 +1881,7 @@ static struct dmar_domain *alloc_domain(int
> flags)
> > domain->flags |= DOMAIN_FLAG_USE_FIRST_LEVEL;
> > domain->has_iotlb_device = false;
> > INIT_LIST_HEAD(>devices);
> > +   INIT_LIST_HEAD(>sub_devices);
> >
> > return domain;
> >  }
> > @@ -5172,33 +5173,79 @@ is_aux_domain(struct device *dev, struct
> > iommu_domain *domain) domain->type ==
> IOMMU_DOMAIN_UNMANAGED;
> >  }
> >
> > +static inline
> > +void _auxiliary_link_device(struct dmar_domain *domain,
> > +   struct subdevice_domain_info *subinfo,
> > +   struct device *dev)
> > +{
> > +   subinfo->users++;
> > +}
> > +
> why pass in more arguments than subinfo? the function name does not match
> what it does, seems just refcount inc.
> 
> > +static inline
> > +int _auxiliary_unlink_device(struct dmar_domain *domain,
> > +struct subdevice_domain_info *subinfo,
> > +struct device *dev)
> > +{
> > +   subinfo->users--;
> > +   return subinfo->users;
> ditto. why not just
>   return subinfo->users--;
> 
> > +}
> > +
> >  static void auxiliary_link_device(struct dmar_domain *domain,
> >   struct device *dev)
> >  {
> > struct device_domain_info *info = get_domain_info(dev);
> > +   struct subdevice_domain_info *subinfo;
> >
> > assert_spin_locked(_domain_lock);
> > if (WARN_ON(!info))
> > return;
> >
> > +   subinfo = kzalloc(sizeof(*subinfo), GFP_ATOMIC);
> > +   if (!subinfo)
> > +   return;
> > +
> > +   subinfo->domain = domain;
> > +   subinfo->dev = dev;
> > +   list_add(>link_domain, >auxiliary_domains);
> > +   list_add(>link_phys, >sub_devices);
> > +   _auxiliary_link_device(domain, subinfo, dev);
> or just opencode subinfo->users++?
> > domain->auxd_refcnt++;
> > -   list_add(>auxd, >auxiliary_domains);
> >  }
> >
> > -static void auxiliary_unlink_device(struct dmar_domain *domain,
> > -   struct device *dev)
> > +static struct subdevice_domain_info *
> > +subdevice_domain_info_lookup(struct dmar_domain *domain, struct
> device
> > *dev) +{
> > +   struct subdevice_domain_info *subinfo;
> > +
> > +   assert_spin_locked(_domain_lock);
> > +
> > +   list_for_each_entry(subinfo, >sub_devices, link_phys)
> > +   if (subinfo->dev == dev)
> > +   return subinfo;
> > +
> > +   return NULL;
> > +}
> > +
> > +static int auxiliary_unlink_device(struct dmar_domain *domain,
> > +  struct 

RE: [PATCH 0/4] iommu/vtd-: Misc fixes on scalable mode

2020-12-22 Thread Liu, Yi L
> From: Jacob Pan 
> Sent: Wednesday, December 23, 2020 2:17 AM
> 
> Hi Yi,
> 
> nit: The cover letter is 0/4, patches are 1/3 - 3/3. You also need to copy
> LKML.
> 
> On Sun, 20 Dec 2020 08:03:49 +0800, Liu Yi L  wrote:
> 
> > Hi,
> >
> > This patchset aims to fix a bug regards to SVM usage on native, and
> perhaps 'native SVM usage'

got it. thanks. will correct it.

Regards,
Yi Liu

> > also several bugs around subdevice (attached to device via auxiliary
> > manner) tracking and ineffective device_tlb flush.
> >
> > Regards,
> > Yi Liu
> >
> > Liu Yi L (3):
> >   iommu/vt-d: Move intel_iommu info from struct intel_svm to struct
> > intel_svm_dev
> >   iommu/vt-d: Track device aux-attach with subdevice_domain_info.
> >   iommu/vt-d: A fix to iommu_flush_dev_iotlb() for aux-domain
> >
> >  drivers/iommu/intel/iommu.c | 182 ++---
> ---
> >  drivers/iommu/intel/svm.c   |   9 +-
> >  include/linux/intel-iommu.h |  13 ++-
> >  3 files changed, 168 insertions(+), 36 deletions(-)
> >
> 
> 
> Thanks,
> 
> Jacob
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH AUTOSEL 4.4 26/38] iommu/tegra-smmu: Expand mutex protection range

2020-12-22 Thread Sasha Levin
From: Nicolin Chen 

[ Upstream commit d5f583bf8654c231b781096bc1a186065cda72b3 ]

This is used to protect potential race condition at use_count.
since probes of client drivers, calling attach_dev(), may run
concurrently.

Signed-off-by: Nicolin Chen 
Tested-by: Dmitry Osipenko 
Reviewed-by: Dmitry Osipenko 
Acked-by: Thierry Reding 
Link: https://lore.kernel.org/r/20201125101013.14953-3-nicoleots...@gmail.com
Signed-off-by: Will Deacon 
Signed-off-by: Sasha Levin 
---
 drivers/iommu/tegra-smmu.c | 34 +-
 1 file changed, 21 insertions(+), 13 deletions(-)

diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index 04cec050e42bf..ae796342717a6 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -241,26 +241,19 @@ static int tegra_smmu_alloc_asid(struct tegra_smmu *smmu, 
unsigned int *idp)
 {
unsigned long id;
 
-   mutex_lock(>lock);
-
id = find_first_zero_bit(smmu->asids, smmu->soc->num_asids);
-   if (id >= smmu->soc->num_asids) {
-   mutex_unlock(>lock);
+   if (id >= smmu->soc->num_asids)
return -ENOSPC;
-   }
 
set_bit(id, smmu->asids);
*idp = id;
 
-   mutex_unlock(>lock);
return 0;
 }
 
 static void tegra_smmu_free_asid(struct tegra_smmu *smmu, unsigned int id)
 {
-   mutex_lock(>lock);
clear_bit(id, smmu->asids);
-   mutex_unlock(>lock);
 }
 
 static bool tegra_smmu_capable(enum iommu_cap cap)
@@ -395,17 +388,21 @@ static int tegra_smmu_as_prepare(struct tegra_smmu *smmu,
 struct tegra_smmu_as *as)
 {
u32 value;
-   int err;
+   int err = 0;
+
+   mutex_lock(>lock);
 
if (as->use_count > 0) {
as->use_count++;
-   return 0;
+   goto unlock;
}
 
as->pd_dma = dma_map_page(smmu->dev, as->pd, 0, SMMU_SIZE_PD,
  DMA_TO_DEVICE);
-   if (dma_mapping_error(smmu->dev, as->pd_dma))
-   return -ENOMEM;
+   if (dma_mapping_error(smmu->dev, as->pd_dma)) {
+   err = -ENOMEM;
+   goto unlock;
+   }
 
/* We can't handle 64-bit DMA addresses */
if (!smmu_dma_addr_valid(smmu, as->pd_dma)) {
@@ -428,24 +425,35 @@ static int tegra_smmu_as_prepare(struct tegra_smmu *smmu,
as->smmu = smmu;
as->use_count++;
 
+   mutex_unlock(>lock);
+
return 0;
 
 err_unmap:
dma_unmap_page(smmu->dev, as->pd_dma, SMMU_SIZE_PD, DMA_TO_DEVICE);
+unlock:
+   mutex_unlock(>lock);
+
return err;
 }
 
 static void tegra_smmu_as_unprepare(struct tegra_smmu *smmu,
struct tegra_smmu_as *as)
 {
-   if (--as->use_count > 0)
+   mutex_lock(>lock);
+
+   if (--as->use_count > 0) {
+   mutex_unlock(>lock);
return;
+   }
 
tegra_smmu_free_asid(smmu, as->id);
 
dma_unmap_page(smmu->dev, as->pd_dma, SMMU_SIZE_PD, DMA_TO_DEVICE);
 
as->smmu = NULL;
+
+   mutex_unlock(>lock);
 }
 
 static int tegra_smmu_attach_dev(struct iommu_domain *domain,
-- 
2.27.0

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


[PATCH AUTOSEL 4.9 31/48] iommu/tegra-smmu: Expand mutex protection range

2020-12-22 Thread Sasha Levin
From: Nicolin Chen 

[ Upstream commit d5f583bf8654c231b781096bc1a186065cda72b3 ]

This is used to protect potential race condition at use_count.
since probes of client drivers, calling attach_dev(), may run
concurrently.

Signed-off-by: Nicolin Chen 
Tested-by: Dmitry Osipenko 
Reviewed-by: Dmitry Osipenko 
Acked-by: Thierry Reding 
Link: https://lore.kernel.org/r/20201125101013.14953-3-nicoleots...@gmail.com
Signed-off-by: Will Deacon 
Signed-off-by: Sasha Levin 
---
 drivers/iommu/tegra-smmu.c | 34 +-
 1 file changed, 21 insertions(+), 13 deletions(-)

diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index 04cec050e42bf..ae796342717a6 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -241,26 +241,19 @@ static int tegra_smmu_alloc_asid(struct tegra_smmu *smmu, 
unsigned int *idp)
 {
unsigned long id;
 
-   mutex_lock(>lock);
-
id = find_first_zero_bit(smmu->asids, smmu->soc->num_asids);
-   if (id >= smmu->soc->num_asids) {
-   mutex_unlock(>lock);
+   if (id >= smmu->soc->num_asids)
return -ENOSPC;
-   }
 
set_bit(id, smmu->asids);
*idp = id;
 
-   mutex_unlock(>lock);
return 0;
 }
 
 static void tegra_smmu_free_asid(struct tegra_smmu *smmu, unsigned int id)
 {
-   mutex_lock(>lock);
clear_bit(id, smmu->asids);
-   mutex_unlock(>lock);
 }
 
 static bool tegra_smmu_capable(enum iommu_cap cap)
@@ -395,17 +388,21 @@ static int tegra_smmu_as_prepare(struct tegra_smmu *smmu,
 struct tegra_smmu_as *as)
 {
u32 value;
-   int err;
+   int err = 0;
+
+   mutex_lock(>lock);
 
if (as->use_count > 0) {
as->use_count++;
-   return 0;
+   goto unlock;
}
 
as->pd_dma = dma_map_page(smmu->dev, as->pd, 0, SMMU_SIZE_PD,
  DMA_TO_DEVICE);
-   if (dma_mapping_error(smmu->dev, as->pd_dma))
-   return -ENOMEM;
+   if (dma_mapping_error(smmu->dev, as->pd_dma)) {
+   err = -ENOMEM;
+   goto unlock;
+   }
 
/* We can't handle 64-bit DMA addresses */
if (!smmu_dma_addr_valid(smmu, as->pd_dma)) {
@@ -428,24 +425,35 @@ static int tegra_smmu_as_prepare(struct tegra_smmu *smmu,
as->smmu = smmu;
as->use_count++;
 
+   mutex_unlock(>lock);
+
return 0;
 
 err_unmap:
dma_unmap_page(smmu->dev, as->pd_dma, SMMU_SIZE_PD, DMA_TO_DEVICE);
+unlock:
+   mutex_unlock(>lock);
+
return err;
 }
 
 static void tegra_smmu_as_unprepare(struct tegra_smmu *smmu,
struct tegra_smmu_as *as)
 {
-   if (--as->use_count > 0)
+   mutex_lock(>lock);
+
+   if (--as->use_count > 0) {
+   mutex_unlock(>lock);
return;
+   }
 
tegra_smmu_free_asid(smmu, as->id);
 
dma_unmap_page(smmu->dev, as->pd_dma, SMMU_SIZE_PD, DMA_TO_DEVICE);
 
as->smmu = NULL;
+
+   mutex_unlock(>lock);
 }
 
 static int tegra_smmu_attach_dev(struct iommu_domain *domain,
-- 
2.27.0

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


[PATCH AUTOSEL 4.14 41/66] iommu/tegra-smmu: Expand mutex protection range

2020-12-22 Thread Sasha Levin
From: Nicolin Chen 

[ Upstream commit d5f583bf8654c231b781096bc1a186065cda72b3 ]

This is used to protect potential race condition at use_count.
since probes of client drivers, calling attach_dev(), may run
concurrently.

Signed-off-by: Nicolin Chen 
Tested-by: Dmitry Osipenko 
Reviewed-by: Dmitry Osipenko 
Acked-by: Thierry Reding 
Link: https://lore.kernel.org/r/20201125101013.14953-3-nicoleots...@gmail.com
Signed-off-by: Will Deacon 
Signed-off-by: Sasha Levin 
---
 drivers/iommu/tegra-smmu.c | 34 +-
 1 file changed, 21 insertions(+), 13 deletions(-)

diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index 848dac3e4580f..30f0c72d685fe 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -244,26 +244,19 @@ static int tegra_smmu_alloc_asid(struct tegra_smmu *smmu, 
unsigned int *idp)
 {
unsigned long id;
 
-   mutex_lock(>lock);
-
id = find_first_zero_bit(smmu->asids, smmu->soc->num_asids);
-   if (id >= smmu->soc->num_asids) {
-   mutex_unlock(>lock);
+   if (id >= smmu->soc->num_asids)
return -ENOSPC;
-   }
 
set_bit(id, smmu->asids);
*idp = id;
 
-   mutex_unlock(>lock);
return 0;
 }
 
 static void tegra_smmu_free_asid(struct tegra_smmu *smmu, unsigned int id)
 {
-   mutex_lock(>lock);
clear_bit(id, smmu->asids);
-   mutex_unlock(>lock);
 }
 
 static bool tegra_smmu_capable(enum iommu_cap cap)
@@ -398,17 +391,21 @@ static int tegra_smmu_as_prepare(struct tegra_smmu *smmu,
 struct tegra_smmu_as *as)
 {
u32 value;
-   int err;
+   int err = 0;
+
+   mutex_lock(>lock);
 
if (as->use_count > 0) {
as->use_count++;
-   return 0;
+   goto unlock;
}
 
as->pd_dma = dma_map_page(smmu->dev, as->pd, 0, SMMU_SIZE_PD,
  DMA_TO_DEVICE);
-   if (dma_mapping_error(smmu->dev, as->pd_dma))
-   return -ENOMEM;
+   if (dma_mapping_error(smmu->dev, as->pd_dma)) {
+   err = -ENOMEM;
+   goto unlock;
+   }
 
/* We can't handle 64-bit DMA addresses */
if (!smmu_dma_addr_valid(smmu, as->pd_dma)) {
@@ -431,24 +428,35 @@ static int tegra_smmu_as_prepare(struct tegra_smmu *smmu,
as->smmu = smmu;
as->use_count++;
 
+   mutex_unlock(>lock);
+
return 0;
 
 err_unmap:
dma_unmap_page(smmu->dev, as->pd_dma, SMMU_SIZE_PD, DMA_TO_DEVICE);
+unlock:
+   mutex_unlock(>lock);
+
return err;
 }
 
 static void tegra_smmu_as_unprepare(struct tegra_smmu *smmu,
struct tegra_smmu_as *as)
 {
-   if (--as->use_count > 0)
+   mutex_lock(>lock);
+
+   if (--as->use_count > 0) {
+   mutex_unlock(>lock);
return;
+   }
 
tegra_smmu_free_asid(smmu, as->id);
 
dma_unmap_page(smmu->dev, as->pd_dma, SMMU_SIZE_PD, DMA_TO_DEVICE);
 
as->smmu = NULL;
+
+   mutex_unlock(>lock);
 }
 
 static int tegra_smmu_attach_dev(struct iommu_domain *domain,
-- 
2.27.0

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


[PATCH AUTOSEL 4.19 49/87] iommu/tegra-smmu: Expand mutex protection range

2020-12-22 Thread Sasha Levin
From: Nicolin Chen 

[ Upstream commit d5f583bf8654c231b781096bc1a186065cda72b3 ]

This is used to protect potential race condition at use_count.
since probes of client drivers, calling attach_dev(), may run
concurrently.

Signed-off-by: Nicolin Chen 
Tested-by: Dmitry Osipenko 
Reviewed-by: Dmitry Osipenko 
Acked-by: Thierry Reding 
Link: https://lore.kernel.org/r/20201125101013.14953-3-nicoleots...@gmail.com
Signed-off-by: Will Deacon 
Signed-off-by: Sasha Levin 
---
 drivers/iommu/tegra-smmu.c | 34 +-
 1 file changed, 21 insertions(+), 13 deletions(-)

diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index fa0ecb5e63809..63679cce95054 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -252,26 +252,19 @@ static int tegra_smmu_alloc_asid(struct tegra_smmu *smmu, 
unsigned int *idp)
 {
unsigned long id;
 
-   mutex_lock(>lock);
-
id = find_first_zero_bit(smmu->asids, smmu->soc->num_asids);
-   if (id >= smmu->soc->num_asids) {
-   mutex_unlock(>lock);
+   if (id >= smmu->soc->num_asids)
return -ENOSPC;
-   }
 
set_bit(id, smmu->asids);
*idp = id;
 
-   mutex_unlock(>lock);
return 0;
 }
 
 static void tegra_smmu_free_asid(struct tegra_smmu *smmu, unsigned int id)
 {
-   mutex_lock(>lock);
clear_bit(id, smmu->asids);
-   mutex_unlock(>lock);
 }
 
 static bool tegra_smmu_capable(enum iommu_cap cap)
@@ -406,17 +399,21 @@ static int tegra_smmu_as_prepare(struct tegra_smmu *smmu,
 struct tegra_smmu_as *as)
 {
u32 value;
-   int err;
+   int err = 0;
+
+   mutex_lock(>lock);
 
if (as->use_count > 0) {
as->use_count++;
-   return 0;
+   goto unlock;
}
 
as->pd_dma = dma_map_page(smmu->dev, as->pd, 0, SMMU_SIZE_PD,
  DMA_TO_DEVICE);
-   if (dma_mapping_error(smmu->dev, as->pd_dma))
-   return -ENOMEM;
+   if (dma_mapping_error(smmu->dev, as->pd_dma)) {
+   err = -ENOMEM;
+   goto unlock;
+   }
 
/* We can't handle 64-bit DMA addresses */
if (!smmu_dma_addr_valid(smmu, as->pd_dma)) {
@@ -439,24 +436,35 @@ static int tegra_smmu_as_prepare(struct tegra_smmu *smmu,
as->smmu = smmu;
as->use_count++;
 
+   mutex_unlock(>lock);
+
return 0;
 
 err_unmap:
dma_unmap_page(smmu->dev, as->pd_dma, SMMU_SIZE_PD, DMA_TO_DEVICE);
+unlock:
+   mutex_unlock(>lock);
+
return err;
 }
 
 static void tegra_smmu_as_unprepare(struct tegra_smmu *smmu,
struct tegra_smmu_as *as)
 {
-   if (--as->use_count > 0)
+   mutex_lock(>lock);
+
+   if (--as->use_count > 0) {
+   mutex_unlock(>lock);
return;
+   }
 
tegra_smmu_free_asid(smmu, as->id);
 
dma_unmap_page(smmu->dev, as->pd_dma, SMMU_SIZE_PD, DMA_TO_DEVICE);
 
as->smmu = NULL;
+
+   mutex_unlock(>lock);
 }
 
 static int tegra_smmu_attach_dev(struct iommu_domain *domain,
-- 
2.27.0

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


[PATCH AUTOSEL 5.4 128/130] x86, swiotlb: Adjust SWIOTLB bounce buffer size for SEV guests

2020-12-22 Thread Sasha Levin
From: Ashish Kalra 

[ Upstream commit e998879d4fb7991856916972168cf27c0d86ed12 ]

For SEV, all DMA to and from guest has to use shared (un-encrypted) pages.
SEV uses SWIOTLB to make this happen without requiring changes to device
drivers.  However, depending on the workload being run, the default 64MB
of it might not be enough and it may run out of buffers to use for DMA,
resulting in I/O errors and/or performance degradation for high
I/O workloads.

Adjust the default size of SWIOTLB for SEV guests using a
percentage of the total memory available to guest for the SWIOTLB buffers.

Adds a new sev_setup_arch() function which is invoked from setup_arch()
and it calls into a new swiotlb generic code function swiotlb_adjust_size()
to do the SWIOTLB buffer adjustment.

v5 fixed build errors and warnings as
Reported-by: kbuild test robot 

Signed-off-by: Ashish Kalra 
Co-developed-by: Borislav Petkov 
Signed-off-by: Borislav Petkov 
Signed-off-by: Konrad Rzeszutek Wilk 
Signed-off-by: Sasha Levin 
---
 arch/x86/include/asm/mem_encrypt.h |  2 ++
 arch/x86/kernel/setup.c|  6 ++
 arch/x86/mm/mem_encrypt.c  | 31 ++
 include/linux/swiotlb.h|  8 
 kernel/dma/swiotlb.c   | 20 +--
 5 files changed, 65 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/mem_encrypt.h 
b/arch/x86/include/asm/mem_encrypt.h
index 848ce43b9040d..6c36956452ca6 100644
--- a/arch/x86/include/asm/mem_encrypt.h
+++ b/arch/x86/include/asm/mem_encrypt.h
@@ -36,6 +36,7 @@ void __init sme_map_bootdata(char *real_mode_data);
 void __init sme_unmap_bootdata(char *real_mode_data);
 
 void __init sme_early_init(void);
+void __init sev_setup_arch(void);
 
 void __init sme_encrypt_kernel(struct boot_params *bp);
 void __init sme_enable(struct boot_params *bp);
@@ -65,6 +66,7 @@ static inline void __init sme_map_bootdata(char 
*real_mode_data) { }
 static inline void __init sme_unmap_bootdata(char *real_mode_data) { }
 
 static inline void __init sme_early_init(void) { }
+static inline void __init sev_setup_arch(void) { }
 
 static inline void __init sme_encrypt_kernel(struct boot_params *bp) { }
 static inline void __init sme_enable(struct boot_params *bp) { }
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 77ea96b794bd1..9dc0c94e1544f 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -1120,6 +1120,12 @@ void __init setup_arch(char **cmdline_p)
memblock_set_current_limit(ISA_END_ADDRESS);
e820__memblock_setup();
 
+   /*
+* Needs to run after memblock setup because it needs the physical
+* memory size.
+*/
+   sev_setup_arch();
+
reserve_bios_regions();
 
if (efi_enabled(EFI_MEMMAP)) {
diff --git a/arch/x86/mm/mem_encrypt.c b/arch/x86/mm/mem_encrypt.c
index 9268c12458c84..5911cfa31bc6d 100644
--- a/arch/x86/mm/mem_encrypt.c
+++ b/arch/x86/mm/mem_encrypt.c
@@ -196,6 +196,37 @@ void __init sme_early_init(void)
swiotlb_force = SWIOTLB_FORCE;
 }
 
+void __init sev_setup_arch(void)
+{
+   phys_addr_t total_mem = memblock_phys_mem_size();
+   unsigned long size;
+
+   if (!sev_active())
+   return;
+
+   /*
+* For SEV, all DMA has to occur via shared/unencrypted pages.
+* SEV uses SWIOTLB to make this happen without changing device
+* drivers. However, depending on the workload being run, the
+* default 64MB of SWIOTLB may not be enough and SWIOTLB may
+* run out of buffers for DMA, resulting in I/O errors and/or
+* performance degradation especially with high I/O workloads.
+*
+* Adjust the default size of SWIOTLB for SEV guests using
+* a percentage of guest memory for SWIOTLB buffers.
+* Also, as the SWIOTLB bounce buffer memory is allocated
+* from low memory, ensure that the adjusted size is within
+* the limits of low available memory.
+*
+* The percentage of guest memory used here for SWIOTLB buffers
+* is more of an approximation of the static adjustment which
+* 64MB for <1G, and ~128M to 256M for 1G-to-4G, i.e., the 6%
+*/
+   size = total_mem * 6 / 100;
+   size = clamp_val(size, IO_TLB_DEFAULT_SIZE, SZ_1G);
+   swiotlb_adjust_size(size);
+}
+
 static void __init __set_clr_pte_enc(pte_t *kpte, int level, bool enc)
 {
pgprot_t old_prot, new_prot;
diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h
index 0a8fced6aaec4..522a0942114ad 100644
--- a/include/linux/swiotlb.h
+++ b/include/linux/swiotlb.h
@@ -30,6 +30,9 @@ enum swiotlb_force {
  */
 #define IO_TLB_SHIFT 11
 
+/* default to 64MB */
+#define IO_TLB_DEFAULT_SIZE (64UL<<20)
+
 extern void swiotlb_init(int verbose);
 int swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, int verbose);
 extern unsigned long swiotlb_nr_tbl(void);
@@ -80,6 +83,7 @@ void __init 

[PATCH AUTOSEL 5.4 070/130] iommu/tegra-smmu: Expand mutex protection range

2020-12-22 Thread Sasha Levin
From: Nicolin Chen 

[ Upstream commit d5f583bf8654c231b781096bc1a186065cda72b3 ]

This is used to protect potential race condition at use_count.
since probes of client drivers, calling attach_dev(), may run
concurrently.

Signed-off-by: Nicolin Chen 
Tested-by: Dmitry Osipenko 
Reviewed-by: Dmitry Osipenko 
Acked-by: Thierry Reding 
Link: https://lore.kernel.org/r/20201125101013.14953-3-nicoleots...@gmail.com
Signed-off-by: Will Deacon 
Signed-off-by: Sasha Levin 
---
 drivers/iommu/tegra-smmu.c | 34 +-
 1 file changed, 21 insertions(+), 13 deletions(-)

diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index dd486233e2828..41be3e2202971 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -247,26 +247,19 @@ static int tegra_smmu_alloc_asid(struct tegra_smmu *smmu, 
unsigned int *idp)
 {
unsigned long id;
 
-   mutex_lock(>lock);
-
id = find_first_zero_bit(smmu->asids, smmu->soc->num_asids);
-   if (id >= smmu->soc->num_asids) {
-   mutex_unlock(>lock);
+   if (id >= smmu->soc->num_asids)
return -ENOSPC;
-   }
 
set_bit(id, smmu->asids);
*idp = id;
 
-   mutex_unlock(>lock);
return 0;
 }
 
 static void tegra_smmu_free_asid(struct tegra_smmu *smmu, unsigned int id)
 {
-   mutex_lock(>lock);
clear_bit(id, smmu->asids);
-   mutex_unlock(>lock);
 }
 
 static bool tegra_smmu_capable(enum iommu_cap cap)
@@ -404,17 +397,21 @@ static int tegra_smmu_as_prepare(struct tegra_smmu *smmu,
 struct tegra_smmu_as *as)
 {
u32 value;
-   int err;
+   int err = 0;
+
+   mutex_lock(>lock);
 
if (as->use_count > 0) {
as->use_count++;
-   return 0;
+   goto unlock;
}
 
as->pd_dma = dma_map_page(smmu->dev, as->pd, 0, SMMU_SIZE_PD,
  DMA_TO_DEVICE);
-   if (dma_mapping_error(smmu->dev, as->pd_dma))
-   return -ENOMEM;
+   if (dma_mapping_error(smmu->dev, as->pd_dma)) {
+   err = -ENOMEM;
+   goto unlock;
+   }
 
/* We can't handle 64-bit DMA addresses */
if (!smmu_dma_addr_valid(smmu, as->pd_dma)) {
@@ -437,24 +434,35 @@ static int tegra_smmu_as_prepare(struct tegra_smmu *smmu,
as->smmu = smmu;
as->use_count++;
 
+   mutex_unlock(>lock);
+
return 0;
 
 err_unmap:
dma_unmap_page(smmu->dev, as->pd_dma, SMMU_SIZE_PD, DMA_TO_DEVICE);
+unlock:
+   mutex_unlock(>lock);
+
return err;
 }
 
 static void tegra_smmu_as_unprepare(struct tegra_smmu *smmu,
struct tegra_smmu_as *as)
 {
-   if (--as->use_count > 0)
+   mutex_lock(>lock);
+
+   if (--as->use_count > 0) {
+   mutex_unlock(>lock);
return;
+   }
 
tegra_smmu_free_asid(smmu, as->id);
 
dma_unmap_page(smmu->dev, as->pd_dma, SMMU_SIZE_PD, DMA_TO_DEVICE);
 
as->smmu = NULL;
+
+   mutex_unlock(>lock);
 }
 
 static int tegra_smmu_attach_dev(struct iommu_domain *domain,
-- 
2.27.0

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


[PATCH AUTOSEL 5.10 065/217] pinctrl: qcom: Kconfig: Rework PINCTRL_MSM to be a depenency rather then a selected config

2020-12-22 Thread Sasha Levin
From: John Stultz 

[ Upstream commit be117ca32261c3331b614f440c737650791a6998 ]

This patch reworks PINCTRL_MSM to be a visible option, and
instead of having the various SoC specific drivers select
PINCTRL_MSM, this switches those configs to depend on
PINCTRL_MSM.

This is useful, as it will be needed in order to cleanly support
having the qcom-scm driver, which pinctrl-msm calls into,
configured as a module. Without this change, we would eventually
have to add dependency lines to every config that selects
PINCTRL_MSM, and that would becomes a maintenance headache.

We also add PINCTRL_MSM to the arm64 defconfig to avoid
surprises as otherwise PINCTRL_MSM/IPQ* options previously
enabled, will be off.

Signed-off-by: John Stultz 
Reviewed-by: Bjorn Andersson 
Cc: Catalin Marinas 
Cc: Will Deacon 
Cc: Andy Gross 
Cc: Bjorn Andersson 
Cc: Joerg Roedel 
Cc: Thomas Gleixner 
Cc: Jason Cooper 
Cc: Marc Zyngier 
Cc: Linus Walleij 
Cc: Vinod Koul 
Cc: Kalle Valo 
Cc: Maulik Shah 
Cc: Lina Iyer 
Cc: Saravana Kannan 
Cc: Todd Kjos 
Cc: Greg Kroah-Hartman 
Cc: linux-arm-...@vger.kernel.org
Cc: iommu@lists.linux-foundation.org
Cc: linux-g...@vger.kernel.org
Link: https://lore.kernel.org/r/20201106042710.55979-1-john.stu...@linaro.org
Signed-off-by: Linus Walleij 
Signed-off-by: Sasha Levin 
---
 arch/arm64/configs/defconfig |  1 +
 drivers/pinctrl/qcom/Kconfig | 48 ++--
 2 files changed, 25 insertions(+), 24 deletions(-)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 5cfe3cf6f2acb..2ac53d8ae76a3 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -483,6 +483,7 @@ CONFIG_PINCTRL_IMX8MP=y
 CONFIG_PINCTRL_IMX8MQ=y
 CONFIG_PINCTRL_IMX8QXP=y
 CONFIG_PINCTRL_IMX8DXL=y
+CONFIG_PINCTRL_MSM=y
 CONFIG_PINCTRL_IPQ8074=y
 CONFIG_PINCTRL_IPQ6018=y
 CONFIG_PINCTRL_MSM8916=y
diff --git a/drivers/pinctrl/qcom/Kconfig b/drivers/pinctrl/qcom/Kconfig
index 5fe7b8aaf69d8..c9bb2d9e49d47 100644
--- a/drivers/pinctrl/qcom/Kconfig
+++ b/drivers/pinctrl/qcom/Kconfig
@@ -2,7 +2,7 @@
 if (ARCH_QCOM || COMPILE_TEST)
 
 config PINCTRL_MSM
-   bool
+   bool "Qualcomm core pin controller driver"
select PINMUX
select PINCONF
select GENERIC_PINCONF
@@ -13,7 +13,7 @@ config PINCTRL_MSM
 config PINCTRL_APQ8064
tristate "Qualcomm APQ8064 pin controller driver"
depends on GPIOLIB && OF
-   select PINCTRL_MSM
+   depends on PINCTRL_MSM
help
  This is the pinctrl, pinmux, pinconf and gpiolib driver for the
  Qualcomm TLMM block found in the Qualcomm APQ8064 platform.
@@ -21,7 +21,7 @@ config PINCTRL_APQ8064
 config PINCTRL_APQ8084
tristate "Qualcomm APQ8084 pin controller driver"
depends on GPIOLIB && OF
-   select PINCTRL_MSM
+   depends on PINCTRL_MSM
help
  This is the pinctrl, pinmux, pinconf and gpiolib driver for the
  Qualcomm TLMM block found in the Qualcomm APQ8084 platform.
@@ -29,7 +29,7 @@ config PINCTRL_APQ8084
 config PINCTRL_IPQ4019
tristate "Qualcomm IPQ4019 pin controller driver"
depends on GPIOLIB && OF
-   select PINCTRL_MSM
+   depends on PINCTRL_MSM
help
  This is the pinctrl, pinmux, pinconf and gpiolib driver for the
  Qualcomm TLMM block found in the Qualcomm IPQ4019 platform.
@@ -37,7 +37,7 @@ config PINCTRL_IPQ4019
 config PINCTRL_IPQ8064
tristate "Qualcomm IPQ8064 pin controller driver"
depends on GPIOLIB && OF
-   select PINCTRL_MSM
+   depends on PINCTRL_MSM
help
  This is the pinctrl, pinmux, pinconf and gpiolib driver for the
  Qualcomm TLMM block found in the Qualcomm IPQ8064 platform.
@@ -45,7 +45,7 @@ config PINCTRL_IPQ8064
 config PINCTRL_IPQ8074
tristate "Qualcomm Technologies, Inc. IPQ8074 pin controller driver"
depends on GPIOLIB && OF
-   select PINCTRL_MSM
+   depends on PINCTRL_MSM
help
  This is the pinctrl, pinmux, pinconf and gpiolib driver for
  the Qualcomm Technologies Inc. TLMM block found on the
@@ -55,7 +55,7 @@ config PINCTRL_IPQ8074
 config PINCTRL_IPQ6018
tristate "Qualcomm Technologies, Inc. IPQ6018 pin controller driver"
depends on GPIOLIB && OF
-   select PINCTRL_MSM
+   depends on PINCTRL_MSM
help
  This is the pinctrl, pinmux, pinconf and gpiolib driver for
  the Qualcomm Technologies Inc. TLMM block found on the
@@ -65,7 +65,7 @@ config PINCTRL_IPQ6018
 config PINCTRL_MSM8226
tristate "Qualcomm 8226 pin controller driver"
depends on GPIOLIB && OF
-   select PINCTRL_MSM
+   depends on PINCTRL_MSM
help
  This is the pinctrl, pinmux, pinconf and gpiolib driver for the
  Qualcomm Technologies Inc TLMM block found on the Qualcomm
@@ -74,7 +74,7 @@ config PINCTRL_MSM8226
 config PINCTRL_MSM8660
tristate "Qualcomm 8660 pin controller driver"
  

[PATCH v3 1/3] iommu/vt-d: Audit IOMMU Capabilities and add helper functions

2020-12-22 Thread Kyung Min Park
Audit IOMMU Capability/Extended Capability and check if the IOMMUs have
the consistent value for features. Report out or scale to the lowest
supported when IOMMU features have incompatibility among IOMMUs.

Report out features when below features are mismatched:
  - First Level 5 Level Paging Support (FL5LP)
  - First Level 1 GByte Page Support (FL1GP)
  - Read Draining (DRD)
  - Write Draining (DWD)
  - Page Selective Invalidation (PSI)
  - Zero Length Read (ZLR)
  - Caching Mode (CM)
  - Protected High/Low-Memory Region (PHMR/PLMR)
  - Required Write-Buffer Flushing (RWBF)
  - Advanced Fault Logging (AFL)
  - RID-PASID Support (RPS)
  - Scalable Mode Page Walk Coherency (SMPWC)
  - First Level Translation Support (FLTS)
  - Second Level Translation Support (SLTS)
  - No Write Flag Support (NWFS)
  - Second Level Accessed/Dirty Support (SLADS)
  - Virtual Command Support (VCS)
  - Scalable Mode Translation Support (SMTS)
  - Device TLB Invalidation Throttle (DIT)
  - Page Drain Support (PDS)
  - Process Address Space ID Support (PASID)
  - Extended Accessed Flag Support (EAFS)
  - Supervisor Request Support (SRS)
  - Execute Request Support (ERS)
  - Page Request Support (PRS)
  - Nested Translation Support (NEST)
  - Snoop Control (SC)
  - Pass Through (PT)
  - Device TLB Support (DT)
  - Queued Invalidation (QI)
  - Page walk Coherency (C)

Set capability to the lowest supported when below features are mismatched:
  - Maximum Address Mask Value (MAMV)
  - Number of Fault Recording Registers (NFR)
  - Second Level Large Page Support (SLLPS)
  - Fault Recording Offset (FRO)
  - Maximum Guest Address Width (MGAW)
  - Supported Adjusted Guest Address Width (SAGAW)
  - Number of Domains supported (NDOMS)
  - Pasid Size Supported (PSS)
  - Maximum Handle Mask Value (MHMV)
  - IOTLB Register Offset (IRO)

Signed-off-by: Kyung Min Park 
---
 drivers/iommu/intel/Makefile|   2 +-
 drivers/iommu/intel/cap_audit.c | 188 
 drivers/iommu/intel/cap_audit.h | 106 
 drivers/iommu/intel/iommu.c |   9 ++
 drivers/iommu/intel/irq_remapping.c |   8 ++
 include/linux/intel-iommu.h |  39 +++---
 6 files changed, 333 insertions(+), 19 deletions(-)
 create mode 100644 drivers/iommu/intel/cap_audit.c
 create mode 100644 drivers/iommu/intel/cap_audit.h

diff --git a/drivers/iommu/intel/Makefile b/drivers/iommu/intel/Makefile
index fb8e1e8c8029..e3576a62612b 100644
--- a/drivers/iommu/intel/Makefile
+++ b/drivers/iommu/intel/Makefile
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 obj-$(CONFIG_DMAR_TABLE) += dmar.o
 obj-$(CONFIG_INTEL_IOMMU) += iommu.o pasid.o
-obj-$(CONFIG_INTEL_IOMMU) += trace.o
+obj-$(CONFIG_INTEL_IOMMU) += trace.o cap_audit.o
 obj-$(CONFIG_INTEL_IOMMU_DEBUGFS) += debugfs.o
 obj-$(CONFIG_INTEL_IOMMU_SVM) += svm.o
 obj-$(CONFIG_IRQ_REMAP) += irq_remapping.o
diff --git a/drivers/iommu/intel/cap_audit.c b/drivers/iommu/intel/cap_audit.c
new file mode 100644
index ..4a062fc719d2
--- /dev/null
+++ b/drivers/iommu/intel/cap_audit.c
@@ -0,0 +1,188 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * cap_audit.c - audit iommu capabilities for boot time and hot plug
+ *
+ * Copyright (C) 2020 Intel Corporation
+ *
+ * Author: Kyung Min Park 
+ * Lu Baolu 
+ */
+
+#define pr_fmt(fmt)"DMAR: " fmt
+
+#include 
+#include "cap_audit.h"
+
+static u64 intel_iommu_cap_sanity;
+static u64 intel_iommu_ecap_sanity;
+
+static inline void check_irq_capabilities(struct intel_iommu *a,
+ struct intel_iommu *b)
+{
+   CHECK_FEATURE_MISMATCH(a, b, cap, pi_support, CAP_PI_MASK);
+   CHECK_FEATURE_MISMATCH(a, b, ecap, eim_support, ECAP_EIM_MASK);
+}
+
+static inline void check_dmar_capabilities(struct intel_iommu *a,
+  struct intel_iommu *b)
+{
+   MINIMAL_FEATURE_IOMMU(b, cap, CAP_MAMV_MASK);
+   MINIMAL_FEATURE_IOMMU(b, cap, CAP_NFR_MASK);
+   MINIMAL_FEATURE_IOMMU(b, cap, CAP_SLLPS_MASK);
+   MINIMAL_FEATURE_IOMMU(b, cap, CAP_FRO_MASK);
+   MINIMAL_FEATURE_IOMMU(b, cap, CAP_MGAW_MASK);
+   MINIMAL_FEATURE_IOMMU(b, cap, CAP_SAGAW_MASK);
+   MINIMAL_FEATURE_IOMMU(b, cap, CAP_NDOMS_MASK);
+   MINIMAL_FEATURE_IOMMU(b, ecap, ECAP_PSS_MASK);
+   MINIMAL_FEATURE_IOMMU(b, ecap, ECAP_MHMV_MASK);
+   MINIMAL_FEATURE_IOMMU(b, ecap, ECAP_IRO_MASK);
+
+   CHECK_FEATURE_MISMATCH(a, b, cap, 5lp_support, CAP_FL5LP_MASK);
+   CHECK_FEATURE_MISMATCH(a, b, cap, fl1gp_support, CAP_FL1GP_MASK);
+   CHECK_FEATURE_MISMATCH(a, b, cap, read_drain, CAP_RD_MASK);
+   CHECK_FEATURE_MISMATCH(a, b, cap, write_drain, CAP_WD_MASK);
+   CHECK_FEATURE_MISMATCH(a, b, cap, pgsel_inv, CAP_PSI_MASK);
+   CHECK_FEATURE_MISMATCH(a, b, cap, zlr, CAP_ZLR_MASK);
+   CHECK_FEATURE_MISMATCH(a, b, cap, caching_mode, CAP_CM_MASK);
+   CHECK_FEATURE_MISMATCH(a, b, cap, phmr, CAP_PHMR_MASK);
+   CHECK_FEATURE_MISMATCH(a, 

[PATCH v3 0/3] Audit Capability and Extended Capability among IOMMUs

2020-12-22 Thread Kyung Min Park
Modern platforms have more than one IOMMU. Each IOMMU has its own
feature set. Some of these features must be consistent among IOMMUs.
Otherwise, these differences can lead to improper behavior in the system.
On the other hand, for some features, each IOMMU can have different
capacity values. So, different actions are required to deal with the
inconsistencies depending on the IOMMU features.

Currently, some inconsistencies are ignored by the IOMMU driver.
This patchset checks IOMMU capabilities and extended capabilities
centralizedly during boot and take different actions according to
the impacts caused by the mismatches.

For example:
 1. Disable Shared Virtual Memory.
 2. Use common capacity values (normally the lowest capacity value) for
all IOMMUs.
 3. Report feature mismatches.

Detailed information on the IOMMU Capability / Extended Capability can
be found in Intel VT-d Specification.

Link: 
https://software.intel.com/sites/default/files/managed/c5/15/vt-directed-io-spec.pdf

ChangeLog:
- Change from v2 to v3:
  1. fix the wrong macro names and rebase to v5.10.
- Change from v1 to v2:
  1. Add missing cap/ecaps for audit.
  2. Refactor function/macros overal suggested by Lu, Baolu.
  2. Skip audit for gfx dedicated IOMMU.
  3. Change commit message.

Kyung Min Park (3):
  iommu/vt-d: Audit IOMMU Capabilities and add helper functions
  iommu/vt-d: Move capability check code to cap_audit files
  iommu/vt-d: Disable SVM in the platform when IOMMUs have
inconsistencies

 drivers/iommu/intel/Makefile|   2 +-
 drivers/iommu/intel/cap_audit.c | 219 
 drivers/iommu/intel/cap_audit.h | 132 +
 drivers/iommu/intel/iommu.c |  85 ++-
 drivers/iommu/intel/irq_remapping.c |   8 +
 drivers/iommu/intel/svm.c   |   3 +-
 include/linux/intel-iommu.h |  39 ++---
 7 files changed, 394 insertions(+), 94 deletions(-)
 create mode 100644 drivers/iommu/intel/cap_audit.c
 create mode 100644 drivers/iommu/intel/cap_audit.h

-- 
2.17.1

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


[PATCH v3 3/3] iommu/vt-d: Disable SVM in the platform when IOMMUs have inconsistencies

2020-12-22 Thread Kyung Min Park
Some IOMMU Capabilities must be consistent for Shared Virtual Memory (SVM).
Audit IOMMU Capability/Extended Capabilities and check if IOMMUs have
the consistent value for features as below. When the features are not
matched among IOMMUs, disable SVMs in the platform during DMAR
initialization. Audit IOMMUs again when a device is hot plugged.

Disable Shared Virtual Memory when below features are mistmatched:
  - First Level Translation Support (FLTS)
  - Process Address Space ID Support (PASID)
  - Extended Accessed Flag Support (EAFS)
  - Supervisor Support (SRS)
  - Execute Request Support (ERS)
  - Page Request Support (PRS)

Signed-off-by: Kyung Min Park 
---
 drivers/iommu/intel/cap_audit.c | 11 +++
 drivers/iommu/intel/cap_audit.h |  6 ++
 drivers/iommu/intel/svm.c   |  3 ++-
 3 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/intel/cap_audit.c b/drivers/iommu/intel/cap_audit.c
index cf5326eb1d72..e6f8616edc3d 100644
--- a/drivers/iommu/intel/cap_audit.c
+++ b/drivers/iommu/intel/cap_audit.c
@@ -130,6 +130,12 @@ static int cap_audit_hotplug(struct intel_iommu *iommu, 
enum cap_audit_type type
MINIMAL_FEATURE_HOTPLUG(iommu, ecap, max_handle_mask, ECAP_MHMV_MASK, 
mismatch);
MINIMAL_FEATURE_HOTPLUG(iommu, ecap, iotlb_offset, ECAP_IRO_MASK, 
mismatch);
 
+   if (IS_ENABLED(CONFIG_INTEL_IOMMU_SVM) &&
+   intel_cap_svm_santiy() && !ecap_svm_sanity(iommu->ecap)) {
+   pr_warn("Abort Hot Plug IOMMU: SVM inconsistent\n");
+   mismatch = true;
+   }
+
 out:
if (mismatch) {
intel_iommu_cap_sanity = old_cap;
@@ -206,3 +212,8 @@ bool intel_cap_flts_sanity(void)
 {
return ecap_flts(intel_iommu_ecap_sanity);
 }
+
+bool intel_cap_svm_santiy(void)
+{
+   return ecap_svm_sanity(intel_iommu_ecap_sanity);
+}
diff --git a/drivers/iommu/intel/cap_audit.h b/drivers/iommu/intel/cap_audit.h
index 1ce1dc314950..beb2589e97e0 100644
--- a/drivers/iommu/intel/cap_audit.h
+++ b/drivers/iommu/intel/cap_audit.h
@@ -60,6 +60,11 @@
 #define ECAP_QI_MASK   BIT_ULL(1)
 #define ECAP_C_MASKBIT_ULL(0)
 
+#define MINIMAL_SVM_ECAP (ECAP_FLTS_MASK | ECAP_PASID_MASK | ECAP_EAFS_MASK | \
+ ECAP_SRS_MASK | ECAP_ERS_MASK | ECAP_PRS_MASK)
+
+#define ecap_svm_sanity(e) (!(((e) & MINIMAL_SVM_ECAP) ^ MINIMAL_SVM_ECAP))
+
 #define DO_CHECK_FEATURE_MISMATCH(a, b, cap, feature, MASK) \
 do { \
if (cap##_##feature(a) != cap##_##feature(b)) { \
@@ -107,6 +112,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_svm_santiy(void);
 
 static inline bool scalable_mode_support(void)
 {
diff --git a/drivers/iommu/intel/svm.c b/drivers/iommu/intel/svm.c
index f1861fa3d0e4..8a116c43f219 100644
--- a/drivers/iommu/intel/svm.c
+++ b/drivers/iommu/intel/svm.c
@@ -22,6 +22,7 @@
 #include 
 
 #include "pasid.h"
+#include "cap_audit.h"
 
 static irqreturn_t prq_event_thread(int irq, void *d);
 static void intel_svm_drain_prq(struct device *dev, u32 pasid);
@@ -98,7 +99,7 @@ static inline bool intel_svm_capable(struct intel_iommu 
*iommu)
 
 void intel_svm_check(struct intel_iommu *iommu)
 {
-   if (!pasid_supported(iommu))
+   if (!intel_cap_svm_santiy())
return;
 
if (cpu_feature_enabled(X86_FEATURE_GBPAGES) &&
-- 
2.17.1

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


[PATCH v3 2/3] iommu/vt-d: Move capability check code to cap_audit files

2020-12-22 Thread Kyung Min Park
Move IOMMU capability check and sanity check code to cap_audit files.
Also implement some helper functions for sanity checks.

Signed-off-by: Kyung Min Park 
---
 drivers/iommu/intel/cap_audit.c | 20 +
 drivers/iommu/intel/cap_audit.h | 20 +
 drivers/iommu/intel/iommu.c | 76 +
 3 files changed, 42 insertions(+), 74 deletions(-)

diff --git a/drivers/iommu/intel/cap_audit.c b/drivers/iommu/intel/cap_audit.c
index 4a062fc719d2..cf5326eb1d72 100644
--- a/drivers/iommu/intel/cap_audit.c
+++ b/drivers/iommu/intel/cap_audit.c
@@ -186,3 +186,23 @@ int intel_cap_audit(enum cap_audit_type type, struct 
intel_iommu *iommu)
 
return -EFAULT;
 }
+
+bool intel_cap_smts_sanity(void)
+{
+   return ecap_smts(intel_iommu_ecap_sanity);
+}
+
+bool intel_cap_pasid_sanity(void)
+{
+   return ecap_pasid(intel_iommu_ecap_sanity);
+}
+
+bool intel_cap_nest_sanity(void)
+{
+   return ecap_nest(intel_iommu_ecap_sanity);
+}
+
+bool intel_cap_flts_sanity(void)
+{
+   return ecap_flts(intel_iommu_ecap_sanity);
+}
diff --git a/drivers/iommu/intel/cap_audit.h b/drivers/iommu/intel/cap_audit.h
index 866236581dd3..1ce1dc314950 100644
--- a/drivers/iommu/intel/cap_audit.h
+++ b/drivers/iommu/intel/cap_audit.h
@@ -103,4 +103,24 @@ enum cap_audit_type {
CAP_AUDIT_HOTPLUG_IRQR,
 };
 
+bool intel_cap_smts_sanity(void);
+bool intel_cap_pasid_sanity(void);
+bool intel_cap_nest_sanity(void);
+bool intel_cap_flts_sanity(void);
+
+static inline bool scalable_mode_support(void)
+{
+   return (intel_iommu_sm && intel_cap_smts_sanity());
+}
+
+static inline bool pasid_mode_support(void)
+{
+   return scalable_mode_support() && intel_cap_pasid_sanity();
+}
+
+static inline bool nested_mode_support(void)
+{
+   return scalable_mode_support() && intel_cap_nest_sanity();
+}
+
 int intel_cap_audit(enum cap_audit_type type, struct intel_iommu *iommu);
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index 592cb6dd5d3a..676f6900f4dc 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -1846,25 +1846,7 @@ static void free_dmar_iommu(struct intel_iommu *iommu)
  */
 static bool first_level_by_default(void)
 {
-   struct dmar_drhd_unit *drhd;
-   struct intel_iommu *iommu;
-   static int first_level_support = -1;
-
-   if (likely(first_level_support != -1))
-   return first_level_support;
-
-   first_level_support = 1;
-
-   rcu_read_lock();
-   for_each_active_iommu(iommu, drhd) {
-   if (!sm_supported(iommu) || !ecap_flts(iommu->ecap)) {
-   first_level_support = 0;
-   break;
-   }
-   }
-   rcu_read_unlock();
-
-   return first_level_support;
+   return scalable_mode_support() && intel_cap_flts_sanity();
 }
 
 static struct dmar_domain *alloc_domain(int flags)
@@ -5663,60 +5645,6 @@ static phys_addr_t intel_iommu_iova_to_phys(struct 
iommu_domain *domain,
return phys;
 }
 
-static inline bool scalable_mode_support(void)
-{
-   struct dmar_drhd_unit *drhd;
-   struct intel_iommu *iommu;
-   bool ret = true;
-
-   rcu_read_lock();
-   for_each_active_iommu(iommu, drhd) {
-   if (!sm_supported(iommu)) {
-   ret = false;
-   break;
-   }
-   }
-   rcu_read_unlock();
-
-   return ret;
-}
-
-static inline bool iommu_pasid_support(void)
-{
-   struct dmar_drhd_unit *drhd;
-   struct intel_iommu *iommu;
-   bool ret = true;
-
-   rcu_read_lock();
-   for_each_active_iommu(iommu, drhd) {
-   if (!pasid_supported(iommu)) {
-   ret = false;
-   break;
-   }
-   }
-   rcu_read_unlock();
-
-   return ret;
-}
-
-static inline bool nested_mode_support(void)
-{
-   struct dmar_drhd_unit *drhd;
-   struct intel_iommu *iommu;
-   bool ret = true;
-
-   rcu_read_lock();
-   for_each_active_iommu(iommu, drhd) {
-   if (!sm_supported(iommu) || !ecap_nest(iommu->ecap)) {
-   ret = false;
-   break;
-   }
-   }
-   rcu_read_unlock();
-
-   return ret;
-}
-
 static bool intel_iommu_capable(enum iommu_cap cap)
 {
if (cap == IOMMU_CAP_CACHE_COHERENCY)
@@ -5970,7 +5898,7 @@ intel_iommu_dev_has_feat(struct device *dev, enum 
iommu_dev_features feat)
int ret;
 
if (!dev_is_pci(dev) || dmar_disabled ||
-   !scalable_mode_support() || !iommu_pasid_support())
+   !scalable_mode_support() || !pasid_mode_support())
return false;
 
ret = pci_pasid_features(to_pci_dev(dev));
-- 
2.17.1

___
iommu mailing list
iommu@lists.linux-foundation.org

Re: [GIT PULL] dma-mapping updates for 5.11

2020-12-22 Thread pr-tracker-bot
The pull request you sent on Tue, 22 Dec 2020 17:01:12 +0100:

> git://git.infradead.org/users/hch/dma-mapping.git tags/dma-mapping-5.11

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/347d81b68b8f7044c9ce3fefa130a736ca916176

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 2/3] iommu/vt-d: Track device aux-attach with subdevice_domain_info.

2020-12-22 Thread Jacob Pan
Hi Yi,

On Sun, 20 Dec 2020 08:03:51 +0800, Liu Yi L  wrote:

> In existing code, if wanting to loop all devices attached to a domain,
> current code can only loop the devices which are attached to the domain
> via normal manner. While for devices attached via auxiliary manner, this
> is subdevice, they are not tracked in the domain. This patch adds struct
How about "In the existing code, loop all devices attached to a domain does
not include sub-devices attached via iommu_aux_attach_device()."

> subdevice_domain_info which is created per domain attachment via auxiliary
> manner. So that such devices are also tracked in domain.
> 
> This was found by when I'm working on the belwo patch, There is no device
> in domain->devices, thus unable to get the cap and ecap of iommu unit. But
> this domain actually has one sub-device which is attached via aux-manner.
> This patch fixes the issue.
> 
> https://lore.kernel.org/kvm/1599734733-6431-17-git-send-email-yi.l@intel.com/
> 
> But looks like, it doesn't affect me only. Such auxiliary track should be
> there for example if wanting to flush device_iotlb for a domain which has
> devices attached by auxiliray manner, then this fix is also necessary.
Perhaps:
This fix goes beyond the patch above, such sub-device tracking is
necessary for other cases. For example, flushing device_iotlb for a domain
which has sub-devices attached by auxiliary manner.

> This issue will also be fixed by another patch in this series with some
> additional changes based on the sudevice tracking framework introduced in
> this patch.
> 
> Co-developed-by: Xin Zeng 
> Signed-off-by: Xin Zeng 
> Co-developed-by: Liu Yi L 
> Signed-off-by: Liu Yi L 
> Co-developed-by: Lu Baolu 
> Signed-off-by: Lu Baolu 
> ---
>  drivers/iommu/intel/iommu.c | 92 -
>  include/linux/intel-iommu.h | 11 -
>  2 files changed, 90 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
> index a49afa11673c..4274b4acc325 100644
> --- a/drivers/iommu/intel/iommu.c
> +++ b/drivers/iommu/intel/iommu.c
> @@ -1881,6 +1881,7 @@ static struct dmar_domain *alloc_domain(int flags)
>   domain->flags |= DOMAIN_FLAG_USE_FIRST_LEVEL;
>   domain->has_iotlb_device = false;
>   INIT_LIST_HEAD(>devices);
> + INIT_LIST_HEAD(>sub_devices);
>  
>   return domain;
>  }
> @@ -5172,33 +5173,79 @@ is_aux_domain(struct device *dev, struct
> iommu_domain *domain) domain->type == IOMMU_DOMAIN_UNMANAGED;
>  }
>  
> +static inline
> +void _auxiliary_link_device(struct dmar_domain *domain,
> + struct subdevice_domain_info *subinfo,
> + struct device *dev)
> +{
> + subinfo->users++;
> +}
> +
why pass in more arguments than subinfo? the function name does not match
what it does, seems just refcount inc.

> +static inline
> +int _auxiliary_unlink_device(struct dmar_domain *domain,
> +  struct subdevice_domain_info *subinfo,
> +  struct device *dev)
> +{
> + subinfo->users--;
> + return subinfo->users;
ditto. why not just
return subinfo->users--;

> +}
> +
>  static void auxiliary_link_device(struct dmar_domain *domain,
> struct device *dev)
>  {
>   struct device_domain_info *info = get_domain_info(dev);
> + struct subdevice_domain_info *subinfo;
>  
>   assert_spin_locked(_domain_lock);
>   if (WARN_ON(!info))
>   return;
>  
> + subinfo = kzalloc(sizeof(*subinfo), GFP_ATOMIC);
> + if (!subinfo)
> + return;
> +
> + subinfo->domain = domain;
> + subinfo->dev = dev;
> + list_add(>link_domain, >auxiliary_domains);
> + list_add(>link_phys, >sub_devices);
> + _auxiliary_link_device(domain, subinfo, dev);
or just opencode subinfo->users++?
>   domain->auxd_refcnt++;
> - list_add(>auxd, >auxiliary_domains);
>  }
>  
> -static void auxiliary_unlink_device(struct dmar_domain *domain,
> - struct device *dev)
> +static struct subdevice_domain_info *
> +subdevice_domain_info_lookup(struct dmar_domain *domain, struct device
> *dev) +{
> + struct subdevice_domain_info *subinfo;
> +
> + assert_spin_locked(_domain_lock);
> +
> + list_for_each_entry(subinfo, >sub_devices, link_phys)
> + if (subinfo->dev == dev)
> + return subinfo;
> +
> + return NULL;
> +}
> +
> +static int auxiliary_unlink_device(struct dmar_domain *domain,
> +struct subdevice_domain_info *subinfo,
> +struct device *dev)
>  {
>   struct device_domain_info *info = get_domain_info(dev);
> + int ret;
>  
>   assert_spin_locked(_domain_lock);
>   if (WARN_ON(!info))
> - return;
> + return -EINVAL;
>  
> - list_del(>auxd);
> + ret = _auxiliary_unlink_device(domain, 

Re: [PATCH v2 1/7] iommu/io-pgtable: Introduce dynamic io-pgtable fmt registration

2020-12-22 Thread isaacm

On 2020-12-22 11:27, Robin Murphy wrote:

On 2020-12-22 00:44, Isaac J. Manjarres wrote:

The io-pgtable code constructs an array of init functions for each
page table format at compile time. This is not ideal, as this
increases the footprint of the io-pgtable code, as well as prevents
io-pgtable formats from being built as kernel modules.

In preparation for modularizing the io-pgtable formats, switch to a
dynamic registration scheme, where each io-pgtable format can register
their init functions with the io-pgtable code at boot or module
insertion time.

Signed-off-by: Isaac J. Manjarres 
---
  drivers/iommu/io-pgtable-arm-v7s.c | 34 +-
  drivers/iommu/io-pgtable-arm.c | 90 
++--
  drivers/iommu/io-pgtable.c | 94 
--

  include/linux/io-pgtable.h | 51 +
  4 files changed, 209 insertions(+), 60 deletions(-)

diff --git a/drivers/iommu/io-pgtable-arm-v7s.c 
b/drivers/iommu/io-pgtable-arm-v7s.c

index 1d92ac9..89aad2f 100644
--- a/drivers/iommu/io-pgtable-arm-v7s.c
+++ b/drivers/iommu/io-pgtable-arm-v7s.c
@@ -28,6 +28,7 @@
  #include 
  #include 
  #include 
+#include 
  #include 
  #include 
  #include 
@@ -835,7 +836,8 @@ static struct io_pgtable 
*arm_v7s_alloc_pgtable(struct io_pgtable_cfg *cfg,

return NULL;
  }
  -struct io_pgtable_init_fns io_pgtable_arm_v7s_init_fns = {
+static struct io_pgtable_init_fns io_pgtable_arm_v7s_init_fns = {
+   .fmt= ARM_V7S,
.alloc  = arm_v7s_alloc_pgtable,
.free   = arm_v7s_free_pgtable,
  };
@@ -982,5 +984,33 @@ static int __init arm_v7s_do_selftests(void)
pr_info("self test ok\n");
return 0;
  }
-subsys_initcall(arm_v7s_do_selftests);
+#else
+static int arm_v7s_do_selftests(void)
+{
+   return 0;
+}
  #endif
+
+static int __init arm_v7s_init(void)
+{
+   int ret;
+
+   ret = io_pgtable_ops_register(_pgtable_arm_v7s_init_fns);
+   if (ret < 0) {
+   pr_err("Failed to register ARM V7S format\n");


Super-nit: I think "v7s" should probably be lowercase there. Also
general consistency WRT to showing the error code and whether or not
to abbreviate "format" would be nice.


Ok, I can fix this accordingly.


+   return ret;
+   }
+
+   ret = arm_v7s_do_selftests();
+   if (ret < 0)
+   io_pgtable_ops_unregister(_pgtable_arm_v7s_init_fns);
+
+   return ret;
+}
+core_initcall(arm_v7s_init);
+
+static void __exit arm_v7s_exit(void)
+{
+   io_pgtable_ops_unregister(_pgtable_arm_v7s_init_fns);
+}
+module_exit(arm_v7s_exit);
diff --git a/drivers/iommu/io-pgtable-arm.c 
b/drivers/iommu/io-pgtable-arm.c

index 87def58..ff0ea2f 100644
--- a/drivers/iommu/io-pgtable-arm.c
+++ b/drivers/iommu/io-pgtable-arm.c
@@ -13,6 +13,7 @@
  #include 
  #include 
  #include 
+#include 
  #include 
  #include 
  #include 
@@ -1043,29 +1044,32 @@ arm_mali_lpae_alloc_pgtable(struct 
io_pgtable_cfg *cfg, void *cookie)

return NULL;
  }
  -struct io_pgtable_init_fns io_pgtable_arm_64_lpae_s1_init_fns = {
-   .alloc  = arm_64_lpae_alloc_pgtable_s1,
-   .free   = arm_lpae_free_pgtable,
-};
-
-struct io_pgtable_init_fns io_pgtable_arm_64_lpae_s2_init_fns = {
-   .alloc  = arm_64_lpae_alloc_pgtable_s2,
-   .free   = arm_lpae_free_pgtable,
-};
-
-struct io_pgtable_init_fns io_pgtable_arm_32_lpae_s1_init_fns = {
-   .alloc  = arm_32_lpae_alloc_pgtable_s1,
-   .free   = arm_lpae_free_pgtable,
-};
-
-struct io_pgtable_init_fns io_pgtable_arm_32_lpae_s2_init_fns = {
-   .alloc  = arm_32_lpae_alloc_pgtable_s2,
-   .free   = arm_lpae_free_pgtable,
-};
-
-struct io_pgtable_init_fns io_pgtable_arm_mali_lpae_init_fns = {
-   .alloc  = arm_mali_lpae_alloc_pgtable,
-   .free   = arm_lpae_free_pgtable,
+static struct io_pgtable_init_fns io_pgtable_arm_lpae_init_fns[] = {
+   {
+   .fmt= ARM_32_LPAE_S1,
+   .alloc  = arm_32_lpae_alloc_pgtable_s1,
+   .free   = arm_lpae_free_pgtable,
+   },
+   {
+   .fmt= ARM_32_LPAE_S2,
+   .alloc  = arm_32_lpae_alloc_pgtable_s2,
+   .free   = arm_lpae_free_pgtable,
+   },
+   {
+   .fmt= ARM_64_LPAE_S1,
+   .alloc  = arm_64_lpae_alloc_pgtable_s1,
+   .free   = arm_lpae_free_pgtable,
+   },
+   {
+   .fmt= ARM_64_LPAE_S2,
+   .alloc  = arm_64_lpae_alloc_pgtable_s2,
+   .free   = arm_lpae_free_pgtable,
+   },
+   {
+   .fmt= ARM_MALI_LPAE,
+   .alloc  = arm_mali_lpae_alloc_pgtable,
+   .free   = arm_lpae_free_pgtable,
+   },
  };
#ifdef CONFIG_IOMMU_IO_PGTABLE_LPAE_SELFTEST
@@ -1250,5 +1254,43 @@ static int __init arm_lpae_do_selftests(void)
pr_info("selftest: completed with %d PASS %d FAIL\n", pass, fail);
return fail ? -EFAULT : 0;
  }

Re: [PATCH v2 3/7] iommu/arm-smmu: Add dependency on io-pgtable format modules

2020-12-22 Thread isaacm

On 2020-12-22 11:27, Robin Murphy wrote:

On 2020-12-22 00:44, Isaac J. Manjarres wrote:

The SMMU driver depends on the availability of the ARM LPAE and
ARM V7S io-pgtable format code to work properly. In preparation


Nit: we don't really depend on v7s - we *can* use it if it's
available, address constraints are suitable, and the SMMU
implementation actually supports it (many don't), but we can still
quite happily not use it even so. LPAE is mandatory in the
architecture so that's our only hard requirement, embodied in the
kconfig select.

This does mean there may technically still be a corner case involving
ARM_SMMU=y and IO_PGTABLE_ARM_V7S=m, but at worst it's now a runtime
failure rather than a build error, so unless and until anyone
demonstrates that it actually matters I don't feel particularly
inclined to give it much thought.

Robin.


Okay, I'll fix up the commit message, as well as the code, so that it
only depends on io-pgtable-arm.

Thanks,
Isaac

for having the io-pgtable formats as modules, add a "pre"
dependency with MODULE_SOFTDEP() to ensure that the io-pgtable
format modules are loaded before loading the ARM SMMU driver module.

Signed-off-by: Isaac J. Manjarres 
---
  drivers/iommu/arm/arm-smmu/arm-smmu.c | 1 +
  1 file changed, 1 insertion(+)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c 
b/drivers/iommu/arm/arm-smmu/arm-smmu.c

index d8c6bfd..a72649f 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -2351,3 +2351,4 @@ MODULE_DESCRIPTION("IOMMU API for ARM 
architected SMMU implementations");

  MODULE_AUTHOR("Will Deacon ");
  MODULE_ALIAS("platform:arm-smmu");
  MODULE_LICENSE("GPL v2");
+MODULE_SOFTDEP("pre: io-pgtable-arm io-pgtable-arm-v7s");



___
linux-arm-kernel mailing list
linux-arm-ker...@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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


Re: [PATCH v2 1/7] iommu/io-pgtable: Introduce dynamic io-pgtable fmt registration

2020-12-22 Thread Robin Murphy

On 2020-12-22 00:44, Isaac J. Manjarres wrote:

The io-pgtable code constructs an array of init functions for each
page table format at compile time. This is not ideal, as this
increases the footprint of the io-pgtable code, as well as prevents
io-pgtable formats from being built as kernel modules.

In preparation for modularizing the io-pgtable formats, switch to a
dynamic registration scheme, where each io-pgtable format can register
their init functions with the io-pgtable code at boot or module
insertion time.

Signed-off-by: Isaac J. Manjarres 
---
  drivers/iommu/io-pgtable-arm-v7s.c | 34 +-
  drivers/iommu/io-pgtable-arm.c | 90 ++--
  drivers/iommu/io-pgtable.c | 94 --
  include/linux/io-pgtable.h | 51 +
  4 files changed, 209 insertions(+), 60 deletions(-)

diff --git a/drivers/iommu/io-pgtable-arm-v7s.c 
b/drivers/iommu/io-pgtable-arm-v7s.c
index 1d92ac9..89aad2f 100644
--- a/drivers/iommu/io-pgtable-arm-v7s.c
+++ b/drivers/iommu/io-pgtable-arm-v7s.c
@@ -28,6 +28,7 @@
  #include 
  #include 
  #include 
+#include 
  #include 
  #include 
  #include 
@@ -835,7 +836,8 @@ static struct io_pgtable *arm_v7s_alloc_pgtable(struct 
io_pgtable_cfg *cfg,
return NULL;
  }
  
-struct io_pgtable_init_fns io_pgtable_arm_v7s_init_fns = {

+static struct io_pgtable_init_fns io_pgtable_arm_v7s_init_fns = {
+   .fmt= ARM_V7S,
.alloc  = arm_v7s_alloc_pgtable,
.free   = arm_v7s_free_pgtable,
  };
@@ -982,5 +984,33 @@ static int __init arm_v7s_do_selftests(void)
pr_info("self test ok\n");
return 0;
  }
-subsys_initcall(arm_v7s_do_selftests);
+#else
+static int arm_v7s_do_selftests(void)
+{
+   return 0;
+}
  #endif
+
+static int __init arm_v7s_init(void)
+{
+   int ret;
+
+   ret = io_pgtable_ops_register(_pgtable_arm_v7s_init_fns);
+   if (ret < 0) {
+   pr_err("Failed to register ARM V7S format\n");


Super-nit: I think "v7s" should probably be lowercase there. Also 
general consistency WRT to showing the error code and whether or not to 
abbreviate "format" would be nice.



+   return ret;
+   }
+
+   ret = arm_v7s_do_selftests();
+   if (ret < 0)
+   io_pgtable_ops_unregister(_pgtable_arm_v7s_init_fns);
+
+   return ret;
+}
+core_initcall(arm_v7s_init);
+
+static void __exit arm_v7s_exit(void)
+{
+   io_pgtable_ops_unregister(_pgtable_arm_v7s_init_fns);
+}
+module_exit(arm_v7s_exit);
diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
index 87def58..ff0ea2f 100644
--- a/drivers/iommu/io-pgtable-arm.c
+++ b/drivers/iommu/io-pgtable-arm.c
@@ -13,6 +13,7 @@
  #include 
  #include 
  #include 
+#include 
  #include 
  #include 
  #include 
@@ -1043,29 +1044,32 @@ arm_mali_lpae_alloc_pgtable(struct io_pgtable_cfg *cfg, 
void *cookie)
return NULL;
  }
  
-struct io_pgtable_init_fns io_pgtable_arm_64_lpae_s1_init_fns = {

-   .alloc  = arm_64_lpae_alloc_pgtable_s1,
-   .free   = arm_lpae_free_pgtable,
-};
-
-struct io_pgtable_init_fns io_pgtable_arm_64_lpae_s2_init_fns = {
-   .alloc  = arm_64_lpae_alloc_pgtable_s2,
-   .free   = arm_lpae_free_pgtable,
-};
-
-struct io_pgtable_init_fns io_pgtable_arm_32_lpae_s1_init_fns = {
-   .alloc  = arm_32_lpae_alloc_pgtable_s1,
-   .free   = arm_lpae_free_pgtable,
-};
-
-struct io_pgtable_init_fns io_pgtable_arm_32_lpae_s2_init_fns = {
-   .alloc  = arm_32_lpae_alloc_pgtable_s2,
-   .free   = arm_lpae_free_pgtable,
-};
-
-struct io_pgtable_init_fns io_pgtable_arm_mali_lpae_init_fns = {
-   .alloc  = arm_mali_lpae_alloc_pgtable,
-   .free   = arm_lpae_free_pgtable,
+static struct io_pgtable_init_fns io_pgtable_arm_lpae_init_fns[] = {
+   {
+   .fmt= ARM_32_LPAE_S1,
+   .alloc  = arm_32_lpae_alloc_pgtable_s1,
+   .free   = arm_lpae_free_pgtable,
+   },
+   {
+   .fmt= ARM_32_LPAE_S2,
+   .alloc  = arm_32_lpae_alloc_pgtable_s2,
+   .free   = arm_lpae_free_pgtable,
+   },
+   {
+   .fmt= ARM_64_LPAE_S1,
+   .alloc  = arm_64_lpae_alloc_pgtable_s1,
+   .free   = arm_lpae_free_pgtable,
+   },
+   {
+   .fmt= ARM_64_LPAE_S2,
+   .alloc  = arm_64_lpae_alloc_pgtable_s2,
+   .free   = arm_lpae_free_pgtable,
+   },
+   {
+   .fmt= ARM_MALI_LPAE,
+   .alloc  = arm_mali_lpae_alloc_pgtable,
+   .free   = arm_lpae_free_pgtable,
+   },
  };
  
  #ifdef CONFIG_IOMMU_IO_PGTABLE_LPAE_SELFTEST

@@ -1250,5 +1254,43 @@ static int __init arm_lpae_do_selftests(void)
pr_info("selftest: completed with %d PASS %d FAIL\n", pass, fail);
return fail ? -EFAULT : 0;
  }
-subsys_initcall(arm_lpae_do_selftests);
+#else
+static int __init 

Re: [PATCH v2 3/7] iommu/arm-smmu: Add dependency on io-pgtable format modules

2020-12-22 Thread Robin Murphy

On 2020-12-22 00:44, Isaac J. Manjarres wrote:

The SMMU driver depends on the availability of the ARM LPAE and
ARM V7S io-pgtable format code to work properly. In preparation


Nit: we don't really depend on v7s - we *can* use it if it's available, 
address constraints are suitable, and the SMMU implementation actually 
supports it (many don't), but we can still quite happily not use it even 
so. LPAE is mandatory in the architecture so that's our only hard 
requirement, embodied in the kconfig select.


This does mean there may technically still be a corner case involving 
ARM_SMMU=y and IO_PGTABLE_ARM_V7S=m, but at worst it's now a runtime 
failure rather than a build error, so unless and until anyone 
demonstrates that it actually matters I don't feel particularly inclined 
to give it much thought.


Robin.


for having the io-pgtable formats as modules, add a "pre"
dependency with MODULE_SOFTDEP() to ensure that the io-pgtable
format modules are loaded before loading the ARM SMMU driver module.

Signed-off-by: Isaac J. Manjarres 
---
  drivers/iommu/arm/arm-smmu/arm-smmu.c | 1 +
  1 file changed, 1 insertion(+)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c 
b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index d8c6bfd..a72649f 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -2351,3 +2351,4 @@ MODULE_DESCRIPTION("IOMMU API for ARM architected SMMU 
implementations");
  MODULE_AUTHOR("Will Deacon ");
  MODULE_ALIAS("platform:arm-smmu");
  MODULE_LICENSE("GPL v2");
+MODULE_SOFTDEP("pre: io-pgtable-arm io-pgtable-arm-v7s");


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


Re: [PATCH 0/4] iommu/vtd-: Misc fixes on scalable mode

2020-12-22 Thread Jacob Pan
Hi Yi,

nit: The cover letter is 0/4, patches are 1/3 - 3/3. You also need to copy
LKML.

On Sun, 20 Dec 2020 08:03:49 +0800, Liu Yi L  wrote:

> Hi,
> 
> This patchset aims to fix a bug regards to SVM usage on native, and
perhaps 'native SVM usage'
> also several bugs around subdevice (attached to device via auxiliary
> manner) tracking and ineffective device_tlb flush.
> 
> Regards,
> Yi Liu
> 
> Liu Yi L (3):
>   iommu/vt-d: Move intel_iommu info from struct intel_svm to struct
> intel_svm_dev
>   iommu/vt-d: Track device aux-attach with subdevice_domain_info.
>   iommu/vt-d: A fix to iommu_flush_dev_iotlb() for aux-domain
> 
>  drivers/iommu/intel/iommu.c | 182 ++--
>  drivers/iommu/intel/svm.c   |   9 +-
>  include/linux/intel-iommu.h |  13 ++-
>  3 files changed, 168 insertions(+), 36 deletions(-)
> 


Thanks,

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


[PATCH] iommu/iova: fix 'domain' typos

2020-12-22 Thread Stefano Garzarella
Replace misspelled 'doamin' with 'domain' in several comments.

Signed-off-by: Stefano Garzarella 
---
 drivers/iommu/iova.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/iommu/iova.c b/drivers/iommu/iova.c
index 4bb3293ae4d7..d20b8b333d30 100644
--- a/drivers/iommu/iova.c
+++ b/drivers/iommu/iova.c
@@ -358,7 +358,7 @@ static void private_free_iova(struct iova_domain *iovad, 
struct iova *iova)
  * @iovad: - iova domain in question.
  * @pfn: - page frame number
  * This function finds and returns an iova belonging to the
- * given doamin which matches the given pfn.
+ * given domain which matches the given pfn.
  */
 struct iova *find_iova(struct iova_domain *iovad, unsigned long pfn)
 {
@@ -601,7 +601,7 @@ void queue_iova(struct iova_domain *iovad,
 EXPORT_SYMBOL_GPL(queue_iova);
 
 /**
- * put_iova_domain - destroys the iova doamin
+ * put_iova_domain - destroys the iova domain
  * @iovad: - iova domain in question.
  * All the iova's in that domain are destroyed.
  */
@@ -712,9 +712,9 @@ EXPORT_SYMBOL_GPL(reserve_iova);
 
 /**
  * copy_reserved_iova - copies the reserved between domains
- * @from: - source doamin from where to copy
+ * @from: - source domain from where to copy
  * @to: - destination domin where to copy
- * This function copies reserved iova's from one doamin to
+ * This function copies reserved iova's from one domain to
  * other.
  */
 void
-- 
2.26.2

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


[GIT PULL] dma-mapping updates for 5.11

2020-12-22 Thread Christoph Hellwig
The following changes since commit 418baf2c28f3473039f2f7377760bd8f6897ae18:

  Linux 5.10-rc5 (2020-11-22 15:36:08 -0800)

are available in the Git repository at:

  git://git.infradead.org/users/hch/dma-mapping.git tags/dma-mapping-5.11

for you to fetch changes up to 7679325702c90aecd393cd7cde685576c14489c0:

  selftests/dma: add test application for DMA_MAP_BENCHMARK (2020-11-27 
10:33:42 +0100)


dma-mapping updates for 5.11:

 - support for a partial IOMMU bypass (Alexey Kardashevskiy)
 - add a DMA API benchmark (Barry Song)
 - misc fixes (Tiezhu Yang, tangjianqiang)


Alexey Kardashevskiy (2):
  dma-mapping: Allow mixing bypass and mapped DMA operation
  powerpc/dma: Fallback to dma_ops when persistent memory present

Barry Song (2):
  dma-mapping: add benchmark support for streaming DMA APIs
  selftests/dma: add test application for DMA_MAP_BENCHMARK

Tiezhu Yang (1):
  dma-pool: no need to check return value of debugfs_create functions

tangjianqiang (1):
  dma-contiguous: fix a typo error in a comment

 MAINTAINERS |   6 +
 arch/powerpc/Kconfig|   1 +
 arch/powerpc/kernel/dma-iommu.c |  71 -
 arch/powerpc/platforms/pseries/iommu.c  |  51 +++-
 include/linux/dma-map-ops.h |  14 +
 kernel/dma/Kconfig  |  13 +
 kernel/dma/Makefile |   1 +
 kernel/dma/contiguous.c |   2 +-
 kernel/dma/map_benchmark.c  | 361 
 kernel/dma/mapping.c|  12 +-
 kernel/dma/pool.c   |   3 -
 tools/testing/selftests/dma/Makefile|   6 +
 tools/testing/selftests/dma/config  |   1 +
 tools/testing/selftests/dma/dma_map_benchmark.c | 123 
 14 files changed, 645 insertions(+), 20 deletions(-)
 create mode 100644 kernel/dma/map_benchmark.c
 create mode 100644 tools/testing/selftests/dma/Makefile
 create mode 100644 tools/testing/selftests/dma/config
 create mode 100644 tools/testing/selftests/dma/dma_map_benchmark.c
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu