Re: [PATCH] iommu/vt-d: Handle hotplug devices' default identity mapping setting

2019-02-21 Thread Lu Baolu

Hi James,

On 2/22/19 2:38 PM, James Dong wrote:


Tried this patch, and the same DMAR fault message came out.

Guess it is because of the iommu code path for hotplug devices. If a hotplug
device is rescanned after removal, iommu_bus_notifier will be called as part
of the notifier chains to handle BUS_NOTIFY_ADD_DEVICE event. Along the code
path, intel_iommu_ops->add_device() created an iommu group for this hotplug
device, but failed to create an iommu domain because of the default domain
type IOMMU_DOMAIN_IDENTITY imposed by current IOMMU command line option got
declined by intel_iommu_ops->domain_alloc().

In your patch, function find_or_alloc_domain() is not even in the code path
of BUS_NOTIFY_ADD_DEVICE event notifier chain.

Please let us know if your have more concerns and suggestions.


Can I reproduce this with a local machine? If so, how should I do?



Best Regards,
James


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


RE: [PATCH] iommu/vt-d: Handle hotplug devices' default identity mapping setting

2019-02-21 Thread James Dong via iommu
Baolu:

Sorry that my last reply email seems not text format. Resend it now.

Thanks for your comments and your patch. Please find below our responses to
each of your comments:

> What does "I/O operation won't work" exactly mean here? Do you see any
> IOMMU fault message? Or, something doesn't work as expected?

Yes, DMAR fault messages as following came out:
[  354.939896] DMAR: DMAR:[DMA Read] Request device [03:00.1]fault addr 
1fdfe8 
[  354.939896] DMAR:[fault reason 02] Present bit in context entry is clear


> Do you mind checking this?
>
> index 6ecdcf8fc8c0..f62f30bc1339 100644
> --- a/drivers/iommu/intel-iommu.c
> +++ b/drivers/iommu/intel-iommu.c
> @@ -2632,6 +2632,9 @@ static struct dmar_domain 
> *find_or_alloc_domain(struct device *dev, int gaw)
>  goto out;
>  }
> 
> +   if (!iommu_should_identity_map(dev, 0))
> +   return si_domain;
> +
>  /* Allocate and initialize new domain for the device */
>  domain = alloc_domain(0);
>  if (!domain)

Tried this patch, and the same DMAR fault message came out.

Guess it is because of the iommu code path for hotplug devices. If a hotplug
device is rescanned after removal, iommu_bus_notifier will be called as part
of the notifier chains to handle BUS_NOTIFY_ADD_DEVICE event. Along the code
path, intel_iommu_ops->add_device() created an iommu group for this hotplug
device, but failed to create an iommu domain because of the default domain
type IOMMU_DOMAIN_IDENTITY imposed by current IOMMU command line option got
declined by intel_iommu_ops->domain_alloc().

Since si_domain is type of "struct dmar_domain", which is platform dependent,
it is hard to make this change in intel_iommu_ops->domain_alloc().

In your patch, function find_or_alloc_domain() is not in the code path of
BUS_NOTIFY_ADD_DEVICE event notifier chain.

Please let us know if your have more concerns and suggestions.

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


Re: [PATCH] iommu/vt-d: Handle hotplug devices' default identity mapping setting

2019-02-21 Thread James Dong via iommu
Baolu:

Thanks for your comments and your patch. Please find below our responses to
each of your comments:

> What does "I/O operation won't work" exactly mean here? Do you see any
> IOMMU fault message? Or, something doesn't work as expected?

Yes, DMAR fault messages as following came out:
[  354.939896] DMAR: DMAR:[DMA Read] Request device [03:00.1]fault addr
1fdfe8
[  354.939896] DMAR:[fault reason 02] Present bit in context entry is clear


> Do you mind checking this?
>
> index 6ecdcf8fc8c0..f62f30bc1339 100644
> --- a/drivers/iommu/intel-iommu.c
> +++ b/drivers/iommu/intel-iommu.c
> @@ -2632,6 +2632,9 @@ static struct dmar_domain
> *find_or_alloc_domain(struct device *dev, int gaw)
>  goto out;
>  }
>
> +   if (!iommu_should_identity_map(dev, 0))
> +   return si_domain;
> +
>  /* Allocate and initialize new domain for the device */
>  domain = alloc_domain(0);
>  if (!domain)

Tried this patch, and the same DMAR fault message came out.

Guess it is because of the iommu code path for hotplug devices. If a hotplug
device is rescanned after removal, iommu_bus_notifier will be called as part
of the notifier chains to handle BUS_NOTIFY_ADD_DEVICE event. Along the code
path, intel_iommu_ops->add_device() created an iommu group for this hotplug
device, but failed to create an iommu domain because of the default domain
type IOMMU_DOMAIN_IDENTITY imposed by current IOMMU command line option got
declined by intel_iommu_ops->domain_alloc().

In your patch, function find_or_alloc_domain() is not even in the code path
of BUS_NOTIFY_ADD_DEVICE event notifier chain.

Please let us know if your have more concerns and suggestions.

Best Regards,
James

On Thu, Feb 21, 2019 at 9:35 PM Lu Baolu  wrote:

> Hi
>
> On 2/22/19 1:06 PM, Lu Baolu wrote:
>
> > Do you mind checking this?
> >
> > diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
> > index 6ecdcf8fc8c0..f62f30bc1339 100644
> > --- a/drivers/iommu/intel-iommu.c
> > +++ b/drivers/iommu/intel-iommu.c
> > @@ -2632,6 +2632,9 @@ static struct dmar_domain
> > *find_or_alloc_domain(struct device *dev, int gaw)
> >  goto out;
> >  }
> >
> > +   if (!iommu_should_identity_map(dev, 0))
> > +   return si_domain;
> > +
> >  /* Allocate and initialize new domain for the device */
> >  domain = alloc_domain(0);
> >  if (!domain)
>
> Oops! This can't be compiled. Please try below instead if you'd like to.
> Sorry about it.
>
> diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
> index 6ecdcf8fc8c0..b89f5ba6a3c8 100644
> --- a/drivers/iommu/intel-iommu.c
> +++ b/drivers/iommu/intel-iommu.c
> @@ -174,6 +174,8 @@ static inline unsigned long virt_to_dma_pfn(void *p)
>  return page_to_dma_pfn(virt_to_page(p));
>   }
>
> +static int iommu_should_identity_map(struct device *dev, int startup);
> +
>   /* global iommu list, set NULL for ignored DMAR units */
>   static struct intel_iommu **g_iommus;
>
> @@ -2632,6 +2634,9 @@ static struct dmar_domain
> *find_or_alloc_domain(struct device *dev, int gaw)
>  goto out;
>  }
>
> +   if (iommu_should_identity_map(dev, 0))
> +   return si_domain;
> +
>  /* Allocate and initialize new domain for the device */
>  domain = alloc_domain(0);
>  if (!domain)
>
> Best regards,
> Lu Baolu
>
>
>
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

Re: [PATCH] iommu/vt-d: Handle hotplug devices' default identity mapping setting

2019-02-21 Thread Lu Baolu

Hi

On 2/22/19 1:06 PM, Lu Baolu wrote:


Do you mind checking this?

diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 6ecdcf8fc8c0..f62f30bc1339 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -2632,6 +2632,9 @@ static struct dmar_domain 
*find_or_alloc_domain(struct device *dev, int gaw)

     goto out;
     }

+   if (!iommu_should_identity_map(dev, 0))
+   return si_domain;
+
     /* Allocate and initialize new domain for the device */
     domain = alloc_domain(0);
     if (!domain)


Oops! This can't be compiled. Please try below instead if you'd like to.
Sorry about it.

diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 6ecdcf8fc8c0..b89f5ba6a3c8 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -174,6 +174,8 @@ static inline unsigned long virt_to_dma_pfn(void *p)
return page_to_dma_pfn(virt_to_page(p));
 }

+static int iommu_should_identity_map(struct device *dev, int startup);
+
 /* global iommu list, set NULL for ignored DMAR units */
 static struct intel_iommu **g_iommus;

@@ -2632,6 +2634,9 @@ static struct dmar_domain 
*find_or_alloc_domain(struct device *dev, int gaw)

goto out;
}

+   if (iommu_should_identity_map(dev, 0))
+   return si_domain;
+
/* Allocate and initialize new domain for the device */
domain = alloc_domain(0);
if (!domain)

Best regards,
Lu Baolu


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

Re: [PATCH] iommu/vt-d: Handle hotplug devices' default identity mapping setting

2019-02-21 Thread Lu Baolu

Hi,

On 2/22/19 10:44 AM, James Dong wrote:

With specific Linux command line option such as "iommu=pt", some types
of hotplug devices will be assigned to the static 1:1 iommu domain by
default during kernel init.

If such a hotplug device is rescanned after being removed, for example,
with following sample commands:
   echo 1 > /sys/bus/pci/devices/\:03\:00.1/remove
   echo 1 > /sys/bus/pci/rescan
, an iommu group for this hotplug device will be added without attaching
it to the default static 1:1 domain. As a result, this device's I/O
operation won't work.


What does "I/O operation won't work" exactly mean here? Do you see any
IOMMU fault message? Or, something doesn't work as expected?



Keep hotplug devices with default static 1:1 iommu mapping in their default
domain after such hotplug devices are rescanned.

Signed-off-by: James Dong 
Reported-by: Jis Ben 
---
  drivers/iommu/intel-iommu.c | 14 +-
  1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 78188bf7e90d..4b02949e58ca 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -5230,6 +5230,7 @@ static int intel_iommu_add_device(struct device *dev)
struct intel_iommu *iommu;
struct iommu_group *group;
u8 bus, devfn;
+   int ret = 0;
  
  	iommu = device_to_iommu(dev, &bus, &devfn);

if (!iommu)
@@ -5242,8 +5243,19 @@ static int intel_iommu_add_device(struct device *dev)
if (IS_ERR(group))
return PTR_ERR(group);
  
+	if (!iommu_group_default_domain(group) &&

+   !find_domain(dev) && iommu_should_identity_map(dev, 0)) {
+   ret = domain_add_dev_info(si_domain, dev);
+   if (!ret)
+   pr_info("identity mapping for device %s\n",
+   dev_name(dev));
+   else
+   pr_info("identity mapping failed (%d) for device %s\n",
+   ret, dev_name(dev));
+   }
+


I am not sure about whether this is a good place to fix this problem
before Intel IOMMU driver switches to default domain.

Do you mind checking this?

diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 6ecdcf8fc8c0..f62f30bc1339 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -2632,6 +2632,9 @@ static struct dmar_domain 
*find_or_alloc_domain(struct device *dev, int gaw)

goto out;
}

+   if (!iommu_should_identity_map(dev, 0))
+   return si_domain;
+
/* Allocate and initialize new domain for the device */
domain = alloc_domain(0);
if (!domain)

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


[PATCH] iommu/vt-d: Handle hotplug devices' default identity mapping setting

2019-02-21 Thread James Dong via iommu
With specific Linux command line option such as "iommu=pt", some types
of hotplug devices will be assigned to the static 1:1 iommu domain by
default during kernel init.

If such a hotplug device is rescanned after being removed, for example,
with following sample commands:
  echo 1 > /sys/bus/pci/devices/\:03\:00.1/remove
  echo 1 > /sys/bus/pci/rescan
, an iommu group for this hotplug device will be added without attaching
it to the default static 1:1 domain. As a result, this device's I/O
operation won't work.

Keep hotplug devices with default static 1:1 iommu mapping in their default
domain after such hotplug devices are rescanned.

Signed-off-by: James Dong 
Reported-by: Jis Ben 
---
 drivers/iommu/intel-iommu.c | 14 +-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 78188bf7e90d..4b02949e58ca 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -5230,6 +5230,7 @@ static int intel_iommu_add_device(struct device *dev)
struct intel_iommu *iommu;
struct iommu_group *group;
u8 bus, devfn;
+   int ret = 0;
 
iommu = device_to_iommu(dev, &bus, &devfn);
if (!iommu)
@@ -5242,8 +5243,19 @@ static int intel_iommu_add_device(struct device *dev)
if (IS_ERR(group))
return PTR_ERR(group);
 
+   if (!iommu_group_default_domain(group) &&
+   !find_domain(dev) && iommu_should_identity_map(dev, 0)) {
+   ret = domain_add_dev_info(si_domain, dev);
+   if (!ret)
+   pr_info("identity mapping for device %s\n",
+   dev_name(dev));
+   else
+   pr_info("identity mapping failed (%d) for device %s\n",
+   ret, dev_name(dev));
+   }
+
iommu_group_put(group);
-   return 0;
+   return ret;
 }
 
 static void intel_iommu_remove_device(struct device *dev)
-- 
2.21.0.rc0.258.g878e2cd30e-goog

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


[PATCH v7 8/9] vfio/type1: Add domain at(de)taching group helpers

2019-02-21 Thread Lu Baolu
This adds helpers to attach or detach a domain to a
group. This will replace iommu_attach_group() which
only works for non-mdev devices.

If a domain is attaching to a group which includes the
mediated devices, it should attach to the iommu device
(a pci device which represents the mdev in iommu scope)
instead. The added helper supports attaching domain to
groups for both pci and mdev devices.

Cc: Ashok Raj 
Cc: Jacob Pan 
Cc: Kevin Tian 
Signed-off-by: Sanjay Kumar 
Signed-off-by: Liu Yi L 
Signed-off-by: Lu Baolu 
Reviewed-by: Jean-Philippe Brucker 
---
 drivers/vfio/vfio_iommu_type1.c | 84 ++---
 1 file changed, 77 insertions(+), 7 deletions(-)

diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
index 73652e21efec..ccc4165474aa 100644
--- a/drivers/vfio/vfio_iommu_type1.c
+++ b/drivers/vfio/vfio_iommu_type1.c
@@ -91,6 +91,7 @@ struct vfio_dma {
 struct vfio_group {
struct iommu_group  *iommu_group;
struct list_headnext;
+   boolmdev_group; /* An mdev group */
 };
 
 /*
@@ -1298,6 +1299,75 @@ static bool vfio_iommu_has_sw_msi(struct iommu_group 
*group, phys_addr_t *base)
return ret;
 }
 
+static struct device *vfio_mdev_get_iommu_device(struct device *dev)
+{
+   struct device *(*fn)(struct device *dev);
+   struct device *iommu_device;
+
+   fn = symbol_get(mdev_get_iommu_device);
+   if (fn) {
+   iommu_device = fn(dev);
+   symbol_put(mdev_get_iommu_device);
+
+   return iommu_device;
+   }
+
+   return NULL;
+}
+
+static int vfio_mdev_attach_domain(struct device *dev, void *data)
+{
+   struct iommu_domain *domain = data;
+   struct device *iommu_device;
+
+   iommu_device = vfio_mdev_get_iommu_device(dev);
+   if (iommu_device) {
+   if (iommu_dev_feature_enabled(iommu_device, IOMMU_DEV_FEAT_AUX))
+   return iommu_aux_attach_device(domain, iommu_device);
+   else
+   return iommu_attach_device(domain, iommu_device);
+   }
+
+   return -EINVAL;
+}
+
+static int vfio_mdev_detach_domain(struct device *dev, void *data)
+{
+   struct iommu_domain *domain = data;
+   struct device *iommu_device;
+
+   iommu_device = vfio_mdev_get_iommu_device(dev);
+   if (iommu_device) {
+   if (iommu_dev_feature_enabled(iommu_device, IOMMU_DEV_FEAT_AUX))
+   iommu_aux_detach_device(domain, iommu_device);
+   else
+   iommu_detach_device(domain, iommu_device);
+   }
+
+   return 0;
+}
+
+static int vfio_iommu_attach_group(struct vfio_domain *domain,
+  struct vfio_group *group)
+{
+   if (group->mdev_group)
+   return iommu_group_for_each_dev(group->iommu_group,
+   domain->domain,
+   vfio_mdev_attach_domain);
+   else
+   return iommu_attach_group(domain->domain, group->iommu_group);
+}
+
+static void vfio_iommu_detach_group(struct vfio_domain *domain,
+   struct vfio_group *group)
+{
+   if (group->mdev_group)
+   iommu_group_for_each_dev(group->iommu_group, domain->domain,
+vfio_mdev_detach_domain);
+   else
+   iommu_detach_group(domain->domain, group->iommu_group);
+}
+
 static int vfio_iommu_type1_attach_group(void *iommu_data,
 struct iommu_group *iommu_group)
 {
@@ -1373,7 +1443,7 @@ static int vfio_iommu_type1_attach_group(void *iommu_data,
goto out_domain;
}
 
-   ret = iommu_attach_group(domain->domain, iommu_group);
+   ret = vfio_iommu_attach_group(domain, group);
if (ret)
goto out_domain;
 
@@ -1405,8 +1475,8 @@ static int vfio_iommu_type1_attach_group(void *iommu_data,
list_for_each_entry(d, &iommu->domain_list, next) {
if (d->domain->ops == domain->domain->ops &&
d->prot == domain->prot) {
-   iommu_detach_group(domain->domain, iommu_group);
-   if (!iommu_attach_group(d->domain, iommu_group)) {
+   vfio_iommu_detach_group(domain, group);
+   if (!vfio_iommu_attach_group(d, group)) {
list_add(&group->next, &d->group_list);
iommu_domain_free(domain->domain);
kfree(domain);
@@ -1414,7 +1484,7 @@ static int vfio_iommu_type1_attach_group(void *iommu_data,
return 0;
}
 
-   ret = iommu_attach_group(domain->domain, iommu_group);
+   ret = vfio_iommu_attach_group(domain, group);
  

[PATCH v7 6/9] iommu/vt-d: Return ID associated with an auxiliary domain

2019-02-21 Thread Lu Baolu
This adds support to return the default pasid associated with
an auxiliary domain. The PCI device which is bound with this
domain should use this value as the pasid for all DMA requests
of the subset of device which is isolated and protected with
this domain.

Cc: Ashok Raj 
Cc: Jacob Pan 
Cc: Kevin Tian 
Signed-off-by: Sanjay Kumar 
Signed-off-by: Liu Yi L 
Signed-off-by: Lu Baolu 
---
 drivers/iommu/intel-iommu.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 8ecf09db6047..b79c72cc5931 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -5684,6 +5684,15 @@ intel_iommu_dev_feat_enabled(struct device *dev, enum 
iommu_dev_features feat)
return false;
 }
 
+static int
+intel_iommu_aux_get_pasid(struct iommu_domain *domain, struct device *dev)
+{
+   struct dmar_domain *dmar_domain = to_dmar_domain(domain);
+
+   return dmar_domain->default_pasid > 0 ?
+   dmar_domain->default_pasid : -EINVAL;
+}
+
 const struct iommu_ops intel_iommu_ops = {
.capable= intel_iommu_capable,
.domain_alloc   = intel_iommu_domain_alloc,
@@ -5692,6 +5701,7 @@ const struct iommu_ops intel_iommu_ops = {
.detach_dev = intel_iommu_detach_device,
.aux_attach_dev = intel_iommu_aux_attach_device,
.aux_detach_dev = intel_iommu_aux_detach_device,
+   .aux_get_pasid  = intel_iommu_aux_get_pasid,
.map= intel_iommu_map,
.unmap  = intel_iommu_unmap,
.iova_to_phys   = intel_iommu_iova_to_phys,
-- 
2.17.1

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


[PATCH v7 5/9] iommu/vt-d: Aux-domain specific domain attach/detach

2019-02-21 Thread Lu Baolu
When multiple domains per device has been enabled by the
device driver, the device will tag the default PASID for
the domain to all DMA traffics out of the subset of this
device; and the IOMMU should translate the DMA requests
in PASID granularity.

This adds the intel_iommu_aux_attach/detach_device() ops
to support managing PASID granular translation structures
when the device driver has enabled multiple domains per
device.

Cc: Ashok Raj 
Cc: Jacob Pan 
Cc: Kevin Tian 
Signed-off-by: Sanjay Kumar 
Signed-off-by: Liu Yi L 
Signed-off-by: Lu Baolu 
---
 drivers/iommu/intel-iommu.c | 152 
 include/linux/intel-iommu.h |  10 +++
 2 files changed, 162 insertions(+)

diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 3d83451a414d..8ecf09db6047 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -2478,6 +2478,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(&info->auxiliary_domains);
 
if (dev && dev_is_pci(dev)) {
struct pci_dev *pdev = to_pci_dev(info->dev);
@@ -5054,6 +5055,131 @@ static void intel_iommu_domain_free(struct iommu_domain 
*domain)
domain_exit(to_dmar_domain(domain));
 }
 
+/*
+ * Check whether a @domain could be attached to the @dev through the
+ * aux-domain attach/detach APIs.
+ */
+static inline bool
+is_aux_domain(struct device *dev, struct iommu_domain *domain)
+{
+   struct device_domain_info *info = dev->archdata.iommu;
+
+   return info && info->auxd_enabled &&
+   domain->type == IOMMU_DOMAIN_UNMANAGED;
+}
+
+static void auxiliary_link_device(struct dmar_domain *domain,
+ struct device *dev)
+{
+   struct device_domain_info *info = dev->archdata.iommu;
+
+   assert_spin_locked(&device_domain_lock);
+   if (WARN_ON(!info))
+   return;
+
+   domain->auxd_refcnt++;
+   list_add(&domain->auxd, &info->auxiliary_domains);
+}
+
+static void auxiliary_unlink_device(struct dmar_domain *domain,
+   struct device *dev)
+{
+   struct device_domain_info *info = dev->archdata.iommu;
+
+   assert_spin_locked(&device_domain_lock);
+   if (WARN_ON(!info))
+   return;
+
+   list_del(&domain->auxd);
+   domain->auxd_refcnt--;
+
+   if (!domain->auxd_refcnt && domain->default_pasid > 0)
+   intel_pasid_free_id(domain->default_pasid);
+}
+
+static int aux_domain_add_dev(struct dmar_domain *domain,
+ struct device *dev)
+{
+   int ret;
+   u8 bus, devfn;
+   unsigned long flags;
+   struct intel_iommu *iommu;
+
+   iommu = device_to_iommu(dev, &bus, &devfn);
+   if (!iommu)
+   return -ENODEV;
+
+   if (domain->default_pasid <= 0) {
+   int pasid;
+
+   pasid = intel_pasid_alloc_id(domain, PASID_MIN,
+pci_max_pasids(to_pci_dev(dev)),
+GFP_KERNEL);
+   if (pasid <= 0) {
+   pr_err("Can't allocate default pasid\n");
+   return -ENODEV;
+   }
+   domain->default_pasid = pasid;
+   }
+
+   spin_lock_irqsave(&device_domain_lock, flags);
+   /*
+* iommu->lock must be held to attach domain to iommu and setup the
+* pasid entry for second level translation.
+*/
+   spin_lock(&iommu->lock);
+   ret = domain_attach_iommu(domain, iommu);
+   if (ret)
+   goto attach_failed;
+
+   /* Setup the PASID entry for mediated devices: */
+   ret = intel_pasid_setup_second_level(iommu, domain, dev,
+domain->default_pasid);
+   if (ret)
+   goto table_failed;
+   spin_unlock(&iommu->lock);
+
+   auxiliary_link_device(domain, dev);
+
+   spin_unlock_irqrestore(&device_domain_lock, flags);
+
+   return 0;
+
+table_failed:
+   domain_detach_iommu(domain, iommu);
+attach_failed:
+   spin_unlock(&iommu->lock);
+   spin_unlock_irqrestore(&device_domain_lock, flags);
+   if (!domain->auxd_refcnt && domain->default_pasid > 0)
+   intel_pasid_free_id(domain->default_pasid);
+
+   return ret;
+}
+
+static void aux_domain_remove_dev(struct dmar_domain *domain,
+ struct device *dev)
+{
+   struct device_domain_info *info;
+   struct intel_iommu *iommu;
+   unsigned long flags;
+
+   if (!is_aux_domain(dev, &domain->domain))
+   return;
+
+   spin_lock_irqsave(&device_domain_lock, flags);
+   info = dev->archdata.iommu;
+   iommu = info->iommu;
+
+   auxiliary_unlink_device(domain, dev);
+
+   spin_loc

[PATCH v7 9/9] vfio/type1: Handle different mdev isolation type

2019-02-21 Thread Lu Baolu
This adds the support to determine the isolation type
of a mediated device group by checking whether it has
an iommu device. If an iommu device exists, an iommu
domain will be allocated and then attached to the iommu
device. Otherwise, keep the same behavior as it is.

Cc: Ashok Raj 
Cc: Jacob Pan 
Cc: Kevin Tian 
Signed-off-by: Sanjay Kumar 
Signed-off-by: Liu Yi L 
Signed-off-by: Lu Baolu 
Reviewed-by: Jean-Philippe Brucker 
---
 drivers/vfio/vfio_iommu_type1.c | 48 -
 1 file changed, 41 insertions(+), 7 deletions(-)

diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
index ccc4165474aa..f1392c582a3c 100644
--- a/drivers/vfio/vfio_iommu_type1.c
+++ b/drivers/vfio/vfio_iommu_type1.c
@@ -1368,13 +1368,40 @@ static void vfio_iommu_detach_group(struct vfio_domain 
*domain,
iommu_detach_group(domain->domain, group->iommu_group);
 }
 
+static bool vfio_bus_is_mdev(struct bus_type *bus)
+{
+   struct bus_type *mdev_bus;
+   bool ret = false;
+
+   mdev_bus = symbol_get(mdev_bus_type);
+   if (mdev_bus) {
+   ret = (bus == mdev_bus);
+   symbol_put(mdev_bus_type);
+   }
+
+   return ret;
+}
+
+static int vfio_mdev_iommu_device(struct device *dev, void *data)
+{
+   struct device **old = data, *new;
+
+   new = vfio_mdev_get_iommu_device(dev);
+   if (!new || (*old && *old != new))
+   return -EINVAL;
+
+   *old = new;
+
+   return 0;
+}
+
 static int vfio_iommu_type1_attach_group(void *iommu_data,
 struct iommu_group *iommu_group)
 {
struct vfio_iommu *iommu = iommu_data;
struct vfio_group *group;
struct vfio_domain *domain, *d;
-   struct bus_type *bus = NULL, *mdev_bus;
+   struct bus_type *bus = NULL;
int ret;
bool resv_msi, msi_remap;
phys_addr_t resv_msi_base;
@@ -1409,23 +1436,30 @@ static int vfio_iommu_type1_attach_group(void 
*iommu_data,
if (ret)
goto out_free;
 
-   mdev_bus = symbol_get(mdev_bus_type);
+   if (vfio_bus_is_mdev(bus)) {
+   struct device *iommu_device = NULL;
 
-   if (mdev_bus) {
-   if ((bus == mdev_bus) && !iommu_present(bus)) {
-   symbol_put(mdev_bus_type);
+   group->mdev_group = true;
+
+   /* Determine the isolation type */
+   ret = iommu_group_for_each_dev(iommu_group, &iommu_device,
+  vfio_mdev_iommu_device);
+   if (ret || !iommu_device) {
if (!iommu->external_domain) {
INIT_LIST_HEAD(&domain->group_list);
iommu->external_domain = domain;
-   } else
+   } else {
kfree(domain);
+   }
 
list_add(&group->next,
 &iommu->external_domain->group_list);
mutex_unlock(&iommu->lock);
+
return 0;
}
-   symbol_put(mdev_bus_type);
+
+   bus = iommu_device->bus;
}
 
domain->domain = iommu_domain_alloc(bus);
-- 
2.17.1

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


[PATCH v7 7/9] vfio/mdev: Add iommu related member in mdev_device

2019-02-21 Thread Lu Baolu
A parent device might create different types of mediated
devices. For example, a mediated device could be created
by the parent device with full isolation and protection
provided by the IOMMU. One usage case could be found on
Intel platforms where a mediated device is an assignable
subset of a PCI, the DMA requests on behalf of it are all
tagged with a PASID. Since IOMMU supports PASID-granular
translations (scalable mode in VT-d 3.0), this mediated
device could be individually protected and isolated by an
IOMMU.

This patch adds a new member in the struct mdev_device to
indicate that the mediated device represented by mdev could
be isolated and protected by attaching a domain to a device
represented by mdev->iommu_device. It also adds a helper to
add or set the iommu device.

* mdev_device->iommu_device
  - This, if set, indicates that the mediated device could
be fully isolated and protected by IOMMU via attaching
an iommu domain to this device. If empty, it indicates
using vendor defined isolation, hence bypass IOMMU.

* mdev_set/get_iommu_device(dev, iommu_device)
  - Set or get the iommu device which represents this mdev
in IOMMU's device scope. Drivers don't need to set the
iommu device if it uses vendor defined isolation.

Cc: Ashok Raj 
Cc: Jacob Pan 
Cc: Kevin Tian 
Cc: Liu Yi L 
Suggested-by: Kevin Tian 
Suggested-by: Alex Williamson 
Signed-off-by: Lu Baolu 
Reviewed-by: Jean-Philippe Brucker 
---
 drivers/vfio/mdev/mdev_core.c| 18 ++
 drivers/vfio/mdev/mdev_private.h |  1 +
 include/linux/mdev.h | 14 ++
 3 files changed, 33 insertions(+)

diff --git a/drivers/vfio/mdev/mdev_core.c b/drivers/vfio/mdev/mdev_core.c
index 0212f0ee8aea..9be58d392d2b 100644
--- a/drivers/vfio/mdev/mdev_core.c
+++ b/drivers/vfio/mdev/mdev_core.c
@@ -390,6 +390,24 @@ int mdev_device_remove(struct device *dev, bool 
force_remove)
return 0;
 }
 
+int mdev_set_iommu_device(struct device *dev, struct device *iommu_device)
+{
+   struct mdev_device *mdev = to_mdev_device(dev);
+
+   mdev->iommu_device = iommu_device;
+
+   return 0;
+}
+EXPORT_SYMBOL(mdev_set_iommu_device);
+
+struct device *mdev_get_iommu_device(struct device *dev)
+{
+   struct mdev_device *mdev = to_mdev_device(dev);
+
+   return mdev->iommu_device;
+}
+EXPORT_SYMBOL(mdev_get_iommu_device);
+
 static int __init mdev_init(void)
 {
return mdev_bus_register();
diff --git a/drivers/vfio/mdev/mdev_private.h b/drivers/vfio/mdev/mdev_private.h
index b5819b7d7ef7..891841862ef8 100644
--- a/drivers/vfio/mdev/mdev_private.h
+++ b/drivers/vfio/mdev/mdev_private.h
@@ -34,6 +34,7 @@ struct mdev_device {
struct list_head next;
struct kobject *type_kobj;
bool active;
+   struct device *iommu_device;
 };
 
 #define to_mdev_device(dev)container_of(dev, struct mdev_device, dev)
diff --git a/include/linux/mdev.h b/include/linux/mdev.h
index b6e048e1045f..c3ab8a9cfcc7 100644
--- a/include/linux/mdev.h
+++ b/include/linux/mdev.h
@@ -15,6 +15,20 @@
 
 struct mdev_device;
 
+/*
+ * Called by the parent device driver to set the device which represents
+ * this mdev in iommu protection scope. By default, the iommu device is
+ * NULL, that indicates using vendor defined isolation.
+ *
+ * @dev: the mediated device that iommu will isolate.
+ * @iommu_device: a pci device which represents the iommu for @dev.
+ *
+ * Return 0 for success, otherwise negative error value.
+ */
+int mdev_set_iommu_device(struct device *dev, struct device *iommu_device);
+
+struct device *mdev_get_iommu_device(struct device *dev);
+
 /**
  * struct mdev_parent_ops - Structure to be registered for each parent device 
to
  * register the device to mdev module.
-- 
2.17.1

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


[PATCH v7 3/9] iommu/vt-d: Add per-device IOMMU feature ops entries

2019-02-21 Thread Lu Baolu
This adds the iommu ops entries for aux-domain per-device
feature query and enable/disable.

Cc: Ashok Raj 
Cc: Jacob Pan 
Cc: Kevin Tian 
Signed-off-by: Sanjay Kumar 
Signed-off-by: Liu Yi L 
Signed-off-by: Lu Baolu 
---
 drivers/iommu/intel-iommu.c | 159 
 include/linux/intel-iommu.h |   1 +
 2 files changed, 160 insertions(+)

diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index c4e0024c9736..a7e2238f869a 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -2477,6 +2477,7 @@ static struct dmar_domain 
*dmar_insert_one_dev_info(struct intel_iommu *iommu,
info->domain = domain;
info->iommu = iommu;
info->pasid_table = NULL;
+   info->auxd_enabled = 0;
 
if (dev && dev_is_pci(dev)) {
struct pci_dev *pdev = to_pci_dev(info->dev);
@@ -5211,6 +5212,42 @@ 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 bool intel_iommu_capable(enum iommu_cap cap)
 {
if (cap == IOMMU_CAP_CACHE_COHERENCY)
@@ -5367,6 +5404,124 @@ struct intel_iommu *intel_svm_device_to_iommu(struct 
device *dev)
 }
 #endif /* CONFIG_INTEL_IOMMU_SVM */
 
+static int intel_iommu_enable_auxd(struct device *dev)
+{
+   struct device_domain_info *info;
+   struct intel_iommu *iommu;
+   unsigned long flags;
+   u8 bus, devfn;
+   int ret;
+
+   iommu = device_to_iommu(dev, &bus, &devfn);
+   if (!iommu || dmar_disabled)
+   return -EINVAL;
+
+   if (!sm_supported(iommu) || !pasid_supported(iommu))
+   return -EINVAL;
+
+   ret = intel_iommu_enable_pasid(iommu, dev);
+   if (ret)
+   return -ENODEV;
+
+   spin_lock_irqsave(&device_domain_lock, flags);
+   info = dev->archdata.iommu;
+   info->auxd_enabled = 1;
+   spin_unlock_irqrestore(&device_domain_lock, flags);
+
+   return 0;
+}
+
+static int intel_iommu_disable_auxd(struct device *dev)
+{
+   struct device_domain_info *info;
+   unsigned long flags;
+
+   spin_lock_irqsave(&device_domain_lock, flags);
+   info = dev->archdata.iommu;
+   if (!WARN_ON(!info))
+   info->auxd_enabled = 0;
+   spin_unlock_irqrestore(&device_domain_lock, flags);
+
+   return 0;
+}
+
+/*
+ * 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, &vendor);
+   pci_read_config_word(pdev, pos + 8, &id);
+   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)
+{
+   if (feat == IOMMU_DEV_FEAT_AUX) {
+   int ret;
+
+   if (!dev_is_pci(dev) || dmar_disabled ||
+   !scalable_mode_support() || !iommu_pasid_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));
+   }
+
+   return false;
+}
+
+static int
+intel_iommu_dev_enable_feat(struct device *dev, enum iommu_dev_features feat)
+{
+   if (feat == IOMMU_DEV_FEAT_AUX)
+   return intel_iommu_enable_auxd(dev);
+
+   return -ENODEV;
+}
+
+static int
+intel_iommu_dev_disable_feat(struct device *dev, enum io

[PATCH v7 1/9] iommu: Add APIs for multiple domains per device

2019-02-21 Thread Lu Baolu
Sharing a physical PCI device in a finer-granularity way
is becoming a consensus in the industry. IOMMU vendors
are also engaging efforts to support such sharing as well
as possible. Among the efforts, the capability of support
finer-granularity DMA isolation is a common requirement
due to the security consideration. With finer-granularity
DMA isolation, subsets of a PCI function can be isolated
from each others by the IOMMU. As a result, there is a
request in software to attach multiple domains to a physical
PCI device. One example of such use model is the Intel
Scalable IOV [1] [2]. The Intel vt-d 3.0 spec [3] introduces
the scalable mode which enables PASID granularity DMA
isolation.

This adds the APIs to support multiple domains per device.
In order to ease the discussions, we call it 'a domain in
auxiliary mode' or simply 'auxiliary domain' when multiple
domains are attached to a physical device.

The APIs include:

* iommu_dev_has_feature(dev, IOMMU_DEV_FEAT_AUX)
  - Detect both IOMMU and PCI endpoint devices supporting
the feature (aux-domain here) without the host driver
dependency.

* iommu_dev_feature_enabled(dev, IOMMU_DEV_FEAT_AUX)
  - Check the enabling status of the feature (aux-domain
here). The aux-domain interfaces are available only
if this returns true.
* iommu_dev_enable/disable_feature(dev, IOMMU_DEV_FEAT_AUX)
  - Enable/disable device specific aux-domain feature.

* iommu_aux_attach_device(domain, dev)
  - Attaches @domain to @dev in the auxiliary mode. Multiple
domains could be attached to a single device in the
auxiliary mode with each domain representing an isolated
address space for an assignable subset of the device.

* iommu_aux_detach_device(domain, dev)
  - Detach @domain which has been attached to @dev in the
auxiliary mode.

* iommu_aux_get_pasid(domain, dev)
  - Return ID used for finer-granularity DMA translation.
For the Intel Scalable IOV usage model, this will be
a PASID. The device which supports Scalable IOV needs
to write this ID to the device register so that DMA
requests could be tagged with a right PASID prefix.

This has been updated with the latest proposal from Joerg
posted here [5].

Many people involved in discussions of this design.

Kevin Tian 
Liu Yi L 
Ashok Raj 
Sanjay Kumar 
Jacob Pan 
Alex Williamson 
Jean-Philippe Brucker 
Joerg Roedel 

and some discussions can be found here [4] [5].

[1] 
https://software.intel.com/en-us/download/intel-scalable-io-virtualization-technical-specification
[2] https://schd.ws/hosted_files/lc32018/00/LC3-SIOV-final.pdf
[3] 
https://software.intel.com/en-us/download/intel-virtualization-technology-for-directed-io-architecture-specification
[4] https://lkml.org/lkml/2018/7/26/4
[5] https://www.spinics.net/lists/iommu/msg31874.html

Cc: Ashok Raj 
Cc: Jacob Pan 
Cc: Kevin Tian 
Cc: Liu Yi L 
Suggested-by: Kevin Tian 
Suggested-by: Jean-Philippe Brucker 
Suggested-by: Joerg Roedel 
Signed-off-by: Lu Baolu 
Reviewed-by: Jean-Philippe Brucker 
---
 drivers/iommu/iommu.c | 96 +++
 include/linux/iommu.h | 70 +++
 2 files changed, 166 insertions(+)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 3ed4db334341..4ad8ff91d742 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -2033,3 +2033,99 @@ int iommu_fwspec_add_ids(struct device *dev, u32 *ids, 
int num_ids)
return 0;
 }
 EXPORT_SYMBOL_GPL(iommu_fwspec_add_ids);
+
+/*
+ * Per device IOMMU features.
+ */
+bool iommu_dev_has_feature(struct device *dev, enum iommu_dev_features feat)
+{
+   const struct iommu_ops *ops = dev->bus->iommu_ops;
+
+   if (ops && ops->dev_has_feat)
+   return ops->dev_has_feat(dev, feat);
+
+   return false;
+}
+EXPORT_SYMBOL_GPL(iommu_dev_has_feature);
+
+int iommu_dev_enable_feature(struct device *dev, enum iommu_dev_features feat)
+{
+   const struct iommu_ops *ops = dev->bus->iommu_ops;
+
+   if (ops && ops->dev_enable_feat)
+   return ops->dev_enable_feat(dev, feat);
+
+   return -ENODEV;
+}
+EXPORT_SYMBOL_GPL(iommu_dev_enable_feature);
+
+/*
+ * The device drivers should do the necessary cleanups before calling this.
+ * For example, before disabling the aux-domain feature, the device driver
+ * should detach all aux-domains. Otherwise, this will return -EBUSY.
+ */
+int iommu_dev_disable_feature(struct device *dev, enum iommu_dev_features feat)
+{
+   const struct iommu_ops *ops = dev->bus->iommu_ops;
+
+   if (ops && ops->dev_disable_feat)
+   return ops->dev_disable_feat(dev, feat);
+
+   return -EBUSY;
+}
+EXPORT_SYMBOL_GPL(iommu_dev_disable_feature);
+
+bool iommu_dev_feature_enabled(struct device *dev, enum iommu_dev_features 
feat)
+{
+   const struct iommu_ops *ops = dev->bus->iommu_ops;
+
+   if (ops && ops->dev_feat_enabled)
+   return ops->dev_feat_enabled(dev, feat);
+
+   return false;
+

[PATCH v7 2/9] iommu/vt-d: Move enable pasid out of CONFIG_INTEL_IOMMU_SVM

2019-02-21 Thread Lu Baolu
This moves intel_iommu_enable_pasid() out of the scope of
CONFIG_INTEL_IOMMU_SVM with more and more features requiring
pasid function.

Cc: Ashok Raj 
Cc: Jacob Pan 
Cc: Kevin Tian 
Signed-off-by: Lu Baolu 
---
 drivers/iommu/intel-iommu.c | 22 +++---
 drivers/iommu/intel-svm.c   | 19 ++-
 include/linux/intel-iommu.h |  2 +-
 3 files changed, 26 insertions(+), 17 deletions(-)

diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index af23cfc2a05e..c4e0024c9736 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -5295,8 +5295,7 @@ static void intel_iommu_put_resv_regions(struct device 
*dev,
}
 }
 
-#ifdef CONFIG_INTEL_IOMMU_SVM
-int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct intel_svm_dev 
*sdev)
+int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct device *dev)
 {
struct device_domain_info *info;
struct context_entry *context;
@@ -5305,7 +5304,7 @@ int intel_iommu_enable_pasid(struct intel_iommu *iommu, 
struct intel_svm_dev *sd
u64 ctx_lo;
int ret;
 
-   domain = get_valid_domain_for_dev(sdev->dev);
+   domain = get_valid_domain_for_dev(dev);
if (!domain)
return -EINVAL;
 
@@ -5313,7 +5312,7 @@ int intel_iommu_enable_pasid(struct intel_iommu *iommu, 
struct intel_svm_dev *sd
spin_lock(&iommu->lock);
 
ret = -EINVAL;
-   info = sdev->dev->archdata.iommu;
+   info = dev->archdata.iommu;
if (!info || !info->pasid_supported)
goto out;
 
@@ -5322,15 +5321,13 @@ int intel_iommu_enable_pasid(struct intel_iommu *iommu, 
struct intel_svm_dev *sd
goto out;
 
ctx_lo = context[0].lo;
-
-   sdev->did = domain->iommu_did[iommu->seq_id];
-   sdev->sid = PCI_DEVID(info->bus, info->devfn);
-
if (!(ctx_lo & CONTEXT_PASIDE)) {
ctx_lo |= CONTEXT_PASIDE;
context[0].lo = ctx_lo;
wmb();
-   iommu->flush.flush_context(iommu, sdev->did, sdev->sid,
+   iommu->flush.flush_context(iommu,
+  domain->iommu_did[iommu->seq_id],
+  PCI_DEVID(info->bus, info->devfn),
   DMA_CCMD_MASK_NOBIT,
   DMA_CCMD_DEVICE_INVL);
}
@@ -5339,12 +5336,6 @@ int intel_iommu_enable_pasid(struct intel_iommu *iommu, 
struct intel_svm_dev *sd
if (!info->pasid_enabled)
iommu_enable_dev_iotlb(info);
 
-   if (info->ats_enabled) {
-   sdev->dev_iotlb = 1;
-   sdev->qdep = info->ats_qdep;
-   if (sdev->qdep >= QI_DEV_EIOTLB_MAX_INVS)
-   sdev->qdep = 0;
-   }
ret = 0;
 
  out:
@@ -5354,6 +5345,7 @@ int intel_iommu_enable_pasid(struct intel_iommu *iommu, 
struct intel_svm_dev *sd
return ret;
 }
 
+#ifdef CONFIG_INTEL_IOMMU_SVM
 struct intel_iommu *intel_svm_device_to_iommu(struct device *dev)
 {
struct intel_iommu *iommu;
diff --git a/drivers/iommu/intel-svm.c b/drivers/iommu/intel-svm.c
index c79540deaf00..ecc255ddf6ae 100644
--- a/drivers/iommu/intel-svm.c
+++ b/drivers/iommu/intel-svm.c
@@ -228,6 +228,7 @@ static LIST_HEAD(global_svm_list);
 int intel_svm_bind_mm(struct device *dev, int *pasid, int flags, struct 
svm_dev_ops *ops)
 {
struct intel_iommu *iommu = intel_svm_device_to_iommu(dev);
+   struct device_domain_info *info;
struct intel_svm_dev *sdev;
struct intel_svm *svm = NULL;
struct mm_struct *mm = NULL;
@@ -291,13 +292,29 @@ int intel_svm_bind_mm(struct device *dev, int *pasid, int 
flags, struct svm_dev_
}
sdev->dev = dev;
 
-   ret = intel_iommu_enable_pasid(iommu, sdev);
+   ret = intel_iommu_enable_pasid(iommu, dev);
if (ret || !pasid) {
/* If they don't actually want to assign a PASID, this is
 * just an enabling check/preparation. */
kfree(sdev);
goto out;
}
+
+   info = dev->archdata.iommu;
+   if (!info || !info->pasid_supported) {
+   kfree(sdev);
+   goto out;
+   }
+
+   sdev->did = info->domain->iommu_did[iommu->seq_id];
+   sdev->sid = PCI_DEVID(info->bus, info->devfn);
+   if (info->ats_enabled) {
+   sdev->dev_iotlb = 1;
+   sdev->qdep = info->ats_qdep;
+   if (sdev->qdep >= QI_DEV_EIOTLB_MAX_INVS)
+   sdev->qdep = 0;
+   }
+
/* Finish the setup now we know we're keeping it */
sdev->users = 1;
sdev->ops = ops;
diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h
index fa364de9db18..b7d1e2fbb9ca 100644
--- a/include/linux/intel-iommu.h
+++ b/include/linux/intel-iommu.h
@@ -650,6 +650,7 @@ struct intel_iommu *domain_get_iommu(struct dmar_domain 
*dom

[PATCH v7 0/9] vfio/mdev: IOMMU aware mediated device

2019-02-21 Thread Lu Baolu
Hi,

The Mediate Device is a framework for fine-grained physical device
sharing across the isolated domains. Currently the mdev framework
is designed to be independent of the platform IOMMU support. As the
result, the DMA isolation relies on the mdev parent device in a
vendor specific way.

There are several cases where a mediated device could be protected
and isolated by the platform IOMMU. For example, Intel vt-d rev3.0
[1] introduces a new translation mode called 'scalable mode', which
enables PASID-granular translations. The vt-d scalable mode is the
key ingredient for Scalable I/O Virtualization [2] [3] which allows
sharing a device in minimal possible granularity (ADI - Assignable
Device Interface).

A mediated device backed by an ADI could be protected and isolated
by the IOMMU since 1) the parent device supports tagging an unique
PASID to all DMA traffic out of the mediated device; and 2) the DMA
translation unit (IOMMU) supports the PASID granular translation.
We can apply IOMMU protection and isolation to this kind of devices
just as what we are doing with an assignable PCI device.

In order to distinguish the IOMMU-capable mediated devices from those
which still need to rely on parent devices, this patch set adds one
new member in struct mdev_device.

* iommu_device
  - This, if set, indicates that the mediated device could
be fully isolated and protected by IOMMU via attaching
an iommu domain to this device. If empty, it indicates
using vendor defined isolation.

Below helpers are added to set and get above iommu device in mdev core
implementation.

* mdev_set/get_iommu_device(dev, iommu_device)
  - Set or get the iommu device which represents this mdev
in IOMMU's device scope. Drivers don't need to set the
iommu device if it uses vendor defined isolation.

The mdev parent device driver could opt-in that the mdev could be
fully isolated and protected by the IOMMU when the mdev is being
created by invoking mdev_set_iommu_device() in its @create().

In the vfio_iommu_type1_attach_group(), a domain allocated through
iommu_domain_alloc() will be attached to the mdev iommu device if
an iommu device has been set. Otherwise, the dummy external domain
will be used and all the DMA isolation and protection are routed to
parent driver as the result.

On IOMMU side, a basic requirement is allowing to attach multiple
domains to a PCI device if the device advertises the capability
and the IOMMU hardware supports finer granularity translations than
the normal PCI Source ID based translation.

As the result, a PCI device could work in two modes: normal mode
and auxiliary mode. In the normal mode, a pci device could be
isolated in the Source ID granularity; the pci device itself could
be assigned to a user application by attaching a single domain
to it. In the auxiliary mode, a pci device could be isolated in
finer granularity, hence subsets of the device could be assigned
to different user level application by attaching a different domain
to each subset.

Below APIs are introduced in iommu generic layer for aux-domain
purpose:

* iommu_dev_has_feature(dev, IOMMU_DEV_FEAT_AUX)
  - Detect both IOMMU and PCI endpoint devices supporting
the feature (aux-domain here) without the host driver
dependency.

* iommu_dev_feature_enabled(dev, IOMMU_DEV_FEAT_AUX)
  - Check the enabling status of the feature (aux-domain
here). The aux-domain interfaces are available only
if this returns true.

* iommu_dev_enable/disable_feature(dev, IOMMU_DEV_FEAT_AUX)
  - Enable/disable device specific aux-domain feature.

* iommu_aux_attach_device(domain, dev)
  - Attaches @domain to @dev in the auxiliary mode. Multiple
domains could be attached to a single device in the
auxiliary mode with each domain representing an isolated
address space for an assignable subset of the device.

* iommu_aux_detach_device(domain, dev)
  - Detach @domain which has been attached to @dev in the
auxiliary mode.

* iommu_aux_get_pasid(domain, dev)
  - Return ID used for finer-granularity DMA translation.
For the Intel Scalable IOV usage model, this will be
a PASID. The device which supports Scalable IOV needs
to write this ID to the device register so that DMA
requests could be tagged with a right PASID prefix.

In order for the ease of discussion, sometimes we call "a domain in
auxiliary mode' or simply 'an auxiliary domain' when a domain is
attached to a device for finer granularity translations. But we need
to keep in mind that this doesn't mean there is a differnt domain
type. A same domain could be bound to a device for Source ID based
translation, and bound to another device for finer granularity
translation at the same time.

This patch series extends both IOMMU and vfio components to support
mdev device passing through when it could be isolated and protected
by the IOMMU units. The first part of this series (PATCH 1/09~6/09)
adds the interfaces and implementation of the multiple domai

[PATCH v7 4/9] iommu/vt-d: Move common code out of iommu_attch_device()

2019-02-21 Thread Lu Baolu
This part of code could be used by both normal and aux
domain specific attach entries. Hence move them into a
common function to avoid duplication.

Cc: Ashok Raj 
Cc: Jacob Pan 
Cc: Kevin Tian 
Signed-off-by: Lu Baolu 
---
 drivers/iommu/intel-iommu.c | 60 ++---
 1 file changed, 36 insertions(+), 24 deletions(-)

diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index a7e2238f869a..3d83451a414d 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -5054,35 +5054,14 @@ static void intel_iommu_domain_free(struct iommu_domain 
*domain)
domain_exit(to_dmar_domain(domain));
 }
 
-static int intel_iommu_attach_device(struct iommu_domain *domain,
-struct device *dev)
+static int prepare_domain_attach_device(struct iommu_domain *domain,
+   struct device *dev)
 {
struct dmar_domain *dmar_domain = to_dmar_domain(domain);
struct intel_iommu *iommu;
int addr_width;
u8 bus, devfn;
 
-   if (device_is_rmrr_locked(dev)) {
-   dev_warn(dev, "Device is ineligible for IOMMU domain attach due 
to platform RMRR requirement.  Contact your platform vendor.\n");
-   return -EPERM;
-   }
-
-   /* normally dev is not mapped */
-   if (unlikely(domain_context_mapped(dev))) {
-   struct dmar_domain *old_domain;
-
-   old_domain = find_domain(dev);
-   if (old_domain) {
-   rcu_read_lock();
-   dmar_remove_one_dev_info(dev);
-   rcu_read_unlock();
-
-   if (!domain_type_is_vm_or_si(old_domain) &&
-list_empty(&old_domain->devices))
-   domain_exit(old_domain);
-   }
-   }
-
iommu = device_to_iommu(dev, &bus, &devfn);
if (!iommu)
return -ENODEV;
@@ -5115,7 +5094,40 @@ static int intel_iommu_attach_device(struct iommu_domain 
*domain,
dmar_domain->agaw--;
}
 
-   return domain_add_dev_info(dmar_domain, dev);
+   return 0;
+}
+
+static int intel_iommu_attach_device(struct iommu_domain *domain,
+struct device *dev)
+{
+   int ret;
+
+   if (device_is_rmrr_locked(dev)) {
+   dev_warn(dev, "Device is ineligible for IOMMU domain attach due 
to platform RMRR requirement.  Contact your platform vendor.\n");
+   return -EPERM;
+   }
+
+   /* normally dev is not mapped */
+   if (unlikely(domain_context_mapped(dev))) {
+   struct dmar_domain *old_domain;
+
+   old_domain = find_domain(dev);
+   if (old_domain) {
+   rcu_read_lock();
+   dmar_remove_one_dev_info(dev);
+   rcu_read_unlock();
+
+   if (!domain_type_is_vm_or_si(old_domain) &&
+   list_empty(&old_domain->devices))
+   domain_exit(old_domain);
+   }
+   }
+
+   ret = prepare_domain_attach_device(domain, dev);
+   if (ret)
+   return ret;
+
+   return domain_add_dev_info(to_dmar_domain(domain), dev);
 }
 
 static void intel_iommu_detach_device(struct iommu_domain *domain,
-- 
2.17.1

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


Re: [PATCHv7] x86/kdump: bugfix, make the behavior of crashkernel=X consistent with kaslr

2019-02-21 Thread Dave Young
On 02/21/19 at 06:13pm, Borislav Petkov wrote:
> On Wed, Feb 20, 2019 at 05:41:46PM +0800, Dave Young wrote:
> > Previously Joerg posted below patch, maybe he has some idea. Joerg?
> 
> Isn't it clear from the commit message?

Then, does it answered your question?

256M is set as a default value in the patch, but it is not a predict to
satisfy all use cases, from the description it is also possible that some
people run out of the 256M and the ,low and ,high format is still
necessary to exist even if we make crashkernel=X do the allocation
automatically in high in case failed in low area.

crashkernel=X:  allocate in low first, if not possible, then allocate in
high

In case people have a lot of devices need more swiotlb, then he manually
set the ,high with ,low together.

What's your suggestion then?  remove ,low and ,high and increase default
256M in case we get failure bug report?
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v6 0/9] vfio/mdev: IOMMU aware mediated device

2019-02-21 Thread Lu Baolu

Hi,

On 2/15/19 4:14 AM, Alex Williamson wrote:

On Wed, 13 Feb 2019 12:02:52 +0800
Lu Baolu  wrote:


Hi,

The Mediate Device is a framework for fine-grained physical device
sharing across the isolated domains. Currently the mdev framework
is designed to be independent of the platform IOMMU support. As the
result, the DMA isolation relies on the mdev parent device in a
vendor specific way.

There are several cases where a mediated device could be protected
and isolated by the platform IOMMU. For example, Intel vt-d rev3.0
[1] introduces a new translation mode called 'scalable mode', which
enables PASID-granular translations. The vt-d scalable mode is the
key ingredient for Scalable I/O Virtualization [2] [3] which allows
sharing a device in minimal possible granularity (ADI - Assignable
Device Interface).

A mediated device backed by an ADI could be protected and isolated
by the IOMMU since 1) the parent device supports tagging an unique
PASID to all DMA traffic out of the mediated device; and 2) the DMA
translation unit (IOMMU) supports the PASID granular translation.
We can apply IOMMU protection and isolation to this kind of devices
just as what we are doing with an assignable PCI device.

In order to distinguish the IOMMU-capable mediated devices from those
which still need to rely on parent devices, this patch set adds one
new member in struct mdev_device.

* iommu_device
   - This, if set, indicates that the mediated device could
 be fully isolated and protected by IOMMU via attaching
 an iommu domain to this device. If empty, it indicates
 using vendor defined isolation.

Below helpers are added to set and get above iommu device in mdev core
implementation.

* mdev_set/get_iommu_device(dev, iommu_device)
   - Set or get the iommu device which represents this mdev
 in IOMMU's device scope. Drivers don't need to set the
 iommu device if it uses vendor defined isolation.

The mdev parent device driver could opt-in that the mdev could be
fully isolated and protected by the IOMMU when the mdev is being
created by invoking mdev_set_iommu_device() in its @create().

In the vfio_iommu_type1_attach_group(), a domain allocated through
iommu_domain_alloc() will be attached to the mdev iommu device if
an iommu device has been set. Otherwise, the dummy external domain
will be used and all the DMA isolation and protection are routed to
parent driver as the result.

On IOMMU side, a basic requirement is allowing to attach multiple
domains to a PCI device if the device advertises the capability
and the IOMMU hardware supports finer granularity translations than
the normal PCI Source ID based translation.

As the result, a PCI device could work in two modes: normal mode
and auxiliary mode. In the normal mode, a pci device could be
isolated in the Source ID granularity; the pci device itself could
be assigned to a user application by attaching a single domain
to it. In the auxiliary mode, a pci device could be isolated in
finer granularity, hence subsets of the device could be assigned
to different user level application by attaching a different domain
to each subset.

Below APIs are introduced in iommu generic layer for aux-domain
purpose:

* iommu_dev_has_feature(dev, IOMMU_DEV_FEAT_AUX)
   - Check whether both IOMMU and device support IOMMU aux
 domain feature. Below aux-domain specific interfaces
 are available only after this returns true.

* iommu_dev_enable/disable_feature(dev, IOMMU_DEV_FEAT_AUX)
   - Enable/disable device specific aux-domain feature.

* iommu_dev_feature_enabled(dev, IOMMU_DEV_FEAT_AUX)
   - Check whether the aux domain specific feature enabled or
 not.

* iommu_aux_attach_device(domain, dev)
   - Attaches @domain to @dev in the auxiliary mode. Multiple
 domains could be attached to a single device in the
 auxiliary mode with each domain representing an isolated
 address space for an assignable subset of the device.

* iommu_aux_detach_device(domain, dev)
   - Detach @domain which has been attached to @dev in the
 auxiliary mode.

* iommu_aux_get_pasid(domain, dev)
   - Return ID used for finer-granularity DMA translation.
 For the Intel Scalable IOV usage model, this will be
 a PASID. The device which supports Scalable IOV needs
 to write this ID to the device register so that DMA
 requests could be tagged with a right PASID prefix.

In order for the ease of discussion, sometimes we call "a domain in
auxiliary mode' or simply 'an auxiliary domain' when a domain is
attached to a device for finer granularity translations. But we need
to keep in mind that this doesn't mean there is a differnt domain
type. A same domain could be bound to a device for Source ID based
translation, and bound to another device for finer granularity
translation at the same time.

This patch series extends both IOMMU and vfio components to support
mdev device passing through when it could be isolated and protected
by the IOMMU units. The first part of 

Re: [PATCH v7 0/7] Add virtio-iommu driver

2019-02-21 Thread Thiago Jung Bauermann

Hello Jean-Philippe,

Jean-Philippe Brucker  writes:
> Makes sense, though I think other virtio devices have been developed a
> little more organically: device and driver code got upstreamed first,
> and then the specification describing their interface got merged into
> the standard. For example I believe that code for crypto, input and GPU
> devices were upstreamed long before the specification was merged. Once
> an implementation is upstream, the interface is expected to be
> backward-compatible (all subsequent changes are introduced using feature
> bits).
>
> So I've been working with this process in mind, also described by Jens
> at KVM forum 2017 [3]:
> (1) Reserve a device ID, and get that merged into virtio (ID 23 for
> virtio-iommu was reserved last year)
> (2) Open-source an implementation (this driver and Eric's device)
> (3) Formalize and upstream the device specification
>
> But I get that some overlap between (2) and (3) would have been better.
> So far the spec document has been reviewed mainly from the IOMMU point
> of view, and might require more changes to be in line with the other
> virtio devices -- hopefully just wording changes. I'll kick off step
> (3), but I think the virtio folks are a bit busy with finalizing the 1.1
> spec so I expect it to take a while.

I read v0.9 of the spec and have some minor comments, hope this is a
good place to send them:

1. In section 2.6.2, one reads

If the VIRTIO_IOMMU_F_INPUT_RANGE feature is offered and the range
described by fields virt_start and virt_end doesn’t fit in the range
described by input_range, the device MAY set status to VIRTIO_-
IOMMU_S_RANGE and ignore the request.

Shouldn't int say "If the VIRTIO_IOMMU_F_INPUT_RANGE feature is
negotiated" instead?

2. There's a typo at the end of section 2.6.5:

The VIRTIO_IOMMU_MAP_F_MMIO flag is a memory type rather than a
protection lag.

s/lag/flag/

3. In section 3.1.2.1.1, the viommu compatible field says "virtio,mmio".
Shouldn't it say "virtio,mmio-iommu" instead, to be consistent with
"virtio,pci-iommu"?

4. There's a typo in section 3.3:

A host bridge may limit the input address space – transaction
accessing some addresses won’t reach the physical IOMMU.

s/transaction/transactions/

I also have one last comment which you may freely ignore, considering
it's clearly just personal opinion and also considering that the
specification is mature at this point: it specifies memory ranges by
specifying start and end addresses. My experience has been that this is
error prone, leading to confusion and bugs regarding whether the end
address is inclusive or exclusive. I tend to prefer expressing memory
ranges by specifying a start address and a length, which eliminates
ambiguity.

--
Thiago Jung Bauermann
IBM Linux Technology Center

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

Re: [PATCH v7 0/7] Add virtio-iommu driver

2019-02-21 Thread Thiago Jung Bauermann


Michael S. Tsirkin  writes:

> On Mon, Jan 21, 2019 at 11:29:05AM +, Jean-Philippe Brucker wrote:
>> Hi,
>>
>> On 18/01/2019 15:51, Michael S. Tsirkin wrote:
>> >
>> > On Tue, Jan 15, 2019 at 12:19:52PM +, Jean-Philippe Brucker wrote:
>> >> Implement the virtio-iommu driver, following specification v0.9 [1].
>> >>
>> >> This is a simple rebase onto Linux v5.0-rc2. We now use the
>> >> dev_iommu_fwspec_get() helper introduced in v5.0 instead of accessing
>> >> dev->iommu_fwspec, but there aren't any functional change from v6 [2].
>> >>
>> >> Our current goal for virtio-iommu is to get a paravirtual IOMMU working
>> >> on Arm, and enable device assignment to guest userspace. In this
>> >> use-case the mappings are static, and don't require optimal performance,
>> >> so this series tries to keep things simple. However there is plenty more
>> >> to do for features and optimizations, and having this base in v5.1 would
>> >> be good. Given that most of the changes are to drivers/iommu, I believe
>> >> the driver and future changes should go via the IOMMU tree.
>> >>
>> >> You can find Linux driver and kvmtool device on v0.9.2 branches [3],
>> >> module and x86 support on virtio-iommu/devel. Also tested with Eric's
>> >> QEMU device [4]. Please note that the series depends on Robin's
>> >> probe-deferral fix [5], which will hopefully land in v5.0.
>> >>
>> >> [1] Virtio-iommu specification v0.9, sources and pdf
>> >> git://linux-arm.org/virtio-iommu.git virtio-iommu/v0.9
>> >> http://jpbrucker.net/virtio-iommu/spec/v0.9/virtio-iommu-v0.9.pdf
>> >>
>> >> [2] [PATCH v6 0/7] Add virtio-iommu driver
>> >> 
>> >> https://lists.linuxfoundation.org/pipermail/iommu/2018-December/032127.html
>> >>
>> >> [3] git://linux-arm.org/linux-jpb.git virtio-iommu/v0.9.2
>> >> git://linux-arm.org/kvmtool-jpb.git virtio-iommu/v0.9.2
>> >>
>> >> [4] [RFC v9 00/17] VIRTIO-IOMMU device
>> >> https://www.mail-archive.com/qemu-devel@nongnu.org/msg575578.html
>> >>
>> >> [5] [PATCH] iommu/of: Fix probe-deferral
>> >> https://www.spinics.net/lists/arm-kernel/msg698371.html
>> >
>> > Thanks for the work!
>> > So really my only issue with this is that there's no
>> > way for the IOMMU to describe the devices that it
>> > covers.
>> >
>> > As a result that is then done in a platform-specific way.
>> >
>> > And this means that for example it does not solve the problem that e.g.
>> > some power people have in that their platform simply does not have a way
>> > to specify which devices are covered by the IOMMU.
>>
>> Isn't power using device tree? I haven't looked much at power because I
>> was told a while ago that they already paravirtualize their IOMMU and
>> don't need virtio-iommu, except perhaps for some legacy platforms. Or
>> something along those lines. But I would certainly be interested in
>> enabling the IOMMU for more architectures.
>
> I have CC'd the relevant ppc developers, let's see what do they think.

I'm far from being an expert, but what could be very useful for us is to
have a way for the guest to request IOMMU bypass for a device.

>From what I understand, the pSeries platform used by POWER guests always
puts devices behind an IOMMU, so at least for current systems a
description of which devices are covered by the IOMMU would always say
"all of them".

>> As for the enumeration problem, I still don't think we can get much
>> better than DT and ACPI as solutions (and IMO they are necessary to make
>> this device portable). But I believe that getting DT and ACPI support is
>> just a one-off inconvenience. That is, once the required bindings are
>> accepted, any future extension can then be done at the virtio level with
>> feature bits and probe requests, without having to update ACPI or DT.

There is a device tree binding that can specify devices connected to a
given IOMMU in Documentation/devicetree/bindings/iommu/iommu.txt.
I don't believe POWER machines use it though.

>> Thanks,
>> Jean
>>
>> > Solving that problem would make me much more excited about
>> > this device.
>> >
>> > On the other hand I can see that while there have been some
>> > developments most of the code has been stable for quite a while now.
>> >
>> > So what I am trying to do right about now, is making a small module that
>> > loads early and pokes at the IOMMU sufficiently to get the data about
>> > which devices use the IOMMU out of it using standard virtio config
>> > space.  IIUC it's claimed to be impossible without messy changes to the
>> > boot sequence.
>> >
>> > If I succeed at least on some platforms I'll ask that this design is
>> > worked into this device, minimizing info that goes through DT/ACPI.  If
>> > I see I can't make it in time to meet the next merge window, I plan
>> > merging the existing patches using DT (barring surprises).
>> >
>> > As I only have a very small amount of time to spend on this attempt, If
>> > someone else wants to try doing that in parallel, that would be great!

--
Thiago Jun

RE: [PATCH V4 2/3] HYPERV/IOMMU: Add Hyper-V stub IOMMU driver

2019-02-21 Thread Michael Kelley via iommu
From: lantianyu1...@gmail.com  Sent: Monday, February 
11, 2019 6:20 AM
> + /*
> +  * Hyper-V doesn't provide irq remapping function for
> +  * IO-APIC and so IO-APIC only accepts 8-bit APIC ID.
> +  * Cpu's APIC ID is read from ACPI MADT table and APIC IDs
> +  * in the MADT table on Hyper-v are sorted monotonic increasingly.
> +  * APIC ID reflects cpu topology. There maybe some APIC ID
> +  * gaps when cpu number in a socket is not power of two. Prepare
> +  * max cpu affinity for IOAPIC irqs. Scan cpu 0-255 and set cpu
> +  * into ioapic_max_cpumask if its APIC ID is less than 256.
> +  */
> + for (i = min_t(unsigned int, num_possible_cpus(), 255); i >= 0; i--)

The above isn't quite right.  For example, if num_possible_cpus() is 8,
then the loop will be executed 9 times, for values 8 down through 0.
It should be executed for values 7 down through 0.

> + if (cpu_physical_id(i) < 256)
> + cpumask_set_cpu(i, &ioapic_max_cpumask);
> +
> + return 0;
> +}

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


Re: [PATCHv7] x86/kdump: bugfix, make the behavior of crashkernel=X consistent with kaslr

2019-02-21 Thread Borislav Petkov
On Wed, Feb 20, 2019 at 05:41:46PM +0800, Dave Young wrote:
> Previously Joerg posted below patch, maybe he has some idea. Joerg?

Isn't it clear from the commit message?

-- 
Regards/Gruss,
Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


RE: [PATCH V4 1/3] x86/Hyper-V: Set x2apic destination mode to physical when x2apic is available

2019-02-21 Thread Michael Kelley via iommu
From: lantianyu1...@gmail.com  Sent: Monday, February 
11, 2019 6:20 AM
> 
> Hyper-V doesn't provide irq remapping for IO-APIC. To enable x2apic,
> set x2apic destination mode to physcial mode when x2apic is available
> and Hyper-V IOMMU driver makes sure cpus assigned with IO-APIC irqs have
> 8-bit APIC id.
> 
> Reviewed-by: Thomas Gleixner 
> Signed-off-by: Lan Tianyu 
> ---
> Change since v2:
>- Fix compile error due to x2apic_phys
>- Fix comment indent
> Change since v1:
>- Remove redundant extern for x2apic_phys
> 
Reviewed-by: Michael Kelley 
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH] iommu: Fix IOMMU debugfs fallout

2019-02-21 Thread Gary R Hook
On 2/20/19 7:05 AM, Geert Uytterhoeven wrote:
> A change made in the final version of IOMMU debugfs support replaced the
> public function iommu_debugfs_new_driver_dir() by the public dentry
> iommu_debugfs_dir in , but forgot to update both the
> implementation in iommu-debugfs.c, and the patch description.
> 
> Fix this by exporting iommu_debugfs_dir, and removing the reference to
> and implementation of iommu_debugfs_new_driver_dir().
> 
> Fixes: bad614b24293ae46 ("iommu: Enable debugfs exposure of IOMMU driver 
> internals")
> Signed-off-by: Geert Uytterhoeven 

Acked-by: Gary R Hook 

> ---
>   drivers/iommu/iommu-debugfs.c | 23 ---
>   1 file changed, 4 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/iommu/iommu-debugfs.c b/drivers/iommu/iommu-debugfs.c
> index 3b1bf88fd1b0494a..f0354894209648fd 100644
> --- a/drivers/iommu/iommu-debugfs.c
> +++ b/drivers/iommu/iommu-debugfs.c
> @@ -12,6 +12,7 @@
>   #include 
>   
>   struct dentry *iommu_debugfs_dir;
> +EXPORT_SYMBOL_GPL(iommu_debugfs_dir);
>   
>   /**
>* iommu_debugfs_setup - create the top-level iommu directory in debugfs
> @@ -23,9 +24,9 @@ struct dentry *iommu_debugfs_dir;
>* Emit a strong warning at boot time to indicate that this feature is
>* enabled.
>*
> - * This function is called from iommu_init; drivers may then call
> - * iommu_debugfs_new_driver_dir() to instantiate a vendor-specific
> - * directory to be used to expose internal data.
> + * This function is called from iommu_init; drivers may then use
> + * iommu_debugfs_dir to instantiate a vendor-specific directory to be used
> + * to expose internal data.
>*/
>   void iommu_debugfs_setup(void)
>   {
> @@ -48,19 +49,3 @@ void iommu_debugfs_setup(void)
>   
> pr_warn("*\n");
>   }
>   }
> -
> -/**
> - * iommu_debugfs_new_driver_dir - create a vendor directory under 
> debugfs/iommu
> - * @vendor: name of the vendor-specific subdirectory to create
> - *
> - * This function is called by an IOMMU driver to create the top-level debugfs
> - * directory for that driver.
> - *
> - * Return: upon success, a pointer to the dentry for the new directory.
> - * NULL in case of failure.
> - */
> -struct dentry *iommu_debugfs_new_driver_dir(const char *vendor)
> -{
> - return debugfs_create_dir(vendor, iommu_debugfs_dir);
> -}
> -EXPORT_SYMBOL_GPL(iommu_debugfs_new_driver_dir);
> 

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


Re: [PATCH v3 0/3] PCIe Host request to reserve IOVA

2019-02-21 Thread Srinath Mannam via iommu
Hi Bjorn,

Please help to review this patch series.
Thank you.

Regards,
Srinath.
On Fri, Jan 25, 2019 at 3:44 PM Srinath Mannam
 wrote:
>
> Few SOCs have limitation that their PCIe host can't allow few inbound
> address ranges. Allowed inbound address ranges are listed in dma-ranges
> DT property and this address ranges are required to do IOVA mapping.
> Remaining address ranges have to be reserved in IOVA mapping.
>
> PCIe Host driver of those SOCs has to list all address ranges which have
> to reserve their IOVA address into PCIe host bridge resource entry list.
> IOMMU framework will reserve these IOVAs while initializing IOMMU domain.
>
> This patch set is based on Linux-5.0-rc2.
>
> Changes from v2:
>   - Patch set rebased to Linux-5.0-rc2
>
> Changes from v1:
>   - Addressed Oza review comments.
>
> Srinath Mannam (3):
>   PCI: Add dma-resv window list
>   iommu/dma: Reserve IOVA for PCI host reserve address list
>   PCI: iproc: Add dma reserve resources to host
>
>  drivers/iommu/dma-iommu.c   |  8 ++
>  drivers/pci/controller/pcie-iproc.c | 51 
> -
>  drivers/pci/probe.c |  3 +++
>  include/linux/pci.h |  1 +
>  4 files changed, 62 insertions(+), 1 deletion(-)
>
> --
> 2.7.4
>
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu