[RFC PATCH 0/4] iommu: Per-group default domain type

2019-12-31 Thread Lu Baolu
An IOMMU group represents the smallest set of devices that are considered
to be isolated. All devices belonging to an IOMMU group share a default
domain for DMA APIs. There are two types of default domain: IOMMU_DOMAIN_DMA
and IOMMU_DOMAIN_IDENTITY. The former means IOMMU translation, while the
latter means IOMMU by-pass.

Currently, the default domain type for the IOMMU groups is determined
globally. All IOMMU groups use a single default domain type. The global
default domain type can be adjusted by kernel build configuration or
kernel parameters.

More and more users are looking forward to a fine grained default domain
type. For example, with the global default domain type set to translation,
the OEM verndors or end users might want some trusted and fast-speed devices
to bypass IOMMU for performance gains. On the other hand, with global
default domain type set to by-pass, some devices with limited system
memory addressing capability might want IOMMU translation to remove the
bounce buffer overhead.

This series proposes per-group default domain type to meet these demands.
It adds a per-device iommu_passthrough attribute. By setting this
attribute, end users or device vendors are able to tell the IOMMU subsystem
that this device is willing to use a default domain of IOMMU_DOMAIN_IDENTITY.
The IOMMU device probe procedure is reformed to pre-allocate groups for
all devices on a specific bus before adding the devices into the groups.
This enables the IOMMU device probe precedure to determine a per-group
default domain type before allocating IOMMU domains and attaching them
to devices.

Please help to review it. Your comments and suggestions are appricated.

Best regards,
baolu 

Lu Baolu (4):
  driver core: Add iommu_passthrough to struct device
  PCI: Add "pci=iommu_passthrough=" parameter for iommu passthrough
  iommu: Preallocate iommu group when probing devices
  iommu: Determine default domain type before allocating domain

 .../admin-guide/kernel-parameters.txt |   5 +
 drivers/iommu/iommu.c | 127 ++
 drivers/pci/pci.c |  34 +
 drivers/pci/pci.h |   1 +
 drivers/pci/probe.c   |   2 +
 include/linux/device.h|   3 +
 6 files changed, 143 insertions(+), 29 deletions(-)

-- 
2.17.1

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


[RFC PATCH 3/4] iommu: Preallocate iommu group when probing devices

2019-12-31 Thread Lu Baolu
This splits iommu group allocation from adding devices. This makes
it possible to determine the default domain type for each group as
all devices belonging to the group have been determined.

Signed-off-by: Lu Baolu 
---
 drivers/iommu/iommu.c | 92 +++
 1 file changed, 66 insertions(+), 26 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index fdd40756dbc1..716326a2ee5b 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -49,6 +49,7 @@ struct group_device {
struct list_head list;
struct device *dev;
char *name;
+   bool added;
 };
 
 struct iommu_group_attribute {
@@ -176,7 +177,6 @@ int iommu_probe_device(struct device *dev)
const struct iommu_ops *ops = dev->bus->iommu_ops;
int ret;
 
-   WARN_ON(dev->iommu_group);
if (!ops)
return -EINVAL;
 
@@ -686,13 +686,28 @@ static int iommu_group_create_direct_mappings(struct 
iommu_group *group,
 int iommu_group_add_device(struct iommu_group *group, struct device *dev)
 {
int ret, i = 0;
-   struct group_device *device;
+   struct group_device *device = NULL;
 
-   device = kzalloc(sizeof(*device), GFP_KERNEL);
-   if (!device)
-   return -ENOMEM;
+   mutex_lock(>mutex);
+   list_for_each_entry(device, >devices, list) {
+   if (device->dev == dev)
+   break;
+   }
+   mutex_unlock(>mutex);
 
-   device->dev = dev;
+   if (!device || device->dev != dev) {
+   device = kzalloc(sizeof(*device), GFP_KERNEL);
+   if (!device)
+   return -ENOMEM;
+
+   device->dev = dev;
+   mutex_lock(>mutex);
+   list_add_tail(>list, >devices);
+   mutex_unlock(>mutex);
+   } else if (device->added) {
+   kobject_get(group->devices_kobj);
+   return 0;
+   }
 
ret = sysfs_create_link(>kobj, >kobj, "iommu_group");
if (ret)
@@ -728,13 +743,14 @@ int iommu_group_add_device(struct iommu_group *group, 
struct device *dev)
iommu_group_create_direct_mappings(group, dev);
 
mutex_lock(>mutex);
-   list_add_tail(>list, >devices);
if (group->domain)
ret = __iommu_attach_device(group->domain, dev);
mutex_unlock(>mutex);
if (ret)
goto err_put_group;
 
+   device->added = true;
+
/* Notify any listeners about change to group. */
blocking_notifier_call_chain(>notifier,
 IOMMU_GROUP_NOTIFY_ADD_DEVICE, dev);
@@ -746,16 +762,16 @@ int iommu_group_add_device(struct iommu_group *group, 
struct device *dev)
return 0;
 
 err_put_group:
-   mutex_lock(>mutex);
-   list_del(>list);
-   mutex_unlock(>mutex);
-   dev->iommu_group = NULL;
kobject_put(group->devices_kobj);
 err_free_name:
kfree(device->name);
 err_remove_link:
sysfs_remove_link(>kobj, "iommu_group");
 err_free_device:
+   mutex_lock(>mutex);
+   list_del(>list);
+   mutex_unlock(>mutex);
+   dev->iommu_group = NULL;
kfree(device);
dev_err(dev, "Failed to add to iommu group %d: %d\n", group->id, ret);
return ret;
@@ -1339,6 +1355,34 @@ struct iommu_group *fsl_mc_device_group(struct device 
*dev)
return group;
 }
 
+static int alloc_iommu_group(struct device *dev, void *data)
+{
+   const struct iommu_ops *ops = dev->bus->iommu_ops;
+   struct group_device *device;
+   struct iommu_group *group;
+
+   if (!ops || WARN_ON(dev->iommu_group))
+   return -EINVAL;
+
+   device = kzalloc(sizeof(*device), GFP_KERNEL);
+   if (!device)
+   return -ENOMEM;
+
+   group = ops->device_group(dev);
+   if (WARN_ON_ONCE(IS_ERR_OR_NULL(group))) {
+   kfree(device);
+   return -EINVAL;
+   }
+
+   device->dev = dev;
+   dev->iommu_group = group;
+   mutex_lock(>mutex);
+   list_add_tail(>list, >devices);
+   mutex_unlock(>mutex);
+
+   return 0;
+}
+
 /**
  * iommu_group_get_for_dev - Find or create the IOMMU group for a device
  * @dev: target device
@@ -1351,23 +1395,15 @@ struct iommu_group *fsl_mc_device_group(struct device 
*dev)
  */
 struct iommu_group *iommu_group_get_for_dev(struct device *dev)
 {
-   const struct iommu_ops *ops = dev->bus->iommu_ops;
-   struct iommu_group *group;
+   struct iommu_group *group = dev->iommu_group;
int ret;
 
-   group = iommu_group_get(dev);
-   if (group)
-   return group;
-
-   if (!ops)
-   return ERR_PTR(-EINVAL);
-
-   group = ops->device_group(dev);
-   if (WARN_ON_ONCE(group == NULL))
-   return ERR_PTR(-EINVAL);
-
-   if (IS_ERR(group))
-   return group;
+   if (!group) {
+   ret = 

[RFC PATCH 4/4] iommu: Determine default domain type before allocating domain

2019-12-31 Thread Lu Baolu
Determine the default domain type for each group and use it to
allocate the iommu domain.

Signed-off-by: Lu Baolu 
---
 drivers/iommu/iommu.c | 35 ---
 1 file changed, 32 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 716326a2ee5b..fc1df1acbd25 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -43,6 +43,7 @@ struct iommu_group {
int id;
struct iommu_domain *default_domain;
struct iommu_domain *domain;
+   unsigned int def_domain_type;
 };
 
 struct group_device {
@@ -1383,6 +1384,33 @@ static int alloc_iommu_group(struct device *dev, void 
*data)
return 0;
 }
 
+static void get_group_def_domain_type(struct iommu_group *group)
+{
+   struct group_device *tmp = NULL;
+
+   mutex_lock(>mutex);
+   list_for_each_entry(tmp, >devices, list) {
+   struct device *dev = tmp->dev;
+
+   /*
+* If there are any untrusted devices in the group, force
+* IOMMU_DOMAIN_DMA to prevent DMA attack from malicious
+* devices.
+*/
+   if (dev_is_pci(dev) && to_pci_dev(dev)->untrusted) {
+   group->def_domain_type = IOMMU_DOMAIN_DMA;
+   break;
+   }
+
+   if (dev->iommu_passthrough)
+   group->def_domain_type = IOMMU_DOMAIN_IDENTITY;
+   }
+   mutex_unlock(>mutex);
+
+   if (!group->def_domain_type)
+   group->def_domain_type = iommu_def_domain_type;
+}
+
 /**
  * iommu_group_get_for_dev - Find or create the IOMMU group for a device
  * @dev: target device
@@ -1412,13 +1440,14 @@ struct iommu_group *iommu_group_get_for_dev(struct 
device *dev)
if (!group->default_domain) {
struct iommu_domain *dom;
 
-   dom = __iommu_domain_alloc(dev->bus, iommu_def_domain_type);
-   if (!dom && iommu_def_domain_type != IOMMU_DOMAIN_DMA) {
+   get_group_def_domain_type(group);
+   dom = __iommu_domain_alloc(dev->bus, group->def_domain_type);
+   if (!dom && group->def_domain_type != IOMMU_DOMAIN_DMA) {
dom = __iommu_domain_alloc(dev->bus, IOMMU_DOMAIN_DMA);
if (dom) {
dev_warn(dev,
 "failed to allocate default IOMMU 
domain of type %u; falling back to IOMMU_DOMAIN_DMA",
-iommu_def_domain_type);
+group->def_domain_type);
}
}
 
-- 
2.17.1

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


[RFC PATCH 2/4] PCI: Add "pci=iommu_passthrough=" parameter for iommu passthrough

2019-12-31 Thread Lu Baolu
The new parameter takes a list of devices separated by a semicolon.
Each device specified will have its iommu_passthrough bit in struct
device set. This is very similar to the existing 'disable_acs_redir'
parameter.

Signed-off-by: Lu Baolu 
---
 .../admin-guide/kernel-parameters.txt |  5 +++
 drivers/pci/pci.c | 34 +++
 drivers/pci/pci.h |  1 +
 drivers/pci/probe.c   |  2 ++
 4 files changed, 42 insertions(+)

diff --git a/Documentation/admin-guide/kernel-parameters.txt 
b/Documentation/admin-guide/kernel-parameters.txt
index ade4e6ec23e0..d3edc2cb6696 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -3583,6 +3583,11 @@
may put more devices in an IOMMU group.
force_floating  [S390] Force usage of floating interrupts.
nomio   [S390] Do not use MIO instructions.
+   iommu_passthrough=[; ...]
+   Specify one or more PCI devices (in the format
+   specified above) separated by semicolons.
+   Each device specified will bypass IOMMU DMA
+   translation.
 
pcie_aspm=  [PCIE] Forcibly enable or disable PCIe Active State 
Power
Management.
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 90dbd7c70371..05bf3f4acc36 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -6401,6 +6401,37 @@ void __weak pci_fixup_cardbus(struct pci_bus *bus)
 }
 EXPORT_SYMBOL(pci_fixup_cardbus);
 
+static const char *iommu_passthrough_param;
+bool pci_iommu_passthrough_match(struct pci_dev *dev)
+{
+   int ret = 0;
+   const char *p = iommu_passthrough_param;
+
+   if (!p)
+   return false;
+
+   while (*p) {
+   ret = pci_dev_str_match(dev, p, );
+   if (ret < 0) {
+   pr_info_once("PCI: Can't parse iommu_passthrough 
parameter: %s\n",
+iommu_passthrough_param);
+
+   break;
+   } else if (ret == 1) {
+   pci_info(dev, "PCI: IOMMU passthrough\n");
+   return true;
+   }
+
+   if (*p != ';' && *p != ',') {
+   /* End of param or invalid format */
+   break;
+   }
+   p++;
+   }
+
+   return false;
+}
+
 static int __init pci_setup(char *str)
 {
while (str) {
@@ -6462,6 +6493,8 @@ static int __init pci_setup(char *str)
pci_add_flags(PCI_SCAN_ALL_PCIE_DEVS);
} else if (!strncmp(str, "disable_acs_redir=", 18)) {
disable_acs_redir_param = str + 18;
+   } else if (!strncmp(str, "iommu_passthrough=", 18)) {
+   iommu_passthrough_param = str + 18;
} else {
pr_err("PCI: Unknown option `%s'\n", str);
}
@@ -6486,6 +6519,7 @@ static int __init pci_realloc_setup_params(void)
resource_alignment_param = kstrdup(resource_alignment_param,
   GFP_KERNEL);
disable_acs_redir_param = kstrdup(disable_acs_redir_param, GFP_KERNEL);
+   iommu_passthrough_param = kstrdup(iommu_passthrough_param, GFP_KERNEL);
 
return 0;
 }
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index a0a53bd05a0b..95f6af06aba6 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -288,6 +288,7 @@ void pci_reassigndev_resource_alignment(struct pci_dev 
*dev);
 void pci_disable_bridge_window(struct pci_dev *dev);
 struct pci_bus *pci_bus_get(struct pci_bus *bus);
 void pci_bus_put(struct pci_bus *bus);
+bool pci_iommu_passthrough_match(struct pci_dev *dev);
 
 /* PCIe link information */
 #define PCIE_SPEED2STR(speed) \
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 512cb4312ddd..4c571ee75621 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -2404,6 +2404,8 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus 
*bus)
 
dev->state_saved = false;
 
+   dev->dev.iommu_passthrough = pci_iommu_passthrough_match(dev);
+
pci_init_capabilities(dev);
 
/*
-- 
2.17.1

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


[RFC PATCH 1/4] driver core: Add iommu_passthrough to struct device

2019-12-31 Thread Lu Baolu
Add iommu_passthrough to struct device. This enables the iommu
subsystem to prepare an identity domain for the device so that
the DMA IOVA will be translated to the same physical address.
This field could be set in various subsystems, such as PCI,
according to the device/firmware properties or kernel command
parameters.

Signed-off-by: Lu Baolu 
---
 include/linux/device.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/include/linux/device.h b/include/linux/device.h
index 96ff76731e93..763d2d078d34 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -1247,6 +1247,8 @@ struct dev_links_info {
  *   sync_state() callback.
  * @dma_coherent: this particular device is dma coherent, even if the
  * architecture supports non-coherent devices.
+ * @iommu_passthrough: this particular device need to by pass the IOMMU DMA
+ * translation.
  *
  * At the lowest level, every device in a Linux system is represented by an
  * instance of struct device. The device structure contains the information
@@ -1347,6 +1349,7 @@ struct device {
 defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU_ALL)
booldma_coherent:1;
 #endif
+   booliommu_passthrough:1;
 };
 
 static inline struct device *kobj_to_dev(struct kobject *kobj)
-- 
2.17.1

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


Re: [RFC 2/5] iommu/vt-d: Unlink device if failed to add to group

2019-12-31 Thread Lu Baolu

On 1/1/20 4:24 AM, Jon Derrick wrote:

If the device fails to be added to the group, make sure to unlink the
reference before returning.

Signed-off-by: Jon Derrick 


This fix looks reasonable to me.

Acked-by: Lu Baolu 

Best regards,
baolu


---
  drivers/iommu/intel-iommu.c | 13 ++---
  1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index b2526a4..978d502 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -5625,8 +5625,10 @@ static int intel_iommu_add_device(struct device *dev)
  
  	group = iommu_group_get_for_dev(dev);
  
-	if (IS_ERR(group))

-   return PTR_ERR(group);
+   if (IS_ERR(group)) {
+   ret = PTR_ERR(group);
+   goto unlink;
+   }
  
  	iommu_group_put(group);
  
@@ -5652,7 +5654,8 @@ static int intel_iommu_add_device(struct device *dev)

if (!get_private_domain_for_dev(dev)) {
dev_warn(dev,
 "Failed to get a private 
domain.\n");
-   return -ENOMEM;
+   ret = -ENOMEM;
+   goto unlink;
}
  
  dev_info(dev,

@@ -5667,6 +5670,10 @@ static int intel_iommu_add_device(struct device *dev)
}
  
  	return 0;

+
+unlink:
+   iommu_device_unlink(>iommu, dev);
+   return ret;
  }
  
  static void intel_iommu_remove_device(struct device *dev)



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


Re: [RFC 1/5] iommu: Remove device link to group on failure

2019-12-31 Thread Lu Baolu

Hi,

On 1/1/20 4:24 AM, Jon Derrick wrote:

This adds the missing teardown step that removes the device link from
the group when the device addition fails.


This change looks good to me.

Reviewed-by: Lu Baolu 

Best regards,
baolu



Signed-off-by: Jon Derrick 
---
  drivers/iommu/iommu.c | 1 +
  1 file changed, 1 insertion(+)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index d5174f0..3e35284 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -768,6 +768,7 @@ int iommu_group_add_device(struct iommu_group *group, 
struct device *dev)
mutex_unlock(>mutex);
dev->iommu_group = NULL;
kobject_put(group->devices_kobj);
+   sysfs_remove_link(group->devices_kobj, device->name);
  err_free_name:
kfree(device->name);
  err_remove_link:


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


[RFC 5/5] x86/PCI: Remove unused X86_DEV_DMA_OPS

2019-12-31 Thread Jon Derrick
VMD was the only user of device dma operations. Now that the IOMMU has
been made aware of direct DMA aliases, VMD domain devices can reference
the VMD endpoint directly and the VMD device dma operations has been
made obsolete.

Signed-off-by: Jon Derrick 
---
 arch/x86/Kconfig  |  3 ---
 arch/x86/include/asm/device.h | 10 --
 arch/x86/pci/common.c | 38 --
 3 files changed, 51 deletions(-)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 5e89499..77f9426 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -2955,9 +2955,6 @@ config HAVE_ATOMIC_IOMAP
def_bool y
depends on X86_32
 
-config X86_DEV_DMA_OPS
-   bool
-
 source "drivers/firmware/Kconfig"
 
 source "arch/x86/kvm/Kconfig"
diff --git a/arch/x86/include/asm/device.h b/arch/x86/include/asm/device.h
index 5e12c63..7e31f7f 100644
--- a/arch/x86/include/asm/device.h
+++ b/arch/x86/include/asm/device.h
@@ -8,16 +8,6 @@ struct dev_archdata {
 #endif
 };
 
-#if defined(CONFIG_X86_DEV_DMA_OPS) && defined(CONFIG_PCI_DOMAINS)
-struct dma_domain {
-   struct list_head node;
-   const struct dma_map_ops *dma_ops;
-   int domain_nr;
-};
-void add_dma_domain(struct dma_domain *domain);
-void del_dma_domain(struct dma_domain *domain);
-#endif
-
 struct pdev_archdata {
 };
 
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index 4022609..fcf03da 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -625,43 +625,6 @@ unsigned int pcibios_assign_all_busses(void)
return (pci_probe & PCI_ASSIGN_ALL_BUSSES) ? 1 : 0;
 }
 
-#if defined(CONFIG_X86_DEV_DMA_OPS) && defined(CONFIG_PCI_DOMAINS)
-static LIST_HEAD(dma_domain_list);
-static DEFINE_SPINLOCK(dma_domain_list_lock);
-
-void add_dma_domain(struct dma_domain *domain)
-{
-   spin_lock(_domain_list_lock);
-   list_add(>node, _domain_list);
-   spin_unlock(_domain_list_lock);
-}
-EXPORT_SYMBOL_GPL(add_dma_domain);
-
-void del_dma_domain(struct dma_domain *domain)
-{
-   spin_lock(_domain_list_lock);
-   list_del(>node);
-   spin_unlock(_domain_list_lock);
-}
-EXPORT_SYMBOL_GPL(del_dma_domain);
-
-static void set_dma_domain_ops(struct pci_dev *pdev)
-{
-   struct dma_domain *domain;
-
-   spin_lock(_domain_list_lock);
-   list_for_each_entry(domain, _domain_list, node) {
-   if (pci_domain_nr(pdev->bus) == domain->domain_nr) {
-   pdev->dev.dma_ops = domain->dma_ops;
-   break;
-   }
-   }
-   spin_unlock(_domain_list_lock);
-}
-#else
-static void set_dma_domain_ops(struct pci_dev *pdev) {}
-#endif
-
 static void set_dev_domain_options(struct pci_dev *pdev)
 {
if (is_vmd(pdev->bus)) {
@@ -701,7 +664,6 @@ int pcibios_add_device(struct pci_dev *dev)
pa_data = data->next;
memunmap(data);
}
-   set_dma_domain_ops(dev);
set_dev_domain_options(dev);
return 0;
 }
-- 
1.8.3.1

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


[RFC 2/5] iommu/vt-d: Unlink device if failed to add to group

2019-12-31 Thread Jon Derrick
If the device fails to be added to the group, make sure to unlink the
reference before returning.

Signed-off-by: Jon Derrick 
---
 drivers/iommu/intel-iommu.c | 13 ++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index b2526a4..978d502 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -5625,8 +5625,10 @@ static int intel_iommu_add_device(struct device *dev)
 
group = iommu_group_get_for_dev(dev);
 
-   if (IS_ERR(group))
-   return PTR_ERR(group);
+   if (IS_ERR(group)) {
+   ret = PTR_ERR(group);
+   goto unlink;
+   }
 
iommu_group_put(group);
 
@@ -5652,7 +5654,8 @@ static int intel_iommu_add_device(struct device *dev)
if (!get_private_domain_for_dev(dev)) {
dev_warn(dev,
 "Failed to get a private 
domain.\n");
-   return -ENOMEM;
+   ret = -ENOMEM;
+   goto unlink;
}
 
dev_info(dev,
@@ -5667,6 +5670,10 @@ static int intel_iommu_add_device(struct device *dev)
}
 
return 0;
+
+unlink:
+   iommu_device_unlink(>iommu, dev);
+   return ret;
 }
 
 static void intel_iommu_remove_device(struct device *dev)
-- 
1.8.3.1

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


[RFC 3/5] x86/PCI: Expose VMD's device in pci_sysdata

2019-12-31 Thread Jon Derrick
To be used by intel-iommu code to find the correct domain.

Signed-off-by: Jon Derrick 
---
 arch/x86/include/asm/pci.h   | 4 ++--
 drivers/pci/controller/vmd.c | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
index 90d0731..7656807 100644
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -25,7 +25,7 @@ struct pci_sysdata {
void*fwnode;/* IRQ domain for MSI assignment */
 #endif
 #if IS_ENABLED(CONFIG_VMD)
-   bool vmd_domain;/* True if in Intel VMD domain */
+   struct device *vmd_dev; /* Non-null if in Intel VMD domain */
 #endif
 };
 
@@ -65,7 +65,7 @@ static inline bool is_vmd(struct pci_bus *bus)
 #if IS_ENABLED(CONFIG_VMD)
struct pci_sysdata *sd = bus->sysdata;
 
-   return sd->vmd_domain;
+   return !!sd->vmd_dev;
 #else
return false;
 #endif
diff --git a/drivers/pci/controller/vmd.c b/drivers/pci/controller/vmd.c
index 2128422..907b5bd 100644
--- a/drivers/pci/controller/vmd.c
+++ b/drivers/pci/controller/vmd.c
@@ -679,7 +679,7 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned 
long features)
.parent = res,
};
 
-   sd->vmd_domain = true;
+   sd->vmd_dev = >dev->dev;
sd->domain = vmd_find_free_domain();
if (sd->domain < 0)
return sd->domain;
-- 
1.8.3.1

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


[RFC 1/5] iommu: Remove device link to group on failure

2019-12-31 Thread Jon Derrick
This adds the missing teardown step that removes the device link from
the group when the device addition fails.

Signed-off-by: Jon Derrick 
---
 drivers/iommu/iommu.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index d5174f0..3e35284 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -768,6 +768,7 @@ int iommu_group_add_device(struct iommu_group *group, 
struct device *dev)
mutex_unlock(>mutex);
dev->iommu_group = NULL;
kobject_put(group->devices_kobj);
+   sysfs_remove_link(group->devices_kobj, device->name);
 err_free_name:
kfree(device->name);
 err_remove_link:
-- 
1.8.3.1

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


[RFC 0/5] Clean up VMD DMA Map Ops

2019-12-31 Thread Jon Derrick
Inspired by Christoph's last set:
https://lkml.org/lkml/2019/8/28/667

VMD currently works with VT-d enabled by pointing DMA and IOMMU actions at the
VMD endpoint. The problem with this approach is that the VMD endpoint's
device-specific attributes, such as the dma mask, are used instead.

This set cleans up VMD by removing the override that redirects dma map
operations to the VMD endpoint. Instead it introduces a new dma alias mechanism
into the existing dma alias infrastructure.

Patch 1 and 2 are miscellaneous fixes discovered during development.
Patch 1 is ready, but 2 likely doesn't go far enough for proper teardown on
addition failure.

Jon Derrick (5):
  iommu: Remove device link to group on failure
  iommu/vt-d: Unlink device if failed to add to group
  x86/PCI: Expose VMD's device in pci_sysdata
  PCI: vmd: Stop overriding dma_map_ops
  x86/PCI: Remove unused X86_DEV_DMA_OPS

 arch/x86/Kconfig   |   3 -
 arch/x86/include/asm/device.h  |  10 ---
 arch/x86/include/asm/pci.h |   4 +-
 arch/x86/pci/common.c  |  44 ++--
 drivers/iommu/intel-iommu.c|  26 ---
 drivers/iommu/iommu.c  |   1 +
 drivers/pci/controller/Kconfig |   1 -
 drivers/pci/controller/vmd.c   | 152 +
 drivers/pci/pci.c  |   4 +-
 drivers/pci/search.c   |   6 ++
 include/linux/pci.h|   1 +
 11 files changed, 37 insertions(+), 215 deletions(-)

-- 
1.8.3.1

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


[RFC 4/5] PCI: vmd: Stop overriding dma_map_ops

2019-12-31 Thread Jon Derrick
Devices on the VMD domain use the VMD endpoint's requester-id and have
been relying on the VMD endpoint's dma operations. The downside of this
was that VMD domain devices would use the VMD endpoint's attributes when
doing DMA and IOMMU mapping. We can be smarter about this by only using
the VMD endpoint when mapping and providing the correct child device's
attributes during dma operations.

This patch adds a new dma alias mechanism by adding a hint to a pci_dev
to point to a singular DMA requester's pci_dev. This integrates into the
existing dma alias infrastructure to reduce the impact of the changes
required to support this mode.

Signed-off-by: Jon Derrick 
---
 arch/x86/pci/common.c  |   6 +-
 drivers/iommu/intel-iommu.c|  13 ++--
 drivers/pci/controller/Kconfig |   1 -
 drivers/pci/controller/vmd.c   | 150 -
 drivers/pci/pci.c  |   4 +-
 drivers/pci/search.c   |   6 ++
 include/linux/pci.h|   1 +
 7 files changed, 23 insertions(+), 158 deletions(-)

diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index 1e59df0..4022609 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -664,8 +664,12 @@ static void set_dma_domain_ops(struct pci_dev *pdev) {}
 
 static void set_dev_domain_options(struct pci_dev *pdev)
 {
-   if (is_vmd(pdev->bus))
+   if (is_vmd(pdev->bus)) {
+   struct pci_sysdata *sd = pdev->bus->sysdata;
+
+   pdev->dma_parent = to_pci_dev(sd->vmd_dev);
pdev->hotplug_user_indicators = 1;
+   }
 }
 
 int pcibios_add_device(struct pci_dev *dev)
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 978d502..5aee648 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -776,11 +776,8 @@ static struct intel_iommu *device_to_iommu(struct device 
*dev, u8 *bus, u8 *devf
 
pdev = to_pci_dev(dev);
 
-#ifdef CONFIG_X86
-   /* VMD child devices currently cannot be handled individually */
-   if (is_vmd(pdev->bus))
-   return NULL;
-#endif
+   if (pdev->dma_parent)
+   pdev = pdev->dma_parent;
 
/* VFs aren't listed in scope tables; we need to look up
 * the PF instead to find the IOMMU. */
@@ -2428,6 +2425,12 @@ static struct dmar_domain *find_domain(struct device 
*dev)
 dev->archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO))
return NULL;
 
+   if (dev_is_pci(dev)) {
+   struct pci_dev *pdev = to_pci_dev(dev);
+   if (pdev->dma_parent)
+   dev = >dma_parent->dev;
+   }
+
/* No lock here, assumes no domain exit in normal case */
info = dev->archdata.iommu;
if (likely(info))
diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
index c77069c..55671429 100644
--- a/drivers/pci/controller/Kconfig
+++ b/drivers/pci/controller/Kconfig
@@ -239,7 +239,6 @@ config PCIE_TANGO_SMP8759
 
 config VMD
depends on PCI_MSI && X86_64 && SRCU
-   select X86_DEV_DMA_OPS
tristate "Intel Volume Management Device Driver"
---help---
  Adds support for the Intel Volume Management Device (VMD). VMD is a
diff --git a/drivers/pci/controller/vmd.c b/drivers/pci/controller/vmd.c
index 907b5bd..5824a39 100644
--- a/drivers/pci/controller/vmd.c
+++ b/drivers/pci/controller/vmd.c
@@ -98,9 +98,6 @@ struct vmd_dev {
struct irq_domain   *irq_domain;
struct pci_bus  *bus;
u8  busn_start;
-
-   struct dma_map_ops  dma_ops;
-   struct dma_domain   dma_domain;
 };
 
 static inline struct vmd_dev *vmd_from_bus(struct pci_bus *bus)
@@ -295,151 +292,6 @@ static void vmd_set_desc(msi_alloc_info_t *arg, struct 
msi_desc *desc)
.chip   = _msi_controller,
 };
 
-/*
- * VMD replaces the requester ID with its own.  DMA mappings for devices in a
- * VMD domain need to be mapped for the VMD, not the device requiring
- * the mapping.
- */
-static struct device *to_vmd_dev(struct device *dev)
-{
-   struct pci_dev *pdev = to_pci_dev(dev);
-   struct vmd_dev *vmd = vmd_from_bus(pdev->bus);
-
-   return >dev->dev;
-}
-
-static void *vmd_alloc(struct device *dev, size_t size, dma_addr_t *addr,
-  gfp_t flag, unsigned long attrs)
-{
-   return dma_alloc_attrs(to_vmd_dev(dev), size, addr, flag, attrs);
-}
-
-static void vmd_free(struct device *dev, size_t size, void *vaddr,
-dma_addr_t addr, unsigned long attrs)
-{
-   return dma_free_attrs(to_vmd_dev(dev), size, vaddr, addr, attrs);
-}
-
-static int vmd_mmap(struct device *dev, struct vm_area_struct *vma,
-   void *cpu_addr, dma_addr_t addr, size_t size,
-   unsigned long attrs)
-{
-   return dma_mmap_attrs(to_vmd_dev(dev), vma, cpu_addr, addr, 

[rfc] dma-mapping: preallocate unencrypted DMA atomic pool

2019-12-31 Thread David Rientjes via iommu
Christoph, Thomas, is something like this (without the diagnosic 
information included in this patch) acceptable for these allocations?  
Adding expansion support when the pool is half depleted wouldn't be *that* 
hard.

Or are there alternatives we should consider?  Thanks!




When AMD SEV is enabled in the guest, all allocations through 
dma_pool_alloc_page() must call set_memory_decrypted() for unencrypted 
DMA.  This includes dma_pool_alloc() and dma_direct_alloc_pages().  These 
calls may block which is not allowed in atomic allocation contexts such as 
from the NVMe driver.

Preallocate a complementary unecrypted DMA atomic pool that is initially 
4MB in size.  This patch does not contain dynamic expansion, but that 
could be added if necessary.

In our stress testing, our peak unecrypted DMA atomic allocation 
requirements is ~1.4MB, so 4MB is plenty.  This pool is similar to the 
existing DMA atomic pool but is unencrypted.

Signed-off-by: David Rientjes 
---
 Based on v5.4 HEAD.

 This commit contains diagnostic information and is not intended for use 
 in a production environment.

 arch/x86/Kconfig|   1 +
 drivers/iommu/dma-iommu.c   |   5 +-
 include/linux/dma-mapping.h |   7 ++-
 kernel/dma/direct.c |  16 -
 kernel/dma/remap.c  | 116 ++--
 5 files changed, 108 insertions(+), 37 deletions(-)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1530,6 +1530,7 @@ config X86_CPA_STATISTICS
 config AMD_MEM_ENCRYPT
bool "AMD Secure Memory Encryption (SME) support"
depends on X86_64 && CPU_SUP_AMD
+   select DMA_DIRECT_REMAP
select DYNAMIC_PHYSICAL_MASK
select ARCH_USE_MEMREMAP_PROT
select ARCH_HAS_FORCE_DMA_UNENCRYPTED
diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -928,7 +928,7 @@ static void __iommu_dma_free(struct device *dev, size_t 
size, void *cpu_addr)
 
/* Non-coherent atomic allocation? Easy */
if (IS_ENABLED(CONFIG_DMA_DIRECT_REMAP) &&
-   dma_free_from_pool(cpu_addr, alloc_size))
+   dma_free_from_pool(dev, cpu_addr, alloc_size))
return;
 
if (IS_ENABLED(CONFIG_DMA_REMAP) && is_vmalloc_addr(cpu_addr)) {
@@ -1011,7 +1011,8 @@ static void *iommu_dma_alloc(struct device *dev, size_t 
size,
 
if (IS_ENABLED(CONFIG_DMA_DIRECT_REMAP) &&
!gfpflags_allow_blocking(gfp) && !coherent)
-   cpu_addr = dma_alloc_from_pool(PAGE_ALIGN(size), , gfp);
+   cpu_addr = dma_alloc_from_pool(dev, PAGE_ALIGN(size), ,
+  gfp);
else
cpu_addr = iommu_dma_alloc_pages(dev, size, , gfp, attrs);
if (!cpu_addr)
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -629,9 +629,10 @@ void *dma_common_pages_remap(struct page **pages, size_t 
size,
pgprot_t prot, const void *caller);
 void dma_common_free_remap(void *cpu_addr, size_t size);
 
-bool dma_in_atomic_pool(void *start, size_t size);
-void *dma_alloc_from_pool(size_t size, struct page **ret_page, gfp_t flags);
-bool dma_free_from_pool(void *start, size_t size);
+bool dma_in_atomic_pool(struct device *dev, void *start, size_t size);
+void *dma_alloc_from_pool(struct device *dev, size_t size,
+ struct page **ret_page, gfp_t flags);
+bool dma_free_from_pool(struct device *dev, void *start, size_t size);
 
 int
 dma_common_get_sgtable(struct device *dev, struct sg_table *sgt, void 
*cpu_addr,
diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c
--- a/kernel/dma/direct.c
+++ b/kernel/dma/direct.c
@@ -10,6 +10,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -131,6 +132,13 @@ void *dma_direct_alloc_pages(struct device *dev, size_t 
size,
struct page *page;
void *ret;
 
+   if (!gfpflags_allow_blocking(gfp) && force_dma_unencrypted(dev)) {
+   ret = dma_alloc_from_pool(dev, size, , gfp);
+   if (!ret)
+   return NULL;
+   goto done;
+   }
+
page = __dma_direct_alloc_pages(dev, size, dma_handle, gfp, attrs);
if (!page)
return NULL;
@@ -156,7 +164,7 @@ void *dma_direct_alloc_pages(struct device *dev, size_t 
size,
__dma_direct_free_pages(dev, size, page);
return NULL;
}
-
+done:
ret = page_address(page);
if (force_dma_unencrypted(dev)) {
set_memory_decrypted((unsigned long)ret, 1 << get_order(size));
@@ -185,6 +193,12 @@ void dma_direct_free_pages(struct device *dev, size_t 
size, void *cpu_addr,
 {
unsigned int page_order = get_order(size);
 
+   if (force_dma_unencrypted(dev) &&
+   

Re: [RESEND,PATCH 03/13] iommu/mediatek: Add mtk_iommu_pgtable structure

2019-12-31 Thread chao hao
On Mon, 2019-12-16 at 20:13 +0800, Yong Wu wrote:
> On Mon, 2019-11-04 at 19:52 +0800, Chao Hao wrote:
> > Start with this patch, we will change the SW architecture
> > to support multiple domains. SW architecture will has a big change,
> > so we need to modify a little bit by more than one patch.
> > The new SW overall architecture is as below:
> > 
> > iommu0   iommu1
> >   | |
> >   ---
> > |
> > mtk_iommu_pgtable
> > |
> > --
> > ||   |
> > mtk_iommu_domain1   mtk_iommu_domain2  mtk_iommu_domain3
> > ||   |
> > iommu_group1 iommu_group2   iommu_group3
> > ||   |
> > iommu_domain1   iommu_domain2   iommu_domain3
> > ||   |
> > iova region1(normal)  iova region2(CCU)iova region3(VPU)
> > 
> > For current structure, no matter how many iommus there are,
> > they use the same page table to simplify the usage of module.
> > In order to make the software architecture more explicit, this
> > patch will create a global mtk_iommu_pgtable structure to describe
> > page table and all the iommus use it.
> 
> Thanks for the hard work of this file. Actually this patch and the later
> ones confuse me. Why do you make this flow change? 
> for making the code "more explicit" or for adding multi-domain support
> in 13/13.
> 
> IMHO, the change is unnecessary.
> a) For me, this change has no improvement. currently we use a global
> mtk_iommu_get_m4u_data to get the M4U data. I will be very glad if you
> could get rid of it. But in this patchset, You use a another global
> mtk_iommu_pgtable to instead. For me. It has no improvement.

Thanks for you advice!

For current SW arch, all the IOMMU HW use the same page table, we can
use a global mtk_iommu_pgtable to discribe the information of page table
and all the IOMMU attach it, I think that it is more clear and
unambiguous. For beginners, it maybe more easily explicable? 

> 
> b) This patchset break the original flow. device_group give you a
> software chance for initializing, then you move pagetable allocating
> code into it. But it isn't device_group job.
> 

As is shown above diagram, mtk_iommu_pgtable includes iommu_group and
iommu_domain,so we need to allocate mtk_iommu_pgtable and initialize it
in device_group firstly,and then execute the original flow, it only
changes place for creating mtk_iommu_pgtable and don't break original
device_group flow.




> I can not decide if your flow is right. But if you only want to add
> support multi-domain, I guess you could extend the current "m4u_group"
> to a array "m4u_group[N]". It may be more simple. To make mt6779
> progress easily, I suggest you can use this way to support multi-domain
> firstly. Then you could send this new mtk_iommu_pgtable patchset for the
> code "more explicit" if you insist.
> 
> > The diagram is as below:
> > 
> > mtk_iommu_data1(MM)   mtk_iommu_data2(APU)
> > |  |
> > |  |
> > --mtk_iommu_pgtable-
> > 
> > We need to create global mtk_iommu_pgtable to include all the iova
> > regions firstly and special iova regions by divided based on it,
> > so the information of pgtable needs to be created in device_group.
> > 
> > Signed-off-by: Chao Hao 
> > ---
> >  drivers/iommu/mtk_iommu.c | 84 +++
> >  drivers/iommu/mtk_iommu.h |  1 +
> >  2 files changed, 85 insertions(+)
> > 
> > diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
> > index f2847e661137..fcbde6b0f58d 100644
> > --- a/drivers/iommu/mtk_iommu.c
> > +++ b/drivers/iommu/mtk_iommu.c
> > @@ -123,6 +123,12 @@ struct mtk_iommu_domain {
> > struct iommu_domain domain;
> >  };
> >  
> > +struct mtk_iommu_pgtable {
> > +   struct io_pgtable_cfg   cfg;
> > +   struct io_pgtable_ops   *iop;
> > +};
> > +
> > +static struct mtk_iommu_pgtable *share_pgtable;
> >  static const struct iommu_ops mtk_iommu_ops;
> >  
> >  /*
> > @@ -170,6 +176,11 @@ static struct mtk_iommu_data 
> > *mtk_iommu_get_m4u_data(void)
> > return NULL;
> >  }
> >  
> > +static struct mtk_iommu_pgtable *mtk_iommu_get_pgtable(void)
> > +{
> > +   return share_pgtable;
> > +}
> > +
> >  static struct mtk_iommu_domain *to_mtk_domain(struct iommu_domain *dom)
> >  {
> > return container_of(dom, struct mtk_iommu_domain, domain);
> > @@ -322,6 +333,13 @@ static int mtk_iommu_domain_finalise(struct 
> > mtk_iommu_domain *dom)
> >  {
> > struct mtk_iommu_data 

[RFT] iommu: omap: Fix -Woverflow warnings when compiling on 64-bit architectures

2019-12-31 Thread Krzysztof Kozlowski
Although the OMAP IOMMU driver supports only ARMv7 (32-bit) platforms,
it can be compile tested for other architectures, including 64-bit ones.
In such case the warning appears:

   In file included from drivers/iommu/omap-iommu.c:33:0:
   drivers/iommu/omap-iommu.c: In function 'omap_iommu_iova_to_phys':
>> drivers/iommu/omap-iopgtable.h:44:21: warning: large integer implicitly 
truncated to unsigned type [-Woverflow]
#define IOPTE_MASK  (~(IOPTE_SIZE - 1))
^
>> drivers/iommu/omap-iommu.c:1641:41: note: in expansion of macro 
'IOPTE_MASK'
   ret = omap_iommu_translate(*pte, da, IOPTE_MASK);
^~

Fix this by using architecture-depending types in omap_iommu_translate():
1. Pointer should be cast to unsigned long,
2. Virtual addresses should be cast to dma_addr_t.

On 32-bit this will be the same as original code (using u32).  On 64-bit
it should produce meaningful result, although it does not really matter.

Reported-by: kbuild test robot 
Signed-off-by: Krzysztof Kozlowski 

---

Not tested on hardware.
---
 drivers/iommu/omap-iopgtable.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/omap-iopgtable.h b/drivers/iommu/omap-iopgtable.h
index 1a4adb59a859..51d74002cc30 100644
--- a/drivers/iommu/omap-iopgtable.h
+++ b/drivers/iommu/omap-iopgtable.h
@@ -63,7 +63,8 @@
  *
  * va to pa translation
  */
-static inline phys_addr_t omap_iommu_translate(u32 d, u32 va, u32 mask)
+static inline phys_addr_t omap_iommu_translate(unsigned long d, dma_addr_t va,
+  dma_addr_t mask)
 {
return (d & mask) | (va & (~mask));
 }
-- 
2.7.4

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


Re: [PATCH 3/3] iommu: Enable compile testing for some of drivers

2019-12-31 Thread Krzysztof Kozlowski
On Tue, Dec 31, 2019 at 09:08:38AM +0800, kbuild test robot wrote:
> Hi Krzysztof,
> 
> I love your patch! Yet something to improve:
> 
> [auto build test ERROR on iommu/next]
> [also build test ERROR on v5.5-rc4 next-20191219]
> [if your patch is applied to the wrong git tree, please drop us a note to help
> improve the system. BTW, we also suggest to use '--base' option to specify the
> base tree in git format-patch, please see 
> https://stackoverflow.com/a/37406982]
> 
> url:
> https://github.com/0day-ci/linux/commits/Krzysztof-Kozlowski/iommu-omap-Fix-pointer-cast-Wpointer-to-int-cast-warnings-on-64-bit/20191231-022212
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git next
> config: sparc64-allmodconfig (attached as .config)
> compiler: sparc64-linux-gcc (GCC) 7.5.0
> reproduce:
> wget 
> https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
> ~/bin/make.cross
> chmod +x ~/bin/make.cross
> # save the attached .config to linux build tree
> GCC_VERSION=7.5.0 make.cross ARCH=sparc64 
> 
> If you fix the issue, kindly add following tag
> Reported-by: kbuild test robot 

Thanks, kbuild!

I sent a fix:
https://lore.kernel.org/linux-arm-kernel/159956-7612-1-git-send-email-k...@kernel.org/

Best regards,
Krzysztof

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


[PATCH] drm/rockchip: Add missing vmalloc header

2019-12-31 Thread Krzysztof Kozlowski
The Rockship DRM GEM code uses vmap()/vunmap() so vmalloc header must be
included to avoid warnings like (on IA64, compile tested):

drivers/gpu/drm/rockchip/rockchip_drm_gem.c: In function 
‘rockchip_gem_alloc_iommu’:
drivers/gpu/drm/rockchip/rockchip_drm_gem.c:134:20: error:
implicit declaration of function ‘vmap’ 
[-Werror=implicit-function-declaration]

Reported-by: kbuild test robot 
Signed-off-by: Krzysztof Kozlowski 
---
 drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
index 7582d0e6a60a..0d1884684dcb 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
@@ -6,6 +6,7 @@
 
 #include 
 #include 
+#include 
 
 #include 
 #include 
-- 
2.7.4

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

Re: [PATCH 3/3] iommu: Enable compile testing for some of drivers

2019-12-31 Thread Krzysztof Kozlowski
On Tue, Dec 31, 2019 at 03:43:39PM +0800, kbuild test robot wrote:
> Hi Krzysztof,
> 
> I love your patch! Perhaps something to improve:
> 
> [auto build test WARNING on iommu/next]
> [also build test WARNING on v5.5-rc4]
> [if your patch is applied to the wrong git tree, please drop us a note to help
> improve the system. BTW, we also suggest to use '--base' option to specify the
> base tree in git format-patch, please see 
> https://stackoverflow.com/a/37406982]
> 
> url:
> https://github.com/0day-ci/linux/commits/Krzysztof-Kozlowski/iommu-omap-Fix-pointer-cast-Wpointer-to-int-cast-warnings-on-64-bit/20191231-022212
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git next
> config: ia64-allmodconfig (attached as .config)
> compiler: ia64-linux-gcc (GCC) 7.5.0
> reproduce:
> wget 
> https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
> ~/bin/make.cross
> chmod +x ~/bin/make.cross
> # save the attached .config to linux build tree
> GCC_VERSION=7.5.0 make.cross ARCH=ia64 
> 
> If you fix the issue, kindly add following tag
> Reported-by: kbuild test robot 

I saw it already while compile testing my patch. I must admit that I
could not find easy/fast fix for it.  Probably the
omap_iommu_translate() helper should be made 64-bit friendly but this
obfuscates the code. The driver and hardware supports only 32-bit addresses.

Best regards,
Krzysztof


> 
> All warnings (new ones prefixed by >>):
> 
>In file included from drivers/iommu/omap-iommu.c:33:0:
>drivers/iommu/omap-iommu.c: In function 'omap_iommu_iova_to_phys':
> >> drivers/iommu/omap-iopgtable.h:44:21: warning: large integer implicitly 
> >> truncated to unsigned type [-Woverflow]
> #define IOPTE_MASK  (~(IOPTE_SIZE - 1))
> ^
> >> drivers/iommu/omap-iommu.c:1641:41: note: in expansion of macro 
> >> 'IOPTE_MASK'
>ret = omap_iommu_translate(*pte, da, IOPTE_MASK);
> ^~
>drivers/iommu/omap-iopgtable.h:51:23: warning: large integer implicitly 
> truncated to unsigned type [-Woverflow]
> #define IOLARGE_MASK  (~(IOLARGE_SIZE - 1))
>   ^
> >> drivers/iommu/omap-iommu.c:1643:41: note: in expansion of macro 
> >> 'IOLARGE_MASK'
>ret = omap_iommu_translate(*pte, da, IOLARGE_MASK);
> ^~~~
>drivers/iommu/omap-iopgtable.h:27:25: warning: large integer implicitly 
> truncated to unsigned type [-Woverflow]
> #define IOSECTION_MASK  (~(IOSECTION_SIZE - 1))
> ^
> >> drivers/iommu/omap-iommu.c:1649:41: note: in expansion of macro 
> >> 'IOSECTION_MASK'
>ret = omap_iommu_translate(*pgd, da, IOSECTION_MASK);
> ^~
>drivers/iommu/omap-iopgtable.h:34:23: warning: large integer implicitly 
> truncated to unsigned type [-Woverflow]
> #define IOSUPER_MASK  (~(IOSUPER_SIZE - 1))
>   ^
> >> drivers/iommu/omap-iommu.c:1651:41: note: in expansion of macro 
> >> 'IOSUPER_MASK'
>ret = omap_iommu_translate(*pgd, da, IOSUPER_MASK);
> ^~~~
> 
> vim +44 drivers/iommu/omap-iopgtable.h
> 
> 97ec7d585b33bb arch/arm/plat-omap/iopgtable.h Hiroshi DOYU 2010-02-15  38  
> 97ec7d585b33bb arch/arm/plat-omap/iopgtable.h Hiroshi DOYU 2010-02-15  39  /*
> 97ec7d585b33bb arch/arm/plat-omap/iopgtable.h Hiroshi DOYU 2010-02-15  40   * 
> "small page" address mask and size definitions.
> 97ec7d585b33bb arch/arm/plat-omap/iopgtable.h Hiroshi DOYU 2010-02-15  41   */
> a9dcad5e375800 arch/arm/plat-omap/iopgtable.h Hiroshi DOYU 2009-01-26  42  
> #define IOPTE_SHIFT12
> 5ff98fa68c88d7 drivers/iommu/omap-iopgtable.h Suman Anna   2015-07-20  43  
> #define IOPTE_SIZE BIT(IOPTE_SHIFT)
> a9dcad5e375800 arch/arm/plat-omap/iopgtable.h Hiroshi DOYU 2009-01-26 @44  
> #define IOPTE_MASK (~(IOPTE_SIZE - 1))
> a9dcad5e375800 arch/arm/plat-omap/iopgtable.h Hiroshi DOYU 2009-01-26  45  
> 
> :: The code at line 44 was first introduced by commit
> :: a9dcad5e375800fcb07f7617dba23b3aade8f09d omap iommu: tlb and pagetable 
> primitives
> 
> :: TO: Hiroshi DOYU 
> :: CC: Hiroshi DOYU 
> 
> ---
> 0-DAY kernel test infrastructure Open Source Technology Center
> https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org Intel Corporation


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