All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v5 00/14] Fix BUG_ON in vfio_iommu_group_notifier()
@ 2022-01-04  1:56 ` Lu Baolu
  0 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-01-04  1:56 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Joerg Roedel, Alex Williamson, Bjorn Helgaas,
	Jason Gunthorpe, Christoph Hellwig, Kevin Tian, Ashok Raj
  Cc: Will Deacon, Robin Murphy, Dan Williams, rafael, Diana Craciun,
	Cornelia Huck, Eric Auger, Liu Yi L, Jacob jun Pan,
	Chaitanya Kulkarni, Stuart Yoder, Laurentiu Tudor,
	Thierry Reding, David Airlie, Daniel Vetter, Jonathan Hunter,
	Li Yang, Dmitry Osipenko, iommu, linux-pci, kvm, linux-kernel,
	Lu Baolu

Hi folks,

The iommu group is the minimal isolation boundary for DMA. Devices in
a group can access each other's MMIO registers via peer to peer DMA
and also need share the same I/O address space.

Once the I/O address space is assigned to user control it is no longer
available to the dma_map* API, which effectively makes the DMA API
non-working.

Second, userspace can use DMA initiated by a device that it controls
to access the MMIO spaces of other devices in the group. This allows
userspace to indirectly attack any kernel owned device and it's driver.

Therefore groups must either be entirely under kernel control or
userspace control, never a mixture. Unfortunately some systems have
problems with the granularity of groups and there are a couple of
important exceptions:

 - pci_stub allows the admin to block driver binding on a device and
   make it permanently shared with userspace. Since PCI stub does not
   do DMA it is safe, however the admin must understand that using
   pci_stub allows userspace to attack whatever device it was bound
   it.

 - PCI bridges are sometimes included in groups. Typically PCI bridges
   do not use DMA, and generally do not have MMIO regions.

Generally any device that does not have any MMIO registers is a
possible candidate for an exception.

Currently vfio adopts a workaround to detect violations of the above
restrictions by monitoring the driver core BOUND event, and hardwiring
the above exceptions. Since there is no way for vfio to reject driver
binding at this point, BUG_ON() is triggered if a violation is
captured (kernel driver BOUND event on a group which already has some
devices assigned to userspace). Aside from the bad user experience
this opens a way for root userspace to crash the kernel, even in high
integrity configurations, by manipulating the module binding and
triggering the BUG_ON.

This series solves this problem by making the user/kernel ownership a
core concept at the IOMMU layer. The driver core enforces kernel
ownership while drivers are bound and violations now result in a error
codes during probe, not BUG_ON failures.

Patch partitions:
  [PATCH 1-7]: Detect DMA ownership conflicts during driver binding;
  [PATCH 8-10]: Add security context management for assigned devices;
  [PATCH 11-14]: Various cleanups.

This is also part one of three initial series for IOMMUFD:
 * Move IOMMU Group security into the iommu layer
 - Generic IOMMUFD implementation
 - VFIO ability to consume IOMMUFD

Change log:
v1: initial post
  - https://lore.kernel.org/linux-iommu/20211115020552.2378167-1-baolu.lu@linux.intel.com/

v2:
  - https://lore.kernel.org/linux-iommu/20211128025051.355578-1-baolu.lu@linux.intel.com/

  - Move kernel dma ownership auto-claiming from driver core to bus
    callback. [Greg/Christoph/Robin/Jason]
    https://lore.kernel.org/linux-iommu/20211115020552.2378167-1-baolu.lu@linux.intel.com/T/#m153706912b770682cb12e3c28f57e171aa1f9d0c

  - Code and interface refactoring for iommu_set/release_dma_owner()
    interfaces. [Jason]
    https://lore.kernel.org/linux-iommu/20211115020552.2378167-1-baolu.lu@linux.intel.com/T/#mea70ed8e4e3665aedf32a5a0a7db095bf680325e

  - [NEW]Add new iommu_attach/detach_device_shared() interfaces for
    multiple devices group. [Robin/Jason]
    https://lore.kernel.org/linux-iommu/20211115020552.2378167-1-baolu.lu@linux.intel.com/T/#mea70ed8e4e3665aedf32a5a0a7db095bf680325e

  - [NEW]Use iommu_attach/detach_device_shared() in drm/tegra drivers.

  - Refactoring and description refinement.

v3:
  - https://lore.kernel.org/linux-iommu/20211206015903.88687-1-baolu.lu@linux.intel.com/

  - Rename bus_type::dma_unconfigure to bus_type::dma_cleanup. [Greg]
    https://lore.kernel.org/linux-iommu/c3230ace-c878-39db-1663-2b752ff5384e@linux.intel.com/T/#m6711e041e47cb0cbe3964fad0a3466f5ae4b3b9b

  - Avoid _platform_dma_configure for platform_bus_type::dma_configure.
    [Greg]
    https://lore.kernel.org/linux-iommu/c3230ace-c878-39db-1663-2b752ff5384e@linux.intel.com/T/#m43fc46286611aa56a5c0eeaad99d539e5519f3f6

  - Patch "0012-iommu-Add-iommu_at-de-tach_device_shared-for-mult.patch"
    and "0018-drm-tegra-Use-the-iommu-dma_owner-mechanism.patch" have
    been tested by Dmitry Osipenko <digetx@gmail.com>.

v4:
  - https://lore.kernel.org/linux-iommu/20211217063708.1740334-1-baolu.lu@linux.intel.com/
  - Remove unnecessary tegra->domain chech in the tegra patch. (Jason)
  - Remove DMA_OWNER_NONE. (Joerg)
  - Change refcount to unsigned int. (Christoph)
  - Move mutex lock into group set_dma_owner functions. (Christoph)
  - Add kernel doc for iommu_attach/detach_domain_shared(). (Christoph)
  - Move dma auto-claim into driver core. (Jason/Christoph)

v5:
  - Move kernel dma ownership auto-claiming from driver core to bus
    callback. (Greg)
  - Refactor the iommu interfaces to make them more specific.
    (Jason/Robin)
  - Simplify the dma ownership implementation by removing the owner
    type. (Jason)
  - Commit message refactoring for PCI drivers. (Bjorn)
  - Move iommu_attach/detach_device() improvement patches into another
    series as there are a lot of code refactoring and cleanup staffs
    in various device drivers.

This is based on next branch of linux-iommu tree:
https://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git
and also available on github:
https://github.com/LuBaolu/intel-iommu/commits/iommu-dma-ownership-v5

Best regards,
baolu

Jason Gunthorpe (1):
  vfio: Delete the unbound_list

Lu Baolu (13):
  iommu: Add dma ownership management interfaces
  driver core: Add dma_cleanup callback in bus_type
  amba: Stop sharing platform_dma_configure()
  driver core: platform: Add driver dma ownership management
  amba: Add driver dma ownership management
  bus: fsl-mc: Add driver dma ownership management
  PCI: Add driver dma ownership management
  PCI: pci_stub: Suppress kernel DMA ownership auto-claiming
  PCI: portdrv: Suppress kernel DMA ownership auto-claiming
  vfio: Set DMA ownership for VFIO devices
  vfio: Remove use of vfio_group_viable()
  vfio: Remove iommu group notifier
  iommu: Remove iommu group changes notifier

 include/linux/amba/bus.h              |   1 +
 include/linux/device/bus.h            |   3 +
 include/linux/fsl/mc.h                |   5 +
 include/linux/iommu.h                 |  54 +++---
 include/linux/pci.h                   |   5 +
 include/linux/platform_device.h       |   3 +-
 drivers/amba/bus.c                    |  39 +++-
 drivers/base/dd.c                     |   5 +
 drivers/base/platform.c               |  23 ++-
 drivers/bus/fsl-mc/fsl-mc-bus.c       |  26 ++-
 drivers/iommu/iommu.c                 | 236 +++++++++++++++++--------
 drivers/pci/pci-driver.c              |  21 +++
 drivers/pci/pci-stub.c                |   1 +
 drivers/pci/pcie/portdrv_pci.c        |   2 +
 drivers/vfio/fsl-mc/vfio_fsl_mc.c     |   1 +
 drivers/vfio/pci/vfio_pci.c           |   1 +
 drivers/vfio/platform/vfio_amba.c     |   1 +
 drivers/vfio/platform/vfio_platform.c |   1 +
 drivers/vfio/vfio.c                   | 245 ++------------------------
 19 files changed, 335 insertions(+), 338 deletions(-)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 112+ messages in thread

* [PATCH v5 00/14] Fix BUG_ON in vfio_iommu_group_notifier()
@ 2022-01-04  1:56 ` Lu Baolu
  0 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-01-04  1:56 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Joerg Roedel, Alex Williamson, Bjorn Helgaas,
	Jason Gunthorpe, Christoph Hellwig, Kevin Tian, Ashok Raj
  Cc: kvm, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Stuart Yoder,
	Jonathan Hunter, Chaitanya Kulkarni, Dan Williams, Cornelia Huck,
	linux-kernel, Li Yang, iommu, Jacob jun Pan, Daniel Vetter,
	Robin Murphy

Hi folks,

The iommu group is the minimal isolation boundary for DMA. Devices in
a group can access each other's MMIO registers via peer to peer DMA
and also need share the same I/O address space.

Once the I/O address space is assigned to user control it is no longer
available to the dma_map* API, which effectively makes the DMA API
non-working.

Second, userspace can use DMA initiated by a device that it controls
to access the MMIO spaces of other devices in the group. This allows
userspace to indirectly attack any kernel owned device and it's driver.

Therefore groups must either be entirely under kernel control or
userspace control, never a mixture. Unfortunately some systems have
problems with the granularity of groups and there are a couple of
important exceptions:

 - pci_stub allows the admin to block driver binding on a device and
   make it permanently shared with userspace. Since PCI stub does not
   do DMA it is safe, however the admin must understand that using
   pci_stub allows userspace to attack whatever device it was bound
   it.

 - PCI bridges are sometimes included in groups. Typically PCI bridges
   do not use DMA, and generally do not have MMIO regions.

Generally any device that does not have any MMIO registers is a
possible candidate for an exception.

Currently vfio adopts a workaround to detect violations of the above
restrictions by monitoring the driver core BOUND event, and hardwiring
the above exceptions. Since there is no way for vfio to reject driver
binding at this point, BUG_ON() is triggered if a violation is
captured (kernel driver BOUND event on a group which already has some
devices assigned to userspace). Aside from the bad user experience
this opens a way for root userspace to crash the kernel, even in high
integrity configurations, by manipulating the module binding and
triggering the BUG_ON.

This series solves this problem by making the user/kernel ownership a
core concept at the IOMMU layer. The driver core enforces kernel
ownership while drivers are bound and violations now result in a error
codes during probe, not BUG_ON failures.

Patch partitions:
  [PATCH 1-7]: Detect DMA ownership conflicts during driver binding;
  [PATCH 8-10]: Add security context management for assigned devices;
  [PATCH 11-14]: Various cleanups.

This is also part one of three initial series for IOMMUFD:
 * Move IOMMU Group security into the iommu layer
 - Generic IOMMUFD implementation
 - VFIO ability to consume IOMMUFD

Change log:
v1: initial post
  - https://lore.kernel.org/linux-iommu/20211115020552.2378167-1-baolu.lu@linux.intel.com/

v2:
  - https://lore.kernel.org/linux-iommu/20211128025051.355578-1-baolu.lu@linux.intel.com/

  - Move kernel dma ownership auto-claiming from driver core to bus
    callback. [Greg/Christoph/Robin/Jason]
    https://lore.kernel.org/linux-iommu/20211115020552.2378167-1-baolu.lu@linux.intel.com/T/#m153706912b770682cb12e3c28f57e171aa1f9d0c

  - Code and interface refactoring for iommu_set/release_dma_owner()
    interfaces. [Jason]
    https://lore.kernel.org/linux-iommu/20211115020552.2378167-1-baolu.lu@linux.intel.com/T/#mea70ed8e4e3665aedf32a5a0a7db095bf680325e

  - [NEW]Add new iommu_attach/detach_device_shared() interfaces for
    multiple devices group. [Robin/Jason]
    https://lore.kernel.org/linux-iommu/20211115020552.2378167-1-baolu.lu@linux.intel.com/T/#mea70ed8e4e3665aedf32a5a0a7db095bf680325e

  - [NEW]Use iommu_attach/detach_device_shared() in drm/tegra drivers.

  - Refactoring and description refinement.

v3:
  - https://lore.kernel.org/linux-iommu/20211206015903.88687-1-baolu.lu@linux.intel.com/

  - Rename bus_type::dma_unconfigure to bus_type::dma_cleanup. [Greg]
    https://lore.kernel.org/linux-iommu/c3230ace-c878-39db-1663-2b752ff5384e@linux.intel.com/T/#m6711e041e47cb0cbe3964fad0a3466f5ae4b3b9b

  - Avoid _platform_dma_configure for platform_bus_type::dma_configure.
    [Greg]
    https://lore.kernel.org/linux-iommu/c3230ace-c878-39db-1663-2b752ff5384e@linux.intel.com/T/#m43fc46286611aa56a5c0eeaad99d539e5519f3f6

  - Patch "0012-iommu-Add-iommu_at-de-tach_device_shared-for-mult.patch"
    and "0018-drm-tegra-Use-the-iommu-dma_owner-mechanism.patch" have
    been tested by Dmitry Osipenko <digetx@gmail.com>.

v4:
  - https://lore.kernel.org/linux-iommu/20211217063708.1740334-1-baolu.lu@linux.intel.com/
  - Remove unnecessary tegra->domain chech in the tegra patch. (Jason)
  - Remove DMA_OWNER_NONE. (Joerg)
  - Change refcount to unsigned int. (Christoph)
  - Move mutex lock into group set_dma_owner functions. (Christoph)
  - Add kernel doc for iommu_attach/detach_domain_shared(). (Christoph)
  - Move dma auto-claim into driver core. (Jason/Christoph)

v5:
  - Move kernel dma ownership auto-claiming from driver core to bus
    callback. (Greg)
  - Refactor the iommu interfaces to make them more specific.
    (Jason/Robin)
  - Simplify the dma ownership implementation by removing the owner
    type. (Jason)
  - Commit message refactoring for PCI drivers. (Bjorn)
  - Move iommu_attach/detach_device() improvement patches into another
    series as there are a lot of code refactoring and cleanup staffs
    in various device drivers.

This is based on next branch of linux-iommu tree:
https://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git
and also available on github:
https://github.com/LuBaolu/intel-iommu/commits/iommu-dma-ownership-v5

Best regards,
baolu

Jason Gunthorpe (1):
  vfio: Delete the unbound_list

Lu Baolu (13):
  iommu: Add dma ownership management interfaces
  driver core: Add dma_cleanup callback in bus_type
  amba: Stop sharing platform_dma_configure()
  driver core: platform: Add driver dma ownership management
  amba: Add driver dma ownership management
  bus: fsl-mc: Add driver dma ownership management
  PCI: Add driver dma ownership management
  PCI: pci_stub: Suppress kernel DMA ownership auto-claiming
  PCI: portdrv: Suppress kernel DMA ownership auto-claiming
  vfio: Set DMA ownership for VFIO devices
  vfio: Remove use of vfio_group_viable()
  vfio: Remove iommu group notifier
  iommu: Remove iommu group changes notifier

 include/linux/amba/bus.h              |   1 +
 include/linux/device/bus.h            |   3 +
 include/linux/fsl/mc.h                |   5 +
 include/linux/iommu.h                 |  54 +++---
 include/linux/pci.h                   |   5 +
 include/linux/platform_device.h       |   3 +-
 drivers/amba/bus.c                    |  39 +++-
 drivers/base/dd.c                     |   5 +
 drivers/base/platform.c               |  23 ++-
 drivers/bus/fsl-mc/fsl-mc-bus.c       |  26 ++-
 drivers/iommu/iommu.c                 | 236 +++++++++++++++++--------
 drivers/pci/pci-driver.c              |  21 +++
 drivers/pci/pci-stub.c                |   1 +
 drivers/pci/pcie/portdrv_pci.c        |   2 +
 drivers/vfio/fsl-mc/vfio_fsl_mc.c     |   1 +
 drivers/vfio/pci/vfio_pci.c           |   1 +
 drivers/vfio/platform/vfio_amba.c     |   1 +
 drivers/vfio/platform/vfio_platform.c |   1 +
 drivers/vfio/vfio.c                   | 245 ++------------------------
 19 files changed, 335 insertions(+), 338 deletions(-)

-- 
2.25.1

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

^ permalink raw reply	[flat|nested] 112+ messages in thread

* [PATCH v5 01/14] iommu: Add dma ownership management interfaces
  2022-01-04  1:56 ` Lu Baolu
@ 2022-01-04  1:56   ` Lu Baolu
  -1 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-01-04  1:56 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Joerg Roedel, Alex Williamson, Bjorn Helgaas,
	Jason Gunthorpe, Christoph Hellwig, Kevin Tian, Ashok Raj
  Cc: Will Deacon, Robin Murphy, Dan Williams, rafael, Diana Craciun,
	Cornelia Huck, Eric Auger, Liu Yi L, Jacob jun Pan,
	Chaitanya Kulkarni, Stuart Yoder, Laurentiu Tudor,
	Thierry Reding, David Airlie, Daniel Vetter, Jonathan Hunter,
	Li Yang, Dmitry Osipenko, iommu, linux-pci, kvm, linux-kernel,
	Lu Baolu

Multiple devices may be placed in the same IOMMU group because they
cannot be isolated from each other. These devices must either be
entirely under kernel control or userspace control, never a mixture.

This adds dma ownership management in iommu core and exposes several
interfaces for the device drivers and the device userspace assignment
framework (i.e. vfio), so that any conflict between user and kernel
controlled DMA could be detected at the beginning.

The device driver oriented interfaces are,

	int iommu_device_use_dma_api(struct device *dev);
	void iommu_device_unuse_dma_api(struct device *dev);

Devices under kernel drivers control must call iommu_device_use_dma_api()
before driver probes. The driver binding process must be aborted if it
returns failure.

The vfio oriented interfaces are,

	int iommu_group_set_dma_owner(struct iommu_group *group,
				      void *owner);
	void iommu_group_release_dma_owner(struct iommu_group *group);
	bool iommu_group_dma_owner_claimed(struct iommu_group *group);

The device userspace assignment must be disallowed if the set dma owner
interface returns failure.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
---
 include/linux/iommu.h |  31 ++++++++
 drivers/iommu/iommu.c | 161 +++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 189 insertions(+), 3 deletions(-)

diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index de0c57a567c8..568f285468cf 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -682,6 +682,13 @@ struct iommu_sva *iommu_sva_bind_device(struct device *dev,
 void iommu_sva_unbind_device(struct iommu_sva *handle);
 u32 iommu_sva_get_pasid(struct iommu_sva *handle);
 
+int iommu_device_use_dma_api(struct device *dev);
+void iommu_device_unuse_dma_api(struct device *dev);
+
+int iommu_group_set_dma_owner(struct iommu_group *group, void *owner);
+void iommu_group_release_dma_owner(struct iommu_group *group);
+bool iommu_group_dma_owner_claimed(struct iommu_group *group);
+
 #else /* CONFIG_IOMMU_API */
 
 struct iommu_ops {};
@@ -1082,6 +1089,30 @@ static inline struct iommu_fwspec *dev_iommu_fwspec_get(struct device *dev)
 {
 	return NULL;
 }
+
+static inline int iommu_device_use_dma_api(struct device *dev)
+{
+	return 0;
+}
+
+static inline void iommu_device_unuse_dma_api(struct device *dev)
+{
+}
+
+static inline int
+iommu_group_set_dma_owner(struct iommu_group *group, void *owner)
+{
+	return -ENODEV;
+}
+
+static inline void iommu_group_release_dma_owner(struct iommu_group *group)
+{
+}
+
+static inline bool iommu_group_dma_owner_claimed(struct iommu_group *group)
+{
+	return false;
+}
 #endif /* CONFIG_IOMMU_API */
 
 /**
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 8b86406b7162..ff0c8c1ad5af 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -48,6 +48,8 @@ struct iommu_group {
 	struct iommu_domain *default_domain;
 	struct iommu_domain *domain;
 	struct list_head entry;
+	unsigned int owner_cnt;
+	void *owner;
 };
 
 struct group_device {
@@ -289,7 +291,12 @@ int iommu_probe_device(struct device *dev)
 	mutex_lock(&group->mutex);
 	iommu_alloc_default_domain(group, dev);
 
-	if (group->default_domain) {
+	/*
+	 * If device joined an existing group which has been claimed
+	 * for none kernel DMA purpose, avoid attaching the default
+	 * domain.
+	 */
+	if (group->default_domain && !group->owner) {
 		ret = __iommu_attach_device(group->default_domain, dev);
 		if (ret) {
 			mutex_unlock(&group->mutex);
@@ -2320,7 +2327,7 @@ static int __iommu_attach_group(struct iommu_domain *domain,
 {
 	int ret;
 
-	if (group->default_domain && group->domain != group->default_domain)
+	if (group->domain && group->domain != group->default_domain)
 		return -EBUSY;
 
 	ret = __iommu_group_for_each_dev(group, domain,
@@ -2357,7 +2364,11 @@ static void __iommu_detach_group(struct iommu_domain *domain,
 {
 	int ret;
 
-	if (!group->default_domain) {
+	/*
+	 * If group has been claimed for none kernel DMA purpose, avoid
+	 * re-attaching the default domain.
+	 */
+	if (!group->default_domain || group->owner) {
 		__iommu_group_for_each_dev(group, domain,
 					   iommu_group_do_detach_device);
 		group->domain = NULL;
@@ -3351,3 +3362,147 @@ static ssize_t iommu_group_store_type(struct iommu_group *group,
 
 	return ret;
 }
+
+/**
+ * iommu_device_use_dma_api() - Device driver wants to do DMA through
+ *                              kernel DMA API.
+ * @dev: The device.
+ *
+ * The device driver about to bind @dev wants to do DMA through the kernel
+ * DMA API. Return 0 if it is allowed, otherwise an error.
+ */
+int iommu_device_use_dma_api(struct device *dev)
+{
+	struct iommu_group *group = iommu_group_get(dev);
+	int ret = 0;
+
+	if (!group)
+		return 0;
+
+	mutex_lock(&group->mutex);
+	if (group->owner_cnt) {
+		if (group->domain != group->default_domain ||
+		    group->owner) {
+			ret = -EBUSY;
+			goto unlock_out;
+		}
+	}
+
+	group->owner_cnt++;
+
+unlock_out:
+	mutex_unlock(&group->mutex);
+	iommu_group_put(group);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(iommu_device_use_dma_api);
+
+/**
+ * iommu_device_unuse_dma_api() - Device driver doesn't want to do DMA
+ *                                through kernel DMA API anymore.
+ * @dev: The device.
+ *
+ * The device driver doesn't want to do DMA through kernel DMA API anymore.
+ * It must be called after iommu_device_use_dma_api().
+ */
+void iommu_device_unuse_dma_api(struct device *dev)
+{
+	struct iommu_group *group = iommu_group_get(dev);
+
+	if (!group)
+		return;
+
+	mutex_lock(&group->mutex);
+	if (!WARN_ON(!group->owner_cnt))
+		group->owner_cnt--;
+
+	mutex_unlock(&group->mutex);
+	iommu_group_put(group);
+}
+EXPORT_SYMBOL_GPL(iommu_device_unuse_dma_api);
+
+/**
+ * iommu_group_set_dma_owner() - Set DMA ownership of a group
+ * @group: The group.
+ * @owner: Caller specified pointer. Used for exclusive ownership.
+ *
+ * This is to support backward compatibility for vfio which manages
+ * the dma ownership in iommu_group level. New invocations on this
+ * interface should be prohibited.
+ */
+int iommu_group_set_dma_owner(struct iommu_group *group, void *owner)
+{
+	int ret = 0;
+
+	mutex_lock(&group->mutex);
+	if (group->owner_cnt) {
+		if (group->owner != owner) {
+			ret = -EPERM;
+			goto unlock_out;
+		}
+	} else {
+		if (group->domain && group->domain != group->default_domain) {
+			ret = -EBUSY;
+			goto unlock_out;
+		}
+
+		group->owner = owner;
+		if (group->domain)
+			__iommu_detach_group(group->domain, group);
+	}
+
+	group->owner_cnt++;
+unlock_out:
+	mutex_unlock(&group->mutex);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(iommu_group_set_dma_owner);
+
+/**
+ * iommu_group_release_dma_owner() - Release DMA ownership of a group
+ * @group: The group.
+ *
+ * Release the DMA ownership claimed by iommu_group_set_dma_owner().
+ */
+void iommu_group_release_dma_owner(struct iommu_group *group)
+{
+	mutex_lock(&group->mutex);
+	if (WARN_ON(!group->owner_cnt || !group->owner))
+		goto unlock_out;
+
+	if (--group->owner_cnt > 0)
+		goto unlock_out;
+
+	/*
+	 * The UNMANAGED domain should be detached before all USER
+	 * owners have been released.
+	 */
+	if (!WARN_ON(group->domain) && group->default_domain)
+		__iommu_attach_group(group->default_domain, group);
+	group->owner = NULL;
+
+unlock_out:
+	mutex_unlock(&group->mutex);
+}
+EXPORT_SYMBOL_GPL(iommu_group_release_dma_owner);
+
+/**
+ * iommu_group_dma_owner_claimed() - Query group dma ownership status
+ * @group: The group.
+ *
+ * This provides status query on a given group. It is racey and only for
+ * non-binding status reporting.
+ */
+bool iommu_group_dma_owner_claimed(struct iommu_group *group)
+{
+	unsigned int user;
+
+	mutex_lock(&group->mutex);
+	user = group->owner_cnt;
+	mutex_unlock(&group->mutex);
+
+	return user;
+}
+EXPORT_SYMBOL_GPL(iommu_group_dma_owner_claimed);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 112+ messages in thread

* [PATCH v5 01/14] iommu: Add dma ownership management interfaces
@ 2022-01-04  1:56   ` Lu Baolu
  0 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-01-04  1:56 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Joerg Roedel, Alex Williamson, Bjorn Helgaas,
	Jason Gunthorpe, Christoph Hellwig, Kevin Tian, Ashok Raj
  Cc: kvm, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Stuart Yoder,
	Jonathan Hunter, Chaitanya Kulkarni, Dan Williams, Cornelia Huck,
	linux-kernel, Li Yang, iommu, Jacob jun Pan, Daniel Vetter,
	Robin Murphy

Multiple devices may be placed in the same IOMMU group because they
cannot be isolated from each other. These devices must either be
entirely under kernel control or userspace control, never a mixture.

This adds dma ownership management in iommu core and exposes several
interfaces for the device drivers and the device userspace assignment
framework (i.e. vfio), so that any conflict between user and kernel
controlled DMA could be detected at the beginning.

The device driver oriented interfaces are,

	int iommu_device_use_dma_api(struct device *dev);
	void iommu_device_unuse_dma_api(struct device *dev);

Devices under kernel drivers control must call iommu_device_use_dma_api()
before driver probes. The driver binding process must be aborted if it
returns failure.

The vfio oriented interfaces are,

	int iommu_group_set_dma_owner(struct iommu_group *group,
				      void *owner);
	void iommu_group_release_dma_owner(struct iommu_group *group);
	bool iommu_group_dma_owner_claimed(struct iommu_group *group);

The device userspace assignment must be disallowed if the set dma owner
interface returns failure.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
---
 include/linux/iommu.h |  31 ++++++++
 drivers/iommu/iommu.c | 161 +++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 189 insertions(+), 3 deletions(-)

diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index de0c57a567c8..568f285468cf 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -682,6 +682,13 @@ struct iommu_sva *iommu_sva_bind_device(struct device *dev,
 void iommu_sva_unbind_device(struct iommu_sva *handle);
 u32 iommu_sva_get_pasid(struct iommu_sva *handle);
 
+int iommu_device_use_dma_api(struct device *dev);
+void iommu_device_unuse_dma_api(struct device *dev);
+
+int iommu_group_set_dma_owner(struct iommu_group *group, void *owner);
+void iommu_group_release_dma_owner(struct iommu_group *group);
+bool iommu_group_dma_owner_claimed(struct iommu_group *group);
+
 #else /* CONFIG_IOMMU_API */
 
 struct iommu_ops {};
@@ -1082,6 +1089,30 @@ static inline struct iommu_fwspec *dev_iommu_fwspec_get(struct device *dev)
 {
 	return NULL;
 }
+
+static inline int iommu_device_use_dma_api(struct device *dev)
+{
+	return 0;
+}
+
+static inline void iommu_device_unuse_dma_api(struct device *dev)
+{
+}
+
+static inline int
+iommu_group_set_dma_owner(struct iommu_group *group, void *owner)
+{
+	return -ENODEV;
+}
+
+static inline void iommu_group_release_dma_owner(struct iommu_group *group)
+{
+}
+
+static inline bool iommu_group_dma_owner_claimed(struct iommu_group *group)
+{
+	return false;
+}
 #endif /* CONFIG_IOMMU_API */
 
 /**
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 8b86406b7162..ff0c8c1ad5af 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -48,6 +48,8 @@ struct iommu_group {
 	struct iommu_domain *default_domain;
 	struct iommu_domain *domain;
 	struct list_head entry;
+	unsigned int owner_cnt;
+	void *owner;
 };
 
 struct group_device {
@@ -289,7 +291,12 @@ int iommu_probe_device(struct device *dev)
 	mutex_lock(&group->mutex);
 	iommu_alloc_default_domain(group, dev);
 
-	if (group->default_domain) {
+	/*
+	 * If device joined an existing group which has been claimed
+	 * for none kernel DMA purpose, avoid attaching the default
+	 * domain.
+	 */
+	if (group->default_domain && !group->owner) {
 		ret = __iommu_attach_device(group->default_domain, dev);
 		if (ret) {
 			mutex_unlock(&group->mutex);
@@ -2320,7 +2327,7 @@ static int __iommu_attach_group(struct iommu_domain *domain,
 {
 	int ret;
 
-	if (group->default_domain && group->domain != group->default_domain)
+	if (group->domain && group->domain != group->default_domain)
 		return -EBUSY;
 
 	ret = __iommu_group_for_each_dev(group, domain,
@@ -2357,7 +2364,11 @@ static void __iommu_detach_group(struct iommu_domain *domain,
 {
 	int ret;
 
-	if (!group->default_domain) {
+	/*
+	 * If group has been claimed for none kernel DMA purpose, avoid
+	 * re-attaching the default domain.
+	 */
+	if (!group->default_domain || group->owner) {
 		__iommu_group_for_each_dev(group, domain,
 					   iommu_group_do_detach_device);
 		group->domain = NULL;
@@ -3351,3 +3362,147 @@ static ssize_t iommu_group_store_type(struct iommu_group *group,
 
 	return ret;
 }
+
+/**
+ * iommu_device_use_dma_api() - Device driver wants to do DMA through
+ *                              kernel DMA API.
+ * @dev: The device.
+ *
+ * The device driver about to bind @dev wants to do DMA through the kernel
+ * DMA API. Return 0 if it is allowed, otherwise an error.
+ */
+int iommu_device_use_dma_api(struct device *dev)
+{
+	struct iommu_group *group = iommu_group_get(dev);
+	int ret = 0;
+
+	if (!group)
+		return 0;
+
+	mutex_lock(&group->mutex);
+	if (group->owner_cnt) {
+		if (group->domain != group->default_domain ||
+		    group->owner) {
+			ret = -EBUSY;
+			goto unlock_out;
+		}
+	}
+
+	group->owner_cnt++;
+
+unlock_out:
+	mutex_unlock(&group->mutex);
+	iommu_group_put(group);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(iommu_device_use_dma_api);
+
+/**
+ * iommu_device_unuse_dma_api() - Device driver doesn't want to do DMA
+ *                                through kernel DMA API anymore.
+ * @dev: The device.
+ *
+ * The device driver doesn't want to do DMA through kernel DMA API anymore.
+ * It must be called after iommu_device_use_dma_api().
+ */
+void iommu_device_unuse_dma_api(struct device *dev)
+{
+	struct iommu_group *group = iommu_group_get(dev);
+
+	if (!group)
+		return;
+
+	mutex_lock(&group->mutex);
+	if (!WARN_ON(!group->owner_cnt))
+		group->owner_cnt--;
+
+	mutex_unlock(&group->mutex);
+	iommu_group_put(group);
+}
+EXPORT_SYMBOL_GPL(iommu_device_unuse_dma_api);
+
+/**
+ * iommu_group_set_dma_owner() - Set DMA ownership of a group
+ * @group: The group.
+ * @owner: Caller specified pointer. Used for exclusive ownership.
+ *
+ * This is to support backward compatibility for vfio which manages
+ * the dma ownership in iommu_group level. New invocations on this
+ * interface should be prohibited.
+ */
+int iommu_group_set_dma_owner(struct iommu_group *group, void *owner)
+{
+	int ret = 0;
+
+	mutex_lock(&group->mutex);
+	if (group->owner_cnt) {
+		if (group->owner != owner) {
+			ret = -EPERM;
+			goto unlock_out;
+		}
+	} else {
+		if (group->domain && group->domain != group->default_domain) {
+			ret = -EBUSY;
+			goto unlock_out;
+		}
+
+		group->owner = owner;
+		if (group->domain)
+			__iommu_detach_group(group->domain, group);
+	}
+
+	group->owner_cnt++;
+unlock_out:
+	mutex_unlock(&group->mutex);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(iommu_group_set_dma_owner);
+
+/**
+ * iommu_group_release_dma_owner() - Release DMA ownership of a group
+ * @group: The group.
+ *
+ * Release the DMA ownership claimed by iommu_group_set_dma_owner().
+ */
+void iommu_group_release_dma_owner(struct iommu_group *group)
+{
+	mutex_lock(&group->mutex);
+	if (WARN_ON(!group->owner_cnt || !group->owner))
+		goto unlock_out;
+
+	if (--group->owner_cnt > 0)
+		goto unlock_out;
+
+	/*
+	 * The UNMANAGED domain should be detached before all USER
+	 * owners have been released.
+	 */
+	if (!WARN_ON(group->domain) && group->default_domain)
+		__iommu_attach_group(group->default_domain, group);
+	group->owner = NULL;
+
+unlock_out:
+	mutex_unlock(&group->mutex);
+}
+EXPORT_SYMBOL_GPL(iommu_group_release_dma_owner);
+
+/**
+ * iommu_group_dma_owner_claimed() - Query group dma ownership status
+ * @group: The group.
+ *
+ * This provides status query on a given group. It is racey and only for
+ * non-binding status reporting.
+ */
+bool iommu_group_dma_owner_claimed(struct iommu_group *group)
+{
+	unsigned int user;
+
+	mutex_lock(&group->mutex);
+	user = group->owner_cnt;
+	mutex_unlock(&group->mutex);
+
+	return user;
+}
+EXPORT_SYMBOL_GPL(iommu_group_dma_owner_claimed);
-- 
2.25.1

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

^ permalink raw reply related	[flat|nested] 112+ messages in thread

* [PATCH v5 02/14] driver core: Add dma_cleanup callback in bus_type
  2022-01-04  1:56 ` Lu Baolu
@ 2022-01-04  1:56   ` Lu Baolu
  -1 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-01-04  1:56 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Joerg Roedel, Alex Williamson, Bjorn Helgaas,
	Jason Gunthorpe, Christoph Hellwig, Kevin Tian, Ashok Raj
  Cc: Will Deacon, Robin Murphy, Dan Williams, rafael, Diana Craciun,
	Cornelia Huck, Eric Auger, Liu Yi L, Jacob jun Pan,
	Chaitanya Kulkarni, Stuart Yoder, Laurentiu Tudor,
	Thierry Reding, David Airlie, Daniel Vetter, Jonathan Hunter,
	Li Yang, Dmitry Osipenko, iommu, linux-pci, kvm, linux-kernel,
	Lu Baolu

The bus_type structure defines dma_configure() callback for bus drivers
to configure DMA on the devices. This adds the paired dma_cleanup()
callback and calls it during driver unbinding so that bus drivers can do
some cleanup work.

One use case for this paired DMA callbacks is for the bus driver to check
for DMA ownership conflicts during driver binding, where multiple devices
belonging to a same IOMMU group (the minimum granularity of isolation and
protection) may be assigned to kernel drivers or user space respectively.

Without this change, for example, the vfio driver has to listen to a bus
BOUND_DRIVER event and then BUG_ON() in case of dma ownership conflict.
This leads to bad user experience since careless driver binding operation
may crash the system if the admin overlooks the group restriction. Aside
from bad design, this leads to a security problem as a root user, even with
lockdown=integrity, can force the kernel to BUG.

With this change, the bus driver could check and set the DMA ownership in
driver binding process and fail on ownership conflicts. The DMA ownership
should be released during driver unbinding.

Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
---
 include/linux/device/bus.h | 3 +++
 drivers/base/dd.c          | 5 +++++
 2 files changed, 8 insertions(+)

diff --git a/include/linux/device/bus.h b/include/linux/device/bus.h
index a039ab809753..d8b29ccd07e5 100644
--- a/include/linux/device/bus.h
+++ b/include/linux/device/bus.h
@@ -59,6 +59,8 @@ struct fwnode_handle;
  *		bus supports.
  * @dma_configure:	Called to setup DMA configuration on a device on
  *			this bus.
+ * @dma_cleanup:	Called to cleanup DMA configuration on a device on
+ *			this bus.
  * @pm:		Power management operations of this bus, callback the specific
  *		device driver's pm-ops.
  * @iommu_ops:  IOMMU specific operations for this bus, used to attach IOMMU
@@ -103,6 +105,7 @@ struct bus_type {
 	int (*num_vf)(struct device *dev);
 
 	int (*dma_configure)(struct device *dev);
+	void (*dma_cleanup)(struct device *dev);
 
 	const struct dev_pm_ops *pm;
 
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 9eaaff2f556c..2bcbd358eda3 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -662,6 +662,8 @@ static int really_probe(struct device *dev, struct device_driver *drv)
 	if (dev->bus)
 		blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
 					     BUS_NOTIFY_DRIVER_NOT_BOUND, dev);
+	if (dev->bus->dma_cleanup)
+		dev->bus->dma_cleanup(dev);
 pinctrl_bind_failed:
 	device_links_no_driver(dev);
 	devres_release_all(dev);
@@ -1205,6 +1207,9 @@ static void __device_release_driver(struct device *dev, struct device *parent)
 		else if (drv->remove)
 			drv->remove(dev);
 
+		if (dev->bus->dma_cleanup)
+			dev->bus->dma_cleanup(dev);
+
 		device_links_driver_cleanup(dev);
 
 		devres_release_all(dev);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 112+ messages in thread

* [PATCH v5 02/14] driver core: Add dma_cleanup callback in bus_type
@ 2022-01-04  1:56   ` Lu Baolu
  0 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-01-04  1:56 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Joerg Roedel, Alex Williamson, Bjorn Helgaas,
	Jason Gunthorpe, Christoph Hellwig, Kevin Tian, Ashok Raj
  Cc: kvm, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Stuart Yoder,
	Jonathan Hunter, Chaitanya Kulkarni, Dan Williams, Cornelia Huck,
	linux-kernel, Li Yang, iommu, Jacob jun Pan, Daniel Vetter,
	Robin Murphy

The bus_type structure defines dma_configure() callback for bus drivers
to configure DMA on the devices. This adds the paired dma_cleanup()
callback and calls it during driver unbinding so that bus drivers can do
some cleanup work.

One use case for this paired DMA callbacks is for the bus driver to check
for DMA ownership conflicts during driver binding, where multiple devices
belonging to a same IOMMU group (the minimum granularity of isolation and
protection) may be assigned to kernel drivers or user space respectively.

Without this change, for example, the vfio driver has to listen to a bus
BOUND_DRIVER event and then BUG_ON() in case of dma ownership conflict.
This leads to bad user experience since careless driver binding operation
may crash the system if the admin overlooks the group restriction. Aside
from bad design, this leads to a security problem as a root user, even with
lockdown=integrity, can force the kernel to BUG.

With this change, the bus driver could check and set the DMA ownership in
driver binding process and fail on ownership conflicts. The DMA ownership
should be released during driver unbinding.

Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
---
 include/linux/device/bus.h | 3 +++
 drivers/base/dd.c          | 5 +++++
 2 files changed, 8 insertions(+)

diff --git a/include/linux/device/bus.h b/include/linux/device/bus.h
index a039ab809753..d8b29ccd07e5 100644
--- a/include/linux/device/bus.h
+++ b/include/linux/device/bus.h
@@ -59,6 +59,8 @@ struct fwnode_handle;
  *		bus supports.
  * @dma_configure:	Called to setup DMA configuration on a device on
  *			this bus.
+ * @dma_cleanup:	Called to cleanup DMA configuration on a device on
+ *			this bus.
  * @pm:		Power management operations of this bus, callback the specific
  *		device driver's pm-ops.
  * @iommu_ops:  IOMMU specific operations for this bus, used to attach IOMMU
@@ -103,6 +105,7 @@ struct bus_type {
 	int (*num_vf)(struct device *dev);
 
 	int (*dma_configure)(struct device *dev);
+	void (*dma_cleanup)(struct device *dev);
 
 	const struct dev_pm_ops *pm;
 
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 9eaaff2f556c..2bcbd358eda3 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -662,6 +662,8 @@ static int really_probe(struct device *dev, struct device_driver *drv)
 	if (dev->bus)
 		blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
 					     BUS_NOTIFY_DRIVER_NOT_BOUND, dev);
+	if (dev->bus->dma_cleanup)
+		dev->bus->dma_cleanup(dev);
 pinctrl_bind_failed:
 	device_links_no_driver(dev);
 	devres_release_all(dev);
@@ -1205,6 +1207,9 @@ static void __device_release_driver(struct device *dev, struct device *parent)
 		else if (drv->remove)
 			drv->remove(dev);
 
+		if (dev->bus->dma_cleanup)
+			dev->bus->dma_cleanup(dev);
+
 		device_links_driver_cleanup(dev);
 
 		devres_release_all(dev);
-- 
2.25.1

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

^ permalink raw reply related	[flat|nested] 112+ messages in thread

* [PATCH v5 03/14] amba: Stop sharing platform_dma_configure()
  2022-01-04  1:56 ` Lu Baolu
@ 2022-01-04  1:56   ` Lu Baolu
  -1 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-01-04  1:56 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Joerg Roedel, Alex Williamson, Bjorn Helgaas,
	Jason Gunthorpe, Christoph Hellwig, Kevin Tian, Ashok Raj
  Cc: Will Deacon, Robin Murphy, Dan Williams, rafael, Diana Craciun,
	Cornelia Huck, Eric Auger, Liu Yi L, Jacob jun Pan,
	Chaitanya Kulkarni, Stuart Yoder, Laurentiu Tudor,
	Thierry Reding, David Airlie, Daniel Vetter, Jonathan Hunter,
	Li Yang, Dmitry Osipenko, iommu, linux-pci, kvm, linux-kernel,
	Lu Baolu

Stop sharing platform_dma_configure() helper as they are about to have
their specific bus dma_configure callbacks.

Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
---
 include/linux/platform_device.h |  2 --
 drivers/amba/bus.c              | 19 ++++++++++++++++++-
 drivers/base/platform.c         |  3 +--
 3 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
index 7c96f169d274..17fde717df68 100644
--- a/include/linux/platform_device.h
+++ b/include/linux/platform_device.h
@@ -328,8 +328,6 @@ extern int platform_pm_restore(struct device *dev);
 #define platform_pm_restore		NULL
 #endif
 
-extern int platform_dma_configure(struct device *dev);
-
 #ifdef CONFIG_PM_SLEEP
 #define USE_PLATFORM_PM_SLEEP_OPS \
 	.suspend = platform_pm_suspend, \
diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
index 720aa6cdd402..850a0a8973c6 100644
--- a/drivers/amba/bus.c
+++ b/drivers/amba/bus.c
@@ -20,6 +20,8 @@
 #include <linux/platform_device.h>
 #include <linux/reset.h>
 #include <linux/of_irq.h>
+#include <linux/of_device.h>
+#include <linux/acpi.h>
 
 #include <asm/irq.h>
 
@@ -251,6 +253,21 @@ static void amba_shutdown(struct device *dev)
 		drv->shutdown(to_amba_device(dev));
 }
 
+static int amba_dma_configure(struct device *dev)
+{
+	enum dev_dma_attr attr;
+	int ret = 0;
+
+	if (dev->of_node) {
+		ret = of_dma_configure(dev, dev->of_node, true);
+	} else if (has_acpi_companion(dev)) {
+		attr = acpi_get_dma_attr(to_acpi_device_node(dev->fwnode));
+		ret = acpi_dma_configure(dev, attr);
+	}
+
+	return ret;
+}
+
 #ifdef CONFIG_PM
 /*
  * Hooks to provide runtime PM of the pclk (bus clock).  It is safe to
@@ -319,7 +336,7 @@ struct bus_type amba_bustype = {
 	.probe		= amba_probe,
 	.remove		= amba_remove,
 	.shutdown	= amba_shutdown,
-	.dma_configure	= platform_dma_configure,
+	.dma_configure	= amba_dma_configure,
 	.pm		= &amba_pm,
 };
 EXPORT_SYMBOL_GPL(amba_bustype);
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 598acf93a360..b4d36b46ab2e 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -1449,8 +1449,7 @@ static void platform_shutdown(struct device *_dev)
 		drv->shutdown(dev);
 }
 
-
-int platform_dma_configure(struct device *dev)
+static int platform_dma_configure(struct device *dev)
 {
 	enum dev_dma_attr attr;
 	int ret = 0;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 112+ messages in thread

* [PATCH v5 03/14] amba: Stop sharing platform_dma_configure()
@ 2022-01-04  1:56   ` Lu Baolu
  0 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-01-04  1:56 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Joerg Roedel, Alex Williamson, Bjorn Helgaas,
	Jason Gunthorpe, Christoph Hellwig, Kevin Tian, Ashok Raj
  Cc: kvm, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Stuart Yoder,
	Jonathan Hunter, Chaitanya Kulkarni, Dan Williams, Cornelia Huck,
	linux-kernel, Li Yang, iommu, Jacob jun Pan, Daniel Vetter,
	Robin Murphy

Stop sharing platform_dma_configure() helper as they are about to have
their specific bus dma_configure callbacks.

Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
---
 include/linux/platform_device.h |  2 --
 drivers/amba/bus.c              | 19 ++++++++++++++++++-
 drivers/base/platform.c         |  3 +--
 3 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
index 7c96f169d274..17fde717df68 100644
--- a/include/linux/platform_device.h
+++ b/include/linux/platform_device.h
@@ -328,8 +328,6 @@ extern int platform_pm_restore(struct device *dev);
 #define platform_pm_restore		NULL
 #endif
 
-extern int platform_dma_configure(struct device *dev);
-
 #ifdef CONFIG_PM_SLEEP
 #define USE_PLATFORM_PM_SLEEP_OPS \
 	.suspend = platform_pm_suspend, \
diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
index 720aa6cdd402..850a0a8973c6 100644
--- a/drivers/amba/bus.c
+++ b/drivers/amba/bus.c
@@ -20,6 +20,8 @@
 #include <linux/platform_device.h>
 #include <linux/reset.h>
 #include <linux/of_irq.h>
+#include <linux/of_device.h>
+#include <linux/acpi.h>
 
 #include <asm/irq.h>
 
@@ -251,6 +253,21 @@ static void amba_shutdown(struct device *dev)
 		drv->shutdown(to_amba_device(dev));
 }
 
+static int amba_dma_configure(struct device *dev)
+{
+	enum dev_dma_attr attr;
+	int ret = 0;
+
+	if (dev->of_node) {
+		ret = of_dma_configure(dev, dev->of_node, true);
+	} else if (has_acpi_companion(dev)) {
+		attr = acpi_get_dma_attr(to_acpi_device_node(dev->fwnode));
+		ret = acpi_dma_configure(dev, attr);
+	}
+
+	return ret;
+}
+
 #ifdef CONFIG_PM
 /*
  * Hooks to provide runtime PM of the pclk (bus clock).  It is safe to
@@ -319,7 +336,7 @@ struct bus_type amba_bustype = {
 	.probe		= amba_probe,
 	.remove		= amba_remove,
 	.shutdown	= amba_shutdown,
-	.dma_configure	= platform_dma_configure,
+	.dma_configure	= amba_dma_configure,
 	.pm		= &amba_pm,
 };
 EXPORT_SYMBOL_GPL(amba_bustype);
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 598acf93a360..b4d36b46ab2e 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -1449,8 +1449,7 @@ static void platform_shutdown(struct device *_dev)
 		drv->shutdown(dev);
 }
 
-
-int platform_dma_configure(struct device *dev)
+static int platform_dma_configure(struct device *dev)
 {
 	enum dev_dma_attr attr;
 	int ret = 0;
-- 
2.25.1

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

^ permalink raw reply related	[flat|nested] 112+ messages in thread

* [PATCH v5 04/14] driver core: platform: Add driver dma ownership management
  2022-01-04  1:56 ` Lu Baolu
@ 2022-01-04  1:56   ` Lu Baolu
  -1 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-01-04  1:56 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Joerg Roedel, Alex Williamson, Bjorn Helgaas,
	Jason Gunthorpe, Christoph Hellwig, Kevin Tian, Ashok Raj
  Cc: Will Deacon, Robin Murphy, Dan Williams, rafael, Diana Craciun,
	Cornelia Huck, Eric Auger, Liu Yi L, Jacob jun Pan,
	Chaitanya Kulkarni, Stuart Yoder, Laurentiu Tudor,
	Thierry Reding, David Airlie, Daniel Vetter, Jonathan Hunter,
	Li Yang, Dmitry Osipenko, iommu, linux-pci, kvm, linux-kernel,
	Lu Baolu

Multiple platform devices may be placed in the same IOMMU group because
they cannot be isolated from each other. These devices must either be
entirely under kernel control or userspace control, never a mixture. This
checks and sets DMA ownership during driver binding, and release the
ownership during driver unbinding.

The device driver may set a new flag (no_kernel_api_dma) to skip calling
iommu_device_use_dma_api() during the binding process. For instance, the
userspace framework drivers (vfio etc.) which need to manually claim
their own dma ownership when assigning the device to userspace.

Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
---
 include/linux/platform_device.h |  1 +
 drivers/base/platform.c         | 20 ++++++++++++++++++++
 2 files changed, 21 insertions(+)

diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
index 17fde717df68..8f0eaafcef47 100644
--- a/include/linux/platform_device.h
+++ b/include/linux/platform_device.h
@@ -210,6 +210,7 @@ struct platform_driver {
 	struct device_driver driver;
 	const struct platform_device_id *id_table;
 	bool prevent_deferred_probe;
+	bool no_kernel_api_dma;
 };
 
 #define to_platform_driver(drv)	(container_of((drv), struct platform_driver, \
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index b4d36b46ab2e..d5171e44d903 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -30,6 +30,7 @@
 #include <linux/property.h>
 #include <linux/kmemleak.h>
 #include <linux/types.h>
+#include <linux/iommu.h>
 
 #include "base.h"
 #include "power/power.h"
@@ -1451,9 +1452,16 @@ static void platform_shutdown(struct device *_dev)
 
 static int platform_dma_configure(struct device *dev)
 {
+	struct platform_driver *drv = to_platform_driver(dev->driver);
 	enum dev_dma_attr attr;
 	int ret = 0;
 
+	if (!drv->no_kernel_api_dma) {
+		ret = iommu_device_use_dma_api(dev);
+		if (ret)
+			return ret;
+	}
+
 	if (dev->of_node) {
 		ret = of_dma_configure(dev, dev->of_node, true);
 	} else if (has_acpi_companion(dev)) {
@@ -1461,9 +1469,20 @@ static int platform_dma_configure(struct device *dev)
 		ret = acpi_dma_configure(dev, attr);
 	}
 
+	if (ret && !drv->no_kernel_api_dma)
+		iommu_device_unuse_dma_api(dev);
+
 	return ret;
 }
 
+static void platform_dma_cleanup(struct device *dev)
+{
+	struct platform_driver *drv = to_platform_driver(dev->driver);
+
+	if (!drv->no_kernel_api_dma)
+		iommu_device_unuse_dma_api(dev);
+}
+
 static const struct dev_pm_ops platform_dev_pm_ops = {
 	SET_RUNTIME_PM_OPS(pm_generic_runtime_suspend, pm_generic_runtime_resume, NULL)
 	USE_PLATFORM_PM_SLEEP_OPS
@@ -1478,6 +1497,7 @@ struct bus_type platform_bus_type = {
 	.remove		= platform_remove,
 	.shutdown	= platform_shutdown,
 	.dma_configure	= platform_dma_configure,
+	.dma_cleanup	= platform_dma_cleanup,
 	.pm		= &platform_dev_pm_ops,
 };
 EXPORT_SYMBOL_GPL(platform_bus_type);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 112+ messages in thread

* [PATCH v5 04/14] driver core: platform: Add driver dma ownership management
@ 2022-01-04  1:56   ` Lu Baolu
  0 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-01-04  1:56 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Joerg Roedel, Alex Williamson, Bjorn Helgaas,
	Jason Gunthorpe, Christoph Hellwig, Kevin Tian, Ashok Raj
  Cc: kvm, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Stuart Yoder,
	Jonathan Hunter, Chaitanya Kulkarni, Dan Williams, Cornelia Huck,
	linux-kernel, Li Yang, iommu, Jacob jun Pan, Daniel Vetter,
	Robin Murphy

Multiple platform devices may be placed in the same IOMMU group because
they cannot be isolated from each other. These devices must either be
entirely under kernel control or userspace control, never a mixture. This
checks and sets DMA ownership during driver binding, and release the
ownership during driver unbinding.

The device driver may set a new flag (no_kernel_api_dma) to skip calling
iommu_device_use_dma_api() during the binding process. For instance, the
userspace framework drivers (vfio etc.) which need to manually claim
their own dma ownership when assigning the device to userspace.

Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
---
 include/linux/platform_device.h |  1 +
 drivers/base/platform.c         | 20 ++++++++++++++++++++
 2 files changed, 21 insertions(+)

diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
index 17fde717df68..8f0eaafcef47 100644
--- a/include/linux/platform_device.h
+++ b/include/linux/platform_device.h
@@ -210,6 +210,7 @@ struct platform_driver {
 	struct device_driver driver;
 	const struct platform_device_id *id_table;
 	bool prevent_deferred_probe;
+	bool no_kernel_api_dma;
 };
 
 #define to_platform_driver(drv)	(container_of((drv), struct platform_driver, \
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index b4d36b46ab2e..d5171e44d903 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -30,6 +30,7 @@
 #include <linux/property.h>
 #include <linux/kmemleak.h>
 #include <linux/types.h>
+#include <linux/iommu.h>
 
 #include "base.h"
 #include "power/power.h"
@@ -1451,9 +1452,16 @@ static void platform_shutdown(struct device *_dev)
 
 static int platform_dma_configure(struct device *dev)
 {
+	struct platform_driver *drv = to_platform_driver(dev->driver);
 	enum dev_dma_attr attr;
 	int ret = 0;
 
+	if (!drv->no_kernel_api_dma) {
+		ret = iommu_device_use_dma_api(dev);
+		if (ret)
+			return ret;
+	}
+
 	if (dev->of_node) {
 		ret = of_dma_configure(dev, dev->of_node, true);
 	} else if (has_acpi_companion(dev)) {
@@ -1461,9 +1469,20 @@ static int platform_dma_configure(struct device *dev)
 		ret = acpi_dma_configure(dev, attr);
 	}
 
+	if (ret && !drv->no_kernel_api_dma)
+		iommu_device_unuse_dma_api(dev);
+
 	return ret;
 }
 
+static void platform_dma_cleanup(struct device *dev)
+{
+	struct platform_driver *drv = to_platform_driver(dev->driver);
+
+	if (!drv->no_kernel_api_dma)
+		iommu_device_unuse_dma_api(dev);
+}
+
 static const struct dev_pm_ops platform_dev_pm_ops = {
 	SET_RUNTIME_PM_OPS(pm_generic_runtime_suspend, pm_generic_runtime_resume, NULL)
 	USE_PLATFORM_PM_SLEEP_OPS
@@ -1478,6 +1497,7 @@ struct bus_type platform_bus_type = {
 	.remove		= platform_remove,
 	.shutdown	= platform_shutdown,
 	.dma_configure	= platform_dma_configure,
+	.dma_cleanup	= platform_dma_cleanup,
 	.pm		= &platform_dev_pm_ops,
 };
 EXPORT_SYMBOL_GPL(platform_bus_type);
-- 
2.25.1

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

^ permalink raw reply related	[flat|nested] 112+ messages in thread

* [PATCH v5 05/14] amba: Add driver dma ownership management
  2022-01-04  1:56 ` Lu Baolu
@ 2022-01-04  1:56   ` Lu Baolu
  -1 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-01-04  1:56 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Joerg Roedel, Alex Williamson, Bjorn Helgaas,
	Jason Gunthorpe, Christoph Hellwig, Kevin Tian, Ashok Raj
  Cc: Will Deacon, Robin Murphy, Dan Williams, rafael, Diana Craciun,
	Cornelia Huck, Eric Auger, Liu Yi L, Jacob jun Pan,
	Chaitanya Kulkarni, Stuart Yoder, Laurentiu Tudor,
	Thierry Reding, David Airlie, Daniel Vetter, Jonathan Hunter,
	Li Yang, Dmitry Osipenko, iommu, linux-pci, kvm, linux-kernel,
	Lu Baolu

Multiple amba devices may be placed in the same IOMMU group because
they cannot be isolated from each other. These devices must either be
entirely under kernel control or userspace control, never a mixture. This
checks and sets DMA ownership during driver binding, and release the
ownership during driver unbinding.

The device driver may set a new flag (no_kernel_api_dma) to skip calling
iommu_device_use_dma_api() during the binding process. For instance, the
userspace framework drivers (vfio etc.) which need to manually claim
their own dma ownership when assigning the device to userspace.

Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
---
 include/linux/amba/bus.h |  1 +
 drivers/amba/bus.c       | 20 ++++++++++++++++++++
 2 files changed, 21 insertions(+)

diff --git a/include/linux/amba/bus.h b/include/linux/amba/bus.h
index edfcf7a14dcd..a4f374e2fd35 100644
--- a/include/linux/amba/bus.h
+++ b/include/linux/amba/bus.h
@@ -79,6 +79,7 @@ struct amba_driver {
 	void			(*remove)(struct amba_device *);
 	void			(*shutdown)(struct amba_device *);
 	const struct amba_id	*id_table;
+	bool no_kernel_api_dma;
 };
 
 /*
diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
index 850a0a8973c6..42b20ecfa50c 100644
--- a/drivers/amba/bus.c
+++ b/drivers/amba/bus.c
@@ -22,6 +22,7 @@
 #include <linux/of_irq.h>
 #include <linux/of_device.h>
 #include <linux/acpi.h>
+#include <linux/iommu.h>
 
 #include <asm/irq.h>
 
@@ -255,9 +256,16 @@ static void amba_shutdown(struct device *dev)
 
 static int amba_dma_configure(struct device *dev)
 {
+	struct amba_driver *drv = to_amba_driver(dev->driver);
 	enum dev_dma_attr attr;
 	int ret = 0;
 
+	if (!drv->no_kernel_api_dma) {
+		ret = iommu_device_use_dma_api(dev);
+		if (ret)
+			return ret;
+	}
+
 	if (dev->of_node) {
 		ret = of_dma_configure(dev, dev->of_node, true);
 	} else if (has_acpi_companion(dev)) {
@@ -265,9 +273,20 @@ static int amba_dma_configure(struct device *dev)
 		ret = acpi_dma_configure(dev, attr);
 	}
 
+	if (ret && !drv->no_kernel_api_dma)
+		iommu_device_unuse_dma_api(dev);
+
 	return ret;
 }
 
+static void amba_dma_cleanup(struct device *dev)
+{
+	struct amba_driver *drv = to_amba_driver(dev->driver);
+
+	if (!drv->no_kernel_api_dma)
+		iommu_device_unuse_dma_api(dev);
+}
+
 #ifdef CONFIG_PM
 /*
  * Hooks to provide runtime PM of the pclk (bus clock).  It is safe to
@@ -337,6 +356,7 @@ struct bus_type amba_bustype = {
 	.remove		= amba_remove,
 	.shutdown	= amba_shutdown,
 	.dma_configure	= amba_dma_configure,
+	.dma_cleanup	= amba_dma_cleanup,
 	.pm		= &amba_pm,
 };
 EXPORT_SYMBOL_GPL(amba_bustype);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 112+ messages in thread

* [PATCH v5 05/14] amba: Add driver dma ownership management
@ 2022-01-04  1:56   ` Lu Baolu
  0 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-01-04  1:56 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Joerg Roedel, Alex Williamson, Bjorn Helgaas,
	Jason Gunthorpe, Christoph Hellwig, Kevin Tian, Ashok Raj
  Cc: kvm, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Stuart Yoder,
	Jonathan Hunter, Chaitanya Kulkarni, Dan Williams, Cornelia Huck,
	linux-kernel, Li Yang, iommu, Jacob jun Pan, Daniel Vetter,
	Robin Murphy

Multiple amba devices may be placed in the same IOMMU group because
they cannot be isolated from each other. These devices must either be
entirely under kernel control or userspace control, never a mixture. This
checks and sets DMA ownership during driver binding, and release the
ownership during driver unbinding.

The device driver may set a new flag (no_kernel_api_dma) to skip calling
iommu_device_use_dma_api() during the binding process. For instance, the
userspace framework drivers (vfio etc.) which need to manually claim
their own dma ownership when assigning the device to userspace.

Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
---
 include/linux/amba/bus.h |  1 +
 drivers/amba/bus.c       | 20 ++++++++++++++++++++
 2 files changed, 21 insertions(+)

diff --git a/include/linux/amba/bus.h b/include/linux/amba/bus.h
index edfcf7a14dcd..a4f374e2fd35 100644
--- a/include/linux/amba/bus.h
+++ b/include/linux/amba/bus.h
@@ -79,6 +79,7 @@ struct amba_driver {
 	void			(*remove)(struct amba_device *);
 	void			(*shutdown)(struct amba_device *);
 	const struct amba_id	*id_table;
+	bool no_kernel_api_dma;
 };
 
 /*
diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
index 850a0a8973c6..42b20ecfa50c 100644
--- a/drivers/amba/bus.c
+++ b/drivers/amba/bus.c
@@ -22,6 +22,7 @@
 #include <linux/of_irq.h>
 #include <linux/of_device.h>
 #include <linux/acpi.h>
+#include <linux/iommu.h>
 
 #include <asm/irq.h>
 
@@ -255,9 +256,16 @@ static void amba_shutdown(struct device *dev)
 
 static int amba_dma_configure(struct device *dev)
 {
+	struct amba_driver *drv = to_amba_driver(dev->driver);
 	enum dev_dma_attr attr;
 	int ret = 0;
 
+	if (!drv->no_kernel_api_dma) {
+		ret = iommu_device_use_dma_api(dev);
+		if (ret)
+			return ret;
+	}
+
 	if (dev->of_node) {
 		ret = of_dma_configure(dev, dev->of_node, true);
 	} else if (has_acpi_companion(dev)) {
@@ -265,9 +273,20 @@ static int amba_dma_configure(struct device *dev)
 		ret = acpi_dma_configure(dev, attr);
 	}
 
+	if (ret && !drv->no_kernel_api_dma)
+		iommu_device_unuse_dma_api(dev);
+
 	return ret;
 }
 
+static void amba_dma_cleanup(struct device *dev)
+{
+	struct amba_driver *drv = to_amba_driver(dev->driver);
+
+	if (!drv->no_kernel_api_dma)
+		iommu_device_unuse_dma_api(dev);
+}
+
 #ifdef CONFIG_PM
 /*
  * Hooks to provide runtime PM of the pclk (bus clock).  It is safe to
@@ -337,6 +356,7 @@ struct bus_type amba_bustype = {
 	.remove		= amba_remove,
 	.shutdown	= amba_shutdown,
 	.dma_configure	= amba_dma_configure,
+	.dma_cleanup	= amba_dma_cleanup,
 	.pm		= &amba_pm,
 };
 EXPORT_SYMBOL_GPL(amba_bustype);
-- 
2.25.1

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

^ permalink raw reply related	[flat|nested] 112+ messages in thread

* [PATCH v5 06/14] bus: fsl-mc: Add driver dma ownership management
  2022-01-04  1:56 ` Lu Baolu
@ 2022-01-04  1:56   ` Lu Baolu
  -1 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-01-04  1:56 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Joerg Roedel, Alex Williamson, Bjorn Helgaas,
	Jason Gunthorpe, Christoph Hellwig, Kevin Tian, Ashok Raj
  Cc: Will Deacon, Robin Murphy, Dan Williams, rafael, Diana Craciun,
	Cornelia Huck, Eric Auger, Liu Yi L, Jacob jun Pan,
	Chaitanya Kulkarni, Stuart Yoder, Laurentiu Tudor,
	Thierry Reding, David Airlie, Daniel Vetter, Jonathan Hunter,
	Li Yang, Dmitry Osipenko, iommu, linux-pci, kvm, linux-kernel,
	Lu Baolu

Multiple fsl-mc devices may be placed in the same IOMMU group because
they cannot be isolated from each other. These devices must either be
entirely under kernel control or userspace control, never a mixture. This
checks and sets DMA ownership during driver binding, and release the
ownership during driver unbinding.

The device driver may set a new flag (no_kernel_api_dma) to skip calling
iommu_device_use_dma_api() during the binding process. For instance, the
userspace framework drivers (vfio etc.) which need to manually claim
their own dma ownership when assigning the device to userspace.

Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
---
 include/linux/fsl/mc.h          |  5 +++++
 drivers/bus/fsl-mc/fsl-mc-bus.c | 26 ++++++++++++++++++++++++--
 2 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/include/linux/fsl/mc.h b/include/linux/fsl/mc.h
index e026f6c48b49..e85a5f18104d 100644
--- a/include/linux/fsl/mc.h
+++ b/include/linux/fsl/mc.h
@@ -32,6 +32,10 @@ struct fsl_mc_io;
  * @shutdown: Function called at shutdown time to quiesce the device
  * @suspend: Function called when a device is stopped
  * @resume: Function called when a device is resumed
+ * @no_kernel_api_dma: Device driver doesn't use kernel DMA API for DMA.
+ *		Drivers which don't require DMA or want to manually claim the
+ *		owner type (e.g. userspace driver frameworks) could set this
+ *		flag.
  *
  * Generic DPAA device driver object for device drivers that are registered
  * with a DPRC bus. This structure is to be embedded in each device-specific
@@ -45,6 +49,7 @@ struct fsl_mc_driver {
 	void (*shutdown)(struct fsl_mc_device *dev);
 	int (*suspend)(struct fsl_mc_device *dev, pm_message_t state);
 	int (*resume)(struct fsl_mc_device *dev);
+	bool no_kernel_api_dma;
 };
 
 #define to_fsl_mc_driver(_drv) \
diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc-bus.c
index 8fd4a356a86e..9ee85f43822a 100644
--- a/drivers/bus/fsl-mc/fsl-mc-bus.c
+++ b/drivers/bus/fsl-mc/fsl-mc-bus.c
@@ -140,15 +140,36 @@ static int fsl_mc_dma_configure(struct device *dev)
 {
 	struct device *dma_dev = dev;
 	struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
+	struct fsl_mc_driver *mc_drv = to_fsl_mc_driver(dev->driver);
 	u32 input_id = mc_dev->icid;
+	int ret;
+
+	if (!mc_drv->no_kernel_api_dma) {
+		ret = iommu_device_use_dma_api(dev);
+		if (ret)
+			return ret;
+	}
 
 	while (dev_is_fsl_mc(dma_dev))
 		dma_dev = dma_dev->parent;
 
 	if (dev_of_node(dma_dev))
-		return of_dma_configure_id(dev, dma_dev->of_node, 0, &input_id);
+		ret = of_dma_configure_id(dev, dma_dev->of_node, 0, &input_id);
+	else
+		ret = acpi_dma_configure_id(dev, DEV_DMA_COHERENT, &input_id);
+
+	if (ret && !mc_drv->no_kernel_api_dma)
+		iommu_device_unuse_dma_api(dev);
+
+	return ret;
+}
+
+static void fsl_mc_dma_cleanup(struct device *dev)
+{
+	struct fsl_mc_driver *mc_drv = to_fsl_mc_driver(dev->driver);
 
-	return acpi_dma_configure_id(dev, DEV_DMA_COHERENT, &input_id);
+	if (!mc_drv->no_kernel_api_dma)
+		iommu_device_unuse_dma_api(dev);
 }
 
 static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
@@ -312,6 +333,7 @@ struct bus_type fsl_mc_bus_type = {
 	.match = fsl_mc_bus_match,
 	.uevent = fsl_mc_bus_uevent,
 	.dma_configure  = fsl_mc_dma_configure,
+	.dma_cleanup = fsl_mc_dma_cleanup,
 	.dev_groups = fsl_mc_dev_groups,
 	.bus_groups = fsl_mc_bus_groups,
 };
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 112+ messages in thread

* [PATCH v5 06/14] bus: fsl-mc: Add driver dma ownership management
@ 2022-01-04  1:56   ` Lu Baolu
  0 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-01-04  1:56 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Joerg Roedel, Alex Williamson, Bjorn Helgaas,
	Jason Gunthorpe, Christoph Hellwig, Kevin Tian, Ashok Raj
  Cc: kvm, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Stuart Yoder,
	Jonathan Hunter, Chaitanya Kulkarni, Dan Williams, Cornelia Huck,
	linux-kernel, Li Yang, iommu, Jacob jun Pan, Daniel Vetter,
	Robin Murphy

Multiple fsl-mc devices may be placed in the same IOMMU group because
they cannot be isolated from each other. These devices must either be
entirely under kernel control or userspace control, never a mixture. This
checks and sets DMA ownership during driver binding, and release the
ownership during driver unbinding.

The device driver may set a new flag (no_kernel_api_dma) to skip calling
iommu_device_use_dma_api() during the binding process. For instance, the
userspace framework drivers (vfio etc.) which need to manually claim
their own dma ownership when assigning the device to userspace.

Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
---
 include/linux/fsl/mc.h          |  5 +++++
 drivers/bus/fsl-mc/fsl-mc-bus.c | 26 ++++++++++++++++++++++++--
 2 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/include/linux/fsl/mc.h b/include/linux/fsl/mc.h
index e026f6c48b49..e85a5f18104d 100644
--- a/include/linux/fsl/mc.h
+++ b/include/linux/fsl/mc.h
@@ -32,6 +32,10 @@ struct fsl_mc_io;
  * @shutdown: Function called at shutdown time to quiesce the device
  * @suspend: Function called when a device is stopped
  * @resume: Function called when a device is resumed
+ * @no_kernel_api_dma: Device driver doesn't use kernel DMA API for DMA.
+ *		Drivers which don't require DMA or want to manually claim the
+ *		owner type (e.g. userspace driver frameworks) could set this
+ *		flag.
  *
  * Generic DPAA device driver object for device drivers that are registered
  * with a DPRC bus. This structure is to be embedded in each device-specific
@@ -45,6 +49,7 @@ struct fsl_mc_driver {
 	void (*shutdown)(struct fsl_mc_device *dev);
 	int (*suspend)(struct fsl_mc_device *dev, pm_message_t state);
 	int (*resume)(struct fsl_mc_device *dev);
+	bool no_kernel_api_dma;
 };
 
 #define to_fsl_mc_driver(_drv) \
diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc-bus.c
index 8fd4a356a86e..9ee85f43822a 100644
--- a/drivers/bus/fsl-mc/fsl-mc-bus.c
+++ b/drivers/bus/fsl-mc/fsl-mc-bus.c
@@ -140,15 +140,36 @@ static int fsl_mc_dma_configure(struct device *dev)
 {
 	struct device *dma_dev = dev;
 	struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
+	struct fsl_mc_driver *mc_drv = to_fsl_mc_driver(dev->driver);
 	u32 input_id = mc_dev->icid;
+	int ret;
+
+	if (!mc_drv->no_kernel_api_dma) {
+		ret = iommu_device_use_dma_api(dev);
+		if (ret)
+			return ret;
+	}
 
 	while (dev_is_fsl_mc(dma_dev))
 		dma_dev = dma_dev->parent;
 
 	if (dev_of_node(dma_dev))
-		return of_dma_configure_id(dev, dma_dev->of_node, 0, &input_id);
+		ret = of_dma_configure_id(dev, dma_dev->of_node, 0, &input_id);
+	else
+		ret = acpi_dma_configure_id(dev, DEV_DMA_COHERENT, &input_id);
+
+	if (ret && !mc_drv->no_kernel_api_dma)
+		iommu_device_unuse_dma_api(dev);
+
+	return ret;
+}
+
+static void fsl_mc_dma_cleanup(struct device *dev)
+{
+	struct fsl_mc_driver *mc_drv = to_fsl_mc_driver(dev->driver);
 
-	return acpi_dma_configure_id(dev, DEV_DMA_COHERENT, &input_id);
+	if (!mc_drv->no_kernel_api_dma)
+		iommu_device_unuse_dma_api(dev);
 }
 
 static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
@@ -312,6 +333,7 @@ struct bus_type fsl_mc_bus_type = {
 	.match = fsl_mc_bus_match,
 	.uevent = fsl_mc_bus_uevent,
 	.dma_configure  = fsl_mc_dma_configure,
+	.dma_cleanup = fsl_mc_dma_cleanup,
 	.dev_groups = fsl_mc_dev_groups,
 	.bus_groups = fsl_mc_bus_groups,
 };
-- 
2.25.1

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

^ permalink raw reply related	[flat|nested] 112+ messages in thread

* [PATCH v5 07/14] PCI: Add driver dma ownership management
  2022-01-04  1:56 ` Lu Baolu
@ 2022-01-04  1:56   ` Lu Baolu
  -1 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-01-04  1:56 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Joerg Roedel, Alex Williamson, Bjorn Helgaas,
	Jason Gunthorpe, Christoph Hellwig, Kevin Tian, Ashok Raj
  Cc: Will Deacon, Robin Murphy, Dan Williams, rafael, Diana Craciun,
	Cornelia Huck, Eric Auger, Liu Yi L, Jacob jun Pan,
	Chaitanya Kulkarni, Stuart Yoder, Laurentiu Tudor,
	Thierry Reding, David Airlie, Daniel Vetter, Jonathan Hunter,
	Li Yang, Dmitry Osipenko, iommu, linux-pci, kvm, linux-kernel,
	Lu Baolu

Multiple PCI devices may be placed in the same IOMMU group because
they cannot be isolated from each other. These devices must either be
entirely under kernel control or userspace control, never a mixture. This
checks and sets DMA ownership during driver binding, and release the
ownership during driver unbinding.

The device driver may set a new flag (no_kernel_api_dma) to skip calling
iommu_device_use_dma_api() during the binding process. For instance, the
userspace framework drivers (vfio etc.) which need to manually claim
their own dma ownership when assigning the device to userspace.

Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
---
 include/linux/pci.h      |  5 +++++
 drivers/pci/pci-driver.c | 21 +++++++++++++++++++++
 2 files changed, 26 insertions(+)

diff --git a/include/linux/pci.h b/include/linux/pci.h
index 18a75c8e615c..d29a990e3f02 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -882,6 +882,10 @@ struct module;
  *              created once it is bound to the driver.
  * @driver:	Driver model structure.
  * @dynids:	List of dynamically added device IDs.
+ * @no_kernel_api_dma: Device driver doesn't use kernel DMA API for DMA.
+ *		Drivers which don't require DMA or want to manually claim the
+ *		owner type (e.g. userspace driver frameworks) could set this
+ *		flag.
  */
 struct pci_driver {
 	struct list_head	node;
@@ -900,6 +904,7 @@ struct pci_driver {
 	const struct attribute_group **dev_groups;
 	struct device_driver	driver;
 	struct pci_dynids	dynids;
+	bool no_kernel_api_dma;
 };
 
 static inline struct pci_driver *to_pci_driver(struct device_driver *drv)
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 588588cfda48..4e003ea12718 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -20,6 +20,7 @@
 #include <linux/of_device.h>
 #include <linux/acpi.h>
 #include <linux/dma-map-ops.h>
+#include <linux/iommu.h>
 #include "pci.h"
 #include "pcie/portdrv.h"
 
@@ -1590,9 +1591,16 @@ static int pci_bus_num_vf(struct device *dev)
  */
 static int pci_dma_configure(struct device *dev)
 {
+	struct pci_driver *driver = to_pci_driver(dev->driver);
 	struct device *bridge;
 	int ret = 0;
 
+	if (!driver->no_kernel_api_dma) {
+		ret = iommu_device_use_dma_api(dev);
+		if (ret)
+			return ret;
+	}
+
 	bridge = pci_get_host_bridge_device(to_pci_dev(dev));
 
 	if (IS_ENABLED(CONFIG_OF) && bridge->parent &&
@@ -1605,9 +1613,21 @@ static int pci_dma_configure(struct device *dev)
 	}
 
 	pci_put_host_bridge_device(bridge);
+
+	if (ret && !driver->no_kernel_api_dma)
+		iommu_device_unuse_dma_api(dev);
+
 	return ret;
 }
 
+static void pci_dma_cleanup(struct device *dev)
+{
+	struct pci_driver *driver = to_pci_driver(dev->driver);
+
+	if (!driver->no_kernel_api_dma)
+		iommu_device_unuse_dma_api(dev);
+}
+
 struct bus_type pci_bus_type = {
 	.name		= "pci",
 	.match		= pci_bus_match,
@@ -1621,6 +1641,7 @@ struct bus_type pci_bus_type = {
 	.pm		= PCI_PM_OPS_PTR,
 	.num_vf		= pci_bus_num_vf,
 	.dma_configure	= pci_dma_configure,
+	.dma_cleanup	= pci_dma_cleanup,
 };
 EXPORT_SYMBOL(pci_bus_type);
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 112+ messages in thread

* [PATCH v5 07/14] PCI: Add driver dma ownership management
@ 2022-01-04  1:56   ` Lu Baolu
  0 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-01-04  1:56 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Joerg Roedel, Alex Williamson, Bjorn Helgaas,
	Jason Gunthorpe, Christoph Hellwig, Kevin Tian, Ashok Raj
  Cc: kvm, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Stuart Yoder,
	Jonathan Hunter, Chaitanya Kulkarni, Dan Williams, Cornelia Huck,
	linux-kernel, Li Yang, iommu, Jacob jun Pan, Daniel Vetter,
	Robin Murphy

Multiple PCI devices may be placed in the same IOMMU group because
they cannot be isolated from each other. These devices must either be
entirely under kernel control or userspace control, never a mixture. This
checks and sets DMA ownership during driver binding, and release the
ownership during driver unbinding.

The device driver may set a new flag (no_kernel_api_dma) to skip calling
iommu_device_use_dma_api() during the binding process. For instance, the
userspace framework drivers (vfio etc.) which need to manually claim
their own dma ownership when assigning the device to userspace.

Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
---
 include/linux/pci.h      |  5 +++++
 drivers/pci/pci-driver.c | 21 +++++++++++++++++++++
 2 files changed, 26 insertions(+)

diff --git a/include/linux/pci.h b/include/linux/pci.h
index 18a75c8e615c..d29a990e3f02 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -882,6 +882,10 @@ struct module;
  *              created once it is bound to the driver.
  * @driver:	Driver model structure.
  * @dynids:	List of dynamically added device IDs.
+ * @no_kernel_api_dma: Device driver doesn't use kernel DMA API for DMA.
+ *		Drivers which don't require DMA or want to manually claim the
+ *		owner type (e.g. userspace driver frameworks) could set this
+ *		flag.
  */
 struct pci_driver {
 	struct list_head	node;
@@ -900,6 +904,7 @@ struct pci_driver {
 	const struct attribute_group **dev_groups;
 	struct device_driver	driver;
 	struct pci_dynids	dynids;
+	bool no_kernel_api_dma;
 };
 
 static inline struct pci_driver *to_pci_driver(struct device_driver *drv)
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 588588cfda48..4e003ea12718 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -20,6 +20,7 @@
 #include <linux/of_device.h>
 #include <linux/acpi.h>
 #include <linux/dma-map-ops.h>
+#include <linux/iommu.h>
 #include "pci.h"
 #include "pcie/portdrv.h"
 
@@ -1590,9 +1591,16 @@ static int pci_bus_num_vf(struct device *dev)
  */
 static int pci_dma_configure(struct device *dev)
 {
+	struct pci_driver *driver = to_pci_driver(dev->driver);
 	struct device *bridge;
 	int ret = 0;
 
+	if (!driver->no_kernel_api_dma) {
+		ret = iommu_device_use_dma_api(dev);
+		if (ret)
+			return ret;
+	}
+
 	bridge = pci_get_host_bridge_device(to_pci_dev(dev));
 
 	if (IS_ENABLED(CONFIG_OF) && bridge->parent &&
@@ -1605,9 +1613,21 @@ static int pci_dma_configure(struct device *dev)
 	}
 
 	pci_put_host_bridge_device(bridge);
+
+	if (ret && !driver->no_kernel_api_dma)
+		iommu_device_unuse_dma_api(dev);
+
 	return ret;
 }
 
+static void pci_dma_cleanup(struct device *dev)
+{
+	struct pci_driver *driver = to_pci_driver(dev->driver);
+
+	if (!driver->no_kernel_api_dma)
+		iommu_device_unuse_dma_api(dev);
+}
+
 struct bus_type pci_bus_type = {
 	.name		= "pci",
 	.match		= pci_bus_match,
@@ -1621,6 +1641,7 @@ struct bus_type pci_bus_type = {
 	.pm		= PCI_PM_OPS_PTR,
 	.num_vf		= pci_bus_num_vf,
 	.dma_configure	= pci_dma_configure,
+	.dma_cleanup	= pci_dma_cleanup,
 };
 EXPORT_SYMBOL(pci_bus_type);
 
-- 
2.25.1

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

^ permalink raw reply related	[flat|nested] 112+ messages in thread

* [PATCH v5 08/14] PCI: pci_stub: Suppress kernel DMA ownership auto-claiming
  2022-01-04  1:56 ` Lu Baolu
@ 2022-01-04  1:56   ` Lu Baolu
  -1 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-01-04  1:56 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Joerg Roedel, Alex Williamson, Bjorn Helgaas,
	Jason Gunthorpe, Christoph Hellwig, Kevin Tian, Ashok Raj
  Cc: Will Deacon, Robin Murphy, Dan Williams, rafael, Diana Craciun,
	Cornelia Huck, Eric Auger, Liu Yi L, Jacob jun Pan,
	Chaitanya Kulkarni, Stuart Yoder, Laurentiu Tudor,
	Thierry Reding, David Airlie, Daniel Vetter, Jonathan Hunter,
	Li Yang, Dmitry Osipenko, iommu, linux-pci, kvm, linux-kernel,
	Lu Baolu

The pci_dma_configure() marks the iommu_group as containing only devices
with kernel drivers that manage DMA. Avoid this default behavior for the
pci_stub because it does not program any DMA itself.  This allows the
pci_stub still able to be used by the admin to block driver binding after
applying the DMA ownership to vfio.

Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
---
 drivers/pci/pci-stub.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/pci/pci-stub.c b/drivers/pci/pci-stub.c
index e408099fea52..1f4c0a58b819 100644
--- a/drivers/pci/pci-stub.c
+++ b/drivers/pci/pci-stub.c
@@ -36,6 +36,7 @@ static struct pci_driver stub_driver = {
 	.name		= "pci-stub",
 	.id_table	= NULL,	/* only dynamic id's */
 	.probe		= pci_stub_probe,
+	.no_kernel_api_dma = true,
 };
 
 static int __init pci_stub_init(void)
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 112+ messages in thread

* [PATCH v5 08/14] PCI: pci_stub: Suppress kernel DMA ownership auto-claiming
@ 2022-01-04  1:56   ` Lu Baolu
  0 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-01-04  1:56 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Joerg Roedel, Alex Williamson, Bjorn Helgaas,
	Jason Gunthorpe, Christoph Hellwig, Kevin Tian, Ashok Raj
  Cc: kvm, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Stuart Yoder,
	Jonathan Hunter, Chaitanya Kulkarni, Dan Williams, Cornelia Huck,
	linux-kernel, Li Yang, iommu, Jacob jun Pan, Daniel Vetter,
	Robin Murphy

The pci_dma_configure() marks the iommu_group as containing only devices
with kernel drivers that manage DMA. Avoid this default behavior for the
pci_stub because it does not program any DMA itself.  This allows the
pci_stub still able to be used by the admin to block driver binding after
applying the DMA ownership to vfio.

Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
---
 drivers/pci/pci-stub.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/pci/pci-stub.c b/drivers/pci/pci-stub.c
index e408099fea52..1f4c0a58b819 100644
--- a/drivers/pci/pci-stub.c
+++ b/drivers/pci/pci-stub.c
@@ -36,6 +36,7 @@ static struct pci_driver stub_driver = {
 	.name		= "pci-stub",
 	.id_table	= NULL,	/* only dynamic id's */
 	.probe		= pci_stub_probe,
+	.no_kernel_api_dma = true,
 };
 
 static int __init pci_stub_init(void)
-- 
2.25.1

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

^ permalink raw reply related	[flat|nested] 112+ messages in thread

* [PATCH v5 09/14] PCI: portdrv: Suppress kernel DMA ownership auto-claiming
  2022-01-04  1:56 ` Lu Baolu
@ 2022-01-04  1:56   ` Lu Baolu
  -1 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-01-04  1:56 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Joerg Roedel, Alex Williamson, Bjorn Helgaas,
	Jason Gunthorpe, Christoph Hellwig, Kevin Tian, Ashok Raj
  Cc: Will Deacon, Robin Murphy, Dan Williams, rafael, Diana Craciun,
	Cornelia Huck, Eric Auger, Liu Yi L, Jacob jun Pan,
	Chaitanya Kulkarni, Stuart Yoder, Laurentiu Tudor,
	Thierry Reding, David Airlie, Daniel Vetter, Jonathan Hunter,
	Li Yang, Dmitry Osipenko, iommu, linux-pci, kvm, linux-kernel,
	Lu Baolu

If a switch lacks ACS P2P Request Redirect, a device below the switch can
bypass the IOMMU and DMA directly to other devices below the switch, so
all the downstream devices must be in the same IOMMU group as the switch
itself. The existing vfio framework allows the portdrv driver to be bound
to the bridge while its downstream devices are assigned to user space.
The pci_dma_configure() marks the iommu_group as containing only devices
with kernel drivers that manage DMA. Avoid this default behavior for the
portdrv driver in order for compatibility with the current vfio policy.

Suggested-by: Jason Gunthorpe <jgg@nvidia.com>
Suggested-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
---
 drivers/pci/pcie/portdrv_pci.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c
index 35eca6277a96..2116f821c005 100644
--- a/drivers/pci/pcie/portdrv_pci.c
+++ b/drivers/pci/pcie/portdrv_pci.c
@@ -202,6 +202,8 @@ static struct pci_driver pcie_portdriver = {
 
 	.err_handler	= &pcie_portdrv_err_handler,
 
+	.no_kernel_api_dma = true,
+
 	.driver.pm	= PCIE_PORTDRV_PM_OPS,
 };
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 112+ messages in thread

* [PATCH v5 09/14] PCI: portdrv: Suppress kernel DMA ownership auto-claiming
@ 2022-01-04  1:56   ` Lu Baolu
  0 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-01-04  1:56 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Joerg Roedel, Alex Williamson, Bjorn Helgaas,
	Jason Gunthorpe, Christoph Hellwig, Kevin Tian, Ashok Raj
  Cc: kvm, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Stuart Yoder,
	Jonathan Hunter, Chaitanya Kulkarni, Dan Williams, Cornelia Huck,
	linux-kernel, Li Yang, iommu, Jacob jun Pan, Daniel Vetter,
	Robin Murphy

If a switch lacks ACS P2P Request Redirect, a device below the switch can
bypass the IOMMU and DMA directly to other devices below the switch, so
all the downstream devices must be in the same IOMMU group as the switch
itself. The existing vfio framework allows the portdrv driver to be bound
to the bridge while its downstream devices are assigned to user space.
The pci_dma_configure() marks the iommu_group as containing only devices
with kernel drivers that manage DMA. Avoid this default behavior for the
portdrv driver in order for compatibility with the current vfio policy.

Suggested-by: Jason Gunthorpe <jgg@nvidia.com>
Suggested-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
---
 drivers/pci/pcie/portdrv_pci.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c
index 35eca6277a96..2116f821c005 100644
--- a/drivers/pci/pcie/portdrv_pci.c
+++ b/drivers/pci/pcie/portdrv_pci.c
@@ -202,6 +202,8 @@ static struct pci_driver pcie_portdriver = {
 
 	.err_handler	= &pcie_portdrv_err_handler,
 
+	.no_kernel_api_dma = true,
+
 	.driver.pm	= PCIE_PORTDRV_PM_OPS,
 };
 
-- 
2.25.1

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

^ permalink raw reply related	[flat|nested] 112+ messages in thread

* [PATCH v5 10/14] vfio: Set DMA ownership for VFIO devices
  2022-01-04  1:56 ` Lu Baolu
@ 2022-01-04  1:56   ` Lu Baolu
  -1 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-01-04  1:56 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Joerg Roedel, Alex Williamson, Bjorn Helgaas,
	Jason Gunthorpe, Christoph Hellwig, Kevin Tian, Ashok Raj
  Cc: Will Deacon, Robin Murphy, Dan Williams, rafael, Diana Craciun,
	Cornelia Huck, Eric Auger, Liu Yi L, Jacob jun Pan,
	Chaitanya Kulkarni, Stuart Yoder, Laurentiu Tudor,
	Thierry Reding, David Airlie, Daniel Vetter, Jonathan Hunter,
	Li Yang, Dmitry Osipenko, iommu, linux-pci, kvm, linux-kernel,
	Lu Baolu

Claim group dma ownership when an iommu group is set to a container,
and release DMA_OWNER_USER once the iommu group is unset from the
container.

Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
---
 drivers/vfio/fsl-mc/vfio_fsl_mc.c     |  1 +
 drivers/vfio/pci/vfio_pci.c           |  1 +
 drivers/vfio/platform/vfio_amba.c     |  1 +
 drivers/vfio/platform/vfio_platform.c |  1 +
 drivers/vfio/vfio.c                   | 10 +++++++++-
 5 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/vfio/fsl-mc/vfio_fsl_mc.c b/drivers/vfio/fsl-mc/vfio_fsl_mc.c
index 6e2e62c6f47a..f133971d1c1f 100644
--- a/drivers/vfio/fsl-mc/vfio_fsl_mc.c
+++ b/drivers/vfio/fsl-mc/vfio_fsl_mc.c
@@ -588,6 +588,7 @@ static struct fsl_mc_driver vfio_fsl_mc_driver = {
 		.name	= "vfio-fsl-mc",
 		.owner	= THIS_MODULE,
 	},
+	.no_kernel_api_dma = true,
 };
 
 static int __init vfio_fsl_mc_driver_init(void)
diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c
index a5ce92beb655..8cd1e5a855da 100644
--- a/drivers/vfio/pci/vfio_pci.c
+++ b/drivers/vfio/pci/vfio_pci.c
@@ -193,6 +193,7 @@ static struct pci_driver vfio_pci_driver = {
 	.remove			= vfio_pci_remove,
 	.sriov_configure	= vfio_pci_sriov_configure,
 	.err_handler		= &vfio_pci_core_err_handlers,
+	.no_kernel_api_dma = true,
 };
 
 static void __init vfio_pci_fill_ids(void)
diff --git a/drivers/vfio/platform/vfio_amba.c b/drivers/vfio/platform/vfio_amba.c
index badfffea14fb..39407ca143d5 100644
--- a/drivers/vfio/platform/vfio_amba.c
+++ b/drivers/vfio/platform/vfio_amba.c
@@ -95,6 +95,7 @@ static struct amba_driver vfio_amba_driver = {
 		.name = "vfio-amba",
 		.owner = THIS_MODULE,
 	},
+	.no_kernel_api_dma = true,
 };
 
 module_amba_driver(vfio_amba_driver);
diff --git a/drivers/vfio/platform/vfio_platform.c b/drivers/vfio/platform/vfio_platform.c
index 68a1c87066d7..46848a58fc99 100644
--- a/drivers/vfio/platform/vfio_platform.c
+++ b/drivers/vfio/platform/vfio_platform.c
@@ -76,6 +76,7 @@ static struct platform_driver vfio_platform_driver = {
 	.driver	= {
 		.name	= "vfio-platform",
 	},
+	.no_kernel_api_dma = true,
 };
 
 module_platform_driver(vfio_platform_driver);
diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c
index 735d1d344af9..ef22fa312c2a 100644
--- a/drivers/vfio/vfio.c
+++ b/drivers/vfio/vfio.c
@@ -1198,6 +1198,8 @@ static void __vfio_group_unset_container(struct vfio_group *group)
 		driver->ops->detach_group(container->iommu_data,
 					  group->iommu_group);
 
+	iommu_group_release_dma_owner(group->iommu_group);
+
 	group->container = NULL;
 	wake_up(&group->container_q);
 	list_del(&group->container_next);
@@ -1282,13 +1284,19 @@ static int vfio_group_set_container(struct vfio_group *group, int container_fd)
 		goto unlock_out;
 	}
 
+	ret = iommu_group_set_dma_owner(group->iommu_group, f.file);
+	if (ret)
+		goto unlock_out;
+
 	driver = container->iommu_driver;
 	if (driver) {
 		ret = driver->ops->attach_group(container->iommu_data,
 						group->iommu_group,
 						group->type);
-		if (ret)
+		if (ret) {
+			iommu_group_release_dma_owner(group->iommu_group);
 			goto unlock_out;
+		}
 	}
 
 	group->container = container;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 112+ messages in thread

* [PATCH v5 10/14] vfio: Set DMA ownership for VFIO devices
@ 2022-01-04  1:56   ` Lu Baolu
  0 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-01-04  1:56 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Joerg Roedel, Alex Williamson, Bjorn Helgaas,
	Jason Gunthorpe, Christoph Hellwig, Kevin Tian, Ashok Raj
  Cc: kvm, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Stuart Yoder,
	Jonathan Hunter, Chaitanya Kulkarni, Dan Williams, Cornelia Huck,
	linux-kernel, Li Yang, iommu, Jacob jun Pan, Daniel Vetter,
	Robin Murphy

Claim group dma ownership when an iommu group is set to a container,
and release DMA_OWNER_USER once the iommu group is unset from the
container.

Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
---
 drivers/vfio/fsl-mc/vfio_fsl_mc.c     |  1 +
 drivers/vfio/pci/vfio_pci.c           |  1 +
 drivers/vfio/platform/vfio_amba.c     |  1 +
 drivers/vfio/platform/vfio_platform.c |  1 +
 drivers/vfio/vfio.c                   | 10 +++++++++-
 5 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/vfio/fsl-mc/vfio_fsl_mc.c b/drivers/vfio/fsl-mc/vfio_fsl_mc.c
index 6e2e62c6f47a..f133971d1c1f 100644
--- a/drivers/vfio/fsl-mc/vfio_fsl_mc.c
+++ b/drivers/vfio/fsl-mc/vfio_fsl_mc.c
@@ -588,6 +588,7 @@ static struct fsl_mc_driver vfio_fsl_mc_driver = {
 		.name	= "vfio-fsl-mc",
 		.owner	= THIS_MODULE,
 	},
+	.no_kernel_api_dma = true,
 };
 
 static int __init vfio_fsl_mc_driver_init(void)
diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c
index a5ce92beb655..8cd1e5a855da 100644
--- a/drivers/vfio/pci/vfio_pci.c
+++ b/drivers/vfio/pci/vfio_pci.c
@@ -193,6 +193,7 @@ static struct pci_driver vfio_pci_driver = {
 	.remove			= vfio_pci_remove,
 	.sriov_configure	= vfio_pci_sriov_configure,
 	.err_handler		= &vfio_pci_core_err_handlers,
+	.no_kernel_api_dma = true,
 };
 
 static void __init vfio_pci_fill_ids(void)
diff --git a/drivers/vfio/platform/vfio_amba.c b/drivers/vfio/platform/vfio_amba.c
index badfffea14fb..39407ca143d5 100644
--- a/drivers/vfio/platform/vfio_amba.c
+++ b/drivers/vfio/platform/vfio_amba.c
@@ -95,6 +95,7 @@ static struct amba_driver vfio_amba_driver = {
 		.name = "vfio-amba",
 		.owner = THIS_MODULE,
 	},
+	.no_kernel_api_dma = true,
 };
 
 module_amba_driver(vfio_amba_driver);
diff --git a/drivers/vfio/platform/vfio_platform.c b/drivers/vfio/platform/vfio_platform.c
index 68a1c87066d7..46848a58fc99 100644
--- a/drivers/vfio/platform/vfio_platform.c
+++ b/drivers/vfio/platform/vfio_platform.c
@@ -76,6 +76,7 @@ static struct platform_driver vfio_platform_driver = {
 	.driver	= {
 		.name	= "vfio-platform",
 	},
+	.no_kernel_api_dma = true,
 };
 
 module_platform_driver(vfio_platform_driver);
diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c
index 735d1d344af9..ef22fa312c2a 100644
--- a/drivers/vfio/vfio.c
+++ b/drivers/vfio/vfio.c
@@ -1198,6 +1198,8 @@ static void __vfio_group_unset_container(struct vfio_group *group)
 		driver->ops->detach_group(container->iommu_data,
 					  group->iommu_group);
 
+	iommu_group_release_dma_owner(group->iommu_group);
+
 	group->container = NULL;
 	wake_up(&group->container_q);
 	list_del(&group->container_next);
@@ -1282,13 +1284,19 @@ static int vfio_group_set_container(struct vfio_group *group, int container_fd)
 		goto unlock_out;
 	}
 
+	ret = iommu_group_set_dma_owner(group->iommu_group, f.file);
+	if (ret)
+		goto unlock_out;
+
 	driver = container->iommu_driver;
 	if (driver) {
 		ret = driver->ops->attach_group(container->iommu_data,
 						group->iommu_group,
 						group->type);
-		if (ret)
+		if (ret) {
+			iommu_group_release_dma_owner(group->iommu_group);
 			goto unlock_out;
+		}
 	}
 
 	group->container = container;
-- 
2.25.1

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

^ permalink raw reply related	[flat|nested] 112+ messages in thread

* [PATCH v5 11/14] vfio: Remove use of vfio_group_viable()
  2022-01-04  1:56 ` Lu Baolu
@ 2022-01-04  1:56   ` Lu Baolu
  -1 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-01-04  1:56 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Joerg Roedel, Alex Williamson, Bjorn Helgaas,
	Jason Gunthorpe, Christoph Hellwig, Kevin Tian, Ashok Raj
  Cc: Will Deacon, Robin Murphy, Dan Williams, rafael, Diana Craciun,
	Cornelia Huck, Eric Auger, Liu Yi L, Jacob jun Pan,
	Chaitanya Kulkarni, Stuart Yoder, Laurentiu Tudor,
	Thierry Reding, David Airlie, Daniel Vetter, Jonathan Hunter,
	Li Yang, Dmitry Osipenko, iommu, linux-pci, kvm, linux-kernel,
	Lu Baolu

As DMA USER ownership is claimed for the iommu group when a vfio group is
added to a vfio container, the vfio group viability is guaranteed as long
as group->container_users > 0. Remove those unnecessary group viability
checks which are only hit when group->container_users is not zero.

The only remaining reference is in GROUP_GET_STATUS, which could be called
at any time when group fd is valid. Here we just replace the
vfio_group_viable() by directly calling iommu core to get viability status.

Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
---
 drivers/vfio/vfio.c | 18 ++++++------------
 1 file changed, 6 insertions(+), 12 deletions(-)

diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c
index ef22fa312c2a..789861853676 100644
--- a/drivers/vfio/vfio.c
+++ b/drivers/vfio/vfio.c
@@ -1313,12 +1313,6 @@ static int vfio_group_set_container(struct vfio_group *group, int container_fd)
 	return ret;
 }
 
-static bool vfio_group_viable(struct vfio_group *group)
-{
-	return (iommu_group_for_each_dev(group->iommu_group,
-					 group, vfio_dev_viable) == 0);
-}
-
 static int vfio_group_add_container_user(struct vfio_group *group)
 {
 	if (!atomic_inc_not_zero(&group->container_users))
@@ -1328,7 +1322,7 @@ static int vfio_group_add_container_user(struct vfio_group *group)
 		atomic_dec(&group->container_users);
 		return -EPERM;
 	}
-	if (!group->container->iommu_driver || !vfio_group_viable(group)) {
+	if (!group->container->iommu_driver) {
 		atomic_dec(&group->container_users);
 		return -EINVAL;
 	}
@@ -1346,7 +1340,7 @@ static int vfio_group_get_device_fd(struct vfio_group *group, char *buf)
 	int ret = 0;
 
 	if (0 == atomic_read(&group->container_users) ||
-	    !group->container->iommu_driver || !vfio_group_viable(group))
+	    !group->container->iommu_driver)
 		return -EINVAL;
 
 	if (group->type == VFIO_NO_IOMMU && !capable(CAP_SYS_RAWIO))
@@ -1438,11 +1432,11 @@ static long vfio_group_fops_unl_ioctl(struct file *filep,
 
 		status.flags = 0;
 
-		if (vfio_group_viable(group))
-			status.flags |= VFIO_GROUP_FLAGS_VIABLE;
-
 		if (group->container)
-			status.flags |= VFIO_GROUP_FLAGS_CONTAINER_SET;
+			status.flags |= VFIO_GROUP_FLAGS_CONTAINER_SET |
+					VFIO_GROUP_FLAGS_VIABLE;
+		else if (!iommu_group_dma_owner_claimed(group->iommu_group))
+			status.flags |= VFIO_GROUP_FLAGS_VIABLE;
 
 		if (copy_to_user((void __user *)arg, &status, minsz))
 			return -EFAULT;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 112+ messages in thread

* [PATCH v5 11/14] vfio: Remove use of vfio_group_viable()
@ 2022-01-04  1:56   ` Lu Baolu
  0 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-01-04  1:56 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Joerg Roedel, Alex Williamson, Bjorn Helgaas,
	Jason Gunthorpe, Christoph Hellwig, Kevin Tian, Ashok Raj
  Cc: kvm, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Stuart Yoder,
	Jonathan Hunter, Chaitanya Kulkarni, Dan Williams, Cornelia Huck,
	linux-kernel, Li Yang, iommu, Jacob jun Pan, Daniel Vetter,
	Robin Murphy

As DMA USER ownership is claimed for the iommu group when a vfio group is
added to a vfio container, the vfio group viability is guaranteed as long
as group->container_users > 0. Remove those unnecessary group viability
checks which are only hit when group->container_users is not zero.

The only remaining reference is in GROUP_GET_STATUS, which could be called
at any time when group fd is valid. Here we just replace the
vfio_group_viable() by directly calling iommu core to get viability status.

Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
---
 drivers/vfio/vfio.c | 18 ++++++------------
 1 file changed, 6 insertions(+), 12 deletions(-)

diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c
index ef22fa312c2a..789861853676 100644
--- a/drivers/vfio/vfio.c
+++ b/drivers/vfio/vfio.c
@@ -1313,12 +1313,6 @@ static int vfio_group_set_container(struct vfio_group *group, int container_fd)
 	return ret;
 }
 
-static bool vfio_group_viable(struct vfio_group *group)
-{
-	return (iommu_group_for_each_dev(group->iommu_group,
-					 group, vfio_dev_viable) == 0);
-}
-
 static int vfio_group_add_container_user(struct vfio_group *group)
 {
 	if (!atomic_inc_not_zero(&group->container_users))
@@ -1328,7 +1322,7 @@ static int vfio_group_add_container_user(struct vfio_group *group)
 		atomic_dec(&group->container_users);
 		return -EPERM;
 	}
-	if (!group->container->iommu_driver || !vfio_group_viable(group)) {
+	if (!group->container->iommu_driver) {
 		atomic_dec(&group->container_users);
 		return -EINVAL;
 	}
@@ -1346,7 +1340,7 @@ static int vfio_group_get_device_fd(struct vfio_group *group, char *buf)
 	int ret = 0;
 
 	if (0 == atomic_read(&group->container_users) ||
-	    !group->container->iommu_driver || !vfio_group_viable(group))
+	    !group->container->iommu_driver)
 		return -EINVAL;
 
 	if (group->type == VFIO_NO_IOMMU && !capable(CAP_SYS_RAWIO))
@@ -1438,11 +1432,11 @@ static long vfio_group_fops_unl_ioctl(struct file *filep,
 
 		status.flags = 0;
 
-		if (vfio_group_viable(group))
-			status.flags |= VFIO_GROUP_FLAGS_VIABLE;
-
 		if (group->container)
-			status.flags |= VFIO_GROUP_FLAGS_CONTAINER_SET;
+			status.flags |= VFIO_GROUP_FLAGS_CONTAINER_SET |
+					VFIO_GROUP_FLAGS_VIABLE;
+		else if (!iommu_group_dma_owner_claimed(group->iommu_group))
+			status.flags |= VFIO_GROUP_FLAGS_VIABLE;
 
 		if (copy_to_user((void __user *)arg, &status, minsz))
 			return -EFAULT;
-- 
2.25.1

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

^ permalink raw reply related	[flat|nested] 112+ messages in thread

* [PATCH v5 12/14] vfio: Delete the unbound_list
  2022-01-04  1:56 ` Lu Baolu
@ 2022-01-04  1:56   ` Lu Baolu
  -1 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-01-04  1:56 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Joerg Roedel, Alex Williamson, Bjorn Helgaas,
	Jason Gunthorpe, Christoph Hellwig, Kevin Tian, Ashok Raj
  Cc: Will Deacon, Robin Murphy, Dan Williams, rafael, Diana Craciun,
	Cornelia Huck, Eric Auger, Liu Yi L, Jacob jun Pan,
	Chaitanya Kulkarni, Stuart Yoder, Laurentiu Tudor,
	Thierry Reding, David Airlie, Daniel Vetter, Jonathan Hunter,
	Li Yang, Dmitry Osipenko, iommu, linux-pci, kvm, linux-kernel,
	Lu Baolu

From: Jason Gunthorpe <jgg@nvidia.com>

commit 60720a0fc646 ("vfio: Add device tracking during unbind") added the
unbound list to plug a problem with KVM where KVM_DEV_VFIO_GROUP_DEL
relied on vfio_group_get_external_user() succeeding to return the
vfio_group from a group file descriptor. The unbound list allowed
vfio_group_get_external_user() to continue to succeed in edge cases.

However commit 5d6dee80a1e9 ("vfio: New external user group/file match")
deleted the call to vfio_group_get_external_user() during
KVM_DEV_VFIO_GROUP_DEL. Instead vfio_external_group_match_file() is used
to directly match the file descriptor to the group pointer.

This in turn avoids the call down to vfio_dev_viable() during
KVM_DEV_VFIO_GROUP_DEL and also avoids the trouble the first commit was
trying to fix.

There are no other users of vfio_dev_viable() that care about the time
after vfio_unregister_group_dev() returns, so simply delete the
unbound_list entirely.

Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
---
 drivers/vfio/vfio.c | 74 ++-------------------------------------------
 1 file changed, 2 insertions(+), 72 deletions(-)

diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c
index 789861853676..2877ec47e32a 100644
--- a/drivers/vfio/vfio.c
+++ b/drivers/vfio/vfio.c
@@ -62,11 +62,6 @@ struct vfio_container {
 	bool				noiommu;
 };
 
-struct vfio_unbound_dev {
-	struct device			*dev;
-	struct list_head		unbound_next;
-};
-
 struct vfio_group {
 	struct device 			dev;
 	struct cdev			cdev;
@@ -79,8 +74,6 @@ struct vfio_group {
 	struct notifier_block		nb;
 	struct list_head		vfio_next;
 	struct list_head		container_next;
-	struct list_head		unbound_list;
-	struct mutex			unbound_lock;
 	atomic_t			opened;
 	wait_queue_head_t		container_q;
 	enum vfio_group_type		type;
@@ -340,16 +333,8 @@ vfio_group_get_from_iommu(struct iommu_group *iommu_group)
 static void vfio_group_release(struct device *dev)
 {
 	struct vfio_group *group = container_of(dev, struct vfio_group, dev);
-	struct vfio_unbound_dev *unbound, *tmp;
-
-	list_for_each_entry_safe(unbound, tmp,
-				 &group->unbound_list, unbound_next) {
-		list_del(&unbound->unbound_next);
-		kfree(unbound);
-	}
 
 	mutex_destroy(&group->device_lock);
-	mutex_destroy(&group->unbound_lock);
 	iommu_group_put(group->iommu_group);
 	ida_free(&vfio.group_ida, MINOR(group->dev.devt));
 	kfree(group);
@@ -381,8 +366,6 @@ static struct vfio_group *vfio_group_alloc(struct iommu_group *iommu_group,
 	refcount_set(&group->users, 1);
 	INIT_LIST_HEAD(&group->device_list);
 	mutex_init(&group->device_lock);
-	INIT_LIST_HEAD(&group->unbound_list);
-	mutex_init(&group->unbound_lock);
 	init_waitqueue_head(&group->container_q);
 	group->iommu_group = iommu_group;
 	/* put in vfio_group_release() */
@@ -571,19 +554,8 @@ static int vfio_dev_viable(struct device *dev, void *data)
 	struct vfio_group *group = data;
 	struct vfio_device *device;
 	struct device_driver *drv = READ_ONCE(dev->driver);
-	struct vfio_unbound_dev *unbound;
-	int ret = -EINVAL;
 
-	mutex_lock(&group->unbound_lock);
-	list_for_each_entry(unbound, &group->unbound_list, unbound_next) {
-		if (dev == unbound->dev) {
-			ret = 0;
-			break;
-		}
-	}
-	mutex_unlock(&group->unbound_lock);
-
-	if (!ret || !drv || vfio_dev_driver_allowed(dev, drv))
+	if (!drv || vfio_dev_driver_allowed(dev, drv))
 		return 0;
 
 	device = vfio_group_get_device(group, dev);
@@ -592,7 +564,7 @@ static int vfio_dev_viable(struct device *dev, void *data)
 		return 0;
 	}
 
-	return ret;
+	return -EINVAL;
 }
 
 /*
@@ -634,7 +606,6 @@ static int vfio_iommu_group_notifier(struct notifier_block *nb,
 {
 	struct vfio_group *group = container_of(nb, struct vfio_group, nb);
 	struct device *dev = data;
-	struct vfio_unbound_dev *unbound;
 
 	switch (action) {
 	case IOMMU_GROUP_NOTIFY_ADD_DEVICE:
@@ -663,28 +634,6 @@ static int vfio_iommu_group_notifier(struct notifier_block *nb,
 			__func__, iommu_group_id(group->iommu_group),
 			dev->driver->name);
 		break;
-	case IOMMU_GROUP_NOTIFY_UNBOUND_DRIVER:
-		dev_dbg(dev, "%s: group %d unbound from driver\n", __func__,
-			iommu_group_id(group->iommu_group));
-		/*
-		 * XXX An unbound device in a live group is ok, but we'd
-		 * really like to avoid the above BUG_ON by preventing other
-		 * drivers from binding to it.  Once that occurs, we have to
-		 * stop the system to maintain isolation.  At a minimum, we'd
-		 * want a toggle to disable driver auto probe for this device.
-		 */
-
-		mutex_lock(&group->unbound_lock);
-		list_for_each_entry(unbound,
-				    &group->unbound_list, unbound_next) {
-			if (dev == unbound->dev) {
-				list_del(&unbound->unbound_next);
-				kfree(unbound);
-				break;
-			}
-		}
-		mutex_unlock(&group->unbound_lock);
-		break;
 	}
 	return NOTIFY_OK;
 }
@@ -889,29 +838,10 @@ static struct vfio_device *vfio_device_get_from_name(struct vfio_group *group,
 void vfio_unregister_group_dev(struct vfio_device *device)
 {
 	struct vfio_group *group = device->group;
-	struct vfio_unbound_dev *unbound;
 	unsigned int i = 0;
 	bool interrupted = false;
 	long rc;
 
-	/*
-	 * When the device is removed from the group, the group suddenly
-	 * becomes non-viable; the device has a driver (until the unbind
-	 * completes), but it's not present in the group.  This is bad news
-	 * for any external users that need to re-acquire a group reference
-	 * in order to match and release their existing reference.  To
-	 * solve this, we track such devices on the unbound_list to bridge
-	 * the gap until they're fully unbound.
-	 */
-	unbound = kzalloc(sizeof(*unbound), GFP_KERNEL);
-	if (unbound) {
-		unbound->dev = device->dev;
-		mutex_lock(&group->unbound_lock);
-		list_add(&unbound->unbound_next, &group->unbound_list);
-		mutex_unlock(&group->unbound_lock);
-	}
-	WARN_ON(!unbound);
-
 	vfio_device_put(device);
 	rc = try_wait_for_completion(&device->comp);
 	while (rc <= 0) {
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 112+ messages in thread

* [PATCH v5 12/14] vfio: Delete the unbound_list
@ 2022-01-04  1:56   ` Lu Baolu
  0 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-01-04  1:56 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Joerg Roedel, Alex Williamson, Bjorn Helgaas,
	Jason Gunthorpe, Christoph Hellwig, Kevin Tian, Ashok Raj
  Cc: kvm, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Stuart Yoder,
	Jonathan Hunter, Chaitanya Kulkarni, Dan Williams, Cornelia Huck,
	linux-kernel, Li Yang, iommu, Jacob jun Pan, Daniel Vetter,
	Robin Murphy

From: Jason Gunthorpe <jgg@nvidia.com>

commit 60720a0fc646 ("vfio: Add device tracking during unbind") added the
unbound list to plug a problem with KVM where KVM_DEV_VFIO_GROUP_DEL
relied on vfio_group_get_external_user() succeeding to return the
vfio_group from a group file descriptor. The unbound list allowed
vfio_group_get_external_user() to continue to succeed in edge cases.

However commit 5d6dee80a1e9 ("vfio: New external user group/file match")
deleted the call to vfio_group_get_external_user() during
KVM_DEV_VFIO_GROUP_DEL. Instead vfio_external_group_match_file() is used
to directly match the file descriptor to the group pointer.

This in turn avoids the call down to vfio_dev_viable() during
KVM_DEV_VFIO_GROUP_DEL and also avoids the trouble the first commit was
trying to fix.

There are no other users of vfio_dev_viable() that care about the time
after vfio_unregister_group_dev() returns, so simply delete the
unbound_list entirely.

Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
---
 drivers/vfio/vfio.c | 74 ++-------------------------------------------
 1 file changed, 2 insertions(+), 72 deletions(-)

diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c
index 789861853676..2877ec47e32a 100644
--- a/drivers/vfio/vfio.c
+++ b/drivers/vfio/vfio.c
@@ -62,11 +62,6 @@ struct vfio_container {
 	bool				noiommu;
 };
 
-struct vfio_unbound_dev {
-	struct device			*dev;
-	struct list_head		unbound_next;
-};
-
 struct vfio_group {
 	struct device 			dev;
 	struct cdev			cdev;
@@ -79,8 +74,6 @@ struct vfio_group {
 	struct notifier_block		nb;
 	struct list_head		vfio_next;
 	struct list_head		container_next;
-	struct list_head		unbound_list;
-	struct mutex			unbound_lock;
 	atomic_t			opened;
 	wait_queue_head_t		container_q;
 	enum vfio_group_type		type;
@@ -340,16 +333,8 @@ vfio_group_get_from_iommu(struct iommu_group *iommu_group)
 static void vfio_group_release(struct device *dev)
 {
 	struct vfio_group *group = container_of(dev, struct vfio_group, dev);
-	struct vfio_unbound_dev *unbound, *tmp;
-
-	list_for_each_entry_safe(unbound, tmp,
-				 &group->unbound_list, unbound_next) {
-		list_del(&unbound->unbound_next);
-		kfree(unbound);
-	}
 
 	mutex_destroy(&group->device_lock);
-	mutex_destroy(&group->unbound_lock);
 	iommu_group_put(group->iommu_group);
 	ida_free(&vfio.group_ida, MINOR(group->dev.devt));
 	kfree(group);
@@ -381,8 +366,6 @@ static struct vfio_group *vfio_group_alloc(struct iommu_group *iommu_group,
 	refcount_set(&group->users, 1);
 	INIT_LIST_HEAD(&group->device_list);
 	mutex_init(&group->device_lock);
-	INIT_LIST_HEAD(&group->unbound_list);
-	mutex_init(&group->unbound_lock);
 	init_waitqueue_head(&group->container_q);
 	group->iommu_group = iommu_group;
 	/* put in vfio_group_release() */
@@ -571,19 +554,8 @@ static int vfio_dev_viable(struct device *dev, void *data)
 	struct vfio_group *group = data;
 	struct vfio_device *device;
 	struct device_driver *drv = READ_ONCE(dev->driver);
-	struct vfio_unbound_dev *unbound;
-	int ret = -EINVAL;
 
-	mutex_lock(&group->unbound_lock);
-	list_for_each_entry(unbound, &group->unbound_list, unbound_next) {
-		if (dev == unbound->dev) {
-			ret = 0;
-			break;
-		}
-	}
-	mutex_unlock(&group->unbound_lock);
-
-	if (!ret || !drv || vfio_dev_driver_allowed(dev, drv))
+	if (!drv || vfio_dev_driver_allowed(dev, drv))
 		return 0;
 
 	device = vfio_group_get_device(group, dev);
@@ -592,7 +564,7 @@ static int vfio_dev_viable(struct device *dev, void *data)
 		return 0;
 	}
 
-	return ret;
+	return -EINVAL;
 }
 
 /*
@@ -634,7 +606,6 @@ static int vfio_iommu_group_notifier(struct notifier_block *nb,
 {
 	struct vfio_group *group = container_of(nb, struct vfio_group, nb);
 	struct device *dev = data;
-	struct vfio_unbound_dev *unbound;
 
 	switch (action) {
 	case IOMMU_GROUP_NOTIFY_ADD_DEVICE:
@@ -663,28 +634,6 @@ static int vfio_iommu_group_notifier(struct notifier_block *nb,
 			__func__, iommu_group_id(group->iommu_group),
 			dev->driver->name);
 		break;
-	case IOMMU_GROUP_NOTIFY_UNBOUND_DRIVER:
-		dev_dbg(dev, "%s: group %d unbound from driver\n", __func__,
-			iommu_group_id(group->iommu_group));
-		/*
-		 * XXX An unbound device in a live group is ok, but we'd
-		 * really like to avoid the above BUG_ON by preventing other
-		 * drivers from binding to it.  Once that occurs, we have to
-		 * stop the system to maintain isolation.  At a minimum, we'd
-		 * want a toggle to disable driver auto probe for this device.
-		 */
-
-		mutex_lock(&group->unbound_lock);
-		list_for_each_entry(unbound,
-				    &group->unbound_list, unbound_next) {
-			if (dev == unbound->dev) {
-				list_del(&unbound->unbound_next);
-				kfree(unbound);
-				break;
-			}
-		}
-		mutex_unlock(&group->unbound_lock);
-		break;
 	}
 	return NOTIFY_OK;
 }
@@ -889,29 +838,10 @@ static struct vfio_device *vfio_device_get_from_name(struct vfio_group *group,
 void vfio_unregister_group_dev(struct vfio_device *device)
 {
 	struct vfio_group *group = device->group;
-	struct vfio_unbound_dev *unbound;
 	unsigned int i = 0;
 	bool interrupted = false;
 	long rc;
 
-	/*
-	 * When the device is removed from the group, the group suddenly
-	 * becomes non-viable; the device has a driver (until the unbind
-	 * completes), but it's not present in the group.  This is bad news
-	 * for any external users that need to re-acquire a group reference
-	 * in order to match and release their existing reference.  To
-	 * solve this, we track such devices on the unbound_list to bridge
-	 * the gap until they're fully unbound.
-	 */
-	unbound = kzalloc(sizeof(*unbound), GFP_KERNEL);
-	if (unbound) {
-		unbound->dev = device->dev;
-		mutex_lock(&group->unbound_lock);
-		list_add(&unbound->unbound_next, &group->unbound_list);
-		mutex_unlock(&group->unbound_lock);
-	}
-	WARN_ON(!unbound);
-
 	vfio_device_put(device);
 	rc = try_wait_for_completion(&device->comp);
 	while (rc <= 0) {
-- 
2.25.1

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

^ permalink raw reply related	[flat|nested] 112+ messages in thread

* [PATCH v5 13/14] vfio: Remove iommu group notifier
  2022-01-04  1:56 ` Lu Baolu
@ 2022-01-04  1:56   ` Lu Baolu
  -1 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-01-04  1:56 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Joerg Roedel, Alex Williamson, Bjorn Helgaas,
	Jason Gunthorpe, Christoph Hellwig, Kevin Tian, Ashok Raj
  Cc: Will Deacon, Robin Murphy, Dan Williams, rafael, Diana Craciun,
	Cornelia Huck, Eric Auger, Liu Yi L, Jacob jun Pan,
	Chaitanya Kulkarni, Stuart Yoder, Laurentiu Tudor,
	Thierry Reding, David Airlie, Daniel Vetter, Jonathan Hunter,
	Li Yang, Dmitry Osipenko, iommu, linux-pci, kvm, linux-kernel,
	Lu Baolu

The iommu core and driver core have been enhanced to avoid unsafe driver
binding to a live group after iommu_group_set_dma_owner(PRIVATE_USER)
has been called. There's no need to register iommu group notifier. This
removes the iommu group notifer which contains BUG_ON() and WARN().

The commit 5f096b14d421b ("vfio: Whitelist PCI bridges") allowed all
pcieport drivers to be bound with devices while the group is assigned to
user space. This is not always safe. For example, The shpchp_core driver
relies on the PCI MMIO access for the controller functionality. With its
downstream devices assigned to the userspace, the MMIO might be changed
through user initiated P2P accesses without any notification. This might
break the kernel driver integrity and lead to some unpredictable
consequences. As the result, currently we only allow the portdrv driver.

For any bridge driver, in order to avoiding default kernel DMA ownership
claiming, we should consider:

 1) Does the bridge driver use DMA? Calling pci_set_master() or
    a dma_map_* API is a sure indicate the driver is doing DMA

 2) If the bridge driver uses MMIO, is it tolerant to hostile
    userspace also touching the same MMIO registers via P2P DMA
    attacks?

Conservatively if the driver maps an MMIO region at all, we can say that
it fails the test.

Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
---
 drivers/vfio/vfio.c | 147 --------------------------------------------
 1 file changed, 147 deletions(-)

diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c
index 2877ec47e32a..dce42ede3190 100644
--- a/drivers/vfio/vfio.c
+++ b/drivers/vfio/vfio.c
@@ -71,7 +71,6 @@ struct vfio_group {
 	struct vfio_container		*container;
 	struct list_head		device_list;
 	struct mutex			device_lock;
-	struct notifier_block		nb;
 	struct list_head		vfio_next;
 	struct list_head		container_next;
 	atomic_t			opened;
@@ -274,8 +273,6 @@ void vfio_unregister_iommu_driver(const struct vfio_iommu_driver_ops *ops)
 }
 EXPORT_SYMBOL_GPL(vfio_unregister_iommu_driver);
 
-static int vfio_iommu_group_notifier(struct notifier_block *nb,
-				     unsigned long action, void *data);
 static void vfio_group_get(struct vfio_group *group);
 
 /*
@@ -395,13 +392,6 @@ static struct vfio_group *vfio_create_group(struct iommu_group *iommu_group,
 		goto err_put;
 	}
 
-	group->nb.notifier_call = vfio_iommu_group_notifier;
-	err = iommu_group_register_notifier(iommu_group, &group->nb);
-	if (err) {
-		ret = ERR_PTR(err);
-		goto err_put;
-	}
-
 	mutex_lock(&vfio.group_lock);
 
 	/* Did we race creating this group? */
@@ -422,7 +412,6 @@ static struct vfio_group *vfio_create_group(struct iommu_group *iommu_group,
 
 err_unlock:
 	mutex_unlock(&vfio.group_lock);
-	iommu_group_unregister_notifier(group->iommu_group, &group->nb);
 err_put:
 	put_device(&group->dev);
 	return ret;
@@ -447,7 +436,6 @@ static void vfio_group_put(struct vfio_group *group)
 	cdev_device_del(&group->cdev, &group->dev);
 	mutex_unlock(&vfio.group_lock);
 
-	iommu_group_unregister_notifier(group->iommu_group, &group->nb);
 	put_device(&group->dev);
 }
 
@@ -503,141 +491,6 @@ static struct vfio_device *vfio_group_get_device(struct vfio_group *group,
 	return NULL;
 }
 
-/*
- * Some drivers, like pci-stub, are only used to prevent other drivers from
- * claiming a device and are therefore perfectly legitimate for a user owned
- * group.  The pci-stub driver has no dependencies on DMA or the IOVA mapping
- * of the device, but it does prevent the user from having direct access to
- * the device, which is useful in some circumstances.
- *
- * We also assume that we can include PCI interconnect devices, ie. bridges.
- * IOMMU grouping on PCI necessitates that if we lack isolation on a bridge
- * then all of the downstream devices will be part of the same IOMMU group as
- * the bridge.  Thus, if placing the bridge into the user owned IOVA space
- * breaks anything, it only does so for user owned devices downstream.  Note
- * that error notification via MSI can be affected for platforms that handle
- * MSI within the same IOVA space as DMA.
- */
-static const char * const vfio_driver_allowed[] = { "pci-stub" };
-
-static bool vfio_dev_driver_allowed(struct device *dev,
-				    struct device_driver *drv)
-{
-	if (dev_is_pci(dev)) {
-		struct pci_dev *pdev = to_pci_dev(dev);
-
-		if (pdev->hdr_type != PCI_HEADER_TYPE_NORMAL)
-			return true;
-	}
-
-	return match_string(vfio_driver_allowed,
-			    ARRAY_SIZE(vfio_driver_allowed),
-			    drv->name) >= 0;
-}
-
-/*
- * A vfio group is viable for use by userspace if all devices are in
- * one of the following states:
- *  - driver-less
- *  - bound to a vfio driver
- *  - bound to an otherwise allowed driver
- *  - a PCI interconnect device
- *
- * We use two methods to determine whether a device is bound to a vfio
- * driver.  The first is to test whether the device exists in the vfio
- * group.  The second is to test if the device exists on the group
- * unbound_list, indicating it's in the middle of transitioning from
- * a vfio driver to driver-less.
- */
-static int vfio_dev_viable(struct device *dev, void *data)
-{
-	struct vfio_group *group = data;
-	struct vfio_device *device;
-	struct device_driver *drv = READ_ONCE(dev->driver);
-
-	if (!drv || vfio_dev_driver_allowed(dev, drv))
-		return 0;
-
-	device = vfio_group_get_device(group, dev);
-	if (device) {
-		vfio_device_put(device);
-		return 0;
-	}
-
-	return -EINVAL;
-}
-
-/*
- * Async device support
- */
-static int vfio_group_nb_add_dev(struct vfio_group *group, struct device *dev)
-{
-	struct vfio_device *device;
-
-	/* Do we already know about it?  We shouldn't */
-	device = vfio_group_get_device(group, dev);
-	if (WARN_ON_ONCE(device)) {
-		vfio_device_put(device);
-		return 0;
-	}
-
-	/* Nothing to do for idle groups */
-	if (!atomic_read(&group->container_users))
-		return 0;
-
-	/* TODO Prevent device auto probing */
-	dev_WARN(dev, "Device added to live group %d!\n",
-		 iommu_group_id(group->iommu_group));
-
-	return 0;
-}
-
-static int vfio_group_nb_verify(struct vfio_group *group, struct device *dev)
-{
-	/* We don't care what happens when the group isn't in use */
-	if (!atomic_read(&group->container_users))
-		return 0;
-
-	return vfio_dev_viable(dev, group);
-}
-
-static int vfio_iommu_group_notifier(struct notifier_block *nb,
-				     unsigned long action, void *data)
-{
-	struct vfio_group *group = container_of(nb, struct vfio_group, nb);
-	struct device *dev = data;
-
-	switch (action) {
-	case IOMMU_GROUP_NOTIFY_ADD_DEVICE:
-		vfio_group_nb_add_dev(group, dev);
-		break;
-	case IOMMU_GROUP_NOTIFY_DEL_DEVICE:
-		/*
-		 * Nothing to do here.  If the device is in use, then the
-		 * vfio sub-driver should block the remove callback until
-		 * it is unused.  If the device is unused or attached to a
-		 * stub driver, then it should be released and we don't
-		 * care that it will be going away.
-		 */
-		break;
-	case IOMMU_GROUP_NOTIFY_BIND_DRIVER:
-		dev_dbg(dev, "%s: group %d binding to driver\n", __func__,
-			iommu_group_id(group->iommu_group));
-		break;
-	case IOMMU_GROUP_NOTIFY_BOUND_DRIVER:
-		dev_dbg(dev, "%s: group %d bound to driver %s\n", __func__,
-			iommu_group_id(group->iommu_group), dev->driver->name);
-		BUG_ON(vfio_group_nb_verify(group, dev));
-		break;
-	case IOMMU_GROUP_NOTIFY_UNBIND_DRIVER:
-		dev_dbg(dev, "%s: group %d unbinding from driver %s\n",
-			__func__, iommu_group_id(group->iommu_group),
-			dev->driver->name);
-		break;
-	}
-	return NOTIFY_OK;
-}
-
 /*
  * VFIO driver API
  */
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 112+ messages in thread

* [PATCH v5 13/14] vfio: Remove iommu group notifier
@ 2022-01-04  1:56   ` Lu Baolu
  0 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-01-04  1:56 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Joerg Roedel, Alex Williamson, Bjorn Helgaas,
	Jason Gunthorpe, Christoph Hellwig, Kevin Tian, Ashok Raj
  Cc: kvm, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Stuart Yoder,
	Jonathan Hunter, Chaitanya Kulkarni, Dan Williams, Cornelia Huck,
	linux-kernel, Li Yang, iommu, Jacob jun Pan, Daniel Vetter,
	Robin Murphy

The iommu core and driver core have been enhanced to avoid unsafe driver
binding to a live group after iommu_group_set_dma_owner(PRIVATE_USER)
has been called. There's no need to register iommu group notifier. This
removes the iommu group notifer which contains BUG_ON() and WARN().

The commit 5f096b14d421b ("vfio: Whitelist PCI bridges") allowed all
pcieport drivers to be bound with devices while the group is assigned to
user space. This is not always safe. For example, The shpchp_core driver
relies on the PCI MMIO access for the controller functionality. With its
downstream devices assigned to the userspace, the MMIO might be changed
through user initiated P2P accesses without any notification. This might
break the kernel driver integrity and lead to some unpredictable
consequences. As the result, currently we only allow the portdrv driver.

For any bridge driver, in order to avoiding default kernel DMA ownership
claiming, we should consider:

 1) Does the bridge driver use DMA? Calling pci_set_master() or
    a dma_map_* API is a sure indicate the driver is doing DMA

 2) If the bridge driver uses MMIO, is it tolerant to hostile
    userspace also touching the same MMIO registers via P2P DMA
    attacks?

Conservatively if the driver maps an MMIO region at all, we can say that
it fails the test.

Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
---
 drivers/vfio/vfio.c | 147 --------------------------------------------
 1 file changed, 147 deletions(-)

diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c
index 2877ec47e32a..dce42ede3190 100644
--- a/drivers/vfio/vfio.c
+++ b/drivers/vfio/vfio.c
@@ -71,7 +71,6 @@ struct vfio_group {
 	struct vfio_container		*container;
 	struct list_head		device_list;
 	struct mutex			device_lock;
-	struct notifier_block		nb;
 	struct list_head		vfio_next;
 	struct list_head		container_next;
 	atomic_t			opened;
@@ -274,8 +273,6 @@ void vfio_unregister_iommu_driver(const struct vfio_iommu_driver_ops *ops)
 }
 EXPORT_SYMBOL_GPL(vfio_unregister_iommu_driver);
 
-static int vfio_iommu_group_notifier(struct notifier_block *nb,
-				     unsigned long action, void *data);
 static void vfio_group_get(struct vfio_group *group);
 
 /*
@@ -395,13 +392,6 @@ static struct vfio_group *vfio_create_group(struct iommu_group *iommu_group,
 		goto err_put;
 	}
 
-	group->nb.notifier_call = vfio_iommu_group_notifier;
-	err = iommu_group_register_notifier(iommu_group, &group->nb);
-	if (err) {
-		ret = ERR_PTR(err);
-		goto err_put;
-	}
-
 	mutex_lock(&vfio.group_lock);
 
 	/* Did we race creating this group? */
@@ -422,7 +412,6 @@ static struct vfio_group *vfio_create_group(struct iommu_group *iommu_group,
 
 err_unlock:
 	mutex_unlock(&vfio.group_lock);
-	iommu_group_unregister_notifier(group->iommu_group, &group->nb);
 err_put:
 	put_device(&group->dev);
 	return ret;
@@ -447,7 +436,6 @@ static void vfio_group_put(struct vfio_group *group)
 	cdev_device_del(&group->cdev, &group->dev);
 	mutex_unlock(&vfio.group_lock);
 
-	iommu_group_unregister_notifier(group->iommu_group, &group->nb);
 	put_device(&group->dev);
 }
 
@@ -503,141 +491,6 @@ static struct vfio_device *vfio_group_get_device(struct vfio_group *group,
 	return NULL;
 }
 
-/*
- * Some drivers, like pci-stub, are only used to prevent other drivers from
- * claiming a device and are therefore perfectly legitimate for a user owned
- * group.  The pci-stub driver has no dependencies on DMA or the IOVA mapping
- * of the device, but it does prevent the user from having direct access to
- * the device, which is useful in some circumstances.
- *
- * We also assume that we can include PCI interconnect devices, ie. bridges.
- * IOMMU grouping on PCI necessitates that if we lack isolation on a bridge
- * then all of the downstream devices will be part of the same IOMMU group as
- * the bridge.  Thus, if placing the bridge into the user owned IOVA space
- * breaks anything, it only does so for user owned devices downstream.  Note
- * that error notification via MSI can be affected for platforms that handle
- * MSI within the same IOVA space as DMA.
- */
-static const char * const vfio_driver_allowed[] = { "pci-stub" };
-
-static bool vfio_dev_driver_allowed(struct device *dev,
-				    struct device_driver *drv)
-{
-	if (dev_is_pci(dev)) {
-		struct pci_dev *pdev = to_pci_dev(dev);
-
-		if (pdev->hdr_type != PCI_HEADER_TYPE_NORMAL)
-			return true;
-	}
-
-	return match_string(vfio_driver_allowed,
-			    ARRAY_SIZE(vfio_driver_allowed),
-			    drv->name) >= 0;
-}
-
-/*
- * A vfio group is viable for use by userspace if all devices are in
- * one of the following states:
- *  - driver-less
- *  - bound to a vfio driver
- *  - bound to an otherwise allowed driver
- *  - a PCI interconnect device
- *
- * We use two methods to determine whether a device is bound to a vfio
- * driver.  The first is to test whether the device exists in the vfio
- * group.  The second is to test if the device exists on the group
- * unbound_list, indicating it's in the middle of transitioning from
- * a vfio driver to driver-less.
- */
-static int vfio_dev_viable(struct device *dev, void *data)
-{
-	struct vfio_group *group = data;
-	struct vfio_device *device;
-	struct device_driver *drv = READ_ONCE(dev->driver);
-
-	if (!drv || vfio_dev_driver_allowed(dev, drv))
-		return 0;
-
-	device = vfio_group_get_device(group, dev);
-	if (device) {
-		vfio_device_put(device);
-		return 0;
-	}
-
-	return -EINVAL;
-}
-
-/*
- * Async device support
- */
-static int vfio_group_nb_add_dev(struct vfio_group *group, struct device *dev)
-{
-	struct vfio_device *device;
-
-	/* Do we already know about it?  We shouldn't */
-	device = vfio_group_get_device(group, dev);
-	if (WARN_ON_ONCE(device)) {
-		vfio_device_put(device);
-		return 0;
-	}
-
-	/* Nothing to do for idle groups */
-	if (!atomic_read(&group->container_users))
-		return 0;
-
-	/* TODO Prevent device auto probing */
-	dev_WARN(dev, "Device added to live group %d!\n",
-		 iommu_group_id(group->iommu_group));
-
-	return 0;
-}
-
-static int vfio_group_nb_verify(struct vfio_group *group, struct device *dev)
-{
-	/* We don't care what happens when the group isn't in use */
-	if (!atomic_read(&group->container_users))
-		return 0;
-
-	return vfio_dev_viable(dev, group);
-}
-
-static int vfio_iommu_group_notifier(struct notifier_block *nb,
-				     unsigned long action, void *data)
-{
-	struct vfio_group *group = container_of(nb, struct vfio_group, nb);
-	struct device *dev = data;
-
-	switch (action) {
-	case IOMMU_GROUP_NOTIFY_ADD_DEVICE:
-		vfio_group_nb_add_dev(group, dev);
-		break;
-	case IOMMU_GROUP_NOTIFY_DEL_DEVICE:
-		/*
-		 * Nothing to do here.  If the device is in use, then the
-		 * vfio sub-driver should block the remove callback until
-		 * it is unused.  If the device is unused or attached to a
-		 * stub driver, then it should be released and we don't
-		 * care that it will be going away.
-		 */
-		break;
-	case IOMMU_GROUP_NOTIFY_BIND_DRIVER:
-		dev_dbg(dev, "%s: group %d binding to driver\n", __func__,
-			iommu_group_id(group->iommu_group));
-		break;
-	case IOMMU_GROUP_NOTIFY_BOUND_DRIVER:
-		dev_dbg(dev, "%s: group %d bound to driver %s\n", __func__,
-			iommu_group_id(group->iommu_group), dev->driver->name);
-		BUG_ON(vfio_group_nb_verify(group, dev));
-		break;
-	case IOMMU_GROUP_NOTIFY_UNBIND_DRIVER:
-		dev_dbg(dev, "%s: group %d unbinding from driver %s\n",
-			__func__, iommu_group_id(group->iommu_group),
-			dev->driver->name);
-		break;
-	}
-	return NOTIFY_OK;
-}
-
 /*
  * VFIO driver API
  */
-- 
2.25.1

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

^ permalink raw reply related	[flat|nested] 112+ messages in thread

* [PATCH v5 14/14] iommu: Remove iommu group changes notifier
  2022-01-04  1:56 ` Lu Baolu
@ 2022-01-04  1:56   ` Lu Baolu
  -1 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-01-04  1:56 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Joerg Roedel, Alex Williamson, Bjorn Helgaas,
	Jason Gunthorpe, Christoph Hellwig, Kevin Tian, Ashok Raj
  Cc: Will Deacon, Robin Murphy, Dan Williams, rafael, Diana Craciun,
	Cornelia Huck, Eric Auger, Liu Yi L, Jacob jun Pan,
	Chaitanya Kulkarni, Stuart Yoder, Laurentiu Tudor,
	Thierry Reding, David Airlie, Daniel Vetter, Jonathan Hunter,
	Li Yang, Dmitry Osipenko, iommu, linux-pci, kvm, linux-kernel,
	Lu Baolu, Christoph Hellwig

The iommu group changes notifer is not referenced in the tree. Remove it
to avoid dead code.

Suggested-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
---
 include/linux/iommu.h | 23 -------------
 drivers/iommu/iommu.c | 75 -------------------------------------------
 2 files changed, 98 deletions(-)

diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 568f285468cf..408a6d2b3034 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -403,13 +403,6 @@ static inline void iommu_iotlb_gather_init(struct iommu_iotlb_gather *gather)
 	};
 }
 
-#define IOMMU_GROUP_NOTIFY_ADD_DEVICE		1 /* Device added */
-#define IOMMU_GROUP_NOTIFY_DEL_DEVICE		2 /* Pre Device removed */
-#define IOMMU_GROUP_NOTIFY_BIND_DRIVER		3 /* Pre Driver bind */
-#define IOMMU_GROUP_NOTIFY_BOUND_DRIVER		4 /* Post Driver bind */
-#define IOMMU_GROUP_NOTIFY_UNBIND_DRIVER	5 /* Pre Driver unbind */
-#define IOMMU_GROUP_NOTIFY_UNBOUND_DRIVER	6 /* Post Driver unbind */
-
 extern int bus_set_iommu(struct bus_type *bus, const struct iommu_ops *ops);
 extern int bus_iommu_probe(struct bus_type *bus);
 extern bool iommu_present(struct bus_type *bus);
@@ -482,10 +475,6 @@ extern int iommu_group_for_each_dev(struct iommu_group *group, void *data,
 extern struct iommu_group *iommu_group_get(struct device *dev);
 extern struct iommu_group *iommu_group_ref_get(struct iommu_group *group);
 extern void iommu_group_put(struct iommu_group *group);
-extern int iommu_group_register_notifier(struct iommu_group *group,
-					 struct notifier_block *nb);
-extern int iommu_group_unregister_notifier(struct iommu_group *group,
-					   struct notifier_block *nb);
 extern int iommu_register_device_fault_handler(struct device *dev,
 					iommu_dev_fault_handler_t handler,
 					void *data);
@@ -885,18 +874,6 @@ static inline void iommu_group_put(struct iommu_group *group)
 {
 }
 
-static inline int iommu_group_register_notifier(struct iommu_group *group,
-						struct notifier_block *nb)
-{
-	return -ENODEV;
-}
-
-static inline int iommu_group_unregister_notifier(struct iommu_group *group,
-						  struct notifier_block *nb)
-{
-	return 0;
-}
-
 static inline
 int iommu_register_device_fault_handler(struct device *dev,
 					iommu_dev_fault_handler_t handler,
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index ff0c8c1ad5af..72a95dea688e 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -18,7 +18,6 @@
 #include <linux/errno.h>
 #include <linux/iommu.h>
 #include <linux/idr.h>
-#include <linux/notifier.h>
 #include <linux/err.h>
 #include <linux/pci.h>
 #include <linux/bitops.h>
@@ -40,7 +39,6 @@ struct iommu_group {
 	struct kobject *devices_kobj;
 	struct list_head devices;
 	struct mutex mutex;
-	struct blocking_notifier_head notifier;
 	void *iommu_data;
 	void (*iommu_data_release)(void *iommu_data);
 	char *name;
@@ -627,7 +625,6 @@ struct iommu_group *iommu_group_alloc(void)
 	mutex_init(&group->mutex);
 	INIT_LIST_HEAD(&group->devices);
 	INIT_LIST_HEAD(&group->entry);
-	BLOCKING_INIT_NOTIFIER_HEAD(&group->notifier);
 
 	ret = ida_simple_get(&iommu_group_ida, 0, 0, GFP_KERNEL);
 	if (ret < 0) {
@@ -902,10 +899,6 @@ int iommu_group_add_device(struct iommu_group *group, struct device *dev)
 	if (ret)
 		goto err_put_group;
 
-	/* Notify any listeners about change to group. */
-	blocking_notifier_call_chain(&group->notifier,
-				     IOMMU_GROUP_NOTIFY_ADD_DEVICE, dev);
-
 	trace_add_device_to_group(group->id, dev);
 
 	dev_info(dev, "Adding to iommu group %d\n", group->id);
@@ -947,10 +940,6 @@ void iommu_group_remove_device(struct device *dev)
 
 	dev_info(dev, "Removing from iommu group %d\n", group->id);
 
-	/* Pre-notify listeners that a device is being removed. */
-	blocking_notifier_call_chain(&group->notifier,
-				     IOMMU_GROUP_NOTIFY_DEL_DEVICE, dev);
-
 	mutex_lock(&group->mutex);
 	list_for_each_entry(tmp_device, &group->devices, list) {
 		if (tmp_device->dev == dev) {
@@ -1073,36 +1062,6 @@ void iommu_group_put(struct iommu_group *group)
 }
 EXPORT_SYMBOL_GPL(iommu_group_put);
 
-/**
- * iommu_group_register_notifier - Register a notifier for group changes
- * @group: the group to watch
- * @nb: notifier block to signal
- *
- * This function allows iommu group users to track changes in a group.
- * See include/linux/iommu.h for actions sent via this notifier.  Caller
- * should hold a reference to the group throughout notifier registration.
- */
-int iommu_group_register_notifier(struct iommu_group *group,
-				  struct notifier_block *nb)
-{
-	return blocking_notifier_chain_register(&group->notifier, nb);
-}
-EXPORT_SYMBOL_GPL(iommu_group_register_notifier);
-
-/**
- * iommu_group_unregister_notifier - Unregister a notifier
- * @group: the group to watch
- * @nb: notifier block to signal
- *
- * Unregister a previously registered group notifier block.
- */
-int iommu_group_unregister_notifier(struct iommu_group *group,
-				    struct notifier_block *nb)
-{
-	return blocking_notifier_chain_unregister(&group->notifier, nb);
-}
-EXPORT_SYMBOL_GPL(iommu_group_unregister_notifier);
-
 /**
  * iommu_register_device_fault_handler() - Register a device fault handler
  * @dev: the device
@@ -1651,14 +1610,8 @@ static int remove_iommu_group(struct device *dev, void *data)
 static int iommu_bus_notifier(struct notifier_block *nb,
 			      unsigned long action, void *data)
 {
-	unsigned long group_action = 0;
 	struct device *dev = data;
-	struct iommu_group *group;
 
-	/*
-	 * ADD/DEL call into iommu driver ops if provided, which may
-	 * result in ADD/DEL notifiers to group->notifier
-	 */
 	if (action == BUS_NOTIFY_ADD_DEVICE) {
 		int ret;
 
@@ -1669,34 +1622,6 @@ static int iommu_bus_notifier(struct notifier_block *nb,
 		return NOTIFY_OK;
 	}
 
-	/*
-	 * Remaining BUS_NOTIFYs get filtered and republished to the
-	 * group, if anyone is listening
-	 */
-	group = iommu_group_get(dev);
-	if (!group)
-		return 0;
-
-	switch (action) {
-	case BUS_NOTIFY_BIND_DRIVER:
-		group_action = IOMMU_GROUP_NOTIFY_BIND_DRIVER;
-		break;
-	case BUS_NOTIFY_BOUND_DRIVER:
-		group_action = IOMMU_GROUP_NOTIFY_BOUND_DRIVER;
-		break;
-	case BUS_NOTIFY_UNBIND_DRIVER:
-		group_action = IOMMU_GROUP_NOTIFY_UNBIND_DRIVER;
-		break;
-	case BUS_NOTIFY_UNBOUND_DRIVER:
-		group_action = IOMMU_GROUP_NOTIFY_UNBOUND_DRIVER;
-		break;
-	}
-
-	if (group_action)
-		blocking_notifier_call_chain(&group->notifier,
-					     group_action, dev);
-
-	iommu_group_put(group);
 	return 0;
 }
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 112+ messages in thread

* [PATCH v5 14/14] iommu: Remove iommu group changes notifier
@ 2022-01-04  1:56   ` Lu Baolu
  0 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-01-04  1:56 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Joerg Roedel, Alex Williamson, Bjorn Helgaas,
	Jason Gunthorpe, Christoph Hellwig, Kevin Tian, Ashok Raj
  Cc: kvm, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Christoph Hellwig,
	Stuart Yoder, Jonathan Hunter, Chaitanya Kulkarni, Dan Williams,
	Cornelia Huck, linux-kernel, Li Yang, iommu, Jacob jun Pan,
	Daniel Vetter, Robin Murphy

The iommu group changes notifer is not referenced in the tree. Remove it
to avoid dead code.

Suggested-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
---
 include/linux/iommu.h | 23 -------------
 drivers/iommu/iommu.c | 75 -------------------------------------------
 2 files changed, 98 deletions(-)

diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 568f285468cf..408a6d2b3034 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -403,13 +403,6 @@ static inline void iommu_iotlb_gather_init(struct iommu_iotlb_gather *gather)
 	};
 }
 
-#define IOMMU_GROUP_NOTIFY_ADD_DEVICE		1 /* Device added */
-#define IOMMU_GROUP_NOTIFY_DEL_DEVICE		2 /* Pre Device removed */
-#define IOMMU_GROUP_NOTIFY_BIND_DRIVER		3 /* Pre Driver bind */
-#define IOMMU_GROUP_NOTIFY_BOUND_DRIVER		4 /* Post Driver bind */
-#define IOMMU_GROUP_NOTIFY_UNBIND_DRIVER	5 /* Pre Driver unbind */
-#define IOMMU_GROUP_NOTIFY_UNBOUND_DRIVER	6 /* Post Driver unbind */
-
 extern int bus_set_iommu(struct bus_type *bus, const struct iommu_ops *ops);
 extern int bus_iommu_probe(struct bus_type *bus);
 extern bool iommu_present(struct bus_type *bus);
@@ -482,10 +475,6 @@ extern int iommu_group_for_each_dev(struct iommu_group *group, void *data,
 extern struct iommu_group *iommu_group_get(struct device *dev);
 extern struct iommu_group *iommu_group_ref_get(struct iommu_group *group);
 extern void iommu_group_put(struct iommu_group *group);
-extern int iommu_group_register_notifier(struct iommu_group *group,
-					 struct notifier_block *nb);
-extern int iommu_group_unregister_notifier(struct iommu_group *group,
-					   struct notifier_block *nb);
 extern int iommu_register_device_fault_handler(struct device *dev,
 					iommu_dev_fault_handler_t handler,
 					void *data);
@@ -885,18 +874,6 @@ static inline void iommu_group_put(struct iommu_group *group)
 {
 }
 
-static inline int iommu_group_register_notifier(struct iommu_group *group,
-						struct notifier_block *nb)
-{
-	return -ENODEV;
-}
-
-static inline int iommu_group_unregister_notifier(struct iommu_group *group,
-						  struct notifier_block *nb)
-{
-	return 0;
-}
-
 static inline
 int iommu_register_device_fault_handler(struct device *dev,
 					iommu_dev_fault_handler_t handler,
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index ff0c8c1ad5af..72a95dea688e 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -18,7 +18,6 @@
 #include <linux/errno.h>
 #include <linux/iommu.h>
 #include <linux/idr.h>
-#include <linux/notifier.h>
 #include <linux/err.h>
 #include <linux/pci.h>
 #include <linux/bitops.h>
@@ -40,7 +39,6 @@ struct iommu_group {
 	struct kobject *devices_kobj;
 	struct list_head devices;
 	struct mutex mutex;
-	struct blocking_notifier_head notifier;
 	void *iommu_data;
 	void (*iommu_data_release)(void *iommu_data);
 	char *name;
@@ -627,7 +625,6 @@ struct iommu_group *iommu_group_alloc(void)
 	mutex_init(&group->mutex);
 	INIT_LIST_HEAD(&group->devices);
 	INIT_LIST_HEAD(&group->entry);
-	BLOCKING_INIT_NOTIFIER_HEAD(&group->notifier);
 
 	ret = ida_simple_get(&iommu_group_ida, 0, 0, GFP_KERNEL);
 	if (ret < 0) {
@@ -902,10 +899,6 @@ int iommu_group_add_device(struct iommu_group *group, struct device *dev)
 	if (ret)
 		goto err_put_group;
 
-	/* Notify any listeners about change to group. */
-	blocking_notifier_call_chain(&group->notifier,
-				     IOMMU_GROUP_NOTIFY_ADD_DEVICE, dev);
-
 	trace_add_device_to_group(group->id, dev);
 
 	dev_info(dev, "Adding to iommu group %d\n", group->id);
@@ -947,10 +940,6 @@ void iommu_group_remove_device(struct device *dev)
 
 	dev_info(dev, "Removing from iommu group %d\n", group->id);
 
-	/* Pre-notify listeners that a device is being removed. */
-	blocking_notifier_call_chain(&group->notifier,
-				     IOMMU_GROUP_NOTIFY_DEL_DEVICE, dev);
-
 	mutex_lock(&group->mutex);
 	list_for_each_entry(tmp_device, &group->devices, list) {
 		if (tmp_device->dev == dev) {
@@ -1073,36 +1062,6 @@ void iommu_group_put(struct iommu_group *group)
 }
 EXPORT_SYMBOL_GPL(iommu_group_put);
 
-/**
- * iommu_group_register_notifier - Register a notifier for group changes
- * @group: the group to watch
- * @nb: notifier block to signal
- *
- * This function allows iommu group users to track changes in a group.
- * See include/linux/iommu.h for actions sent via this notifier.  Caller
- * should hold a reference to the group throughout notifier registration.
- */
-int iommu_group_register_notifier(struct iommu_group *group,
-				  struct notifier_block *nb)
-{
-	return blocking_notifier_chain_register(&group->notifier, nb);
-}
-EXPORT_SYMBOL_GPL(iommu_group_register_notifier);
-
-/**
- * iommu_group_unregister_notifier - Unregister a notifier
- * @group: the group to watch
- * @nb: notifier block to signal
- *
- * Unregister a previously registered group notifier block.
- */
-int iommu_group_unregister_notifier(struct iommu_group *group,
-				    struct notifier_block *nb)
-{
-	return blocking_notifier_chain_unregister(&group->notifier, nb);
-}
-EXPORT_SYMBOL_GPL(iommu_group_unregister_notifier);
-
 /**
  * iommu_register_device_fault_handler() - Register a device fault handler
  * @dev: the device
@@ -1651,14 +1610,8 @@ static int remove_iommu_group(struct device *dev, void *data)
 static int iommu_bus_notifier(struct notifier_block *nb,
 			      unsigned long action, void *data)
 {
-	unsigned long group_action = 0;
 	struct device *dev = data;
-	struct iommu_group *group;
 
-	/*
-	 * ADD/DEL call into iommu driver ops if provided, which may
-	 * result in ADD/DEL notifiers to group->notifier
-	 */
 	if (action == BUS_NOTIFY_ADD_DEVICE) {
 		int ret;
 
@@ -1669,34 +1622,6 @@ static int iommu_bus_notifier(struct notifier_block *nb,
 		return NOTIFY_OK;
 	}
 
-	/*
-	 * Remaining BUS_NOTIFYs get filtered and republished to the
-	 * group, if anyone is listening
-	 */
-	group = iommu_group_get(dev);
-	if (!group)
-		return 0;
-
-	switch (action) {
-	case BUS_NOTIFY_BIND_DRIVER:
-		group_action = IOMMU_GROUP_NOTIFY_BIND_DRIVER;
-		break;
-	case BUS_NOTIFY_BOUND_DRIVER:
-		group_action = IOMMU_GROUP_NOTIFY_BOUND_DRIVER;
-		break;
-	case BUS_NOTIFY_UNBIND_DRIVER:
-		group_action = IOMMU_GROUP_NOTIFY_UNBIND_DRIVER;
-		break;
-	case BUS_NOTIFY_UNBOUND_DRIVER:
-		group_action = IOMMU_GROUP_NOTIFY_UNBOUND_DRIVER;
-		break;
-	}
-
-	if (group_action)
-		blocking_notifier_call_chain(&group->notifier,
-					     group_action, dev);
-
-	iommu_group_put(group);
 	return 0;
 }
 
-- 
2.25.1

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

^ permalink raw reply related	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 01/14] iommu: Add dma ownership management interfaces
  2022-01-04  1:56   ` Lu Baolu
@ 2022-01-04 10:08     ` Christoph Hellwig
  -1 siblings, 0 replies; 112+ messages in thread
From: Christoph Hellwig @ 2022-01-04 10:08 UTC (permalink / raw)
  To: Lu Baolu
  Cc: Greg Kroah-Hartman, Joerg Roedel, Alex Williamson, Bjorn Helgaas,
	Jason Gunthorpe, Christoph Hellwig, Kevin Tian, Ashok Raj,
	Will Deacon, Robin Murphy, Dan Williams, rafael, Diana Craciun,
	Cornelia Huck, Eric Auger, Liu Yi L, Jacob jun Pan,
	Chaitanya Kulkarni, Stuart Yoder, Laurentiu Tudor,
	Thierry Reding, David Airlie, Daniel Vetter, Jonathan Hunter,
	Li Yang, Dmitry Osipenko, iommu, linux-pci, kvm, linux-kernel

On Tue, Jan 04, 2022 at 09:56:31AM +0800, Lu Baolu wrote:
> Multiple devices may be placed in the same IOMMU group because they
> cannot be isolated from each other. These devices must either be
> entirely under kernel control or userspace control, never a mixture.
> 
> This adds dma ownership management in iommu core and exposes several
> interfaces for the device drivers and the device userspace assignment
> framework (i.e. vfio), so that any conflict between user and kernel
> controlled DMA could be detected at the beginning.
> 
> The device driver oriented interfaces are,
> 
> 	int iommu_device_use_dma_api(struct device *dev);
> 	void iommu_device_unuse_dma_api(struct device *dev);
> 
> Devices under kernel drivers control must call iommu_device_use_dma_api()
> before driver probes. The driver binding process must be aborted if it
> returns failure.
> 
> The vfio oriented interfaces are,
> 
> 	int iommu_group_set_dma_owner(struct iommu_group *group,
> 				      void *owner);
> 	void iommu_group_release_dma_owner(struct iommu_group *group);
> 	bool iommu_group_dma_owner_claimed(struct iommu_group *group);
> 
> The device userspace assignment must be disallowed if the set dma owner
> interface returns failure.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> Signed-off-by: Kevin Tian <kevin.tian@intel.com>
> Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
> ---
>  include/linux/iommu.h |  31 ++++++++
>  drivers/iommu/iommu.c | 161 +++++++++++++++++++++++++++++++++++++++++-
>  2 files changed, 189 insertions(+), 3 deletions(-)
> 
> diff --git a/include/linux/iommu.h b/include/linux/iommu.h
> index de0c57a567c8..568f285468cf 100644
> --- a/include/linux/iommu.h
> +++ b/include/linux/iommu.h
> @@ -682,6 +682,13 @@ struct iommu_sva *iommu_sva_bind_device(struct device *dev,
>  void iommu_sva_unbind_device(struct iommu_sva *handle);
>  u32 iommu_sva_get_pasid(struct iommu_sva *handle);
>  
> +int iommu_device_use_dma_api(struct device *dev);
> +void iommu_device_unuse_dma_api(struct device *dev);
> +
> +int iommu_group_set_dma_owner(struct iommu_group *group, void *owner);
> +void iommu_group_release_dma_owner(struct iommu_group *group);
> +bool iommu_group_dma_owner_claimed(struct iommu_group *group);
> +
>  #else /* CONFIG_IOMMU_API */
>  
>  struct iommu_ops {};
> @@ -1082,6 +1089,30 @@ static inline struct iommu_fwspec *dev_iommu_fwspec_get(struct device *dev)
>  {
>  	return NULL;
>  }
> +
> +static inline int iommu_device_use_dma_api(struct device *dev)
> +{
> +	return 0;
> +}
> +
> +static inline void iommu_device_unuse_dma_api(struct device *dev)
> +{
> +}
> +
> +static inline int
> +iommu_group_set_dma_owner(struct iommu_group *group, void *owner)
> +{
> +	return -ENODEV;
> +}
> +
> +static inline void iommu_group_release_dma_owner(struct iommu_group *group)
> +{
> +}
> +
> +static inline bool iommu_group_dma_owner_claimed(struct iommu_group *group)
> +{
> +	return false;
> +}
>  #endif /* CONFIG_IOMMU_API */
>  
>  /**
> diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> index 8b86406b7162..ff0c8c1ad5af 100644
> --- a/drivers/iommu/iommu.c
> +++ b/drivers/iommu/iommu.c
> @@ -48,6 +48,8 @@ struct iommu_group {
>  	struct iommu_domain *default_domain;
>  	struct iommu_domain *domain;
>  	struct list_head entry;
> +	unsigned int owner_cnt;
> +	void *owner;
>  };
>  
>  struct group_device {
> @@ -289,7 +291,12 @@ int iommu_probe_device(struct device *dev)
>  	mutex_lock(&group->mutex);
>  	iommu_alloc_default_domain(group, dev);
>  
> -	if (group->default_domain) {
> +	/*
> +	 * If device joined an existing group which has been claimed
> +	 * for none kernel DMA purpose, avoid attaching the default
> +	 * domain.
> +	 */
> +	if (group->default_domain && !group->owner) {
>  		ret = __iommu_attach_device(group->default_domain, dev);
>  		if (ret) {
>  			mutex_unlock(&group->mutex);
> @@ -2320,7 +2327,7 @@ static int __iommu_attach_group(struct iommu_domain *domain,
>  {
>  	int ret;
>  
> -	if (group->default_domain && group->domain != group->default_domain)
> +	if (group->domain && group->domain != group->default_domain)
>  		return -EBUSY;
>  
>  	ret = __iommu_group_for_each_dev(group, domain,
> @@ -2357,7 +2364,11 @@ static void __iommu_detach_group(struct iommu_domain *domain,
>  {
>  	int ret;
>  
> -	if (!group->default_domain) {
> +	/*
> +	 * If group has been claimed for none kernel DMA purpose, avoid
> +	 * re-attaching the default domain.
> +	 */

none kernel reads odd.  But maybe drop that and just say 'claimed
already' ala:

	/*
	 * If the group has been claimed already, do not re-attach the default
	 * domain.
	 */

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 01/14] iommu: Add dma ownership management interfaces
@ 2022-01-04 10:08     ` Christoph Hellwig
  0 siblings, 0 replies; 112+ messages in thread
From: Christoph Hellwig @ 2022-01-04 10:08 UTC (permalink / raw)
  To: Lu Baolu
  Cc: Stuart Yoder, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Ashok Raj,
	Jonathan Hunter, Christoph Hellwig, Jason Gunthorpe, Kevin Tian,
	Chaitanya Kulkarni, Alex Williamson, kvm, Bjorn Helgaas,
	Dan Williams, Greg Kroah-Hartman, Cornelia Huck, linux-kernel,
	Li Yang, iommu, Jacob jun Pan, Daniel Vetter, Robin Murphy

On Tue, Jan 04, 2022 at 09:56:31AM +0800, Lu Baolu wrote:
> Multiple devices may be placed in the same IOMMU group because they
> cannot be isolated from each other. These devices must either be
> entirely under kernel control or userspace control, never a mixture.
> 
> This adds dma ownership management in iommu core and exposes several
> interfaces for the device drivers and the device userspace assignment
> framework (i.e. vfio), so that any conflict between user and kernel
> controlled DMA could be detected at the beginning.
> 
> The device driver oriented interfaces are,
> 
> 	int iommu_device_use_dma_api(struct device *dev);
> 	void iommu_device_unuse_dma_api(struct device *dev);
> 
> Devices under kernel drivers control must call iommu_device_use_dma_api()
> before driver probes. The driver binding process must be aborted if it
> returns failure.
> 
> The vfio oriented interfaces are,
> 
> 	int iommu_group_set_dma_owner(struct iommu_group *group,
> 				      void *owner);
> 	void iommu_group_release_dma_owner(struct iommu_group *group);
> 	bool iommu_group_dma_owner_claimed(struct iommu_group *group);
> 
> The device userspace assignment must be disallowed if the set dma owner
> interface returns failure.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> Signed-off-by: Kevin Tian <kevin.tian@intel.com>
> Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
> ---
>  include/linux/iommu.h |  31 ++++++++
>  drivers/iommu/iommu.c | 161 +++++++++++++++++++++++++++++++++++++++++-
>  2 files changed, 189 insertions(+), 3 deletions(-)
> 
> diff --git a/include/linux/iommu.h b/include/linux/iommu.h
> index de0c57a567c8..568f285468cf 100644
> --- a/include/linux/iommu.h
> +++ b/include/linux/iommu.h
> @@ -682,6 +682,13 @@ struct iommu_sva *iommu_sva_bind_device(struct device *dev,
>  void iommu_sva_unbind_device(struct iommu_sva *handle);
>  u32 iommu_sva_get_pasid(struct iommu_sva *handle);
>  
> +int iommu_device_use_dma_api(struct device *dev);
> +void iommu_device_unuse_dma_api(struct device *dev);
> +
> +int iommu_group_set_dma_owner(struct iommu_group *group, void *owner);
> +void iommu_group_release_dma_owner(struct iommu_group *group);
> +bool iommu_group_dma_owner_claimed(struct iommu_group *group);
> +
>  #else /* CONFIG_IOMMU_API */
>  
>  struct iommu_ops {};
> @@ -1082,6 +1089,30 @@ static inline struct iommu_fwspec *dev_iommu_fwspec_get(struct device *dev)
>  {
>  	return NULL;
>  }
> +
> +static inline int iommu_device_use_dma_api(struct device *dev)
> +{
> +	return 0;
> +}
> +
> +static inline void iommu_device_unuse_dma_api(struct device *dev)
> +{
> +}
> +
> +static inline int
> +iommu_group_set_dma_owner(struct iommu_group *group, void *owner)
> +{
> +	return -ENODEV;
> +}
> +
> +static inline void iommu_group_release_dma_owner(struct iommu_group *group)
> +{
> +}
> +
> +static inline bool iommu_group_dma_owner_claimed(struct iommu_group *group)
> +{
> +	return false;
> +}
>  #endif /* CONFIG_IOMMU_API */
>  
>  /**
> diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> index 8b86406b7162..ff0c8c1ad5af 100644
> --- a/drivers/iommu/iommu.c
> +++ b/drivers/iommu/iommu.c
> @@ -48,6 +48,8 @@ struct iommu_group {
>  	struct iommu_domain *default_domain;
>  	struct iommu_domain *domain;
>  	struct list_head entry;
> +	unsigned int owner_cnt;
> +	void *owner;
>  };
>  
>  struct group_device {
> @@ -289,7 +291,12 @@ int iommu_probe_device(struct device *dev)
>  	mutex_lock(&group->mutex);
>  	iommu_alloc_default_domain(group, dev);
>  
> -	if (group->default_domain) {
> +	/*
> +	 * If device joined an existing group which has been claimed
> +	 * for none kernel DMA purpose, avoid attaching the default
> +	 * domain.
> +	 */
> +	if (group->default_domain && !group->owner) {
>  		ret = __iommu_attach_device(group->default_domain, dev);
>  		if (ret) {
>  			mutex_unlock(&group->mutex);
> @@ -2320,7 +2327,7 @@ static int __iommu_attach_group(struct iommu_domain *domain,
>  {
>  	int ret;
>  
> -	if (group->default_domain && group->domain != group->default_domain)
> +	if (group->domain && group->domain != group->default_domain)
>  		return -EBUSY;
>  
>  	ret = __iommu_group_for_each_dev(group, domain,
> @@ -2357,7 +2364,11 @@ static void __iommu_detach_group(struct iommu_domain *domain,
>  {
>  	int ret;
>  
> -	if (!group->default_domain) {
> +	/*
> +	 * If group has been claimed for none kernel DMA purpose, avoid
> +	 * re-attaching the default domain.
> +	 */

none kernel reads odd.  But maybe drop that and just say 'claimed
already' ala:

	/*
	 * If the group has been claimed already, do not re-attach the default
	 * domain.
	 */
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 02/14] driver core: Add dma_cleanup callback in bus_type
  2022-01-04  1:56   ` Lu Baolu
@ 2022-01-04 10:08     ` Christoph Hellwig
  -1 siblings, 0 replies; 112+ messages in thread
From: Christoph Hellwig @ 2022-01-04 10:08 UTC (permalink / raw)
  To: Lu Baolu
  Cc: Greg Kroah-Hartman, Joerg Roedel, Alex Williamson, Bjorn Helgaas,
	Jason Gunthorpe, Christoph Hellwig, Kevin Tian, Ashok Raj,
	Will Deacon, Robin Murphy, Dan Williams, rafael, Diana Craciun,
	Cornelia Huck, Eric Auger, Liu Yi L, Jacob jun Pan,
	Chaitanya Kulkarni, Stuart Yoder, Laurentiu Tudor,
	Thierry Reding, David Airlie, Daniel Vetter, Jonathan Hunter,
	Li Yang, Dmitry Osipenko, iommu, linux-pci, kvm, linux-kernel

All these bus callouts still looks horrible and just create tons of
boilerplate code.

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 02/14] driver core: Add dma_cleanup callback in bus_type
@ 2022-01-04 10:08     ` Christoph Hellwig
  0 siblings, 0 replies; 112+ messages in thread
From: Christoph Hellwig @ 2022-01-04 10:08 UTC (permalink / raw)
  To: Lu Baolu
  Cc: Stuart Yoder, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Ashok Raj,
	Jonathan Hunter, Christoph Hellwig, Jason Gunthorpe, Kevin Tian,
	Chaitanya Kulkarni, Alex Williamson, kvm, Bjorn Helgaas,
	Dan Williams, Greg Kroah-Hartman, Cornelia Huck, linux-kernel,
	Li Yang, iommu, Jacob jun Pan, Daniel Vetter, Robin Murphy

All these bus callouts still looks horrible and just create tons of
boilerplate code.
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 02/14] driver core: Add dma_cleanup callback in bus_type
  2022-01-04 10:08     ` Christoph Hellwig
@ 2022-01-04 12:39       ` Jason Gunthorpe via iommu
  -1 siblings, 0 replies; 112+ messages in thread
From: Jason Gunthorpe @ 2022-01-04 12:39 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Lu Baolu, Greg Kroah-Hartman, Joerg Roedel, Alex Williamson,
	Bjorn Helgaas, Kevin Tian, Ashok Raj, Will Deacon, Robin Murphy,
	Dan Williams, rafael, Diana Craciun, Cornelia Huck, Eric Auger,
	Liu Yi L, Jacob jun Pan, Chaitanya Kulkarni, Stuart Yoder,
	Laurentiu Tudor, Thierry Reding, David Airlie, Daniel Vetter,
	Jonathan Hunter, Li Yang, Dmitry Osipenko, iommu, linux-pci, kvm,
	linux-kernel

On Tue, Jan 04, 2022 at 02:08:36AM -0800, Christoph Hellwig wrote:
> All these bus callouts still looks horrible and just create tons of
> boilerplate code.

Yes, Lu - Greg asked questions then didn't respond to their answers
meaning he accepts them, you should stick with the v4 version.

Jason

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 02/14] driver core: Add dma_cleanup callback in bus_type
@ 2022-01-04 12:39       ` Jason Gunthorpe via iommu
  0 siblings, 0 replies; 112+ messages in thread
From: Jason Gunthorpe via iommu @ 2022-01-04 12:39 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Stuart Yoder, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Ashok Raj,
	Jonathan Hunter, Kevin Tian, Chaitanya Kulkarni, Alex Williamson,
	kvm, Bjorn Helgaas, Dan Williams, Greg Kroah-Hartman,
	Cornelia Huck, linux-kernel, Li Yang, iommu, Jacob jun Pan,
	Daniel Vetter, Robin Murphy

On Tue, Jan 04, 2022 at 02:08:36AM -0800, Christoph Hellwig wrote:
> All these bus callouts still looks horrible and just create tons of
> boilerplate code.

Yes, Lu - Greg asked questions then didn't respond to their answers
meaning he accepts them, you should stick with the v4 version.

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

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 00/14] Fix BUG_ON in vfio_iommu_group_notifier()
  2022-01-04  1:56 ` Lu Baolu
@ 2022-01-04 12:48   ` Jason Gunthorpe via iommu
  -1 siblings, 0 replies; 112+ messages in thread
From: Jason Gunthorpe @ 2022-01-04 12:48 UTC (permalink / raw)
  To: Lu Baolu
  Cc: Greg Kroah-Hartman, Joerg Roedel, Alex Williamson, Bjorn Helgaas,
	Christoph Hellwig, Kevin Tian, Ashok Raj, Will Deacon,
	Robin Murphy, Dan Williams, rafael, Diana Craciun, Cornelia Huck,
	Eric Auger, Liu Yi L, Jacob jun Pan, Chaitanya Kulkarni,
	Stuart Yoder, Laurentiu Tudor, Thierry Reding, David Airlie,
	Daniel Vetter, Jonathan Hunter, Li Yang, Dmitry Osipenko, iommu,
	linux-pci, kvm, linux-kernel

On Tue, Jan 04, 2022 at 09:56:30AM +0800, Lu Baolu wrote:

> v5:
>   - Move kernel dma ownership auto-claiming from driver core to bus
>     callback. (Greg)
>   - Refactor the iommu interfaces to make them more specific.
>     (Jason/Robin)
>   - Simplify the dma ownership implementation by removing the owner
>     type. (Jason)
>   - Commit message refactoring for PCI drivers. (Bjorn)
>   - Move iommu_attach/detach_device() improvement patches into another
>     series as there are a lot of code refactoring and cleanup staffs
>     in various device drivers.

Since you already have the code you should make this 'other series'
right now. It should delete iommu_group_attach() and fix
iommu_device_attach().

You also didn't really do my suggestion, this messes up the normal
__iommu_attach_group()/__iommu_detach_group() instead of adding the
clear to purpose iommu_replace_group() for VFIO to use. This just
makes it more difficult to normalize the APIs.

Otherwise it does seem to have turned out to be more understandable.

Jason

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 00/14] Fix BUG_ON in vfio_iommu_group_notifier()
@ 2022-01-04 12:48   ` Jason Gunthorpe via iommu
  0 siblings, 0 replies; 112+ messages in thread
From: Jason Gunthorpe via iommu @ 2022-01-04 12:48 UTC (permalink / raw)
  To: Lu Baolu
  Cc: Stuart Yoder, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Ashok Raj,
	Jonathan Hunter, Christoph Hellwig, Kevin Tian,
	Chaitanya Kulkarni, Alex Williamson, kvm, Bjorn Helgaas,
	Dan Williams, Greg Kroah-Hartman, Cornelia Huck, linux-kernel,
	Li Yang, iommu, Jacob jun Pan, Daniel Vetter, Robin Murphy

On Tue, Jan 04, 2022 at 09:56:30AM +0800, Lu Baolu wrote:

> v5:
>   - Move kernel dma ownership auto-claiming from driver core to bus
>     callback. (Greg)
>   - Refactor the iommu interfaces to make them more specific.
>     (Jason/Robin)
>   - Simplify the dma ownership implementation by removing the owner
>     type. (Jason)
>   - Commit message refactoring for PCI drivers. (Bjorn)
>   - Move iommu_attach/detach_device() improvement patches into another
>     series as there are a lot of code refactoring and cleanup staffs
>     in various device drivers.

Since you already have the code you should make this 'other series'
right now. It should delete iommu_group_attach() and fix
iommu_device_attach().

You also didn't really do my suggestion, this messes up the normal
__iommu_attach_group()/__iommu_detach_group() instead of adding the
clear to purpose iommu_replace_group() for VFIO to use. This just
makes it more difficult to normalize the APIs.

Otherwise it does seem to have turned out to be more understandable.

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

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 02/14] driver core: Add dma_cleanup callback in bus_type
  2022-01-04 12:39       ` Jason Gunthorpe via iommu
@ 2022-01-04 13:04         ` Greg Kroah-Hartman
  -1 siblings, 0 replies; 112+ messages in thread
From: Greg Kroah-Hartman @ 2022-01-04 13:04 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Christoph Hellwig, Lu Baolu, Joerg Roedel, Alex Williamson,
	Bjorn Helgaas, Kevin Tian, Ashok Raj, Will Deacon, Robin Murphy,
	Dan Williams, rafael, Diana Craciun, Cornelia Huck, Eric Auger,
	Liu Yi L, Jacob jun Pan, Chaitanya Kulkarni, Stuart Yoder,
	Laurentiu Tudor, Thierry Reding, David Airlie, Daniel Vetter,
	Jonathan Hunter, Li Yang, Dmitry Osipenko, iommu, linux-pci, kvm,
	linux-kernel

On Tue, Jan 04, 2022 at 08:39:11AM -0400, Jason Gunthorpe wrote:
> On Tue, Jan 04, 2022 at 02:08:36AM -0800, Christoph Hellwig wrote:
> > All these bus callouts still looks horrible and just create tons of
> > boilerplate code.
> 
> Yes, Lu - Greg asked questions then didn't respond to their answers
> meaning he accepts them, you should stick with the v4 version.

Trying to catch up on emails from the break, that was way down my list
of things to get back to as it's messy and non-obvious.  I'll revisit it
again after 5.17-rc1 is out, this is too late for that merge window
anyway.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 02/14] driver core: Add dma_cleanup callback in bus_type
@ 2022-01-04 13:04         ` Greg Kroah-Hartman
  0 siblings, 0 replies; 112+ messages in thread
From: Greg Kroah-Hartman @ 2022-01-04 13:04 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Stuart Yoder, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Ashok Raj,
	Jonathan Hunter, Christoph Hellwig, Kevin Tian,
	Chaitanya Kulkarni, Alex Williamson, kvm, Bjorn Helgaas,
	Dan Williams, Cornelia Huck, linux-kernel, Li Yang, iommu,
	Jacob jun Pan, Daniel Vetter, Robin Murphy

On Tue, Jan 04, 2022 at 08:39:11AM -0400, Jason Gunthorpe wrote:
> On Tue, Jan 04, 2022 at 02:08:36AM -0800, Christoph Hellwig wrote:
> > All these bus callouts still looks horrible and just create tons of
> > boilerplate code.
> 
> Yes, Lu - Greg asked questions then didn't respond to their answers
> meaning he accepts them, you should stick with the v4 version.

Trying to catch up on emails from the break, that was way down my list
of things to get back to as it's messy and non-obvious.  I'll revisit it
again after 5.17-rc1 is out, this is too late for that merge window
anyway.

thanks,

greg k-h
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 01/14] iommu: Add dma ownership management interfaces
  2022-01-04 10:08     ` Christoph Hellwig
@ 2022-01-04 16:41       ` Bjorn Helgaas
  -1 siblings, 0 replies; 112+ messages in thread
From: Bjorn Helgaas @ 2022-01-04 16:41 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Lu Baolu, Greg Kroah-Hartman, Joerg Roedel, Alex Williamson,
	Bjorn Helgaas, Jason Gunthorpe, Kevin Tian, Ashok Raj,
	Will Deacon, Robin Murphy, Dan Williams, rafael, Diana Craciun,
	Cornelia Huck, Eric Auger, Liu Yi L, Jacob jun Pan,
	Chaitanya Kulkarni, Stuart Yoder, Laurentiu Tudor,
	Thierry Reding, David Airlie, Daniel Vetter, Jonathan Hunter,
	Li Yang, Dmitry Osipenko, iommu, linux-pci, kvm, linux-kernel

On Tue, Jan 04, 2022 at 02:08:00AM -0800, Christoph Hellwig wrote:
> On Tue, Jan 04, 2022 at 09:56:31AM +0800, Lu Baolu wrote:
> > Multiple devices may be placed in the same IOMMU group because they
> > cannot be isolated from each other. These devices must either be
> > entirely under kernel control or userspace control, never a mixture.

I guess the reason is that if a group contained a mixture, userspace
could attack the kernel by programming a device to DMA to a device
owned by the kernel?

> > This adds dma ownership management in iommu core and exposes several
> > interfaces for the device drivers and the device userspace assignment
> > framework (i.e. vfio), so that any conflict between user and kernel
> > controlled DMA could be detected at the beginning.

Maybe I'm missing the point because I don't know what "conflict
between user and kernel controlled DMA" is.  Are you talking about
both userspace and the kernel programming the same device to do DMA?

> > The device driver oriented interfaces are,
> > 
> > 	int iommu_device_use_dma_api(struct device *dev);
> > 	void iommu_device_unuse_dma_api(struct device *dev);

Nit, do we care whether it uses the actual DMA API?  Or is it just
that iommu_device_use_dma_api() tells us the driver may program the
device to do DMA?

> > Devices under kernel drivers control must call iommu_device_use_dma_api()
> > before driver probes. The driver binding process must be aborted if it
> > returns failure.

"Devices" don't call functions.  Drivers do, or in this case, it looks
like the bus DMA code (platform, amba, fsl, pci, etc).

These functions are EXPORT_SYMBOL_GPL(), but it looks like all the
callers are built-in, so maybe the export is unnecessary?

You use "iommu"/"IOMMU" and "dma"/"DMA" interchangeably above.  Would
be easier to read if you picked one.

> > The vfio oriented interfaces are,
> > 
> > 	int iommu_group_set_dma_owner(struct iommu_group *group,
> > 				      void *owner);
> > 	void iommu_group_release_dma_owner(struct iommu_group *group);
> > 	bool iommu_group_dma_owner_claimed(struct iommu_group *group);
> > 
> > The device userspace assignment must be disallowed if the set dma owner
> > interface returns failure.

Can you connect this back to the "never a mixture" from the beginning?
If all you cared about was prevent an IOMMU group from containing
devices with a mixture of kernel drivers and userspace drivers, I
assume you could do that without iommu_device_use_dma_api().  So is
this a way to *allow* a mixture under certain restricted conditions?

Another nit below.

> > Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> > Signed-off-by: Kevin Tian <kevin.tian@intel.com>
> > Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
> > ---
> >  include/linux/iommu.h |  31 ++++++++
> >  drivers/iommu/iommu.c | 161 +++++++++++++++++++++++++++++++++++++++++-
> >  2 files changed, 189 insertions(+), 3 deletions(-)
> > 
> > diff --git a/include/linux/iommu.h b/include/linux/iommu.h
> > index de0c57a567c8..568f285468cf 100644
> > --- a/include/linux/iommu.h
> > +++ b/include/linux/iommu.h
> > @@ -682,6 +682,13 @@ struct iommu_sva *iommu_sva_bind_device(struct device *dev,
> >  void iommu_sva_unbind_device(struct iommu_sva *handle);
> >  u32 iommu_sva_get_pasid(struct iommu_sva *handle);
> >  
> > +int iommu_device_use_dma_api(struct device *dev);
> > +void iommu_device_unuse_dma_api(struct device *dev);
> > +
> > +int iommu_group_set_dma_owner(struct iommu_group *group, void *owner);
> > +void iommu_group_release_dma_owner(struct iommu_group *group);
> > +bool iommu_group_dma_owner_claimed(struct iommu_group *group);
> > +
> >  #else /* CONFIG_IOMMU_API */
> >  
> >  struct iommu_ops {};
> > @@ -1082,6 +1089,30 @@ static inline struct iommu_fwspec *dev_iommu_fwspec_get(struct device *dev)
> >  {
> >  	return NULL;
> >  }
> > +
> > +static inline int iommu_device_use_dma_api(struct device *dev)
> > +{
> > +	return 0;
> > +}
> > +
> > +static inline void iommu_device_unuse_dma_api(struct device *dev)
> > +{
> > +}
> > +
> > +static inline int
> > +iommu_group_set_dma_owner(struct iommu_group *group, void *owner)
> > +{
> > +	return -ENODEV;
> > +}
> > +
> > +static inline void iommu_group_release_dma_owner(struct iommu_group *group)
> > +{
> > +}
> > +
> > +static inline bool iommu_group_dma_owner_claimed(struct iommu_group *group)
> > +{
> > +	return false;
> > +}
> >  #endif /* CONFIG_IOMMU_API */
> >  
> >  /**
> > diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> > index 8b86406b7162..ff0c8c1ad5af 100644
> > --- a/drivers/iommu/iommu.c
> > +++ b/drivers/iommu/iommu.c
> > @@ -48,6 +48,8 @@ struct iommu_group {
> >  	struct iommu_domain *default_domain;
> >  	struct iommu_domain *domain;
> >  	struct list_head entry;
> > +	unsigned int owner_cnt;
> > +	void *owner;
> >  };
> >  
> >  struct group_device {
> > @@ -289,7 +291,12 @@ int iommu_probe_device(struct device *dev)
> >  	mutex_lock(&group->mutex);
> >  	iommu_alloc_default_domain(group, dev);
> >  
> > -	if (group->default_domain) {
> > +	/*
> > +	 * If device joined an existing group which has been claimed
> > +	 * for none kernel DMA purpose, avoid attaching the default
> > +	 * domain.

AOL: another "none kernel DMA purpose" that doesn't read well.  Is
this supposed to be "non-kernel"?  What does "claimed for non-kernel
DMA purpose" mean?  What interface does that?

> > +	 */
> > +	if (group->default_domain && !group->owner) {
> >  		ret = __iommu_attach_device(group->default_domain, dev);
> >  		if (ret) {
> >  			mutex_unlock(&group->mutex);
> > @@ -2320,7 +2327,7 @@ static int __iommu_attach_group(struct iommu_domain *domain,
> >  {
> >  	int ret;
> >  
> > -	if (group->default_domain && group->domain != group->default_domain)
> > +	if (group->domain && group->domain != group->default_domain)
> >  		return -EBUSY;
> >  
> >  	ret = __iommu_group_for_each_dev(group, domain,
> > @@ -2357,7 +2364,11 @@ static void __iommu_detach_group(struct iommu_domain *domain,
> >  {
> >  	int ret;
> >  
> > -	if (!group->default_domain) {
> > +	/*
> > +	 * If group has been claimed for none kernel DMA purpose, avoid
> > +	 * re-attaching the default domain.
> > +	 */
> 
> none kernel reads odd.  But maybe drop that and just say 'claimed
> already' ala:
> 
> 	/*
> 	 * If the group has been claimed already, do not re-attach the default
> 	 * domain.
> 	 */

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 01/14] iommu: Add dma ownership management interfaces
@ 2022-01-04 16:41       ` Bjorn Helgaas
  0 siblings, 0 replies; 112+ messages in thread
From: Bjorn Helgaas @ 2022-01-04 16:41 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Stuart Yoder, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Ashok Raj,
	Jonathan Hunter, Jason Gunthorpe, Kevin Tian, Chaitanya Kulkarni,
	Alex Williamson, kvm, Bjorn Helgaas, Dan Williams,
	Greg Kroah-Hartman, Cornelia Huck, linux-kernel, Li Yang, iommu,
	Jacob jun Pan, Daniel Vetter, Robin Murphy

On Tue, Jan 04, 2022 at 02:08:00AM -0800, Christoph Hellwig wrote:
> On Tue, Jan 04, 2022 at 09:56:31AM +0800, Lu Baolu wrote:
> > Multiple devices may be placed in the same IOMMU group because they
> > cannot be isolated from each other. These devices must either be
> > entirely under kernel control or userspace control, never a mixture.

I guess the reason is that if a group contained a mixture, userspace
could attack the kernel by programming a device to DMA to a device
owned by the kernel?

> > This adds dma ownership management in iommu core and exposes several
> > interfaces for the device drivers and the device userspace assignment
> > framework (i.e. vfio), so that any conflict between user and kernel
> > controlled DMA could be detected at the beginning.

Maybe I'm missing the point because I don't know what "conflict
between user and kernel controlled DMA" is.  Are you talking about
both userspace and the kernel programming the same device to do DMA?

> > The device driver oriented interfaces are,
> > 
> > 	int iommu_device_use_dma_api(struct device *dev);
> > 	void iommu_device_unuse_dma_api(struct device *dev);

Nit, do we care whether it uses the actual DMA API?  Or is it just
that iommu_device_use_dma_api() tells us the driver may program the
device to do DMA?

> > Devices under kernel drivers control must call iommu_device_use_dma_api()
> > before driver probes. The driver binding process must be aborted if it
> > returns failure.

"Devices" don't call functions.  Drivers do, or in this case, it looks
like the bus DMA code (platform, amba, fsl, pci, etc).

These functions are EXPORT_SYMBOL_GPL(), but it looks like all the
callers are built-in, so maybe the export is unnecessary?

You use "iommu"/"IOMMU" and "dma"/"DMA" interchangeably above.  Would
be easier to read if you picked one.

> > The vfio oriented interfaces are,
> > 
> > 	int iommu_group_set_dma_owner(struct iommu_group *group,
> > 				      void *owner);
> > 	void iommu_group_release_dma_owner(struct iommu_group *group);
> > 	bool iommu_group_dma_owner_claimed(struct iommu_group *group);
> > 
> > The device userspace assignment must be disallowed if the set dma owner
> > interface returns failure.

Can you connect this back to the "never a mixture" from the beginning?
If all you cared about was prevent an IOMMU group from containing
devices with a mixture of kernel drivers and userspace drivers, I
assume you could do that without iommu_device_use_dma_api().  So is
this a way to *allow* a mixture under certain restricted conditions?

Another nit below.

> > Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> > Signed-off-by: Kevin Tian <kevin.tian@intel.com>
> > Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
> > ---
> >  include/linux/iommu.h |  31 ++++++++
> >  drivers/iommu/iommu.c | 161 +++++++++++++++++++++++++++++++++++++++++-
> >  2 files changed, 189 insertions(+), 3 deletions(-)
> > 
> > diff --git a/include/linux/iommu.h b/include/linux/iommu.h
> > index de0c57a567c8..568f285468cf 100644
> > --- a/include/linux/iommu.h
> > +++ b/include/linux/iommu.h
> > @@ -682,6 +682,13 @@ struct iommu_sva *iommu_sva_bind_device(struct device *dev,
> >  void iommu_sva_unbind_device(struct iommu_sva *handle);
> >  u32 iommu_sva_get_pasid(struct iommu_sva *handle);
> >  
> > +int iommu_device_use_dma_api(struct device *dev);
> > +void iommu_device_unuse_dma_api(struct device *dev);
> > +
> > +int iommu_group_set_dma_owner(struct iommu_group *group, void *owner);
> > +void iommu_group_release_dma_owner(struct iommu_group *group);
> > +bool iommu_group_dma_owner_claimed(struct iommu_group *group);
> > +
> >  #else /* CONFIG_IOMMU_API */
> >  
> >  struct iommu_ops {};
> > @@ -1082,6 +1089,30 @@ static inline struct iommu_fwspec *dev_iommu_fwspec_get(struct device *dev)
> >  {
> >  	return NULL;
> >  }
> > +
> > +static inline int iommu_device_use_dma_api(struct device *dev)
> > +{
> > +	return 0;
> > +}
> > +
> > +static inline void iommu_device_unuse_dma_api(struct device *dev)
> > +{
> > +}
> > +
> > +static inline int
> > +iommu_group_set_dma_owner(struct iommu_group *group, void *owner)
> > +{
> > +	return -ENODEV;
> > +}
> > +
> > +static inline void iommu_group_release_dma_owner(struct iommu_group *group)
> > +{
> > +}
> > +
> > +static inline bool iommu_group_dma_owner_claimed(struct iommu_group *group)
> > +{
> > +	return false;
> > +}
> >  #endif /* CONFIG_IOMMU_API */
> >  
> >  /**
> > diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> > index 8b86406b7162..ff0c8c1ad5af 100644
> > --- a/drivers/iommu/iommu.c
> > +++ b/drivers/iommu/iommu.c
> > @@ -48,6 +48,8 @@ struct iommu_group {
> >  	struct iommu_domain *default_domain;
> >  	struct iommu_domain *domain;
> >  	struct list_head entry;
> > +	unsigned int owner_cnt;
> > +	void *owner;
> >  };
> >  
> >  struct group_device {
> > @@ -289,7 +291,12 @@ int iommu_probe_device(struct device *dev)
> >  	mutex_lock(&group->mutex);
> >  	iommu_alloc_default_domain(group, dev);
> >  
> > -	if (group->default_domain) {
> > +	/*
> > +	 * If device joined an existing group which has been claimed
> > +	 * for none kernel DMA purpose, avoid attaching the default
> > +	 * domain.

AOL: another "none kernel DMA purpose" that doesn't read well.  Is
this supposed to be "non-kernel"?  What does "claimed for non-kernel
DMA purpose" mean?  What interface does that?

> > +	 */
> > +	if (group->default_domain && !group->owner) {
> >  		ret = __iommu_attach_device(group->default_domain, dev);
> >  		if (ret) {
> >  			mutex_unlock(&group->mutex);
> > @@ -2320,7 +2327,7 @@ static int __iommu_attach_group(struct iommu_domain *domain,
> >  {
> >  	int ret;
> >  
> > -	if (group->default_domain && group->domain != group->default_domain)
> > +	if (group->domain && group->domain != group->default_domain)
> >  		return -EBUSY;
> >  
> >  	ret = __iommu_group_for_each_dev(group, domain,
> > @@ -2357,7 +2364,11 @@ static void __iommu_detach_group(struct iommu_domain *domain,
> >  {
> >  	int ret;
> >  
> > -	if (!group->default_domain) {
> > +	/*
> > +	 * If group has been claimed for none kernel DMA purpose, avoid
> > +	 * re-attaching the default domain.
> > +	 */
> 
> none kernel reads odd.  But maybe drop that and just say 'claimed
> already' ala:
> 
> 	/*
> 	 * If the group has been claimed already, do not re-attach the default
> 	 * domain.
> 	 */
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 09/14] PCI: portdrv: Suppress kernel DMA ownership auto-claiming
  2022-01-04  1:56   ` Lu Baolu
@ 2022-01-04 17:06     ` Bjorn Helgaas
  -1 siblings, 0 replies; 112+ messages in thread
From: Bjorn Helgaas @ 2022-01-04 17:06 UTC (permalink / raw)
  To: Lu Baolu
  Cc: Stuart Yoder, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Ashok Raj,
	Jonathan Hunter, Christoph Hellwig, Jason Gunthorpe, Kevin Tian,
	Chaitanya Kulkarni, Alex Williamson, kvm, Bjorn Helgaas,
	Dan Williams, Greg Kroah-Hartman, Cornelia Huck, linux-kernel,
	Li Yang, iommu, Jacob jun Pan, Daniel Vetter, Robin Murphy

On Tue, Jan 04, 2022 at 09:56:39AM +0800, Lu Baolu wrote:
> If a switch lacks ACS P2P Request Redirect, a device below the switch can
> bypass the IOMMU and DMA directly to other devices below the switch, so
> all the downstream devices must be in the same IOMMU group as the switch
> itself.

Help me think through what's going on here.  IIUC, we put devices in
the same IOMMU group when they can interfere with each other in any
way (DMA, config access, etc).

(We said "DMA" above, but I guess this would also apply to config
requests, right?)

*This* patch doesn't check for any ACS features.  Can you connect the
dots for me?  I guess the presence or absence of P2P Request Redirect
determines the size of the IOMMU group.  And the following says
something about what is allowed in the group?  And .no_kernel_api_dma
allows an exception to the general rule?

> The existing vfio framework allows the portdrv driver to be bound
> to the bridge while its downstream devices are assigned to user space.

I.e., the existing VFIO framework allows a switch to be in the same
IOMMU group as the devices below it, even though the switch has a
kernel driver and the other devices may have userspace drivers?

Is this a function of VFIO design or of the IOMMU driver?

> The pci_dma_configure() marks the iommu_group as containing only devices
> with kernel drivers that manage DMA. Avoid this default behavior for the
> portdrv driver in order for compatibility with the current vfio policy.

I assume "IOMMU group" means the same as "iommu_group"; maybe we can
use one of them consistently?

> Suggested-by: Jason Gunthorpe <jgg@nvidia.com>
> Suggested-by: Kevin Tian <kevin.tian@intel.com>
> Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
> ---
>  drivers/pci/pcie/portdrv_pci.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c
> index 35eca6277a96..2116f821c005 100644
> --- a/drivers/pci/pcie/portdrv_pci.c
> +++ b/drivers/pci/pcie/portdrv_pci.c
> @@ -202,6 +202,8 @@ static struct pci_driver pcie_portdriver = {
>  
>  	.err_handler	= &pcie_portdrv_err_handler,
>  
> +	.no_kernel_api_dma = true,
> +
>  	.driver.pm	= PCIE_PORTDRV_PM_OPS,
>  };
>  
> -- 
> 2.25.1
> 
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 09/14] PCI: portdrv: Suppress kernel DMA ownership auto-claiming
@ 2022-01-04 17:06     ` Bjorn Helgaas
  0 siblings, 0 replies; 112+ messages in thread
From: Bjorn Helgaas @ 2022-01-04 17:06 UTC (permalink / raw)
  To: Lu Baolu
  Cc: Greg Kroah-Hartman, Joerg Roedel, Alex Williamson, Bjorn Helgaas,
	Jason Gunthorpe, Christoph Hellwig, Kevin Tian, Ashok Raj,
	Will Deacon, Robin Murphy, Dan Williams, rafael, Diana Craciun,
	Cornelia Huck, Eric Auger, Liu Yi L, Jacob jun Pan,
	Chaitanya Kulkarni, Stuart Yoder, Laurentiu Tudor,
	Thierry Reding, David Airlie, Daniel Vetter, Jonathan Hunter,
	Li Yang, Dmitry Osipenko, iommu, linux-pci, kvm, linux-kernel

On Tue, Jan 04, 2022 at 09:56:39AM +0800, Lu Baolu wrote:
> If a switch lacks ACS P2P Request Redirect, a device below the switch can
> bypass the IOMMU and DMA directly to other devices below the switch, so
> all the downstream devices must be in the same IOMMU group as the switch
> itself.

Help me think through what's going on here.  IIUC, we put devices in
the same IOMMU group when they can interfere with each other in any
way (DMA, config access, etc).

(We said "DMA" above, but I guess this would also apply to config
requests, right?)

*This* patch doesn't check for any ACS features.  Can you connect the
dots for me?  I guess the presence or absence of P2P Request Redirect
determines the size of the IOMMU group.  And the following says
something about what is allowed in the group?  And .no_kernel_api_dma
allows an exception to the general rule?

> The existing vfio framework allows the portdrv driver to be bound
> to the bridge while its downstream devices are assigned to user space.

I.e., the existing VFIO framework allows a switch to be in the same
IOMMU group as the devices below it, even though the switch has a
kernel driver and the other devices may have userspace drivers?

Is this a function of VFIO design or of the IOMMU driver?

> The pci_dma_configure() marks the iommu_group as containing only devices
> with kernel drivers that manage DMA. Avoid this default behavior for the
> portdrv driver in order for compatibility with the current vfio policy.

I assume "IOMMU group" means the same as "iommu_group"; maybe we can
use one of them consistently?

> Suggested-by: Jason Gunthorpe <jgg@nvidia.com>
> Suggested-by: Kevin Tian <kevin.tian@intel.com>
> Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
> ---
>  drivers/pci/pcie/portdrv_pci.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c
> index 35eca6277a96..2116f821c005 100644
> --- a/drivers/pci/pcie/portdrv_pci.c
> +++ b/drivers/pci/pcie/portdrv_pci.c
> @@ -202,6 +202,8 @@ static struct pci_driver pcie_portdriver = {
>  
>  	.err_handler	= &pcie_portdrv_err_handler,
>  
> +	.no_kernel_api_dma = true,
> +
>  	.driver.pm	= PCIE_PORTDRV_PM_OPS,
>  };
>  
> -- 
> 2.25.1
> 

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 01/14] iommu: Add dma ownership management interfaces
  2022-01-04 16:41       ` Bjorn Helgaas
@ 2022-01-04 19:23         ` Jason Gunthorpe via iommu
  -1 siblings, 0 replies; 112+ messages in thread
From: Jason Gunthorpe @ 2022-01-04 19:23 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Christoph Hellwig, Lu Baolu, Greg Kroah-Hartman, Joerg Roedel,
	Alex Williamson, Bjorn Helgaas, Kevin Tian, Ashok Raj,
	Will Deacon, Robin Murphy, Dan Williams, rafael, Diana Craciun,
	Cornelia Huck, Eric Auger, Liu Yi L, Jacob jun Pan,
	Chaitanya Kulkarni, Stuart Yoder, Laurentiu Tudor,
	Thierry Reding, David Airlie, Daniel Vetter, Jonathan Hunter,
	Li Yang, Dmitry Osipenko, iommu, linux-pci, kvm, linux-kernel

On Tue, Jan 04, 2022 at 10:41:00AM -0600, Bjorn Helgaas wrote:
> On Tue, Jan 04, 2022 at 02:08:00AM -0800, Christoph Hellwig wrote:
> > On Tue, Jan 04, 2022 at 09:56:31AM +0800, Lu Baolu wrote:
> > > Multiple devices may be placed in the same IOMMU group because they
> > > cannot be isolated from each other. These devices must either be
> > > entirely under kernel control or userspace control, never a mixture.
> 
> I guess the reason is that if a group contained a mixture, userspace
> could attack the kernel by programming a device to DMA to a device
> owned by the kernel?

There are several of reasons, including what you guess, but for the
design of the series now we can just focus on the group's domain.

If the kernel is using a device then the kernel driver uses the DMA
API and the group's domain must always point to the default domain so
long as a DMA API user exists. Hopefully it is clear to understand

> > > The device driver oriented interfaces are,
> > > 
> > > 	int iommu_device_use_dma_api(struct device *dev);
> > > 	void iommu_device_unuse_dma_api(struct device *dev);
> 
> Nit, do we care whether it uses the actual DMA API?  Or is it just
> that iommu_device_use_dma_api() tells us the driver may program the
> device to do DMA?

As the main purpose, yes this is all about the DMA API because it
asserts the group domain is the DMA API's domain.

There is a secondary purpose that has to do with the user/kernel
attack you mentioned above. Maintaining the DMA API domain also
prevents VFIO from allowing userspace to operate any device in the
group which blocks P2P attacks to MMIO of other devices.

This is why, even if the driver doesn't use DMA, it should still do a
iommu_device_use_dma_api(), except in the special cases where we don't
care about P2P attacks (eg pci-stub, bridges, etc).

> > > The vfio oriented interfaces are,
> > > 
> > > 	int iommu_group_set_dma_owner(struct iommu_group *group,
> > > 				      void *owner);
> > > 	void iommu_group_release_dma_owner(struct iommu_group *group);
> > > 	bool iommu_group_dma_owner_claimed(struct iommu_group *group);
> > > 
> > > The device userspace assignment must be disallowed if the set dma owner
> > > interface returns failure.
> 
> Can you connect this back to the "never a mixture" from the beginning?
> If all you cared about was prevent an IOMMU group from containing
> devices with a mixture of kernel drivers and userspace drivers, I
> assume you could do that without iommu_device_use_dma_api().  So is
> this a way to *allow* a mixture under certain restricted conditions?

It is not about user/kernel, it is about arbitrating the shared
group->domain against multiple different requests to set it to
something else.

Lu, Given that the word 'user' was deleted from the API entirely it
makes sense to reword these commit messages to focus less on user vs
kernel and more on ownership of the domain pointer.

Jason

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 01/14] iommu: Add dma ownership management interfaces
@ 2022-01-04 19:23         ` Jason Gunthorpe via iommu
  0 siblings, 0 replies; 112+ messages in thread
From: Jason Gunthorpe via iommu @ 2022-01-04 19:23 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Stuart Yoder, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Ashok Raj,
	Jonathan Hunter, Christoph Hellwig, Kevin Tian,
	Chaitanya Kulkarni, Alex Williamson, kvm, Bjorn Helgaas,
	Dan Williams, Greg Kroah-Hartman, Cornelia Huck, linux-kernel,
	Li Yang, iommu, Jacob jun Pan, Daniel Vetter, Robin Murphy

On Tue, Jan 04, 2022 at 10:41:00AM -0600, Bjorn Helgaas wrote:
> On Tue, Jan 04, 2022 at 02:08:00AM -0800, Christoph Hellwig wrote:
> > On Tue, Jan 04, 2022 at 09:56:31AM +0800, Lu Baolu wrote:
> > > Multiple devices may be placed in the same IOMMU group because they
> > > cannot be isolated from each other. These devices must either be
> > > entirely under kernel control or userspace control, never a mixture.
> 
> I guess the reason is that if a group contained a mixture, userspace
> could attack the kernel by programming a device to DMA to a device
> owned by the kernel?

There are several of reasons, including what you guess, but for the
design of the series now we can just focus on the group's domain.

If the kernel is using a device then the kernel driver uses the DMA
API and the group's domain must always point to the default domain so
long as a DMA API user exists. Hopefully it is clear to understand

> > > The device driver oriented interfaces are,
> > > 
> > > 	int iommu_device_use_dma_api(struct device *dev);
> > > 	void iommu_device_unuse_dma_api(struct device *dev);
> 
> Nit, do we care whether it uses the actual DMA API?  Or is it just
> that iommu_device_use_dma_api() tells us the driver may program the
> device to do DMA?

As the main purpose, yes this is all about the DMA API because it
asserts the group domain is the DMA API's domain.

There is a secondary purpose that has to do with the user/kernel
attack you mentioned above. Maintaining the DMA API domain also
prevents VFIO from allowing userspace to operate any device in the
group which blocks P2P attacks to MMIO of other devices.

This is why, even if the driver doesn't use DMA, it should still do a
iommu_device_use_dma_api(), except in the special cases where we don't
care about P2P attacks (eg pci-stub, bridges, etc).

> > > The vfio oriented interfaces are,
> > > 
> > > 	int iommu_group_set_dma_owner(struct iommu_group *group,
> > > 				      void *owner);
> > > 	void iommu_group_release_dma_owner(struct iommu_group *group);
> > > 	bool iommu_group_dma_owner_claimed(struct iommu_group *group);
> > > 
> > > The device userspace assignment must be disallowed if the set dma owner
> > > interface returns failure.
> 
> Can you connect this back to the "never a mixture" from the beginning?
> If all you cared about was prevent an IOMMU group from containing
> devices with a mixture of kernel drivers and userspace drivers, I
> assume you could do that without iommu_device_use_dma_api().  So is
> this a way to *allow* a mixture under certain restricted conditions?

It is not about user/kernel, it is about arbitrating the shared
group->domain against multiple different requests to set it to
something else.

Lu, Given that the word 'user' was deleted from the API entirely it
makes sense to reword these commit messages to focus less on user vs
kernel and more on ownership of the domain pointer.

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

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 09/14] PCI: portdrv: Suppress kernel DMA ownership auto-claiming
  2022-01-04 17:06     ` Bjorn Helgaas
@ 2022-01-04 19:26       ` Jason Gunthorpe via iommu
  -1 siblings, 0 replies; 112+ messages in thread
From: Jason Gunthorpe @ 2022-01-04 19:26 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Lu Baolu, Greg Kroah-Hartman, Joerg Roedel, Alex Williamson,
	Bjorn Helgaas, Christoph Hellwig, Kevin Tian, Ashok Raj,
	Will Deacon, Robin Murphy, Dan Williams, rafael, Diana Craciun,
	Cornelia Huck, Eric Auger, Liu Yi L, Jacob jun Pan,
	Chaitanya Kulkarni, Stuart Yoder, Laurentiu Tudor,
	Thierry Reding, David Airlie, Daniel Vetter, Jonathan Hunter,
	Li Yang, Dmitry Osipenko, iommu, linux-pci, kvm, linux-kernel

On Tue, Jan 04, 2022 at 11:06:31AM -0600, Bjorn Helgaas wrote:

> > The existing vfio framework allows the portdrv driver to be bound
> > to the bridge while its downstream devices are assigned to user space.
> 
> I.e., the existing VFIO framework allows a switch to be in the same
> IOMMU group as the devices below it, even though the switch has a
> kernel driver and the other devices may have userspace drivers?

Yes, this patch exists to maintain current VFIO behavior which has this
same check.

I belive the basis for VFIO doing this is that the these devices
cannot do DMA, so don't care about the DMA API or the group->domain,
and do not expose MMIO memory so do not care about the P2P attack.

A comment in the code to this effect would be good, IMHO.

Jason

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 09/14] PCI: portdrv: Suppress kernel DMA ownership auto-claiming
@ 2022-01-04 19:26       ` Jason Gunthorpe via iommu
  0 siblings, 0 replies; 112+ messages in thread
From: Jason Gunthorpe via iommu @ 2022-01-04 19:26 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Stuart Yoder, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Ashok Raj,
	Jonathan Hunter, Christoph Hellwig, Kevin Tian,
	Chaitanya Kulkarni, Alex Williamson, kvm, Bjorn Helgaas,
	Dan Williams, Greg Kroah-Hartman, Cornelia Huck, linux-kernel,
	Li Yang, iommu, Jacob jun Pan, Daniel Vetter, Robin Murphy

On Tue, Jan 04, 2022 at 11:06:31AM -0600, Bjorn Helgaas wrote:

> > The existing vfio framework allows the portdrv driver to be bound
> > to the bridge while its downstream devices are assigned to user space.
> 
> I.e., the existing VFIO framework allows a switch to be in the same
> IOMMU group as the devices below it, even though the switch has a
> kernel driver and the other devices may have userspace drivers?

Yes, this patch exists to maintain current VFIO behavior which has this
same check.

I belive the basis for VFIO doing this is that the these devices
cannot do DMA, so don't care about the DMA API or the group->domain,
and do not expose MMIO memory so do not care about the P2P attack.

A comment in the code to this effect would be good, IMHO.

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

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 09/14] PCI: portdrv: Suppress kernel DMA ownership auto-claiming
  2022-01-04 19:26       ` Jason Gunthorpe via iommu
@ 2022-01-04 19:51         ` Bjorn Helgaas
  -1 siblings, 0 replies; 112+ messages in thread
From: Bjorn Helgaas @ 2022-01-04 19:51 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Lu Baolu, Greg Kroah-Hartman, Joerg Roedel, Alex Williamson,
	Bjorn Helgaas, Christoph Hellwig, Kevin Tian, Ashok Raj,
	Will Deacon, Robin Murphy, Dan Williams, rafael, Diana Craciun,
	Cornelia Huck, Eric Auger, Liu Yi L, Jacob jun Pan,
	Chaitanya Kulkarni, Stuart Yoder, Laurentiu Tudor,
	Thierry Reding, David Airlie, Daniel Vetter, Jonathan Hunter,
	Li Yang, Dmitry Osipenko, iommu, linux-pci, kvm, linux-kernel

On Tue, Jan 04, 2022 at 03:26:14PM -0400, Jason Gunthorpe wrote:
> On Tue, Jan 04, 2022 at 11:06:31AM -0600, Bjorn Helgaas wrote:
> 
> > > The existing vfio framework allows the portdrv driver to be bound
> > > to the bridge while its downstream devices are assigned to user space.
> > 
> > I.e., the existing VFIO framework allows a switch to be in the same
> > IOMMU group as the devices below it, even though the switch has a
> > kernel driver and the other devices may have userspace drivers?
> 
> Yes, this patch exists to maintain current VFIO behavior which has this
> same check.
> 
> I belive the basis for VFIO doing this is that the these devices
> cannot do DMA, so don't care about the DMA API or the group->domain,
> and do not expose MMIO memory so do not care about the P2P attack.

"These devices" means bridges, right?  Not sure why we wouldn't care
about the P2P attack.

PCIe switches use MSI or MSI-X for hotplug, PME, etc, so they do DMA
for that.  Is that not relevant here?

Is there something that *prohibits* a bridge from having
device-specific functionality including DMA?

I know some bridges have device-specific BARs for performance counters
and the like.

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 09/14] PCI: portdrv: Suppress kernel DMA ownership auto-claiming
@ 2022-01-04 19:51         ` Bjorn Helgaas
  0 siblings, 0 replies; 112+ messages in thread
From: Bjorn Helgaas @ 2022-01-04 19:51 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Stuart Yoder, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Ashok Raj,
	Jonathan Hunter, Christoph Hellwig, Kevin Tian,
	Chaitanya Kulkarni, Alex Williamson, kvm, Bjorn Helgaas,
	Dan Williams, Greg Kroah-Hartman, Cornelia Huck, linux-kernel,
	Li Yang, iommu, Jacob jun Pan, Daniel Vetter, Robin Murphy

On Tue, Jan 04, 2022 at 03:26:14PM -0400, Jason Gunthorpe wrote:
> On Tue, Jan 04, 2022 at 11:06:31AM -0600, Bjorn Helgaas wrote:
> 
> > > The existing vfio framework allows the portdrv driver to be bound
> > > to the bridge while its downstream devices are assigned to user space.
> > 
> > I.e., the existing VFIO framework allows a switch to be in the same
> > IOMMU group as the devices below it, even though the switch has a
> > kernel driver and the other devices may have userspace drivers?
> 
> Yes, this patch exists to maintain current VFIO behavior which has this
> same check.
> 
> I belive the basis for VFIO doing this is that the these devices
> cannot do DMA, so don't care about the DMA API or the group->domain,
> and do not expose MMIO memory so do not care about the P2P attack.

"These devices" means bridges, right?  Not sure why we wouldn't care
about the P2P attack.

PCIe switches use MSI or MSI-X for hotplug, PME, etc, so they do DMA
for that.  Is that not relevant here?

Is there something that *prohibits* a bridge from having
device-specific functionality including DMA?

I know some bridges have device-specific BARs for performance counters
and the like.
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 09/14] PCI: portdrv: Suppress kernel DMA ownership auto-claiming
  2022-01-04 19:51         ` Bjorn Helgaas
@ 2022-01-05  0:35           ` Jason Gunthorpe via iommu
  -1 siblings, 0 replies; 112+ messages in thread
From: Jason Gunthorpe @ 2022-01-05  0:35 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Lu Baolu, Greg Kroah-Hartman, Joerg Roedel, Alex Williamson,
	Bjorn Helgaas, Christoph Hellwig, Kevin Tian, Ashok Raj,
	Will Deacon, Robin Murphy, Dan Williams, rafael, Diana Craciun,
	Cornelia Huck, Eric Auger, Liu Yi L, Jacob jun Pan,
	Chaitanya Kulkarni, Stuart Yoder, Laurentiu Tudor,
	Thierry Reding, David Airlie, Daniel Vetter, Jonathan Hunter,
	Li Yang, Dmitry Osipenko, iommu, linux-pci, kvm, linux-kernel

On Tue, Jan 04, 2022 at 01:51:30PM -0600, Bjorn Helgaas wrote:
> On Tue, Jan 04, 2022 at 03:26:14PM -0400, Jason Gunthorpe wrote:
> > On Tue, Jan 04, 2022 at 11:06:31AM -0600, Bjorn Helgaas wrote:
> > 
> > > > The existing vfio framework allows the portdrv driver to be bound
> > > > to the bridge while its downstream devices are assigned to user space.
> > > 
> > > I.e., the existing VFIO framework allows a switch to be in the same
> > > IOMMU group as the devices below it, even though the switch has a
> > > kernel driver and the other devices may have userspace drivers?
> > 
> > Yes, this patch exists to maintain current VFIO behavior which has this
> > same check.
> > 
> > I belive the basis for VFIO doing this is that the these devices
> > cannot do DMA, so don't care about the DMA API or the group->domain,
> > and do not expose MMIO memory so do not care about the P2P attack.
> 
> "These devices" means bridges, right?  Not sure why we wouldn't care
> about the P2P attack.

Yes bridges. I said "I belive" because VFIO was changed to ignore
bridges a long time ago and the security rational was a bit unclear in
the commit.

See 5f096b14d421 ("vfio: Whitelist PCI bridges")

> PCIe switches use MSI or MSI-X for hotplug, PME, etc, so they do DMA
> for that.  Is that not relevant here?

Alex's comment in the above commit notes about interrupts, but I think
the answer today is that it does not matter.

For platforms like x86 that keep interrupts and DMA seperate it
works fine.

For platforms that comingle the iommu_domain and interrupts (do some
exist?) we expect the platform to do whatever is necessary at
iommu_domain attach time to ensure interrupts continue to
work. (AFAICT at least)

In other words we don't have an API restriction to use
iommu_device_use_dma_api() to use request_irq().

So the main concern should be P2P attacks on bridge MMIO registers.

> Is there something that *prohibits* a bridge from having
> device-specific functionality including DMA?

I'm not sure, I think not, but the 'Bus Master Enable' language does
have a different definition for Type 1..

However, it doesn't matter - the question here is not about what the
device HW is capable of, but what does the kernel driver do. The
portdrv does not use the DMA API, so that alone is half the
requirement to skip the iommu_device_use_dma_api() call.

Some future device-specific bridge driver that is able to issue the
device-specific MMIO's and operate the DMA API should be coded to use
iommu_device_use_dma_api(), probably by using a different
device_driver for the bridge.

> I know some bridges have device-specific BARs for performance counters
> and the like.

Yep.

IMHO it is probably not so great as-is..

However, this patch is just porting the status-quo of commit 5f09 into
this new framework.

What this new framework does allow is for portdrv to police itself. eg
it could check if there is a MMIO BAR and call
iommu_device_use_dma_api() out of caution. It could also have an
allowance list of devices where we know hostile writes to the MMIO are
known harmless.

Without knowing more about what motivated 5f09 it is hard to say,
other than it has been 7 years like this and nobody has complained
yet :)

Jason

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 09/14] PCI: portdrv: Suppress kernel DMA ownership auto-claiming
@ 2022-01-05  0:35           ` Jason Gunthorpe via iommu
  0 siblings, 0 replies; 112+ messages in thread
From: Jason Gunthorpe via iommu @ 2022-01-05  0:35 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Stuart Yoder, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Ashok Raj,
	Jonathan Hunter, Christoph Hellwig, Kevin Tian,
	Chaitanya Kulkarni, Alex Williamson, kvm, Bjorn Helgaas,
	Dan Williams, Greg Kroah-Hartman, Cornelia Huck, linux-kernel,
	Li Yang, iommu, Jacob jun Pan, Daniel Vetter, Robin Murphy

On Tue, Jan 04, 2022 at 01:51:30PM -0600, Bjorn Helgaas wrote:
> On Tue, Jan 04, 2022 at 03:26:14PM -0400, Jason Gunthorpe wrote:
> > On Tue, Jan 04, 2022 at 11:06:31AM -0600, Bjorn Helgaas wrote:
> > 
> > > > The existing vfio framework allows the portdrv driver to be bound
> > > > to the bridge while its downstream devices are assigned to user space.
> > > 
> > > I.e., the existing VFIO framework allows a switch to be in the same
> > > IOMMU group as the devices below it, even though the switch has a
> > > kernel driver and the other devices may have userspace drivers?
> > 
> > Yes, this patch exists to maintain current VFIO behavior which has this
> > same check.
> > 
> > I belive the basis for VFIO doing this is that the these devices
> > cannot do DMA, so don't care about the DMA API or the group->domain,
> > and do not expose MMIO memory so do not care about the P2P attack.
> 
> "These devices" means bridges, right?  Not sure why we wouldn't care
> about the P2P attack.

Yes bridges. I said "I belive" because VFIO was changed to ignore
bridges a long time ago and the security rational was a bit unclear in
the commit.

See 5f096b14d421 ("vfio: Whitelist PCI bridges")

> PCIe switches use MSI or MSI-X for hotplug, PME, etc, so they do DMA
> for that.  Is that not relevant here?

Alex's comment in the above commit notes about interrupts, but I think
the answer today is that it does not matter.

For platforms like x86 that keep interrupts and DMA seperate it
works fine.

For platforms that comingle the iommu_domain and interrupts (do some
exist?) we expect the platform to do whatever is necessary at
iommu_domain attach time to ensure interrupts continue to
work. (AFAICT at least)

In other words we don't have an API restriction to use
iommu_device_use_dma_api() to use request_irq().

So the main concern should be P2P attacks on bridge MMIO registers.

> Is there something that *prohibits* a bridge from having
> device-specific functionality including DMA?

I'm not sure, I think not, but the 'Bus Master Enable' language does
have a different definition for Type 1..

However, it doesn't matter - the question here is not about what the
device HW is capable of, but what does the kernel driver do. The
portdrv does not use the DMA API, so that alone is half the
requirement to skip the iommu_device_use_dma_api() call.

Some future device-specific bridge driver that is able to issue the
device-specific MMIO's and operate the DMA API should be coded to use
iommu_device_use_dma_api(), probably by using a different
device_driver for the bridge.

> I know some bridges have device-specific BARs for performance counters
> and the like.

Yep.

IMHO it is probably not so great as-is..

However, this patch is just porting the status-quo of commit 5f09 into
this new framework.

What this new framework does allow is for portdrv to police itself. eg
it could check if there is a MMIO BAR and call
iommu_device_use_dma_api() out of caution. It could also have an
allowance list of devices where we know hostile writes to the MMIO are
known harmless.

Without knowing more about what motivated 5f09 it is hard to say,
other than it has been 7 years like this and nobody has complained
yet :)

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

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 00/14] Fix BUG_ON in vfio_iommu_group_notifier()
  2022-01-04 12:48   ` Jason Gunthorpe via iommu
@ 2022-01-05  6:52     ` Lu Baolu
  -1 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-01-05  6:52 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: baolu.lu, Greg Kroah-Hartman, Joerg Roedel, Alex Williamson,
	Bjorn Helgaas, Christoph Hellwig, Kevin Tian, Ashok Raj,
	Will Deacon, Robin Murphy, Dan Williams, rafael, Diana Craciun,
	Cornelia Huck, Eric Auger, Liu Yi L, Jacob jun Pan,
	Chaitanya Kulkarni, Stuart Yoder, Laurentiu Tudor,
	Thierry Reding, David Airlie, Daniel Vetter, Jonathan Hunter,
	Li Yang, Dmitry Osipenko, iommu, linux-pci, kvm, linux-kernel

Hi Jason,

On 1/4/22 8:48 PM, Jason Gunthorpe wrote:
> On Tue, Jan 04, 2022 at 09:56:30AM +0800, Lu Baolu wrote:
> 
>> v5:
>>    - Move kernel dma ownership auto-claiming from driver core to bus
>>      callback. (Greg)
>>    - Refactor the iommu interfaces to make them more specific.
>>      (Jason/Robin)
>>    - Simplify the dma ownership implementation by removing the owner
>>      type. (Jason)
>>    - Commit message refactoring for PCI drivers. (Bjorn)
>>    - Move iommu_attach/detach_device() improvement patches into another
>>      series as there are a lot of code refactoring and cleanup staffs
>>      in various device drivers.
> 
> Since you already have the code you should make this 'other series'
> right now. It should delete iommu_group_attach() and fix
> iommu_device_attach().

Yes. I am doing the functional and compile tests. I will post it once I
complete the testing.

> 
> You also didn't really do my suggestion, this messes up the normal
> __iommu_attach_group()/__iommu_detach_group() instead of adding the
> clear to purpose iommu_replace_group() for VFIO to use. This just
> makes it more difficult to normalize the APIs.

I didn't forget that. :-) It's part of the new series.

> 
> Otherwise it does seem to have turned out to be more understandable.
> 
> Jason
> 

Best regards,
baolu

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 00/14] Fix BUG_ON in vfio_iommu_group_notifier()
@ 2022-01-05  6:52     ` Lu Baolu
  0 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-01-05  6:52 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Stuart Yoder, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Ashok Raj,
	Jonathan Hunter, Christoph Hellwig, Kevin Tian,
	Chaitanya Kulkarni, Alex Williamson, kvm, Bjorn Helgaas,
	Dan Williams, Greg Kroah-Hartman, Cornelia Huck, linux-kernel,
	Li Yang, iommu, Jacob jun Pan, Daniel Vetter, Robin Murphy

Hi Jason,

On 1/4/22 8:48 PM, Jason Gunthorpe wrote:
> On Tue, Jan 04, 2022 at 09:56:30AM +0800, Lu Baolu wrote:
> 
>> v5:
>>    - Move kernel dma ownership auto-claiming from driver core to bus
>>      callback. (Greg)
>>    - Refactor the iommu interfaces to make them more specific.
>>      (Jason/Robin)
>>    - Simplify the dma ownership implementation by removing the owner
>>      type. (Jason)
>>    - Commit message refactoring for PCI drivers. (Bjorn)
>>    - Move iommu_attach/detach_device() improvement patches into another
>>      series as there are a lot of code refactoring and cleanup staffs
>>      in various device drivers.
> 
> Since you already have the code you should make this 'other series'
> right now. It should delete iommu_group_attach() and fix
> iommu_device_attach().

Yes. I am doing the functional and compile tests. I will post it once I
complete the testing.

> 
> You also didn't really do my suggestion, this messes up the normal
> __iommu_attach_group()/__iommu_detach_group() instead of adding the
> clear to purpose iommu_replace_group() for VFIO to use. This just
> makes it more difficult to normalize the APIs.

I didn't forget that. :-) It's part of the new series.

> 
> Otherwise it does seem to have turned out to be more understandable.
> 
> Jason
> 

Best regards,
baolu
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 01/14] iommu: Add dma ownership management interfaces
  2022-01-04 10:08     ` Christoph Hellwig
@ 2022-01-05  6:57       ` Lu Baolu
  -1 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-01-05  6:57 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: baolu.lu, Greg Kroah-Hartman, Joerg Roedel, Alex Williamson,
	Bjorn Helgaas, Jason Gunthorpe, Kevin Tian, Ashok Raj,
	Will Deacon, Robin Murphy, Dan Williams, rafael, Diana Craciun,
	Cornelia Huck, Eric Auger, Liu Yi L, Jacob jun Pan,
	Chaitanya Kulkarni, Stuart Yoder, Laurentiu Tudor,
	Thierry Reding, David Airlie, Daniel Vetter, Jonathan Hunter,
	Li Yang, Dmitry Osipenko, iommu, linux-pci, kvm, linux-kernel

Hi Christoph,

On 1/4/22 6:08 PM, Christoph Hellwig wrote:
> On Tue, Jan 04, 2022 at 09:56:31AM +0800, Lu Baolu wrote:
>> Multiple devices may be placed in the same IOMMU group because they
>> cannot be isolated from each other. These devices must either be
>> entirely under kernel control or userspace control, never a mixture.
>>
>> This adds dma ownership management in iommu core and exposes several
>> interfaces for the device drivers and the device userspace assignment
>> framework (i.e. vfio), so that any conflict between user and kernel
>> controlled DMA could be detected at the beginning.
>>
>> The device driver oriented interfaces are,
>>
>> 	int iommu_device_use_dma_api(struct device *dev);
>> 	void iommu_device_unuse_dma_api(struct device *dev);
>>
>> Devices under kernel drivers control must call iommu_device_use_dma_api()
>> before driver probes. The driver binding process must be aborted if it
>> returns failure.
>>
>> The vfio oriented interfaces are,
>>
>> 	int iommu_group_set_dma_owner(struct iommu_group *group,
>> 				      void *owner);
>> 	void iommu_group_release_dma_owner(struct iommu_group *group);
>> 	bool iommu_group_dma_owner_claimed(struct iommu_group *group);
>>
>> The device userspace assignment must be disallowed if the set dma owner
>> interface returns failure.
>>
>> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
>> Signed-off-by: Kevin Tian <kevin.tian@intel.com>
>> Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
>> ---
>>   include/linux/iommu.h |  31 ++++++++
>>   drivers/iommu/iommu.c | 161 +++++++++++++++++++++++++++++++++++++++++-
>>   2 files changed, 189 insertions(+), 3 deletions(-)
>>
>> diff --git a/include/linux/iommu.h b/include/linux/iommu.h
>> index de0c57a567c8..568f285468cf 100644
>> --- a/include/linux/iommu.h
>> +++ b/include/linux/iommu.h
>> @@ -682,6 +682,13 @@ struct iommu_sva *iommu_sva_bind_device(struct device *dev,
>>   void iommu_sva_unbind_device(struct iommu_sva *handle);
>>   u32 iommu_sva_get_pasid(struct iommu_sva *handle);
>>   
>> +int iommu_device_use_dma_api(struct device *dev);
>> +void iommu_device_unuse_dma_api(struct device *dev);
>> +
>> +int iommu_group_set_dma_owner(struct iommu_group *group, void *owner);
>> +void iommu_group_release_dma_owner(struct iommu_group *group);
>> +bool iommu_group_dma_owner_claimed(struct iommu_group *group);
>> +
>>   #else /* CONFIG_IOMMU_API */
>>   
>>   struct iommu_ops {};
>> @@ -1082,6 +1089,30 @@ static inline struct iommu_fwspec *dev_iommu_fwspec_get(struct device *dev)
>>   {
>>   	return NULL;
>>   }
>> +
>> +static inline int iommu_device_use_dma_api(struct device *dev)
>> +{
>> +	return 0;
>> +}
>> +
>> +static inline void iommu_device_unuse_dma_api(struct device *dev)
>> +{
>> +}
>> +
>> +static inline int
>> +iommu_group_set_dma_owner(struct iommu_group *group, void *owner)
>> +{
>> +	return -ENODEV;
>> +}
>> +
>> +static inline void iommu_group_release_dma_owner(struct iommu_group *group)
>> +{
>> +}
>> +
>> +static inline bool iommu_group_dma_owner_claimed(struct iommu_group *group)
>> +{
>> +	return false;
>> +}
>>   #endif /* CONFIG_IOMMU_API */
>>   
>>   /**
>> diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
>> index 8b86406b7162..ff0c8c1ad5af 100644
>> --- a/drivers/iommu/iommu.c
>> +++ b/drivers/iommu/iommu.c
>> @@ -48,6 +48,8 @@ struct iommu_group {
>>   	struct iommu_domain *default_domain;
>>   	struct iommu_domain *domain;
>>   	struct list_head entry;
>> +	unsigned int owner_cnt;
>> +	void *owner;
>>   };
>>   
>>   struct group_device {
>> @@ -289,7 +291,12 @@ int iommu_probe_device(struct device *dev)
>>   	mutex_lock(&group->mutex);
>>   	iommu_alloc_default_domain(group, dev);
>>   
>> -	if (group->default_domain) {
>> +	/*
>> +	 * If device joined an existing group which has been claimed
>> +	 * for none kernel DMA purpose, avoid attaching the default
>> +	 * domain.
>> +	 */
>> +	if (group->default_domain && !group->owner) {
>>   		ret = __iommu_attach_device(group->default_domain, dev);
>>   		if (ret) {
>>   			mutex_unlock(&group->mutex);
>> @@ -2320,7 +2327,7 @@ static int __iommu_attach_group(struct iommu_domain *domain,
>>   {
>>   	int ret;
>>   
>> -	if (group->default_domain && group->domain != group->default_domain)
>> +	if (group->domain && group->domain != group->default_domain)
>>   		return -EBUSY;
>>   
>>   	ret = __iommu_group_for_each_dev(group, domain,
>> @@ -2357,7 +2364,11 @@ static void __iommu_detach_group(struct iommu_domain *domain,
>>   {
>>   	int ret;
>>   
>> -	if (!group->default_domain) {
>> +	/*
>> +	 * If group has been claimed for none kernel DMA purpose, avoid
>> +	 * re-attaching the default domain.
>> +	 */
> 
> none kernel reads odd.  But maybe drop that and just say 'claimed
> already' ala:
> 
> 	/*
> 	 * If the group has been claimed already, do not re-attach the default
> 	 * domain.
> 	 */
> 

Sure!

Best regards,
baolu

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 01/14] iommu: Add dma ownership management interfaces
@ 2022-01-05  6:57       ` Lu Baolu
  0 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-01-05  6:57 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Stuart Yoder, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Ashok Raj,
	Jonathan Hunter, Jason Gunthorpe, Kevin Tian, Chaitanya Kulkarni,
	Alex Williamson, kvm, Bjorn Helgaas, Dan Williams,
	Greg Kroah-Hartman, Cornelia Huck, linux-kernel, Li Yang, iommu,
	Jacob jun Pan, Daniel Vetter, Robin Murphy

Hi Christoph,

On 1/4/22 6:08 PM, Christoph Hellwig wrote:
> On Tue, Jan 04, 2022 at 09:56:31AM +0800, Lu Baolu wrote:
>> Multiple devices may be placed in the same IOMMU group because they
>> cannot be isolated from each other. These devices must either be
>> entirely under kernel control or userspace control, never a mixture.
>>
>> This adds dma ownership management in iommu core and exposes several
>> interfaces for the device drivers and the device userspace assignment
>> framework (i.e. vfio), so that any conflict between user and kernel
>> controlled DMA could be detected at the beginning.
>>
>> The device driver oriented interfaces are,
>>
>> 	int iommu_device_use_dma_api(struct device *dev);
>> 	void iommu_device_unuse_dma_api(struct device *dev);
>>
>> Devices under kernel drivers control must call iommu_device_use_dma_api()
>> before driver probes. The driver binding process must be aborted if it
>> returns failure.
>>
>> The vfio oriented interfaces are,
>>
>> 	int iommu_group_set_dma_owner(struct iommu_group *group,
>> 				      void *owner);
>> 	void iommu_group_release_dma_owner(struct iommu_group *group);
>> 	bool iommu_group_dma_owner_claimed(struct iommu_group *group);
>>
>> The device userspace assignment must be disallowed if the set dma owner
>> interface returns failure.
>>
>> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
>> Signed-off-by: Kevin Tian <kevin.tian@intel.com>
>> Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
>> ---
>>   include/linux/iommu.h |  31 ++++++++
>>   drivers/iommu/iommu.c | 161 +++++++++++++++++++++++++++++++++++++++++-
>>   2 files changed, 189 insertions(+), 3 deletions(-)
>>
>> diff --git a/include/linux/iommu.h b/include/linux/iommu.h
>> index de0c57a567c8..568f285468cf 100644
>> --- a/include/linux/iommu.h
>> +++ b/include/linux/iommu.h
>> @@ -682,6 +682,13 @@ struct iommu_sva *iommu_sva_bind_device(struct device *dev,
>>   void iommu_sva_unbind_device(struct iommu_sva *handle);
>>   u32 iommu_sva_get_pasid(struct iommu_sva *handle);
>>   
>> +int iommu_device_use_dma_api(struct device *dev);
>> +void iommu_device_unuse_dma_api(struct device *dev);
>> +
>> +int iommu_group_set_dma_owner(struct iommu_group *group, void *owner);
>> +void iommu_group_release_dma_owner(struct iommu_group *group);
>> +bool iommu_group_dma_owner_claimed(struct iommu_group *group);
>> +
>>   #else /* CONFIG_IOMMU_API */
>>   
>>   struct iommu_ops {};
>> @@ -1082,6 +1089,30 @@ static inline struct iommu_fwspec *dev_iommu_fwspec_get(struct device *dev)
>>   {
>>   	return NULL;
>>   }
>> +
>> +static inline int iommu_device_use_dma_api(struct device *dev)
>> +{
>> +	return 0;
>> +}
>> +
>> +static inline void iommu_device_unuse_dma_api(struct device *dev)
>> +{
>> +}
>> +
>> +static inline int
>> +iommu_group_set_dma_owner(struct iommu_group *group, void *owner)
>> +{
>> +	return -ENODEV;
>> +}
>> +
>> +static inline void iommu_group_release_dma_owner(struct iommu_group *group)
>> +{
>> +}
>> +
>> +static inline bool iommu_group_dma_owner_claimed(struct iommu_group *group)
>> +{
>> +	return false;
>> +}
>>   #endif /* CONFIG_IOMMU_API */
>>   
>>   /**
>> diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
>> index 8b86406b7162..ff0c8c1ad5af 100644
>> --- a/drivers/iommu/iommu.c
>> +++ b/drivers/iommu/iommu.c
>> @@ -48,6 +48,8 @@ struct iommu_group {
>>   	struct iommu_domain *default_domain;
>>   	struct iommu_domain *domain;
>>   	struct list_head entry;
>> +	unsigned int owner_cnt;
>> +	void *owner;
>>   };
>>   
>>   struct group_device {
>> @@ -289,7 +291,12 @@ int iommu_probe_device(struct device *dev)
>>   	mutex_lock(&group->mutex);
>>   	iommu_alloc_default_domain(group, dev);
>>   
>> -	if (group->default_domain) {
>> +	/*
>> +	 * If device joined an existing group which has been claimed
>> +	 * for none kernel DMA purpose, avoid attaching the default
>> +	 * domain.
>> +	 */
>> +	if (group->default_domain && !group->owner) {
>>   		ret = __iommu_attach_device(group->default_domain, dev);
>>   		if (ret) {
>>   			mutex_unlock(&group->mutex);
>> @@ -2320,7 +2327,7 @@ static int __iommu_attach_group(struct iommu_domain *domain,
>>   {
>>   	int ret;
>>   
>> -	if (group->default_domain && group->domain != group->default_domain)
>> +	if (group->domain && group->domain != group->default_domain)
>>   		return -EBUSY;
>>   
>>   	ret = __iommu_group_for_each_dev(group, domain,
>> @@ -2357,7 +2364,11 @@ static void __iommu_detach_group(struct iommu_domain *domain,
>>   {
>>   	int ret;
>>   
>> -	if (!group->default_domain) {
>> +	/*
>> +	 * If group has been claimed for none kernel DMA purpose, avoid
>> +	 * re-attaching the default domain.
>> +	 */
> 
> none kernel reads odd.  But maybe drop that and just say 'claimed
> already' ala:
> 
> 	/*
> 	 * If the group has been claimed already, do not re-attach the default
> 	 * domain.
> 	 */
> 

Sure!

Best regards,
baolu
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 01/14] iommu: Add dma ownership management interfaces
  2022-01-04 19:23         ` Jason Gunthorpe via iommu
@ 2022-01-06  3:18           ` Lu Baolu
  -1 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-01-06  3:18 UTC (permalink / raw)
  To: Jason Gunthorpe, Bjorn Helgaas
  Cc: baolu.lu, Christoph Hellwig, Greg Kroah-Hartman, Joerg Roedel,
	Alex Williamson, Bjorn Helgaas, Kevin Tian, Ashok Raj,
	Will Deacon, Robin Murphy, Dan Williams, rafael, Diana Craciun,
	Cornelia Huck, Eric Auger, Liu Yi L, Jacob jun Pan,
	Chaitanya Kulkarni, Stuart Yoder, Laurentiu Tudor,
	Thierry Reding, David Airlie, Daniel Vetter, Jonathan Hunter,
	Li Yang, Dmitry Osipenko, iommu, linux-pci, kvm, linux-kernel

On 1/5/22 3:23 AM, Jason Gunthorpe wrote:
>>>> The vfio oriented interfaces are,
>>>>
>>>> 	int iommu_group_set_dma_owner(struct iommu_group *group,
>>>> 				      void *owner);
>>>> 	void iommu_group_release_dma_owner(struct iommu_group *group);
>>>> 	bool iommu_group_dma_owner_claimed(struct iommu_group *group);
>>>>
>>>> The device userspace assignment must be disallowed if the set dma owner
>>>> interface returns failure.
>> Can you connect this back to the "never a mixture" from the beginning?
>> If all you cared about was prevent an IOMMU group from containing
>> devices with a mixture of kernel drivers and userspace drivers, I
>> assume you could do that without iommu_device_use_dma_api().  So is
>> this a way to*allow*  a mixture under certain restricted conditions?
> It is not about user/kernel, it is about arbitrating the shared
> group->domain against multiple different requests to set it to
> something else.
> 
> Lu, Given that the word 'user' was deleted from the API entirely it
> makes sense to reword these commit messages to focus less on user vs
> kernel and more on ownership of the domain pointer.

Sure. Will do it.

Best regards,
baolu

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 01/14] iommu: Add dma ownership management interfaces
@ 2022-01-06  3:18           ` Lu Baolu
  0 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-01-06  3:18 UTC (permalink / raw)
  To: Jason Gunthorpe, Bjorn Helgaas
  Cc: Stuart Yoder, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Ashok Raj,
	Jonathan Hunter, Christoph Hellwig, Kevin Tian,
	Chaitanya Kulkarni, Alex Williamson, kvm, Bjorn Helgaas,
	Dan Williams, Greg Kroah-Hartman, Cornelia Huck, linux-kernel,
	Li Yang, iommu, Jacob jun Pan, Daniel Vetter, Robin Murphy

On 1/5/22 3:23 AM, Jason Gunthorpe wrote:
>>>> The vfio oriented interfaces are,
>>>>
>>>> 	int iommu_group_set_dma_owner(struct iommu_group *group,
>>>> 				      void *owner);
>>>> 	void iommu_group_release_dma_owner(struct iommu_group *group);
>>>> 	bool iommu_group_dma_owner_claimed(struct iommu_group *group);
>>>>
>>>> The device userspace assignment must be disallowed if the set dma owner
>>>> interface returns failure.
>> Can you connect this back to the "never a mixture" from the beginning?
>> If all you cared about was prevent an IOMMU group from containing
>> devices with a mixture of kernel drivers and userspace drivers, I
>> assume you could do that without iommu_device_use_dma_api().  So is
>> this a way to*allow*  a mixture under certain restricted conditions?
> It is not about user/kernel, it is about arbitrating the shared
> group->domain against multiple different requests to set it to
> something else.
> 
> Lu, Given that the word 'user' was deleted from the API entirely it
> makes sense to reword these commit messages to focus less on user vs
> kernel and more on ownership of the domain pointer.

Sure. Will do it.

Best regards,
baolu
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 01/14] iommu: Add dma ownership management interfaces
  2022-01-04 16:41       ` Bjorn Helgaas
@ 2022-01-06  3:43         ` Lu Baolu
  -1 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-01-06  3:43 UTC (permalink / raw)
  To: Bjorn Helgaas, Christoph Hellwig
  Cc: baolu.lu, Greg Kroah-Hartman, Joerg Roedel, Alex Williamson,
	Bjorn Helgaas, Jason Gunthorpe, Kevin Tian, Ashok Raj,
	Will Deacon, Robin Murphy, Dan Williams, rafael, Diana Craciun,
	Cornelia Huck, Eric Auger, Liu Yi L, Jacob jun Pan,
	Chaitanya Kulkarni, Stuart Yoder, Laurentiu Tudor,
	Thierry Reding, David Airlie, Daniel Vetter, Jonathan Hunter,
	Li Yang, Dmitry Osipenko, iommu, linux-pci, kvm, linux-kernel

Hi Bjorn,

On 1/5/22 12:41 AM, Bjorn Helgaas wrote:
>>> This adds dma ownership management in iommu core and exposes several
>>> interfaces for the device drivers and the device userspace assignment
>>> framework (i.e. vfio), so that any conflict between user and kernel
>>> controlled DMA could be detected at the beginning.
> Maybe I'm missing the point because I don't know what "conflict
> between user and kernel controlled DMA" is.  Are you talking about
> both userspace and the kernel programming the same device to do DMA?

It's about both userspace and kernel programming different devices
belonging to a same iommu group to do DMA. For example, PCI device A and
B sit in a some iommu group. Userspace programs device A for DMA and a
kernel driver programs device B. Userspace may intentionally or
unintentionally program device A to access and change device B's MMIO
with P2P DMA transactions which cause the kernel driver for device B
result in an inconsistent state.

This may not be all, just an example.

Best regards,
baolu


^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 01/14] iommu: Add dma ownership management interfaces
@ 2022-01-06  3:43         ` Lu Baolu
  0 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-01-06  3:43 UTC (permalink / raw)
  To: Bjorn Helgaas, Christoph Hellwig
  Cc: Stuart Yoder, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Ashok Raj,
	Jonathan Hunter, Jason Gunthorpe, Kevin Tian, Chaitanya Kulkarni,
	Alex Williamson, kvm, Bjorn Helgaas, Dan Williams,
	Greg Kroah-Hartman, Cornelia Huck, linux-kernel, Li Yang, iommu,
	Jacob jun Pan, Daniel Vetter, Robin Murphy

Hi Bjorn,

On 1/5/22 12:41 AM, Bjorn Helgaas wrote:
>>> This adds dma ownership management in iommu core and exposes several
>>> interfaces for the device drivers and the device userspace assignment
>>> framework (i.e. vfio), so that any conflict between user and kernel
>>> controlled DMA could be detected at the beginning.
> Maybe I'm missing the point because I don't know what "conflict
> between user and kernel controlled DMA" is.  Are you talking about
> both userspace and the kernel programming the same device to do DMA?

It's about both userspace and kernel programming different devices
belonging to a same iommu group to do DMA. For example, PCI device A and
B sit in a some iommu group. Userspace programs device A for DMA and a
kernel driver programs device B. Userspace may intentionally or
unintentionally program device A to access and change device B's MMIO
with P2P DMA transactions which cause the kernel driver for device B
result in an inconsistent state.

This may not be all, just an example.

Best regards,
baolu

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

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 01/14] iommu: Add dma ownership management interfaces
  2022-01-04 16:41       ` Bjorn Helgaas
@ 2022-01-06  3:47         ` Lu Baolu
  -1 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-01-06  3:47 UTC (permalink / raw)
  To: Bjorn Helgaas, Christoph Hellwig
  Cc: baolu.lu, Greg Kroah-Hartman, Joerg Roedel, Alex Williamson,
	Bjorn Helgaas, Jason Gunthorpe, Kevin Tian, Ashok Raj,
	Will Deacon, Robin Murphy, Dan Williams, rafael, Diana Craciun,
	Cornelia Huck, Eric Auger, Liu Yi L, Jacob jun Pan,
	Chaitanya Kulkarni, Stuart Yoder, Laurentiu Tudor,
	Thierry Reding, David Airlie, Daniel Vetter, Jonathan Hunter,
	Li Yang, Dmitry Osipenko, iommu, linux-pci, kvm, linux-kernel

On 1/5/22 12:41 AM, Bjorn Helgaas wrote:
>>> Devices under kernel drivers control must call iommu_device_use_dma_api()
>>> before driver probes. The driver binding process must be aborted if it
>>> returns failure.
> "Devices" don't call functions.  Drivers do, or in this case, it looks
> like the bus DMA code (platform, amba, fsl, pci, etc).
> 
> These functions are EXPORT_SYMBOL_GPL(), but it looks like all the
> callers are built-in, so maybe the export is unnecessary?

Yes. If all callers are built-in, we can remove this export.

> 
> You use "iommu"/"IOMMU" and "dma"/"DMA" interchangeably above.  Would
> be easier to read if you picked one.
> 

I should cleanup all these. I also realized that I forgot to
cleanup some typos you pointed out in v4:

https://lore.kernel.org/linux-iommu/20211229211626.GA1701512@bhelgaas/

Sorry about it. I will take care of all these in the next version.

Best regards,
baolu

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 01/14] iommu: Add dma ownership management interfaces
@ 2022-01-06  3:47         ` Lu Baolu
  0 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-01-06  3:47 UTC (permalink / raw)
  To: Bjorn Helgaas, Christoph Hellwig
  Cc: Stuart Yoder, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Ashok Raj,
	Jonathan Hunter, Jason Gunthorpe, Kevin Tian, Chaitanya Kulkarni,
	Alex Williamson, kvm, Bjorn Helgaas, Dan Williams,
	Greg Kroah-Hartman, Cornelia Huck, linux-kernel, Li Yang, iommu,
	Jacob jun Pan, Daniel Vetter, Robin Murphy

On 1/5/22 12:41 AM, Bjorn Helgaas wrote:
>>> Devices under kernel drivers control must call iommu_device_use_dma_api()
>>> before driver probes. The driver binding process must be aborted if it
>>> returns failure.
> "Devices" don't call functions.  Drivers do, or in this case, it looks
> like the bus DMA code (platform, amba, fsl, pci, etc).
> 
> These functions are EXPORT_SYMBOL_GPL(), but it looks like all the
> callers are built-in, so maybe the export is unnecessary?

Yes. If all callers are built-in, we can remove this export.

> 
> You use "iommu"/"IOMMU" and "dma"/"DMA" interchangeably above.  Would
> be easier to read if you picked one.
> 

I should cleanup all these. I also realized that I forgot to
cleanup some typos you pointed out in v4:

https://lore.kernel.org/linux-iommu/20211229211626.GA1701512@bhelgaas/

Sorry about it. I will take care of all these in the next version.

Best regards,
baolu
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 01/14] iommu: Add dma ownership management interfaces
  2022-01-04 16:41       ` Bjorn Helgaas
@ 2022-01-06  3:51         ` Lu Baolu
  -1 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-01-06  3:51 UTC (permalink / raw)
  To: Bjorn Helgaas, Christoph Hellwig
  Cc: baolu.lu, Greg Kroah-Hartman, Joerg Roedel, Alex Williamson,
	Bjorn Helgaas, Jason Gunthorpe, Kevin Tian, Ashok Raj,
	Will Deacon, Robin Murphy, Dan Williams, rafael, Diana Craciun,
	Cornelia Huck, Eric Auger, Liu Yi L, Jacob jun Pan,
	Chaitanya Kulkarni, Stuart Yoder, Laurentiu Tudor,
	Thierry Reding, David Airlie, Daniel Vetter, Jonathan Hunter,
	Li Yang, Dmitry Osipenko, iommu, linux-pci, kvm, linux-kernel

On 1/5/22 12:41 AM, Bjorn Helgaas wrote:
>>>   struct group_device {
>>> @@ -289,7 +291,12 @@ int iommu_probe_device(struct device *dev)
>>>   	mutex_lock(&group->mutex);
>>>   	iommu_alloc_default_domain(group, dev);
>>>   
>>> -	if (group->default_domain) {
>>> +	/*
>>> +	 * If device joined an existing group which has been claimed
>>> +	 * for none kernel DMA purpose, avoid attaching the default
>>> +	 * domain.
> AOL: another "none kernel DMA purpose" that doesn't read well.  Is
> this supposed to be "non-kernel"?  What does "claimed for non-kernel
> DMA purpose" mean?  What interface does that?
> 

It's hard to read. I will rephrase it like this:

/*
  * If device joined an existing group which has been claimed, don't
  * attach the default domain.
  */

Best regards,
baolu

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 01/14] iommu: Add dma ownership management interfaces
@ 2022-01-06  3:51         ` Lu Baolu
  0 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-01-06  3:51 UTC (permalink / raw)
  To: Bjorn Helgaas, Christoph Hellwig
  Cc: Stuart Yoder, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Ashok Raj,
	Jonathan Hunter, Jason Gunthorpe, Kevin Tian, Chaitanya Kulkarni,
	Alex Williamson, kvm, Bjorn Helgaas, Dan Williams,
	Greg Kroah-Hartman, Cornelia Huck, linux-kernel, Li Yang, iommu,
	Jacob jun Pan, Daniel Vetter, Robin Murphy

On 1/5/22 12:41 AM, Bjorn Helgaas wrote:
>>>   struct group_device {
>>> @@ -289,7 +291,12 @@ int iommu_probe_device(struct device *dev)
>>>   	mutex_lock(&group->mutex);
>>>   	iommu_alloc_default_domain(group, dev);
>>>   
>>> -	if (group->default_domain) {
>>> +	/*
>>> +	 * If device joined an existing group which has been claimed
>>> +	 * for none kernel DMA purpose, avoid attaching the default
>>> +	 * domain.
> AOL: another "none kernel DMA purpose" that doesn't read well.  Is
> this supposed to be "non-kernel"?  What does "claimed for non-kernel
> DMA purpose" mean?  What interface does that?
> 

It's hard to read. I will rephrase it like this:

/*
  * If device joined an existing group which has been claimed, don't
  * attach the default domain.
  */

Best regards,
baolu
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 01/14] iommu: Add dma ownership management interfaces
  2022-01-04 19:23         ` Jason Gunthorpe via iommu
@ 2022-01-06  3:54           ` Lu Baolu
  -1 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-01-06  3:54 UTC (permalink / raw)
  To: Jason Gunthorpe, Bjorn Helgaas
  Cc: baolu.lu, Christoph Hellwig, Greg Kroah-Hartman, Joerg Roedel,
	Alex Williamson, Bjorn Helgaas, Kevin Tian, Ashok Raj,
	Will Deacon, Robin Murphy, Dan Williams, rafael, Diana Craciun,
	Cornelia Huck, Eric Auger, Liu Yi L, Jacob jun Pan,
	Chaitanya Kulkarni, Stuart Yoder, Laurentiu Tudor,
	Thierry Reding, David Airlie, Daniel Vetter, Jonathan Hunter,
	Li Yang, Dmitry Osipenko, iommu, linux-pci, kvm, linux-kernel

On 1/5/22 3:23 AM, Jason Gunthorpe wrote:
>>>> The device driver oriented interfaces are,
>>>>
>>>> 	int iommu_device_use_dma_api(struct device *dev);
>>>> 	void iommu_device_unuse_dma_api(struct device *dev);
>> Nit, do we care whether it uses the actual DMA API?  Or is it just
>> that iommu_device_use_dma_api() tells us the driver may program the
>> device to do DMA?
> As the main purpose, yes this is all about the DMA API because it
> asserts the group domain is the DMA API's domain.
> 
> There is a secondary purpose that has to do with the user/kernel
> attack you mentioned above. Maintaining the DMA API domain also
> prevents VFIO from allowing userspace to operate any device in the
> group which blocks P2P attacks to MMIO of other devices.
> 
> This is why, even if the driver doesn't use DMA, it should still do a
> iommu_device_use_dma_api(), except in the special cases where we don't
> care about P2P attacks (eg pci-stub, bridges, etc).
> 

By the way, use_dma_api seems hard to read. How about

	iommu_device_use_default_dma()?

Best regards,
baolu

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 01/14] iommu: Add dma ownership management interfaces
@ 2022-01-06  3:54           ` Lu Baolu
  0 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-01-06  3:54 UTC (permalink / raw)
  To: Jason Gunthorpe, Bjorn Helgaas
  Cc: Stuart Yoder, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Ashok Raj,
	Jonathan Hunter, Christoph Hellwig, Kevin Tian,
	Chaitanya Kulkarni, Alex Williamson, kvm, Bjorn Helgaas,
	Dan Williams, Greg Kroah-Hartman, Cornelia Huck, linux-kernel,
	Li Yang, iommu, Jacob jun Pan, Daniel Vetter, Robin Murphy

On 1/5/22 3:23 AM, Jason Gunthorpe wrote:
>>>> The device driver oriented interfaces are,
>>>>
>>>> 	int iommu_device_use_dma_api(struct device *dev);
>>>> 	void iommu_device_unuse_dma_api(struct device *dev);
>> Nit, do we care whether it uses the actual DMA API?  Or is it just
>> that iommu_device_use_dma_api() tells us the driver may program the
>> device to do DMA?
> As the main purpose, yes this is all about the DMA API because it
> asserts the group domain is the DMA API's domain.
> 
> There is a secondary purpose that has to do with the user/kernel
> attack you mentioned above. Maintaining the DMA API domain also
> prevents VFIO from allowing userspace to operate any device in the
> group which blocks P2P attacks to MMIO of other devices.
> 
> This is why, even if the driver doesn't use DMA, it should still do a
> iommu_device_use_dma_api(), except in the special cases where we don't
> care about P2P attacks (eg pci-stub, bridges, etc).
> 

By the way, use_dma_api seems hard to read. How about

	iommu_device_use_default_dma()?

Best regards,
baolu
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 09/14] PCI: portdrv: Suppress kernel DMA ownership auto-claiming
  2022-01-04 17:06     ` Bjorn Helgaas
@ 2022-01-06  4:12       ` Lu Baolu
  -1 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-01-06  4:12 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: baolu.lu, Greg Kroah-Hartman, Joerg Roedel, Alex Williamson,
	Bjorn Helgaas, Jason Gunthorpe, Christoph Hellwig, Kevin Tian,
	Ashok Raj, Will Deacon, Robin Murphy, Dan Williams, rafael,
	Diana Craciun, Cornelia Huck, Eric Auger, Liu Yi L,
	Jacob jun Pan, Chaitanya Kulkarni, Stuart Yoder, Laurentiu Tudor,
	Thierry Reding, David Airlie, Daniel Vetter, Jonathan Hunter,
	Li Yang, Dmitry Osipenko, iommu, linux-pci, kvm, linux-kernel

Hi Bjorn,

On 1/5/22 1:06 AM, Bjorn Helgaas wrote:
> On Tue, Jan 04, 2022 at 09:56:39AM +0800, Lu Baolu wrote:
>> If a switch lacks ACS P2P Request Redirect, a device below the switch can
>> bypass the IOMMU and DMA directly to other devices below the switch, so
>> all the downstream devices must be in the same IOMMU group as the switch
>> itself.
> Help me think through what's going on here.  IIUC, we put devices in
> the same IOMMU group when they can interfere with each other in any
> way (DMA, config access, etc).
> 
> (We said "DMA" above, but I guess this would also apply to config
> requests, right?)

I am not sure whether devices could interfere each other through config
space access. The IOMMU hardware only protects and isolates DMA
accesses, so that userspace could control DMA directly. The config
accesses will always be intercepted by VFIO. Hence, I don't see a
problem.

> 
> *This*  patch doesn't check for any ACS features.  Can you connect the
> dots for me?  I guess the presence or absence of P2P Request Redirect
> determines the size of the IOMMU group.  And the following says

It's done in iommu core (drivers/iommu/iommu.c):

/*
  * Use standard PCI bus topology, isolation features, and DMA alias quirks
  * to find or create an IOMMU group for a device.
  */
struct iommu_group *pci_device_group(struct device *dev)


> something about what is allowed in the group?  And .no_kernel_api_dma
> allows an exception to the general rule?
> 

Yes.

>> The pci_dma_configure() marks the iommu_group as containing only devices
>> with kernel drivers that manage DMA. Avoid this default behavior for the
>> portdrv driver in order for compatibility with the current vfio policy.
> I assume "IOMMU group" means the same as "iommu_group"; maybe we can
> use one of them consistently?

Sure.

Best regards,
baolu

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 09/14] PCI: portdrv: Suppress kernel DMA ownership auto-claiming
@ 2022-01-06  4:12       ` Lu Baolu
  0 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-01-06  4:12 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Stuart Yoder, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Ashok Raj,
	Jonathan Hunter, Christoph Hellwig, Jason Gunthorpe, Kevin Tian,
	Chaitanya Kulkarni, Alex Williamson, kvm, Bjorn Helgaas,
	Dan Williams, Greg Kroah-Hartman, Cornelia Huck, linux-kernel,
	Li Yang, iommu, Jacob jun Pan, Daniel Vetter, Robin Murphy

Hi Bjorn,

On 1/5/22 1:06 AM, Bjorn Helgaas wrote:
> On Tue, Jan 04, 2022 at 09:56:39AM +0800, Lu Baolu wrote:
>> If a switch lacks ACS P2P Request Redirect, a device below the switch can
>> bypass the IOMMU and DMA directly to other devices below the switch, so
>> all the downstream devices must be in the same IOMMU group as the switch
>> itself.
> Help me think through what's going on here.  IIUC, we put devices in
> the same IOMMU group when they can interfere with each other in any
> way (DMA, config access, etc).
> 
> (We said "DMA" above, but I guess this would also apply to config
> requests, right?)

I am not sure whether devices could interfere each other through config
space access. The IOMMU hardware only protects and isolates DMA
accesses, so that userspace could control DMA directly. The config
accesses will always be intercepted by VFIO. Hence, I don't see a
problem.

> 
> *This*  patch doesn't check for any ACS features.  Can you connect the
> dots for me?  I guess the presence or absence of P2P Request Redirect
> determines the size of the IOMMU group.  And the following says

It's done in iommu core (drivers/iommu/iommu.c):

/*
  * Use standard PCI bus topology, isolation features, and DMA alias quirks
  * to find or create an IOMMU group for a device.
  */
struct iommu_group *pci_device_group(struct device *dev)


> something about what is allowed in the group?  And .no_kernel_api_dma
> allows an exception to the general rule?
> 

Yes.

>> The pci_dma_configure() marks the iommu_group as containing only devices
>> with kernel drivers that manage DMA. Avoid this default behavior for the
>> portdrv driver in order for compatibility with the current vfio policy.
> I assume "IOMMU group" means the same as "iommu_group"; maybe we can
> use one of them consistently?

Sure.

Best regards,
baolu
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 01/14] iommu: Add dma ownership management interfaces
  2022-01-06  3:54           ` Lu Baolu
@ 2022-01-06 15:46             ` Jason Gunthorpe via iommu
  -1 siblings, 0 replies; 112+ messages in thread
From: Jason Gunthorpe @ 2022-01-06 15:46 UTC (permalink / raw)
  To: Lu Baolu
  Cc: Bjorn Helgaas, Christoph Hellwig, Greg Kroah-Hartman,
	Joerg Roedel, Alex Williamson, Bjorn Helgaas, Kevin Tian,
	Ashok Raj, Will Deacon, Robin Murphy, Dan Williams, rafael,
	Diana Craciun, Cornelia Huck, Eric Auger, Liu Yi L,
	Jacob jun Pan, Chaitanya Kulkarni, Stuart Yoder, Laurentiu Tudor,
	Thierry Reding, David Airlie, Daniel Vetter, Jonathan Hunter,
	Li Yang, Dmitry Osipenko, iommu, linux-pci, kvm, linux-kernel

On Thu, Jan 06, 2022 at 11:54:06AM +0800, Lu Baolu wrote:
> On 1/5/22 3:23 AM, Jason Gunthorpe wrote:
> > > > > The device driver oriented interfaces are,
> > > > > 
> > > > > 	int iommu_device_use_dma_api(struct device *dev);
> > > > > 	void iommu_device_unuse_dma_api(struct device *dev);
> > > Nit, do we care whether it uses the actual DMA API?  Or is it just
> > > that iommu_device_use_dma_api() tells us the driver may program the
> > > device to do DMA?
> > As the main purpose, yes this is all about the DMA API because it
> > asserts the group domain is the DMA API's domain.
> > 
> > There is a secondary purpose that has to do with the user/kernel
> > attack you mentioned above. Maintaining the DMA API domain also
> > prevents VFIO from allowing userspace to operate any device in the
> > group which blocks P2P attacks to MMIO of other devices.
> > 
> > This is why, even if the driver doesn't use DMA, it should still do a
> > iommu_device_use_dma_api(), except in the special cases where we don't
> > care about P2P attacks (eg pci-stub, bridges, etc).
> > 
> 
> By the way, use_dma_api seems hard to read. How about
> 
> 	iommu_device_use_default_dma()?

You could just say "use default domain"

IMHO the way the iommu subsystem has its own wonky language is a
little troublesome. In the rest of the kernel we call this the DMA
API, while the iommu subsystem calls the domain that the DMA API uses
the 'default domain' not the 'DMA API' domain.

Still, it is probably better to align to the iommu language - just be
sure to put in the function comment that this API 'allows the driver
to use the DMA API eg dma_map_sg()'

Jason

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 01/14] iommu: Add dma ownership management interfaces
@ 2022-01-06 15:46             ` Jason Gunthorpe via iommu
  0 siblings, 0 replies; 112+ messages in thread
From: Jason Gunthorpe via iommu @ 2022-01-06 15:46 UTC (permalink / raw)
  To: Lu Baolu
  Cc: Stuart Yoder, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Ashok Raj,
	Jonathan Hunter, Christoph Hellwig, Bjorn Helgaas, Kevin Tian,
	Chaitanya Kulkarni, Alex Williamson, kvm, Bjorn Helgaas,
	Dan Williams, Greg Kroah-Hartman, Cornelia Huck, linux-kernel,
	Li Yang, iommu, Jacob jun Pan, Daniel Vetter, Robin Murphy

On Thu, Jan 06, 2022 at 11:54:06AM +0800, Lu Baolu wrote:
> On 1/5/22 3:23 AM, Jason Gunthorpe wrote:
> > > > > The device driver oriented interfaces are,
> > > > > 
> > > > > 	int iommu_device_use_dma_api(struct device *dev);
> > > > > 	void iommu_device_unuse_dma_api(struct device *dev);
> > > Nit, do we care whether it uses the actual DMA API?  Or is it just
> > > that iommu_device_use_dma_api() tells us the driver may program the
> > > device to do DMA?
> > As the main purpose, yes this is all about the DMA API because it
> > asserts the group domain is the DMA API's domain.
> > 
> > There is a secondary purpose that has to do with the user/kernel
> > attack you mentioned above. Maintaining the DMA API domain also
> > prevents VFIO from allowing userspace to operate any device in the
> > group which blocks P2P attacks to MMIO of other devices.
> > 
> > This is why, even if the driver doesn't use DMA, it should still do a
> > iommu_device_use_dma_api(), except in the special cases where we don't
> > care about P2P attacks (eg pci-stub, bridges, etc).
> > 
> 
> By the way, use_dma_api seems hard to read. How about
> 
> 	iommu_device_use_default_dma()?

You could just say "use default domain"

IMHO the way the iommu subsystem has its own wonky language is a
little troublesome. In the rest of the kernel we call this the DMA
API, while the iommu subsystem calls the domain that the DMA API uses
the 'default domain' not the 'DMA API' domain.

Still, it is probably better to align to the iommu language - just be
sure to put in the function comment that this API 'allows the driver
to use the DMA API eg dma_map_sg()'

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

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 09/14] PCI: portdrv: Suppress kernel DMA ownership auto-claiming
  2022-01-06  4:12       ` Lu Baolu
@ 2022-01-06 18:32         ` Bjorn Helgaas
  -1 siblings, 0 replies; 112+ messages in thread
From: Bjorn Helgaas @ 2022-01-06 18:32 UTC (permalink / raw)
  To: Lu Baolu
  Cc: Greg Kroah-Hartman, Joerg Roedel, Alex Williamson, Bjorn Helgaas,
	Jason Gunthorpe, Christoph Hellwig, Kevin Tian, Ashok Raj,
	Will Deacon, Robin Murphy, Dan Williams, rafael, Diana Craciun,
	Cornelia Huck, Eric Auger, Liu Yi L, Jacob jun Pan,
	Chaitanya Kulkarni, Stuart Yoder, Laurentiu Tudor,
	Thierry Reding, David Airlie, Daniel Vetter, Jonathan Hunter,
	Li Yang, Dmitry Osipenko, iommu, linux-pci, kvm, linux-kernel

On Thu, Jan 06, 2022 at 12:12:35PM +0800, Lu Baolu wrote:
> On 1/5/22 1:06 AM, Bjorn Helgaas wrote:
> > On Tue, Jan 04, 2022 at 09:56:39AM +0800, Lu Baolu wrote:
> > > If a switch lacks ACS P2P Request Redirect, a device below the switch can
> > > bypass the IOMMU and DMA directly to other devices below the switch, so
> > > all the downstream devices must be in the same IOMMU group as the switch
> > > itself.
> > Help me think through what's going on here.  IIUC, we put devices in
> > the same IOMMU group when they can interfere with each other in any
> > way (DMA, config access, etc).
> > 
> > (We said "DMA" above, but I guess this would also apply to config
> > requests, right?)
> 
> I am not sure whether devices could interfere each other through config
> space access. The IOMMU hardware only protects and isolates DMA
> accesses, so that userspace could control DMA directly. The config
> accesses will always be intercepted by VFIO. Hence, I don't see a
> problem.

I was wondering about config accesses generated by an endpoint, e.g.,
an endpoint doing config writes to a peer or the upstream bridge.

But I think that is prohibited by spec - PCIe r5.0, sec 7.3.3, says
"Propagation of Configuration Requests from Downstream to Upstream as
well as peer-to-peer are not supported" and "Configuration Requests
are initiated only by the Host Bridge, including those passed through
the SFI CAM mechanism."

Bjorn

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 09/14] PCI: portdrv: Suppress kernel DMA ownership auto-claiming
@ 2022-01-06 18:32         ` Bjorn Helgaas
  0 siblings, 0 replies; 112+ messages in thread
From: Bjorn Helgaas @ 2022-01-06 18:32 UTC (permalink / raw)
  To: Lu Baolu
  Cc: Stuart Yoder, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Ashok Raj,
	Jonathan Hunter, Christoph Hellwig, Jason Gunthorpe, Kevin Tian,
	Chaitanya Kulkarni, Alex Williamson, kvm, Bjorn Helgaas,
	Dan Williams, Greg Kroah-Hartman, Cornelia Huck, linux-kernel,
	Li Yang, iommu, Jacob jun Pan, Daniel Vetter, Robin Murphy

On Thu, Jan 06, 2022 at 12:12:35PM +0800, Lu Baolu wrote:
> On 1/5/22 1:06 AM, Bjorn Helgaas wrote:
> > On Tue, Jan 04, 2022 at 09:56:39AM +0800, Lu Baolu wrote:
> > > If a switch lacks ACS P2P Request Redirect, a device below the switch can
> > > bypass the IOMMU and DMA directly to other devices below the switch, so
> > > all the downstream devices must be in the same IOMMU group as the switch
> > > itself.
> > Help me think through what's going on here.  IIUC, we put devices in
> > the same IOMMU group when they can interfere with each other in any
> > way (DMA, config access, etc).
> > 
> > (We said "DMA" above, but I guess this would also apply to config
> > requests, right?)
> 
> I am not sure whether devices could interfere each other through config
> space access. The IOMMU hardware only protects and isolates DMA
> accesses, so that userspace could control DMA directly. The config
> accesses will always be intercepted by VFIO. Hence, I don't see a
> problem.

I was wondering about config accesses generated by an endpoint, e.g.,
an endpoint doing config writes to a peer or the upstream bridge.

But I think that is prohibited by spec - PCIe r5.0, sec 7.3.3, says
"Propagation of Configuration Requests from Downstream to Upstream as
well as peer-to-peer are not supported" and "Configuration Requests
are initiated only by the Host Bridge, including those passed through
the SFI CAM mechanism."

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

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 01/14] iommu: Add dma ownership management interfaces
  2022-01-06 15:46             ` Jason Gunthorpe via iommu
@ 2022-01-07  1:50               ` Lu Baolu
  -1 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-01-07  1:50 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: baolu.lu, Bjorn Helgaas, Christoph Hellwig, Greg Kroah-Hartman,
	Joerg Roedel, Alex Williamson, Bjorn Helgaas, Kevin Tian,
	Ashok Raj, Will Deacon, Robin Murphy, Dan Williams, rafael,
	Diana Craciun, Cornelia Huck, Eric Auger, Liu Yi L,
	Jacob jun Pan, Chaitanya Kulkarni, Stuart Yoder, Laurentiu Tudor,
	Thierry Reding, David Airlie, Daniel Vetter, Jonathan Hunter,
	Li Yang, Dmitry Osipenko, iommu, linux-pci, kvm, linux-kernel

On 1/6/22 11:46 PM, Jason Gunthorpe wrote:
> On Thu, Jan 06, 2022 at 11:54:06AM +0800, Lu Baolu wrote:
>> On 1/5/22 3:23 AM, Jason Gunthorpe wrote:
>>>>>> The device driver oriented interfaces are,
>>>>>>
>>>>>> 	int iommu_device_use_dma_api(struct device *dev);
>>>>>> 	void iommu_device_unuse_dma_api(struct device *dev);
>>>> Nit, do we care whether it uses the actual DMA API?  Or is it just
>>>> that iommu_device_use_dma_api() tells us the driver may program the
>>>> device to do DMA?
>>> As the main purpose, yes this is all about the DMA API because it
>>> asserts the group domain is the DMA API's domain.
>>>
>>> There is a secondary purpose that has to do with the user/kernel
>>> attack you mentioned above. Maintaining the DMA API domain also
>>> prevents VFIO from allowing userspace to operate any device in the
>>> group which blocks P2P attacks to MMIO of other devices.
>>>
>>> This is why, even if the driver doesn't use DMA, it should still do a
>>> iommu_device_use_dma_api(), except in the special cases where we don't
>>> care about P2P attacks (eg pci-stub, bridges, etc).
>>>
>>
>> By the way, use_dma_api seems hard to read. How about
>>
>> 	iommu_device_use_default_dma()?
> 
> You could just say "use default domain"
> 
> IMHO the way the iommu subsystem has its own wonky language is a
> little troublesome. In the rest of the kernel we call this the DMA
> API, while the iommu subsystem calls the domain that the DMA API uses
> the 'default domain' not the 'DMA API' domain.
> 
> Still, it is probably better to align to the iommu language - just be
> sure to put in the function comment that this API 'allows the driver
> to use the DMA API eg dma_map_sg()'

iommu_device_use_default_domain() reads better. And add some comments
to link "default domain" with "DMA API". Thanks!

> 
> Jason
> 

Best regards,
baolu

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 01/14] iommu: Add dma ownership management interfaces
@ 2022-01-07  1:50               ` Lu Baolu
  0 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-01-07  1:50 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Stuart Yoder, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Ashok Raj,
	Jonathan Hunter, Christoph Hellwig, Bjorn Helgaas, Kevin Tian,
	Chaitanya Kulkarni, Alex Williamson, kvm, Bjorn Helgaas,
	Dan Williams, Greg Kroah-Hartman, Cornelia Huck, linux-kernel,
	Li Yang, iommu, Jacob jun Pan, Daniel Vetter, Robin Murphy

On 1/6/22 11:46 PM, Jason Gunthorpe wrote:
> On Thu, Jan 06, 2022 at 11:54:06AM +0800, Lu Baolu wrote:
>> On 1/5/22 3:23 AM, Jason Gunthorpe wrote:
>>>>>> The device driver oriented interfaces are,
>>>>>>
>>>>>> 	int iommu_device_use_dma_api(struct device *dev);
>>>>>> 	void iommu_device_unuse_dma_api(struct device *dev);
>>>> Nit, do we care whether it uses the actual DMA API?  Or is it just
>>>> that iommu_device_use_dma_api() tells us the driver may program the
>>>> device to do DMA?
>>> As the main purpose, yes this is all about the DMA API because it
>>> asserts the group domain is the DMA API's domain.
>>>
>>> There is a secondary purpose that has to do with the user/kernel
>>> attack you mentioned above. Maintaining the DMA API domain also
>>> prevents VFIO from allowing userspace to operate any device in the
>>> group which blocks P2P attacks to MMIO of other devices.
>>>
>>> This is why, even if the driver doesn't use DMA, it should still do a
>>> iommu_device_use_dma_api(), except in the special cases where we don't
>>> care about P2P attacks (eg pci-stub, bridges, etc).
>>>
>>
>> By the way, use_dma_api seems hard to read. How about
>>
>> 	iommu_device_use_default_dma()?
> 
> You could just say "use default domain"
> 
> IMHO the way the iommu subsystem has its own wonky language is a
> little troublesome. In the rest of the kernel we call this the DMA
> API, while the iommu subsystem calls the domain that the DMA API uses
> the 'default domain' not the 'DMA API' domain.
> 
> Still, it is probably better to align to the iommu language - just be
> sure to put in the function comment that this API 'allows the driver
> to use the DMA API eg dma_map_sg()'

iommu_device_use_default_domain() reads better. And add some comments
to link "default domain" with "DMA API". Thanks!

> 
> Jason
> 

Best regards,
baolu
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 09/14] PCI: portdrv: Suppress kernel DMA ownership auto-claiming
  2022-01-06 18:32         ` Bjorn Helgaas
@ 2022-01-07  1:53           ` Lu Baolu
  -1 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-01-07  1:53 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: baolu.lu, Greg Kroah-Hartman, Joerg Roedel, Alex Williamson,
	Bjorn Helgaas, Jason Gunthorpe, Christoph Hellwig, Kevin Tian,
	Ashok Raj, Will Deacon, Robin Murphy, Dan Williams, rafael,
	Diana Craciun, Cornelia Huck, Eric Auger, Liu Yi L,
	Jacob jun Pan, Chaitanya Kulkarni, Stuart Yoder, Laurentiu Tudor,
	Thierry Reding, David Airlie, Daniel Vetter, Jonathan Hunter,
	Li Yang, Dmitry Osipenko, iommu, linux-pci, kvm, linux-kernel

On 1/7/22 2:32 AM, Bjorn Helgaas wrote:
> On Thu, Jan 06, 2022 at 12:12:35PM +0800, Lu Baolu wrote:
>> On 1/5/22 1:06 AM, Bjorn Helgaas wrote:
>>> On Tue, Jan 04, 2022 at 09:56:39AM +0800, Lu Baolu wrote:
>>>> If a switch lacks ACS P2P Request Redirect, a device below the switch can
>>>> bypass the IOMMU and DMA directly to other devices below the switch, so
>>>> all the downstream devices must be in the same IOMMU group as the switch
>>>> itself.
>>> Help me think through what's going on here.  IIUC, we put devices in
>>> the same IOMMU group when they can interfere with each other in any
>>> way (DMA, config access, etc).
>>>
>>> (We said "DMA" above, but I guess this would also apply to config
>>> requests, right?)
>>
>> I am not sure whether devices could interfere each other through config
>> space access. The IOMMU hardware only protects and isolates DMA
>> accesses, so that userspace could control DMA directly. The config
>> accesses will always be intercepted by VFIO. Hence, I don't see a
>> problem.
> 
> I was wondering about config accesses generated by an endpoint, e.g.,
> an endpoint doing config writes to a peer or the upstream bridge.
> 
> But I think that is prohibited by spec - PCIe r5.0, sec 7.3.3, says
> "Propagation of Configuration Requests from Downstream to Upstream as
> well as peer-to-peer are not supported" and "Configuration Requests
> are initiated only by the Host Bridge, including those passed through
> the SFI CAM mechanism."

That's clear. Thank you for the clarification.

> 
> Bjorn
> 

Best regards,
baolu

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 09/14] PCI: portdrv: Suppress kernel DMA ownership auto-claiming
@ 2022-01-07  1:53           ` Lu Baolu
  0 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-01-07  1:53 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Stuart Yoder, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Ashok Raj,
	Jonathan Hunter, Christoph Hellwig, Jason Gunthorpe, Kevin Tian,
	Chaitanya Kulkarni, Alex Williamson, kvm, Bjorn Helgaas,
	Dan Williams, Greg Kroah-Hartman, Cornelia Huck, linux-kernel,
	Li Yang, iommu, Jacob jun Pan, Daniel Vetter, Robin Murphy

On 1/7/22 2:32 AM, Bjorn Helgaas wrote:
> On Thu, Jan 06, 2022 at 12:12:35PM +0800, Lu Baolu wrote:
>> On 1/5/22 1:06 AM, Bjorn Helgaas wrote:
>>> On Tue, Jan 04, 2022 at 09:56:39AM +0800, Lu Baolu wrote:
>>>> If a switch lacks ACS P2P Request Redirect, a device below the switch can
>>>> bypass the IOMMU and DMA directly to other devices below the switch, so
>>>> all the downstream devices must be in the same IOMMU group as the switch
>>>> itself.
>>> Help me think through what's going on here.  IIUC, we put devices in
>>> the same IOMMU group when they can interfere with each other in any
>>> way (DMA, config access, etc).
>>>
>>> (We said "DMA" above, but I guess this would also apply to config
>>> requests, right?)
>>
>> I am not sure whether devices could interfere each other through config
>> space access. The IOMMU hardware only protects and isolates DMA
>> accesses, so that userspace could control DMA directly. The config
>> accesses will always be intercepted by VFIO. Hence, I don't see a
>> problem.
> 
> I was wondering about config accesses generated by an endpoint, e.g.,
> an endpoint doing config writes to a peer or the upstream bridge.
> 
> But I think that is prohibited by spec - PCIe r5.0, sec 7.3.3, says
> "Propagation of Configuration Requests from Downstream to Upstream as
> well as peer-to-peer are not supported" and "Configuration Requests
> are initiated only by the Host Bridge, including those passed through
> the SFI CAM mechanism."

That's clear. Thank you for the clarification.

> 
> Bjorn
> 

Best regards,
baolu
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 02/14] driver core: Add dma_cleanup callback in bus_type
  2022-01-04 13:04         ` Greg Kroah-Hartman
@ 2022-02-08  5:55           ` Lu Baolu
  -1 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-02-08  5:55 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jason Gunthorpe
  Cc: baolu.lu, Christoph Hellwig, Joerg Roedel, Alex Williamson,
	Bjorn Helgaas, Kevin Tian, Ashok Raj, Will Deacon, Robin Murphy,
	Dan Williams, rafael, Diana Craciun, Cornelia Huck, Eric Auger,
	Liu Yi L, Jacob jun Pan, Chaitanya Kulkarni, Stuart Yoder,
	Laurentiu Tudor, Thierry Reding, David Airlie, Daniel Vetter,
	Jonathan Hunter, Li Yang, Dmitry Osipenko, iommu, linux-pci, kvm,
	linux-kernel

Hi Greg,

On 1/4/22 9:04 PM, Greg Kroah-Hartman wrote:
> On Tue, Jan 04, 2022 at 08:39:11AM -0400, Jason Gunthorpe wrote:
>> On Tue, Jan 04, 2022 at 02:08:36AM -0800, Christoph Hellwig wrote:
>>> All these bus callouts still looks horrible and just create tons of
>>> boilerplate code.
>>
>> Yes, Lu - Greg asked questions then didn't respond to their answers
>> meaning he accepts them, you should stick with the v4 version.
> 
> Trying to catch up on emails from the break, that was way down my list
> of things to get back to as it's messy and non-obvious.  I'll revisit it
> again after 5.17-rc1 is out, this is too late for that merge window
> anyway.

In this series we want to add calls into the iommu subsystem during
device driver binding/unbinding, so that the device DMA ownership
conflict (kernel driver vs. user-space) could be detected and avoided
before calling into device driver's .probe().

In this v5 series, we implemented this in the affected buses (amba/
platform/fsl-mc/pci) which are known to support assigning devices to
user space through the vfio framework currently. And more buses are
possible to be affected in the future if they also want to support
device assignment. Christoph commented that this will create boilerplate
code in various bus drivers.

Back to v4 of this series (please refer to below link [1]), we added
this call in the driver core if buses have provided the dma_configure()
callback (please refer to below link [2]).

Which would you prefer, or any other suggestions? We need your guide to
move this series ahead. Please help to suggest.

[1] 
https://lore.kernel.org/linux-iommu/20211217063708.1740334-1-baolu.lu@linux.intel.com/
[2] 
https://lore.kernel.org/linux-iommu/20211217063708.1740334-3-baolu.lu@linux.intel.com/

Best regards,
baolu

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 02/14] driver core: Add dma_cleanup callback in bus_type
@ 2022-02-08  5:55           ` Lu Baolu
  0 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-02-08  5:55 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jason Gunthorpe
  Cc: Stuart Yoder, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Ashok Raj,
	Jonathan Hunter, Christoph Hellwig, Kevin Tian,
	Chaitanya Kulkarni, Alex Williamson, kvm, Bjorn Helgaas,
	Dan Williams, Cornelia Huck, linux-kernel, Li Yang, iommu,
	Jacob jun Pan, Daniel Vetter, Robin Murphy

Hi Greg,

On 1/4/22 9:04 PM, Greg Kroah-Hartman wrote:
> On Tue, Jan 04, 2022 at 08:39:11AM -0400, Jason Gunthorpe wrote:
>> On Tue, Jan 04, 2022 at 02:08:36AM -0800, Christoph Hellwig wrote:
>>> All these bus callouts still looks horrible and just create tons of
>>> boilerplate code.
>>
>> Yes, Lu - Greg asked questions then didn't respond to their answers
>> meaning he accepts them, you should stick with the v4 version.
> 
> Trying to catch up on emails from the break, that was way down my list
> of things to get back to as it's messy and non-obvious.  I'll revisit it
> again after 5.17-rc1 is out, this is too late for that merge window
> anyway.

In this series we want to add calls into the iommu subsystem during
device driver binding/unbinding, so that the device DMA ownership
conflict (kernel driver vs. user-space) could be detected and avoided
before calling into device driver's .probe().

In this v5 series, we implemented this in the affected buses (amba/
platform/fsl-mc/pci) which are known to support assigning devices to
user space through the vfio framework currently. And more buses are
possible to be affected in the future if they also want to support
device assignment. Christoph commented that this will create boilerplate
code in various bus drivers.

Back to v4 of this series (please refer to below link [1]), we added
this call in the driver core if buses have provided the dma_configure()
callback (please refer to below link [2]).

Which would you prefer, or any other suggestions? We need your guide to
move this series ahead. Please help to suggest.

[1] 
https://lore.kernel.org/linux-iommu/20211217063708.1740334-1-baolu.lu@linux.intel.com/
[2] 
https://lore.kernel.org/linux-iommu/20211217063708.1740334-3-baolu.lu@linux.intel.com/

Best regards,
baolu
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 02/14] driver core: Add dma_cleanup callback in bus_type
  2022-02-08  5:55           ` Lu Baolu
@ 2022-02-08 11:35             ` Greg Kroah-Hartman
  -1 siblings, 0 replies; 112+ messages in thread
From: Greg Kroah-Hartman @ 2022-02-08 11:35 UTC (permalink / raw)
  To: Lu Baolu
  Cc: Stuart Yoder, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Ashok Raj,
	Jonathan Hunter, Christoph Hellwig, Jason Gunthorpe, Kevin Tian,
	Chaitanya Kulkarni, Alex Williamson, kvm, Bjorn Helgaas,
	Dan Williams, Cornelia Huck, linux-kernel, Li Yang, iommu,
	Jacob jun Pan, Daniel Vetter, Robin Murphy

On Tue, Feb 08, 2022 at 01:55:29PM +0800, Lu Baolu wrote:
> Hi Greg,
> 
> On 1/4/22 9:04 PM, Greg Kroah-Hartman wrote:
> > On Tue, Jan 04, 2022 at 08:39:11AM -0400, Jason Gunthorpe wrote:
> > > On Tue, Jan 04, 2022 at 02:08:36AM -0800, Christoph Hellwig wrote:
> > > > All these bus callouts still looks horrible and just create tons of
> > > > boilerplate code.
> > > 
> > > Yes, Lu - Greg asked questions then didn't respond to their answers
> > > meaning he accepts them, you should stick with the v4 version.
> > 
> > Trying to catch up on emails from the break, that was way down my list
> > of things to get back to as it's messy and non-obvious.  I'll revisit it
> > again after 5.17-rc1 is out, this is too late for that merge window
> > anyway.
> 
> In this series we want to add calls into the iommu subsystem during
> device driver binding/unbinding, so that the device DMA ownership
> conflict (kernel driver vs. user-space) could be detected and avoided
> before calling into device driver's .probe().
> 
> In this v5 series, we implemented this in the affected buses (amba/
> platform/fsl-mc/pci) which are known to support assigning devices to
> user space through the vfio framework currently. And more buses are
> possible to be affected in the future if they also want to support
> device assignment. Christoph commented that this will create boilerplate
> code in various bus drivers.
> 
> Back to v4 of this series (please refer to below link [1]), we added
> this call in the driver core if buses have provided the dma_configure()
> callback (please refer to below link [2]).
> 
> Which would you prefer, or any other suggestions? We need your guide to
> move this series ahead. Please help to suggest.
> 
> [1] https://lore.kernel.org/linux-iommu/20211217063708.1740334-1-baolu.lu@linux.intel.com/
> [2] https://lore.kernel.org/linux-iommu/20211217063708.1740334-3-baolu.lu@linux.intel.com/

Let me look over the series again this afternooon.

thanks,

greg k-h
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 02/14] driver core: Add dma_cleanup callback in bus_type
@ 2022-02-08 11:35             ` Greg Kroah-Hartman
  0 siblings, 0 replies; 112+ messages in thread
From: Greg Kroah-Hartman @ 2022-02-08 11:35 UTC (permalink / raw)
  To: Lu Baolu
  Cc: Jason Gunthorpe, Christoph Hellwig, Joerg Roedel,
	Alex Williamson, Bjorn Helgaas, Kevin Tian, Ashok Raj,
	Will Deacon, Robin Murphy, Dan Williams, rafael, Diana Craciun,
	Cornelia Huck, Eric Auger, Liu Yi L, Jacob jun Pan,
	Chaitanya Kulkarni, Stuart Yoder, Laurentiu Tudor,
	Thierry Reding, David Airlie, Daniel Vetter, Jonathan Hunter,
	Li Yang, Dmitry Osipenko, iommu, linux-pci, kvm, linux-kernel

On Tue, Feb 08, 2022 at 01:55:29PM +0800, Lu Baolu wrote:
> Hi Greg,
> 
> On 1/4/22 9:04 PM, Greg Kroah-Hartman wrote:
> > On Tue, Jan 04, 2022 at 08:39:11AM -0400, Jason Gunthorpe wrote:
> > > On Tue, Jan 04, 2022 at 02:08:36AM -0800, Christoph Hellwig wrote:
> > > > All these bus callouts still looks horrible and just create tons of
> > > > boilerplate code.
> > > 
> > > Yes, Lu - Greg asked questions then didn't respond to their answers
> > > meaning he accepts them, you should stick with the v4 version.
> > 
> > Trying to catch up on emails from the break, that was way down my list
> > of things to get back to as it's messy and non-obvious.  I'll revisit it
> > again after 5.17-rc1 is out, this is too late for that merge window
> > anyway.
> 
> In this series we want to add calls into the iommu subsystem during
> device driver binding/unbinding, so that the device DMA ownership
> conflict (kernel driver vs. user-space) could be detected and avoided
> before calling into device driver's .probe().
> 
> In this v5 series, we implemented this in the affected buses (amba/
> platform/fsl-mc/pci) which are known to support assigning devices to
> user space through the vfio framework currently. And more buses are
> possible to be affected in the future if they also want to support
> device assignment. Christoph commented that this will create boilerplate
> code in various bus drivers.
> 
> Back to v4 of this series (please refer to below link [1]), we added
> this call in the driver core if buses have provided the dma_configure()
> callback (please refer to below link [2]).
> 
> Which would you prefer, or any other suggestions? We need your guide to
> move this series ahead. Please help to suggest.
> 
> [1] https://lore.kernel.org/linux-iommu/20211217063708.1740334-1-baolu.lu@linux.intel.com/
> [2] https://lore.kernel.org/linux-iommu/20211217063708.1740334-3-baolu.lu@linux.intel.com/

Let me look over the series again this afternooon.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 04/14] driver core: platform: Add driver dma ownership management
  2022-01-04  1:56   ` Lu Baolu
@ 2022-02-14  9:59     ` Greg Kroah-Hartman
  -1 siblings, 0 replies; 112+ messages in thread
From: Greg Kroah-Hartman @ 2022-02-14  9:59 UTC (permalink / raw)
  To: Lu Baolu
  Cc: Stuart Yoder, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Ashok Raj,
	Jonathan Hunter, Christoph Hellwig, Jason Gunthorpe, Kevin Tian,
	Chaitanya Kulkarni, Alex Williamson, kvm, Bjorn Helgaas,
	Dan Williams, Cornelia Huck, linux-kernel, Li Yang, iommu,
	Jacob jun Pan, Daniel Vetter, Robin Murphy

On Tue, Jan 04, 2022 at 09:56:34AM +0800, Lu Baolu wrote:
> Multiple platform devices may be placed in the same IOMMU group because
> they cannot be isolated from each other. These devices must either be
> entirely under kernel control or userspace control, never a mixture. This
> checks and sets DMA ownership during driver binding, and release the
> ownership during driver unbinding.
> 
> The device driver may set a new flag (no_kernel_api_dma) to skip calling
> iommu_device_use_dma_api() during the binding process. For instance, the
> userspace framework drivers (vfio etc.) which need to manually claim
> their own dma ownership when assigning the device to userspace.
> 
> Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
> ---
>  include/linux/platform_device.h |  1 +
>  drivers/base/platform.c         | 20 ++++++++++++++++++++
>  2 files changed, 21 insertions(+)
> 
> diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
> index 17fde717df68..8f0eaafcef47 100644
> --- a/include/linux/platform_device.h
> +++ b/include/linux/platform_device.h
> @@ -210,6 +210,7 @@ struct platform_driver {
>  	struct device_driver driver;
>  	const struct platform_device_id *id_table;
>  	bool prevent_deferred_probe;
> +	bool no_kernel_api_dma;
>  };
>  
>  #define to_platform_driver(drv)	(container_of((drv), struct platform_driver, \
> diff --git a/drivers/base/platform.c b/drivers/base/platform.c
> index b4d36b46ab2e..d5171e44d903 100644
> --- a/drivers/base/platform.c
> +++ b/drivers/base/platform.c
> @@ -30,6 +30,7 @@
>  #include <linux/property.h>
>  #include <linux/kmemleak.h>
>  #include <linux/types.h>
> +#include <linux/iommu.h>
>  
>  #include "base.h"
>  #include "power/power.h"
> @@ -1451,9 +1452,16 @@ static void platform_shutdown(struct device *_dev)
>  
>  static int platform_dma_configure(struct device *dev)
>  {
> +	struct platform_driver *drv = to_platform_driver(dev->driver);
>  	enum dev_dma_attr attr;
>  	int ret = 0;
>  
> +	if (!drv->no_kernel_api_dma) {
> +		ret = iommu_device_use_dma_api(dev);
> +		if (ret)
> +			return ret;
> +	}
> +
>  	if (dev->of_node) {
>  		ret = of_dma_configure(dev, dev->of_node, true);
>  	} else if (has_acpi_companion(dev)) {
> @@ -1461,9 +1469,20 @@ static int platform_dma_configure(struct device *dev)
>  		ret = acpi_dma_configure(dev, attr);
>  	}
>  
> +	if (ret && !drv->no_kernel_api_dma)
> +		iommu_device_unuse_dma_api(dev);

So you are now going to call this for every platform driver _unless_
they set this flag?

And having "negative" flags is rough to parse at times.  Yes, we have
"prevent_deferred_probe" already here, so maybe keep this in the same
nameing scheme and use "prevent_dma_api"?

And it would be good to document this somewhere as to what this means.

thanks,

greg k-h
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 04/14] driver core: platform: Add driver dma ownership management
@ 2022-02-14  9:59     ` Greg Kroah-Hartman
  0 siblings, 0 replies; 112+ messages in thread
From: Greg Kroah-Hartman @ 2022-02-14  9:59 UTC (permalink / raw)
  To: Lu Baolu
  Cc: Joerg Roedel, Alex Williamson, Bjorn Helgaas, Jason Gunthorpe,
	Christoph Hellwig, Kevin Tian, Ashok Raj, Will Deacon,
	Robin Murphy, Dan Williams, rafael, Diana Craciun, Cornelia Huck,
	Eric Auger, Liu Yi L, Jacob jun Pan, Chaitanya Kulkarni,
	Stuart Yoder, Laurentiu Tudor, Thierry Reding, David Airlie,
	Daniel Vetter, Jonathan Hunter, Li Yang, Dmitry Osipenko, iommu,
	linux-pci, kvm, linux-kernel

On Tue, Jan 04, 2022 at 09:56:34AM +0800, Lu Baolu wrote:
> Multiple platform devices may be placed in the same IOMMU group because
> they cannot be isolated from each other. These devices must either be
> entirely under kernel control or userspace control, never a mixture. This
> checks and sets DMA ownership during driver binding, and release the
> ownership during driver unbinding.
> 
> The device driver may set a new flag (no_kernel_api_dma) to skip calling
> iommu_device_use_dma_api() during the binding process. For instance, the
> userspace framework drivers (vfio etc.) which need to manually claim
> their own dma ownership when assigning the device to userspace.
> 
> Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
> ---
>  include/linux/platform_device.h |  1 +
>  drivers/base/platform.c         | 20 ++++++++++++++++++++
>  2 files changed, 21 insertions(+)
> 
> diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
> index 17fde717df68..8f0eaafcef47 100644
> --- a/include/linux/platform_device.h
> +++ b/include/linux/platform_device.h
> @@ -210,6 +210,7 @@ struct platform_driver {
>  	struct device_driver driver;
>  	const struct platform_device_id *id_table;
>  	bool prevent_deferred_probe;
> +	bool no_kernel_api_dma;
>  };
>  
>  #define to_platform_driver(drv)	(container_of((drv), struct platform_driver, \
> diff --git a/drivers/base/platform.c b/drivers/base/platform.c
> index b4d36b46ab2e..d5171e44d903 100644
> --- a/drivers/base/platform.c
> +++ b/drivers/base/platform.c
> @@ -30,6 +30,7 @@
>  #include <linux/property.h>
>  #include <linux/kmemleak.h>
>  #include <linux/types.h>
> +#include <linux/iommu.h>
>  
>  #include "base.h"
>  #include "power/power.h"
> @@ -1451,9 +1452,16 @@ static void platform_shutdown(struct device *_dev)
>  
>  static int platform_dma_configure(struct device *dev)
>  {
> +	struct platform_driver *drv = to_platform_driver(dev->driver);
>  	enum dev_dma_attr attr;
>  	int ret = 0;
>  
> +	if (!drv->no_kernel_api_dma) {
> +		ret = iommu_device_use_dma_api(dev);
> +		if (ret)
> +			return ret;
> +	}
> +
>  	if (dev->of_node) {
>  		ret = of_dma_configure(dev, dev->of_node, true);
>  	} else if (has_acpi_companion(dev)) {
> @@ -1461,9 +1469,20 @@ static int platform_dma_configure(struct device *dev)
>  		ret = acpi_dma_configure(dev, attr);
>  	}
>  
> +	if (ret && !drv->no_kernel_api_dma)
> +		iommu_device_unuse_dma_api(dev);

So you are now going to call this for every platform driver _unless_
they set this flag?

And having "negative" flags is rough to parse at times.  Yes, we have
"prevent_deferred_probe" already here, so maybe keep this in the same
nameing scheme and use "prevent_dma_api"?

And it would be good to document this somewhere as to what this means.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 02/14] driver core: Add dma_cleanup callback in bus_type
  2022-01-04 10:08     ` Christoph Hellwig
@ 2022-02-14 10:01       ` Greg Kroah-Hartman
  -1 siblings, 0 replies; 112+ messages in thread
From: Greg Kroah-Hartman @ 2022-02-14 10:01 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Stuart Yoder, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Ashok Raj,
	Jonathan Hunter, Jason Gunthorpe, Kevin Tian, Chaitanya Kulkarni,
	Alex Williamson, kvm, Bjorn Helgaas, Dan Williams, Cornelia Huck,
	linux-kernel, Li Yang, iommu, Jacob jun Pan, Daniel Vetter,
	Robin Murphy

On Tue, Jan 04, 2022 at 02:08:36AM -0800, Christoph Hellwig wrote:
> All these bus callouts still looks horrible and just create tons of
> boilerplate code.

I can't remember anymore what one vs. the other looks like.  Having an
explicit "opt-in" for a bus is good, in that no code breaks and only if
you want to use this do you have to set the flag.  Why do you want it to
be "always"?

thanks,

greg k-h
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 02/14] driver core: Add dma_cleanup callback in bus_type
@ 2022-02-14 10:01       ` Greg Kroah-Hartman
  0 siblings, 0 replies; 112+ messages in thread
From: Greg Kroah-Hartman @ 2022-02-14 10:01 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Lu Baolu, Joerg Roedel, Alex Williamson, Bjorn Helgaas,
	Jason Gunthorpe, Kevin Tian, Ashok Raj, Will Deacon,
	Robin Murphy, Dan Williams, rafael, Diana Craciun, Cornelia Huck,
	Eric Auger, Liu Yi L, Jacob jun Pan, Chaitanya Kulkarni,
	Stuart Yoder, Laurentiu Tudor, Thierry Reding, David Airlie,
	Daniel Vetter, Jonathan Hunter, Li Yang, Dmitry Osipenko, iommu,
	linux-pci, kvm, linux-kernel

On Tue, Jan 04, 2022 at 02:08:36AM -0800, Christoph Hellwig wrote:
> All these bus callouts still looks horrible and just create tons of
> boilerplate code.

I can't remember anymore what one vs. the other looks like.  Having an
explicit "opt-in" for a bus is good, in that no code breaks and only if
you want to use this do you have to set the flag.  Why do you want it to
be "always"?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 02/14] driver core: Add dma_cleanup callback in bus_type
  2022-01-04  1:56   ` Lu Baolu
@ 2022-02-14 10:02     ` Greg Kroah-Hartman
  -1 siblings, 0 replies; 112+ messages in thread
From: Greg Kroah-Hartman @ 2022-02-14 10:02 UTC (permalink / raw)
  To: Lu Baolu
  Cc: Stuart Yoder, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Ashok Raj,
	Jonathan Hunter, Christoph Hellwig, Jason Gunthorpe, Kevin Tian,
	Chaitanya Kulkarni, Alex Williamson, kvm, Bjorn Helgaas,
	Dan Williams, Cornelia Huck, linux-kernel, Li Yang, iommu,
	Jacob jun Pan, Daniel Vetter, Robin Murphy

On Tue, Jan 04, 2022 at 09:56:32AM +0800, Lu Baolu wrote:
> The bus_type structure defines dma_configure() callback for bus drivers
> to configure DMA on the devices. This adds the paired dma_cleanup()
> callback and calls it during driver unbinding so that bus drivers can do
> some cleanup work.
> 
> One use case for this paired DMA callbacks is for the bus driver to check
> for DMA ownership conflicts during driver binding, where multiple devices
> belonging to a same IOMMU group (the minimum granularity of isolation and
> protection) may be assigned to kernel drivers or user space respectively.
> 
> Without this change, for example, the vfio driver has to listen to a bus
> BOUND_DRIVER event and then BUG_ON() in case of dma ownership conflict.
> This leads to bad user experience since careless driver binding operation
> may crash the system if the admin overlooks the group restriction. Aside
> from bad design, this leads to a security problem as a root user, even with
> lockdown=integrity, can force the kernel to BUG.
> 
> With this change, the bus driver could check and set the DMA ownership in
> driver binding process and fail on ownership conflicts. The DMA ownership
> should be released during driver unbinding.
> 
> Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>

Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 02/14] driver core: Add dma_cleanup callback in bus_type
@ 2022-02-14 10:02     ` Greg Kroah-Hartman
  0 siblings, 0 replies; 112+ messages in thread
From: Greg Kroah-Hartman @ 2022-02-14 10:02 UTC (permalink / raw)
  To: Lu Baolu
  Cc: Joerg Roedel, Alex Williamson, Bjorn Helgaas, Jason Gunthorpe,
	Christoph Hellwig, Kevin Tian, Ashok Raj, Will Deacon,
	Robin Murphy, Dan Williams, rafael, Diana Craciun, Cornelia Huck,
	Eric Auger, Liu Yi L, Jacob jun Pan, Chaitanya Kulkarni,
	Stuart Yoder, Laurentiu Tudor, Thierry Reding, David Airlie,
	Daniel Vetter, Jonathan Hunter, Li Yang, Dmitry Osipenko, iommu,
	linux-pci, kvm, linux-kernel

On Tue, Jan 04, 2022 at 09:56:32AM +0800, Lu Baolu wrote:
> The bus_type structure defines dma_configure() callback for bus drivers
> to configure DMA on the devices. This adds the paired dma_cleanup()
> callback and calls it during driver unbinding so that bus drivers can do
> some cleanup work.
> 
> One use case for this paired DMA callbacks is for the bus driver to check
> for DMA ownership conflicts during driver binding, where multiple devices
> belonging to a same IOMMU group (the minimum granularity of isolation and
> protection) may be assigned to kernel drivers or user space respectively.
> 
> Without this change, for example, the vfio driver has to listen to a bus
> BOUND_DRIVER event and then BUG_ON() in case of dma ownership conflict.
> This leads to bad user experience since careless driver binding operation
> may crash the system if the admin overlooks the group restriction. Aside
> from bad design, this leads to a security problem as a root user, even with
> lockdown=integrity, can force the kernel to BUG.
> 
> With this change, the bus driver could check and set the DMA ownership in
> driver binding process and fail on ownership conflicts. The DMA ownership
> should be released during driver unbinding.
> 
> Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>

Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 07/14] PCI: Add driver dma ownership management
  2022-01-04  1:56   ` Lu Baolu
@ 2022-02-14 10:03     ` Greg Kroah-Hartman
  -1 siblings, 0 replies; 112+ messages in thread
From: Greg Kroah-Hartman @ 2022-02-14 10:03 UTC (permalink / raw)
  To: Lu Baolu
  Cc: Stuart Yoder, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Ashok Raj,
	Jonathan Hunter, Christoph Hellwig, Jason Gunthorpe, Kevin Tian,
	Chaitanya Kulkarni, Alex Williamson, kvm, Bjorn Helgaas,
	Dan Williams, Cornelia Huck, linux-kernel, Li Yang, iommu,
	Jacob jun Pan, Daniel Vetter, Robin Murphy

On Tue, Jan 04, 2022 at 09:56:37AM +0800, Lu Baolu wrote:
> Multiple PCI devices may be placed in the same IOMMU group because
> they cannot be isolated from each other. These devices must either be
> entirely under kernel control or userspace control, never a mixture. This
> checks and sets DMA ownership during driver binding, and release the
> ownership during driver unbinding.
> 
> The device driver may set a new flag (no_kernel_api_dma) to skip calling
> iommu_device_use_dma_api() during the binding process. For instance, the
> userspace framework drivers (vfio etc.) which need to manually claim
> their own dma ownership when assigning the device to userspace.
> 
> Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
> ---
>  include/linux/pci.h      |  5 +++++
>  drivers/pci/pci-driver.c | 21 +++++++++++++++++++++
>  2 files changed, 26 insertions(+)
> 
> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index 18a75c8e615c..d29a990e3f02 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -882,6 +882,10 @@ struct module;
>   *              created once it is bound to the driver.
>   * @driver:	Driver model structure.
>   * @dynids:	List of dynamically added device IDs.
> + * @no_kernel_api_dma: Device driver doesn't use kernel DMA API for DMA.
> + *		Drivers which don't require DMA or want to manually claim the
> + *		owner type (e.g. userspace driver frameworks) could set this
> + *		flag.

Again with the bikeshedding, but this name is a bit odd.  Of course it's
in the kernel, this is all kernel code, so you can drop that.  And
again, "negative" flags are rough.  So maybe just "prevent_dma"?

thanks,

greg k-h
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 07/14] PCI: Add driver dma ownership management
@ 2022-02-14 10:03     ` Greg Kroah-Hartman
  0 siblings, 0 replies; 112+ messages in thread
From: Greg Kroah-Hartman @ 2022-02-14 10:03 UTC (permalink / raw)
  To: Lu Baolu
  Cc: Joerg Roedel, Alex Williamson, Bjorn Helgaas, Jason Gunthorpe,
	Christoph Hellwig, Kevin Tian, Ashok Raj, Will Deacon,
	Robin Murphy, Dan Williams, rafael, Diana Craciun, Cornelia Huck,
	Eric Auger, Liu Yi L, Jacob jun Pan, Chaitanya Kulkarni,
	Stuart Yoder, Laurentiu Tudor, Thierry Reding, David Airlie,
	Daniel Vetter, Jonathan Hunter, Li Yang, Dmitry Osipenko, iommu,
	linux-pci, kvm, linux-kernel

On Tue, Jan 04, 2022 at 09:56:37AM +0800, Lu Baolu wrote:
> Multiple PCI devices may be placed in the same IOMMU group because
> they cannot be isolated from each other. These devices must either be
> entirely under kernel control or userspace control, never a mixture. This
> checks and sets DMA ownership during driver binding, and release the
> ownership during driver unbinding.
> 
> The device driver may set a new flag (no_kernel_api_dma) to skip calling
> iommu_device_use_dma_api() during the binding process. For instance, the
> userspace framework drivers (vfio etc.) which need to manually claim
> their own dma ownership when assigning the device to userspace.
> 
> Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
> ---
>  include/linux/pci.h      |  5 +++++
>  drivers/pci/pci-driver.c | 21 +++++++++++++++++++++
>  2 files changed, 26 insertions(+)
> 
> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index 18a75c8e615c..d29a990e3f02 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -882,6 +882,10 @@ struct module;
>   *              created once it is bound to the driver.
>   * @driver:	Driver model structure.
>   * @dynids:	List of dynamically added device IDs.
> + * @no_kernel_api_dma: Device driver doesn't use kernel DMA API for DMA.
> + *		Drivers which don't require DMA or want to manually claim the
> + *		owner type (e.g. userspace driver frameworks) could set this
> + *		flag.

Again with the bikeshedding, but this name is a bit odd.  Of course it's
in the kernel, this is all kernel code, so you can drop that.  And
again, "negative" flags are rough.  So maybe just "prevent_dma"?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 07/14] PCI: Add driver dma ownership management
  2022-02-14 10:03     ` Greg Kroah-Hartman
@ 2022-02-14 12:38       ` Jason Gunthorpe via iommu
  -1 siblings, 0 replies; 112+ messages in thread
From: Jason Gunthorpe @ 2022-02-14 12:38 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Lu Baolu, Joerg Roedel, Alex Williamson, Bjorn Helgaas,
	Christoph Hellwig, Kevin Tian, Ashok Raj, Will Deacon,
	Robin Murphy, Dan Williams, rafael, Diana Craciun, Cornelia Huck,
	Eric Auger, Liu Yi L, Jacob jun Pan, Chaitanya Kulkarni,
	Stuart Yoder, Laurentiu Tudor, Thierry Reding, David Airlie,
	Daniel Vetter, Jonathan Hunter, Li Yang, Dmitry Osipenko, iommu,
	linux-pci, kvm, linux-kernel

On Mon, Feb 14, 2022 at 11:03:42AM +0100, Greg Kroah-Hartman wrote:
> On Tue, Jan 04, 2022 at 09:56:37AM +0800, Lu Baolu wrote:
> > Multiple PCI devices may be placed in the same IOMMU group because
> > they cannot be isolated from each other. These devices must either be
> > entirely under kernel control or userspace control, never a mixture. This
> > checks and sets DMA ownership during driver binding, and release the
> > ownership during driver unbinding.
> > 
> > The device driver may set a new flag (no_kernel_api_dma) to skip calling
> > iommu_device_use_dma_api() during the binding process. For instance, the
> > userspace framework drivers (vfio etc.) which need to manually claim
> > their own dma ownership when assigning the device to userspace.
> > 
> > Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
> >  include/linux/pci.h      |  5 +++++
> >  drivers/pci/pci-driver.c | 21 +++++++++++++++++++++
> >  2 files changed, 26 insertions(+)
> > 
> > diff --git a/include/linux/pci.h b/include/linux/pci.h
> > index 18a75c8e615c..d29a990e3f02 100644
> > +++ b/include/linux/pci.h
> > @@ -882,6 +882,10 @@ struct module;
> >   *              created once it is bound to the driver.
> >   * @driver:	Driver model structure.
> >   * @dynids:	List of dynamically added device IDs.
> > + * @no_kernel_api_dma: Device driver doesn't use kernel DMA API for DMA.
> > + *		Drivers which don't require DMA or want to manually claim the
> > + *		owner type (e.g. userspace driver frameworks) could set this
> > + *		flag.
> 
> Again with the bikeshedding, but this name is a bit odd.  Of course it's
> in the kernel, this is all kernel code, so you can drop that.  And
> again, "negative" flags are rough.  So maybe just "prevent_dma"?

That is misleading too, it is not that DMA is prevented, but that the
kernel's dma_api has not been setup.

Though I agree the name as-is isn't great, I think the comment is good.

Jason

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 07/14] PCI: Add driver dma ownership management
@ 2022-02-14 12:38       ` Jason Gunthorpe via iommu
  0 siblings, 0 replies; 112+ messages in thread
From: Jason Gunthorpe via iommu @ 2022-02-14 12:38 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Stuart Yoder, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Ashok Raj,
	Jonathan Hunter, Christoph Hellwig, Kevin Tian,
	Chaitanya Kulkarni, Alex Williamson, kvm, Bjorn Helgaas,
	Dan Williams, Cornelia Huck, linux-kernel, Li Yang, iommu,
	Jacob jun Pan, Daniel Vetter, Robin Murphy

On Mon, Feb 14, 2022 at 11:03:42AM +0100, Greg Kroah-Hartman wrote:
> On Tue, Jan 04, 2022 at 09:56:37AM +0800, Lu Baolu wrote:
> > Multiple PCI devices may be placed in the same IOMMU group because
> > they cannot be isolated from each other. These devices must either be
> > entirely under kernel control or userspace control, never a mixture. This
> > checks and sets DMA ownership during driver binding, and release the
> > ownership during driver unbinding.
> > 
> > The device driver may set a new flag (no_kernel_api_dma) to skip calling
> > iommu_device_use_dma_api() during the binding process. For instance, the
> > userspace framework drivers (vfio etc.) which need to manually claim
> > their own dma ownership when assigning the device to userspace.
> > 
> > Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
> >  include/linux/pci.h      |  5 +++++
> >  drivers/pci/pci-driver.c | 21 +++++++++++++++++++++
> >  2 files changed, 26 insertions(+)
> > 
> > diff --git a/include/linux/pci.h b/include/linux/pci.h
> > index 18a75c8e615c..d29a990e3f02 100644
> > +++ b/include/linux/pci.h
> > @@ -882,6 +882,10 @@ struct module;
> >   *              created once it is bound to the driver.
> >   * @driver:	Driver model structure.
> >   * @dynids:	List of dynamically added device IDs.
> > + * @no_kernel_api_dma: Device driver doesn't use kernel DMA API for DMA.
> > + *		Drivers which don't require DMA or want to manually claim the
> > + *		owner type (e.g. userspace driver frameworks) could set this
> > + *		flag.
> 
> Again with the bikeshedding, but this name is a bit odd.  Of course it's
> in the kernel, this is all kernel code, so you can drop that.  And
> again, "negative" flags are rough.  So maybe just "prevent_dma"?

That is misleading too, it is not that DMA is prevented, but that the
kernel's dma_api has not been setup.

Though I agree the name as-is isn't great, I think the comment is good.

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

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 07/14] PCI: Add driver dma ownership management
  2022-02-14 12:38       ` Jason Gunthorpe via iommu
@ 2022-02-14 12:51         ` Greg Kroah-Hartman
  -1 siblings, 0 replies; 112+ messages in thread
From: Greg Kroah-Hartman @ 2022-02-14 12:51 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Lu Baolu, Joerg Roedel, Alex Williamson, Bjorn Helgaas,
	Christoph Hellwig, Kevin Tian, Ashok Raj, Will Deacon,
	Robin Murphy, Dan Williams, rafael, Diana Craciun, Cornelia Huck,
	Eric Auger, Liu Yi L, Jacob jun Pan, Chaitanya Kulkarni,
	Stuart Yoder, Laurentiu Tudor, Thierry Reding, David Airlie,
	Daniel Vetter, Jonathan Hunter, Li Yang, Dmitry Osipenko, iommu,
	linux-pci, kvm, linux-kernel

On Mon, Feb 14, 2022 at 08:38:42AM -0400, Jason Gunthorpe wrote:
> On Mon, Feb 14, 2022 at 11:03:42AM +0100, Greg Kroah-Hartman wrote:
> > On Tue, Jan 04, 2022 at 09:56:37AM +0800, Lu Baolu wrote:
> > > Multiple PCI devices may be placed in the same IOMMU group because
> > > they cannot be isolated from each other. These devices must either be
> > > entirely under kernel control or userspace control, never a mixture. This
> > > checks and sets DMA ownership during driver binding, and release the
> > > ownership during driver unbinding.
> > > 
> > > The device driver may set a new flag (no_kernel_api_dma) to skip calling
> > > iommu_device_use_dma_api() during the binding process. For instance, the
> > > userspace framework drivers (vfio etc.) which need to manually claim
> > > their own dma ownership when assigning the device to userspace.
> > > 
> > > Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
> > >  include/linux/pci.h      |  5 +++++
> > >  drivers/pci/pci-driver.c | 21 +++++++++++++++++++++
> > >  2 files changed, 26 insertions(+)
> > > 
> > > diff --git a/include/linux/pci.h b/include/linux/pci.h
> > > index 18a75c8e615c..d29a990e3f02 100644
> > > +++ b/include/linux/pci.h
> > > @@ -882,6 +882,10 @@ struct module;
> > >   *              created once it is bound to the driver.
> > >   * @driver:	Driver model structure.
> > >   * @dynids:	List of dynamically added device IDs.
> > > + * @no_kernel_api_dma: Device driver doesn't use kernel DMA API for DMA.
> > > + *		Drivers which don't require DMA or want to manually claim the
> > > + *		owner type (e.g. userspace driver frameworks) could set this
> > > + *		flag.
> > 
> > Again with the bikeshedding, but this name is a bit odd.  Of course it's
> > in the kernel, this is all kernel code, so you can drop that.  And
> > again, "negative" flags are rough.  So maybe just "prevent_dma"?
> 
> That is misleading too, it is not that DMA is prevented, but that the
> kernel's dma_api has not been setup.

"has not been" or "will not be"?

What you want to prevent is the iommu core claiming the device
automatically, right?  So how about "prevent_iommu_dma"?

naming is hard,

greg k-h

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 07/14] PCI: Add driver dma ownership management
@ 2022-02-14 12:51         ` Greg Kroah-Hartman
  0 siblings, 0 replies; 112+ messages in thread
From: Greg Kroah-Hartman @ 2022-02-14 12:51 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Stuart Yoder, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Ashok Raj,
	Jonathan Hunter, Christoph Hellwig, Kevin Tian,
	Chaitanya Kulkarni, Alex Williamson, kvm, Bjorn Helgaas,
	Dan Williams, Cornelia Huck, linux-kernel, Li Yang, iommu,
	Jacob jun Pan, Daniel Vetter, Robin Murphy

On Mon, Feb 14, 2022 at 08:38:42AM -0400, Jason Gunthorpe wrote:
> On Mon, Feb 14, 2022 at 11:03:42AM +0100, Greg Kroah-Hartman wrote:
> > On Tue, Jan 04, 2022 at 09:56:37AM +0800, Lu Baolu wrote:
> > > Multiple PCI devices may be placed in the same IOMMU group because
> > > they cannot be isolated from each other. These devices must either be
> > > entirely under kernel control or userspace control, never a mixture. This
> > > checks and sets DMA ownership during driver binding, and release the
> > > ownership during driver unbinding.
> > > 
> > > The device driver may set a new flag (no_kernel_api_dma) to skip calling
> > > iommu_device_use_dma_api() during the binding process. For instance, the
> > > userspace framework drivers (vfio etc.) which need to manually claim
> > > their own dma ownership when assigning the device to userspace.
> > > 
> > > Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
> > >  include/linux/pci.h      |  5 +++++
> > >  drivers/pci/pci-driver.c | 21 +++++++++++++++++++++
> > >  2 files changed, 26 insertions(+)
> > > 
> > > diff --git a/include/linux/pci.h b/include/linux/pci.h
> > > index 18a75c8e615c..d29a990e3f02 100644
> > > +++ b/include/linux/pci.h
> > > @@ -882,6 +882,10 @@ struct module;
> > >   *              created once it is bound to the driver.
> > >   * @driver:	Driver model structure.
> > >   * @dynids:	List of dynamically added device IDs.
> > > + * @no_kernel_api_dma: Device driver doesn't use kernel DMA API for DMA.
> > > + *		Drivers which don't require DMA or want to manually claim the
> > > + *		owner type (e.g. userspace driver frameworks) could set this
> > > + *		flag.
> > 
> > Again with the bikeshedding, but this name is a bit odd.  Of course it's
> > in the kernel, this is all kernel code, so you can drop that.  And
> > again, "negative" flags are rough.  So maybe just "prevent_dma"?
> 
> That is misleading too, it is not that DMA is prevented, but that the
> kernel's dma_api has not been setup.

"has not been" or "will not be"?

What you want to prevent is the iommu core claiming the device
automatically, right?  So how about "prevent_iommu_dma"?

naming is hard,

greg k-h
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 07/14] PCI: Add driver dma ownership management
  2022-02-14 12:51         ` Greg Kroah-Hartman
@ 2022-02-14 13:11           ` Jason Gunthorpe via iommu
  -1 siblings, 0 replies; 112+ messages in thread
From: Jason Gunthorpe @ 2022-02-14 13:11 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Lu Baolu, Joerg Roedel, Alex Williamson, Bjorn Helgaas,
	Christoph Hellwig, Kevin Tian, Ashok Raj, Will Deacon,
	Robin Murphy, Dan Williams, rafael, Diana Craciun, Cornelia Huck,
	Eric Auger, Liu Yi L, Jacob jun Pan, Chaitanya Kulkarni,
	Stuart Yoder, Laurentiu Tudor, Thierry Reding, David Airlie,
	Daniel Vetter, Jonathan Hunter, Li Yang, Dmitry Osipenko, iommu,
	linux-pci, kvm, linux-kernel

On Mon, Feb 14, 2022 at 01:51:06PM +0100, Greg Kroah-Hartman wrote:
> On Mon, Feb 14, 2022 at 08:38:42AM -0400, Jason Gunthorpe wrote:
> > On Mon, Feb 14, 2022 at 11:03:42AM +0100, Greg Kroah-Hartman wrote:
> > > On Tue, Jan 04, 2022 at 09:56:37AM +0800, Lu Baolu wrote:
> > > > Multiple PCI devices may be placed in the same IOMMU group because
> > > > they cannot be isolated from each other. These devices must either be
> > > > entirely under kernel control or userspace control, never a mixture. This
> > > > checks and sets DMA ownership during driver binding, and release the
> > > > ownership during driver unbinding.
> > > > 
> > > > The device driver may set a new flag (no_kernel_api_dma) to skip calling
> > > > iommu_device_use_dma_api() during the binding process. For instance, the
> > > > userspace framework drivers (vfio etc.) which need to manually claim
> > > > their own dma ownership when assigning the device to userspace.
> > > > 
> > > > Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
> > > >  include/linux/pci.h      |  5 +++++
> > > >  drivers/pci/pci-driver.c | 21 +++++++++++++++++++++
> > > >  2 files changed, 26 insertions(+)
> > > > 
> > > > diff --git a/include/linux/pci.h b/include/linux/pci.h
> > > > index 18a75c8e615c..d29a990e3f02 100644
> > > > +++ b/include/linux/pci.h
> > > > @@ -882,6 +882,10 @@ struct module;
> > > >   *              created once it is bound to the driver.
> > > >   * @driver:	Driver model structure.
> > > >   * @dynids:	List of dynamically added device IDs.
> > > > + * @no_kernel_api_dma: Device driver doesn't use kernel DMA API for DMA.
> > > > + *		Drivers which don't require DMA or want to manually claim the
> > > > + *		owner type (e.g. userspace driver frameworks) could set this
> > > > + *		flag.
> > > 
> > > Again with the bikeshedding, but this name is a bit odd.  Of course it's
> > > in the kernel, this is all kernel code, so you can drop that.  And
> > > again, "negative" flags are rough.  So maybe just "prevent_dma"?
> > 
> > That is misleading too, it is not that DMA is prevented, but that the
> > kernel's dma_api has not been setup.
> 
> "has not been" or "will not be"?

"has not been" as that action was supposed to happen before probe(),
but the flag skips it.

A driver that sets this flag can still decide to enable the dma API on
its own. eg tegra drivers do this.

> What you want to prevent is the iommu core claiming the device
> automatically, right?  So how about "prevent_iommu_dma"?

"claim" is not a good description. iommu always "claims" the device -
eg sets a domain, sets the dev and bus parameters, etc.

This really is only about setting up the in-kernel dma api, eg
allowing dma_map_sg()/etc to work.

dma api is just one way to operate the iommu, there are others too.

Think of this flag as 
  false = the driver is going to use the dma api (most common)
  true = the driver will decide how to use the iommu by itself

Does it help think of a clearer name?

Jason

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 07/14] PCI: Add driver dma ownership management
@ 2022-02-14 13:11           ` Jason Gunthorpe via iommu
  0 siblings, 0 replies; 112+ messages in thread
From: Jason Gunthorpe via iommu @ 2022-02-14 13:11 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Stuart Yoder, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Ashok Raj,
	Jonathan Hunter, Christoph Hellwig, Kevin Tian,
	Chaitanya Kulkarni, Alex Williamson, kvm, Bjorn Helgaas,
	Dan Williams, Cornelia Huck, linux-kernel, Li Yang, iommu,
	Jacob jun Pan, Daniel Vetter, Robin Murphy

On Mon, Feb 14, 2022 at 01:51:06PM +0100, Greg Kroah-Hartman wrote:
> On Mon, Feb 14, 2022 at 08:38:42AM -0400, Jason Gunthorpe wrote:
> > On Mon, Feb 14, 2022 at 11:03:42AM +0100, Greg Kroah-Hartman wrote:
> > > On Tue, Jan 04, 2022 at 09:56:37AM +0800, Lu Baolu wrote:
> > > > Multiple PCI devices may be placed in the same IOMMU group because
> > > > they cannot be isolated from each other. These devices must either be
> > > > entirely under kernel control or userspace control, never a mixture. This
> > > > checks and sets DMA ownership during driver binding, and release the
> > > > ownership during driver unbinding.
> > > > 
> > > > The device driver may set a new flag (no_kernel_api_dma) to skip calling
> > > > iommu_device_use_dma_api() during the binding process. For instance, the
> > > > userspace framework drivers (vfio etc.) which need to manually claim
> > > > their own dma ownership when assigning the device to userspace.
> > > > 
> > > > Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
> > > >  include/linux/pci.h      |  5 +++++
> > > >  drivers/pci/pci-driver.c | 21 +++++++++++++++++++++
> > > >  2 files changed, 26 insertions(+)
> > > > 
> > > > diff --git a/include/linux/pci.h b/include/linux/pci.h
> > > > index 18a75c8e615c..d29a990e3f02 100644
> > > > +++ b/include/linux/pci.h
> > > > @@ -882,6 +882,10 @@ struct module;
> > > >   *              created once it is bound to the driver.
> > > >   * @driver:	Driver model structure.
> > > >   * @dynids:	List of dynamically added device IDs.
> > > > + * @no_kernel_api_dma: Device driver doesn't use kernel DMA API for DMA.
> > > > + *		Drivers which don't require DMA or want to manually claim the
> > > > + *		owner type (e.g. userspace driver frameworks) could set this
> > > > + *		flag.
> > > 
> > > Again with the bikeshedding, but this name is a bit odd.  Of course it's
> > > in the kernel, this is all kernel code, so you can drop that.  And
> > > again, "negative" flags are rough.  So maybe just "prevent_dma"?
> > 
> > That is misleading too, it is not that DMA is prevented, but that the
> > kernel's dma_api has not been setup.
> 
> "has not been" or "will not be"?

"has not been" as that action was supposed to happen before probe(),
but the flag skips it.

A driver that sets this flag can still decide to enable the dma API on
its own. eg tegra drivers do this.

> What you want to prevent is the iommu core claiming the device
> automatically, right?  So how about "prevent_iommu_dma"?

"claim" is not a good description. iommu always "claims" the device -
eg sets a domain, sets the dev and bus parameters, etc.

This really is only about setting up the in-kernel dma api, eg
allowing dma_map_sg()/etc to work.

dma api is just one way to operate the iommu, there are others too.

Think of this flag as 
  false = the driver is going to use the dma api (most common)
  true = the driver will decide how to use the iommu by itself

Does it help think of a clearer name?

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

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 04/14] driver core: platform: Add driver dma ownership management
  2022-02-14  9:59     ` Greg Kroah-Hartman
@ 2022-02-14 13:18       ` Jason Gunthorpe via iommu
  -1 siblings, 0 replies; 112+ messages in thread
From: Jason Gunthorpe @ 2022-02-14 13:18 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Lu Baolu, Joerg Roedel, Alex Williamson, Bjorn Helgaas,
	Christoph Hellwig, Kevin Tian, Ashok Raj, Will Deacon,
	Robin Murphy, Dan Williams, rafael, Diana Craciun, Cornelia Huck,
	Eric Auger, Liu Yi L, Jacob jun Pan, Chaitanya Kulkarni,
	Stuart Yoder, Laurentiu Tudor, Thierry Reding, David Airlie,
	Daniel Vetter, Jonathan Hunter, Li Yang, Dmitry Osipenko, iommu,
	linux-pci, kvm, linux-kernel

On Mon, Feb 14, 2022 at 10:59:50AM +0100, Greg Kroah-Hartman wrote:

> > +	if (ret && !drv->no_kernel_api_dma)
> > +		iommu_device_unuse_dma_api(dev);
> 
> So you are now going to call this for every platform driver _unless_
> they set this flag?

Yes, it is necessary because VFIO supports platform devices as well
and needs to ensure security. Conflicting kernel driver attachements
must be blocked, just like for PCI.

Jason

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 04/14] driver core: platform: Add driver dma ownership management
@ 2022-02-14 13:18       ` Jason Gunthorpe via iommu
  0 siblings, 0 replies; 112+ messages in thread
From: Jason Gunthorpe via iommu @ 2022-02-14 13:18 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Stuart Yoder, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Ashok Raj,
	Jonathan Hunter, Christoph Hellwig, Kevin Tian,
	Chaitanya Kulkarni, Alex Williamson, kvm, Bjorn Helgaas,
	Dan Williams, Cornelia Huck, linux-kernel, Li Yang, iommu,
	Jacob jun Pan, Daniel Vetter, Robin Murphy

On Mon, Feb 14, 2022 at 10:59:50AM +0100, Greg Kroah-Hartman wrote:

> > +	if (ret && !drv->no_kernel_api_dma)
> > +		iommu_device_unuse_dma_api(dev);
> 
> So you are now going to call this for every platform driver _unless_
> they set this flag?

Yes, it is necessary because VFIO supports platform devices as well
and needs to ensure security. Conflicting kernel driver attachements
must be blocked, just like for PCI.

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

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 04/14] driver core: platform: Add driver dma ownership management
  2022-02-14 13:18       ` Jason Gunthorpe via iommu
@ 2022-02-14 13:37         ` Greg Kroah-Hartman
  -1 siblings, 0 replies; 112+ messages in thread
From: Greg Kroah-Hartman @ 2022-02-14 13:37 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Lu Baolu, Joerg Roedel, Alex Williamson, Bjorn Helgaas,
	Christoph Hellwig, Kevin Tian, Ashok Raj, Will Deacon,
	Robin Murphy, Dan Williams, rafael, Diana Craciun, Cornelia Huck,
	Eric Auger, Liu Yi L, Jacob jun Pan, Chaitanya Kulkarni,
	Stuart Yoder, Laurentiu Tudor, Thierry Reding, David Airlie,
	Daniel Vetter, Jonathan Hunter, Li Yang, Dmitry Osipenko, iommu,
	linux-pci, kvm, linux-kernel

On Mon, Feb 14, 2022 at 09:18:53AM -0400, Jason Gunthorpe wrote:
> On Mon, Feb 14, 2022 at 10:59:50AM +0100, Greg Kroah-Hartman wrote:
> 
> > > +	if (ret && !drv->no_kernel_api_dma)
> > > +		iommu_device_unuse_dma_api(dev);
> > 
> > So you are now going to call this for every platform driver _unless_
> > they set this flag?
> 
> Yes, it is necessary because VFIO supports platform devices as well
> and needs to ensure security. Conflicting kernel driver attachements
> must be blocked, just like for PCI.

A platform device shouldn't be using VFIO, but ugh, oh well, that ship
has sailed :(

And stop it with the "security" mess, do not give people a false sense
of it here please.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 04/14] driver core: platform: Add driver dma ownership management
@ 2022-02-14 13:37         ` Greg Kroah-Hartman
  0 siblings, 0 replies; 112+ messages in thread
From: Greg Kroah-Hartman @ 2022-02-14 13:37 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Stuart Yoder, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Ashok Raj,
	Jonathan Hunter, Christoph Hellwig, Kevin Tian,
	Chaitanya Kulkarni, Alex Williamson, kvm, Bjorn Helgaas,
	Dan Williams, Cornelia Huck, linux-kernel, Li Yang, iommu,
	Jacob jun Pan, Daniel Vetter, Robin Murphy

On Mon, Feb 14, 2022 at 09:18:53AM -0400, Jason Gunthorpe wrote:
> On Mon, Feb 14, 2022 at 10:59:50AM +0100, Greg Kroah-Hartman wrote:
> 
> > > +	if (ret && !drv->no_kernel_api_dma)
> > > +		iommu_device_unuse_dma_api(dev);
> > 
> > So you are now going to call this for every platform driver _unless_
> > they set this flag?
> 
> Yes, it is necessary because VFIO supports platform devices as well
> and needs to ensure security. Conflicting kernel driver attachements
> must be blocked, just like for PCI.

A platform device shouldn't be using VFIO, but ugh, oh well, that ship
has sailed :(

And stop it with the "security" mess, do not give people a false sense
of it here please.

thanks,

greg k-h
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 07/14] PCI: Add driver dma ownership management
  2022-02-14 13:11           ` Jason Gunthorpe via iommu
@ 2022-02-14 13:39             ` Greg Kroah-Hartman
  -1 siblings, 0 replies; 112+ messages in thread
From: Greg Kroah-Hartman @ 2022-02-14 13:39 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Lu Baolu, Joerg Roedel, Alex Williamson, Bjorn Helgaas,
	Christoph Hellwig, Kevin Tian, Ashok Raj, Will Deacon,
	Robin Murphy, Dan Williams, rafael, Diana Craciun, Cornelia Huck,
	Eric Auger, Liu Yi L, Jacob jun Pan, Chaitanya Kulkarni,
	Stuart Yoder, Laurentiu Tudor, Thierry Reding, David Airlie,
	Daniel Vetter, Jonathan Hunter, Li Yang, Dmitry Osipenko, iommu,
	linux-pci, kvm, linux-kernel

On Mon, Feb 14, 2022 at 09:11:17AM -0400, Jason Gunthorpe wrote:
> On Mon, Feb 14, 2022 at 01:51:06PM +0100, Greg Kroah-Hartman wrote:
> > On Mon, Feb 14, 2022 at 08:38:42AM -0400, Jason Gunthorpe wrote:
> > > On Mon, Feb 14, 2022 at 11:03:42AM +0100, Greg Kroah-Hartman wrote:
> > > > On Tue, Jan 04, 2022 at 09:56:37AM +0800, Lu Baolu wrote:
> > > > > Multiple PCI devices may be placed in the same IOMMU group because
> > > > > they cannot be isolated from each other. These devices must either be
> > > > > entirely under kernel control or userspace control, never a mixture. This
> > > > > checks and sets DMA ownership during driver binding, and release the
> > > > > ownership during driver unbinding.
> > > > > 
> > > > > The device driver may set a new flag (no_kernel_api_dma) to skip calling
> > > > > iommu_device_use_dma_api() during the binding process. For instance, the
> > > > > userspace framework drivers (vfio etc.) which need to manually claim
> > > > > their own dma ownership when assigning the device to userspace.
> > > > > 
> > > > > Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
> > > > >  include/linux/pci.h      |  5 +++++
> > > > >  drivers/pci/pci-driver.c | 21 +++++++++++++++++++++
> > > > >  2 files changed, 26 insertions(+)
> > > > > 
> > > > > diff --git a/include/linux/pci.h b/include/linux/pci.h
> > > > > index 18a75c8e615c..d29a990e3f02 100644
> > > > > +++ b/include/linux/pci.h
> > > > > @@ -882,6 +882,10 @@ struct module;
> > > > >   *              created once it is bound to the driver.
> > > > >   * @driver:	Driver model structure.
> > > > >   * @dynids:	List of dynamically added device IDs.
> > > > > + * @no_kernel_api_dma: Device driver doesn't use kernel DMA API for DMA.
> > > > > + *		Drivers which don't require DMA or want to manually claim the
> > > > > + *		owner type (e.g. userspace driver frameworks) could set this
> > > > > + *		flag.
> > > > 
> > > > Again with the bikeshedding, but this name is a bit odd.  Of course it's
> > > > in the kernel, this is all kernel code, so you can drop that.  And
> > > > again, "negative" flags are rough.  So maybe just "prevent_dma"?
> > > 
> > > That is misleading too, it is not that DMA is prevented, but that the
> > > kernel's dma_api has not been setup.
> > 
> > "has not been" or "will not be"?
> 
> "has not been" as that action was supposed to happen before probe(),
> but the flag skips it.
> 
> A driver that sets this flag can still decide to enable the dma API on
> its own. eg tegra drivers do this.

So you are just forcing the driver to manage this all on their own, so
how about, "driver_managed_dma", or even shorter "managed_dma"?

> > What you want to prevent is the iommu core claiming the device
> > automatically, right?  So how about "prevent_iommu_dma"?
> 
> "claim" is not a good description. iommu always "claims" the device -
> eg sets a domain, sets the dev and bus parameters, etc.
> 
> This really is only about setting up the in-kernel dma api, eg
> allowing dma_map_sg()/etc to work.
> 
> dma api is just one way to operate the iommu, there are others too.
> 
> Think of this flag as 
>   false = the driver is going to use the dma api (most common)
>   true = the driver will decide how to use the iommu by itself
> 
> Does it help think of a clearer name?

See above, you want a driver author to know instantly what this is and
not have to look anything up.
"I_will_manage_the_dma_myself_as_I_really_know_what_I_am_doing" might be
good, but a bit too long :)

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 07/14] PCI: Add driver dma ownership management
@ 2022-02-14 13:39             ` Greg Kroah-Hartman
  0 siblings, 0 replies; 112+ messages in thread
From: Greg Kroah-Hartman @ 2022-02-14 13:39 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Stuart Yoder, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Ashok Raj,
	Jonathan Hunter, Christoph Hellwig, Kevin Tian,
	Chaitanya Kulkarni, Alex Williamson, kvm, Bjorn Helgaas,
	Dan Williams, Cornelia Huck, linux-kernel, Li Yang, iommu,
	Jacob jun Pan, Daniel Vetter, Robin Murphy

On Mon, Feb 14, 2022 at 09:11:17AM -0400, Jason Gunthorpe wrote:
> On Mon, Feb 14, 2022 at 01:51:06PM +0100, Greg Kroah-Hartman wrote:
> > On Mon, Feb 14, 2022 at 08:38:42AM -0400, Jason Gunthorpe wrote:
> > > On Mon, Feb 14, 2022 at 11:03:42AM +0100, Greg Kroah-Hartman wrote:
> > > > On Tue, Jan 04, 2022 at 09:56:37AM +0800, Lu Baolu wrote:
> > > > > Multiple PCI devices may be placed in the same IOMMU group because
> > > > > they cannot be isolated from each other. These devices must either be
> > > > > entirely under kernel control or userspace control, never a mixture. This
> > > > > checks and sets DMA ownership during driver binding, and release the
> > > > > ownership during driver unbinding.
> > > > > 
> > > > > The device driver may set a new flag (no_kernel_api_dma) to skip calling
> > > > > iommu_device_use_dma_api() during the binding process. For instance, the
> > > > > userspace framework drivers (vfio etc.) which need to manually claim
> > > > > their own dma ownership when assigning the device to userspace.
> > > > > 
> > > > > Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
> > > > >  include/linux/pci.h      |  5 +++++
> > > > >  drivers/pci/pci-driver.c | 21 +++++++++++++++++++++
> > > > >  2 files changed, 26 insertions(+)
> > > > > 
> > > > > diff --git a/include/linux/pci.h b/include/linux/pci.h
> > > > > index 18a75c8e615c..d29a990e3f02 100644
> > > > > +++ b/include/linux/pci.h
> > > > > @@ -882,6 +882,10 @@ struct module;
> > > > >   *              created once it is bound to the driver.
> > > > >   * @driver:	Driver model structure.
> > > > >   * @dynids:	List of dynamically added device IDs.
> > > > > + * @no_kernel_api_dma: Device driver doesn't use kernel DMA API for DMA.
> > > > > + *		Drivers which don't require DMA or want to manually claim the
> > > > > + *		owner type (e.g. userspace driver frameworks) could set this
> > > > > + *		flag.
> > > > 
> > > > Again with the bikeshedding, but this name is a bit odd.  Of course it's
> > > > in the kernel, this is all kernel code, so you can drop that.  And
> > > > again, "negative" flags are rough.  So maybe just "prevent_dma"?
> > > 
> > > That is misleading too, it is not that DMA is prevented, but that the
> > > kernel's dma_api has not been setup.
> > 
> > "has not been" or "will not be"?
> 
> "has not been" as that action was supposed to happen before probe(),
> but the flag skips it.
> 
> A driver that sets this flag can still decide to enable the dma API on
> its own. eg tegra drivers do this.

So you are just forcing the driver to manage this all on their own, so
how about, "driver_managed_dma", or even shorter "managed_dma"?

> > What you want to prevent is the iommu core claiming the device
> > automatically, right?  So how about "prevent_iommu_dma"?
> 
> "claim" is not a good description. iommu always "claims" the device -
> eg sets a domain, sets the dev and bus parameters, etc.
> 
> This really is only about setting up the in-kernel dma api, eg
> allowing dma_map_sg()/etc to work.
> 
> dma api is just one way to operate the iommu, there are others too.
> 
> Think of this flag as 
>   false = the driver is going to use the dma api (most common)
>   true = the driver will decide how to use the iommu by itself
> 
> Does it help think of a clearer name?

See above, you want a driver author to know instantly what this is and
not have to look anything up.
"I_will_manage_the_dma_myself_as_I_really_know_what_I_am_doing" might be
good, but a bit too long :)

thanks,

greg k-h
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 04/14] driver core: platform: Add driver dma ownership management
  2022-02-14 13:37         ` Greg Kroah-Hartman
@ 2022-02-14 13:43           ` Jason Gunthorpe via iommu
  -1 siblings, 0 replies; 112+ messages in thread
From: Jason Gunthorpe @ 2022-02-14 13:43 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Lu Baolu, Joerg Roedel, Alex Williamson, Bjorn Helgaas,
	Christoph Hellwig, Kevin Tian, Ashok Raj, Will Deacon,
	Robin Murphy, Dan Williams, rafael, Diana Craciun, Cornelia Huck,
	Eric Auger, Liu Yi L, Jacob jun Pan, Chaitanya Kulkarni,
	Stuart Yoder, Laurentiu Tudor, Thierry Reding, David Airlie,
	Daniel Vetter, Jonathan Hunter, Li Yang, Dmitry Osipenko, iommu,
	linux-pci, kvm, linux-kernel

On Mon, Feb 14, 2022 at 02:37:15PM +0100, Greg Kroah-Hartman wrote:
> On Mon, Feb 14, 2022 at 09:18:53AM -0400, Jason Gunthorpe wrote:
> > On Mon, Feb 14, 2022 at 10:59:50AM +0100, Greg Kroah-Hartman wrote:
> > 
> > > > +	if (ret && !drv->no_kernel_api_dma)
> > > > +		iommu_device_unuse_dma_api(dev);
> > > 
> > > So you are now going to call this for every platform driver _unless_
> > > they set this flag?
> > 
> > Yes, it is necessary because VFIO supports platform devices as well
> > and needs to ensure security. Conflicting kernel driver attachements
> > must be blocked, just like for PCI.
> 
> A platform device shouldn't be using VFIO, but ugh, oh well, that ship
> has sailed :(

I don't know why you say that, but yes, this is was set long ago.

> And stop it with the "security" mess, do not give people a false sense
> of it here please.

I'm confused by what you mean. This is all about what we tend to refer
to as DMA security - meaning a device's DMA can be controled by a
hostile environment and not impact the integrity of the kernel.

Jason

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 04/14] driver core: platform: Add driver dma ownership management
@ 2022-02-14 13:43           ` Jason Gunthorpe via iommu
  0 siblings, 0 replies; 112+ messages in thread
From: Jason Gunthorpe via iommu @ 2022-02-14 13:43 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Stuart Yoder, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Ashok Raj,
	Jonathan Hunter, Christoph Hellwig, Kevin Tian,
	Chaitanya Kulkarni, Alex Williamson, kvm, Bjorn Helgaas,
	Dan Williams, Cornelia Huck, linux-kernel, Li Yang, iommu,
	Jacob jun Pan, Daniel Vetter, Robin Murphy

On Mon, Feb 14, 2022 at 02:37:15PM +0100, Greg Kroah-Hartman wrote:
> On Mon, Feb 14, 2022 at 09:18:53AM -0400, Jason Gunthorpe wrote:
> > On Mon, Feb 14, 2022 at 10:59:50AM +0100, Greg Kroah-Hartman wrote:
> > 
> > > > +	if (ret && !drv->no_kernel_api_dma)
> > > > +		iommu_device_unuse_dma_api(dev);
> > > 
> > > So you are now going to call this for every platform driver _unless_
> > > they set this flag?
> > 
> > Yes, it is necessary because VFIO supports platform devices as well
> > and needs to ensure security. Conflicting kernel driver attachements
> > must be blocked, just like for PCI.
> 
> A platform device shouldn't be using VFIO, but ugh, oh well, that ship
> has sailed :(

I don't know why you say that, but yes, this is was set long ago.

> And stop it with the "security" mess, do not give people a false sense
> of it here please.

I'm confused by what you mean. This is all about what we tend to refer
to as DMA security - meaning a device's DMA can be controled by a
hostile environment and not impact the integrity of the kernel.

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

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 07/14] PCI: Add driver dma ownership management
  2022-02-14 13:39             ` Greg Kroah-Hartman
@ 2022-02-14 13:43               ` Jason Gunthorpe via iommu
  -1 siblings, 0 replies; 112+ messages in thread
From: Jason Gunthorpe @ 2022-02-14 13:43 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Lu Baolu, Joerg Roedel, Alex Williamson, Bjorn Helgaas,
	Christoph Hellwig, Kevin Tian, Ashok Raj, Will Deacon,
	Robin Murphy, Dan Williams, rafael, Diana Craciun, Cornelia Huck,
	Eric Auger, Liu Yi L, Jacob jun Pan, Chaitanya Kulkarni,
	Stuart Yoder, Laurentiu Tudor, Thierry Reding, David Airlie,
	Daniel Vetter, Jonathan Hunter, Li Yang, Dmitry Osipenko, iommu,
	linux-pci, kvm, linux-kernel

On Mon, Feb 14, 2022 at 02:39:18PM +0100, Greg Kroah-Hartman wrote:

> > A driver that sets this flag can still decide to enable the dma API on
> > its own. eg tegra drivers do this.
> 
> So you are just forcing the driver to manage this all on their own, so
> how about, "driver_managed_dma", or even shorter "managed_dma"?

Yeah, I like "driver_managed_dma" alot, it captures the entire idea

Thanks,
Jason

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 07/14] PCI: Add driver dma ownership management
@ 2022-02-14 13:43               ` Jason Gunthorpe via iommu
  0 siblings, 0 replies; 112+ messages in thread
From: Jason Gunthorpe via iommu @ 2022-02-14 13:43 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Stuart Yoder, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Ashok Raj,
	Jonathan Hunter, Christoph Hellwig, Kevin Tian,
	Chaitanya Kulkarni, Alex Williamson, kvm, Bjorn Helgaas,
	Dan Williams, Cornelia Huck, linux-kernel, Li Yang, iommu,
	Jacob jun Pan, Daniel Vetter, Robin Murphy

On Mon, Feb 14, 2022 at 02:39:18PM +0100, Greg Kroah-Hartman wrote:

> > A driver that sets this flag can still decide to enable the dma API on
> > its own. eg tegra drivers do this.
> 
> So you are just forcing the driver to manage this all on their own, so
> how about, "driver_managed_dma", or even shorter "managed_dma"?

Yeah, I like "driver_managed_dma" alot, it captures the entire idea

Thanks,
Jason
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 07/14] PCI: Add driver dma ownership management
  2022-02-14 13:43               ` Jason Gunthorpe via iommu
@ 2022-02-15  3:06                 ` Lu Baolu
  -1 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-02-15  3:06 UTC (permalink / raw)
  To: Jason Gunthorpe, Greg Kroah-Hartman
  Cc: baolu.lu, Joerg Roedel, Alex Williamson, Bjorn Helgaas,
	Christoph Hellwig, Kevin Tian, Ashok Raj, Will Deacon,
	Robin Murphy, Dan Williams, rafael, Diana Craciun, Cornelia Huck,
	Eric Auger, Liu Yi L, Jacob jun Pan, Chaitanya Kulkarni,
	Stuart Yoder, Laurentiu Tudor, Thierry Reding, David Airlie,
	Daniel Vetter, Jonathan Hunter, Li Yang, Dmitry Osipenko, iommu,
	linux-pci, kvm, linux-kernel

On 2/14/22 9:43 PM, Jason Gunthorpe wrote:
> On Mon, Feb 14, 2022 at 02:39:18PM +0100, Greg Kroah-Hartman wrote:
> 
>>> A driver that sets this flag can still decide to enable the dma API on
>>> its own. eg tegra drivers do this.
>>
>> So you are just forcing the driver to manage this all on their own, so
>> how about, "driver_managed_dma", or even shorter "managed_dma"?
> 
> Yeah, I like "driver_managed_dma" alot, it captures the entire idea

This makes a lot of sense. For most drivers, they don't need to care
about this flag as all DMAs are handled through the kernel DMA API. For
VFIO or similar drivers, they know how to manage the DMA themselves and
set this flag so that the IOMMU layer will allow them to setup and
manage their own I/O address space.

If there is no better naming, I'd like to use this and add some comments
for device drivers developers.

Thanks a lot to Greg and Jason.

Best regards,
baolu

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 07/14] PCI: Add driver dma ownership management
@ 2022-02-15  3:06                 ` Lu Baolu
  0 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-02-15  3:06 UTC (permalink / raw)
  To: Jason Gunthorpe, Greg Kroah-Hartman
  Cc: Stuart Yoder, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Ashok Raj,
	Jonathan Hunter, Christoph Hellwig, Kevin Tian,
	Chaitanya Kulkarni, Alex Williamson, kvm, Bjorn Helgaas,
	Dan Williams, Cornelia Huck, linux-kernel, Li Yang, iommu,
	Jacob jun Pan, Daniel Vetter, Robin Murphy

On 2/14/22 9:43 PM, Jason Gunthorpe wrote:
> On Mon, Feb 14, 2022 at 02:39:18PM +0100, Greg Kroah-Hartman wrote:
> 
>>> A driver that sets this flag can still decide to enable the dma API on
>>> its own. eg tegra drivers do this.
>>
>> So you are just forcing the driver to manage this all on their own, so
>> how about, "driver_managed_dma", or even shorter "managed_dma"?
> 
> Yeah, I like "driver_managed_dma" alot, it captures the entire idea

This makes a lot of sense. For most drivers, they don't need to care
about this flag as all DMAs are handled through the kernel DMA API. For
VFIO or similar drivers, they know how to manage the DMA themselves and
set this flag so that the IOMMU layer will allow them to setup and
manage their own I/O address space.

If there is no better naming, I'd like to use this and add some comments
for device drivers developers.

Thanks a lot to Greg and Jason.

Best regards,
baolu
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 00/14] Fix BUG_ON in vfio_iommu_group_notifier()
  2022-01-04  1:56 ` Lu Baolu
@ 2022-02-18  1:07   ` Lu Baolu
  -1 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-02-18  1:07 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Joerg Roedel, Alex Williamson, Bjorn Helgaas,
	Jason Gunthorpe, Christoph Hellwig, Kevin Tian, Ashok Raj
  Cc: baolu.lu, Will Deacon, Robin Murphy, Dan Williams, rafael,
	Diana Craciun, Cornelia Huck, Eric Auger, Liu Yi L,
	Jacob jun Pan, Chaitanya Kulkarni, Stuart Yoder, Laurentiu Tudor,
	Thierry Reding, David Airlie, Daniel Vetter, Jonathan Hunter,
	Li Yang, Dmitry Osipenko, iommu, linux-pci, kvm, linux-kernel

On 1/4/22 9:56 AM, Lu Baolu wrote:
> Hi folks,
> 
> The iommu group is the minimal isolation boundary for DMA. Devices in
> a group can access each other's MMIO registers via peer to peer DMA
> and also need share the same I/O address space.
> 
> Once the I/O address space is assigned to user control it is no longer
> available to the dma_map* API, which effectively makes the DMA API
> non-working.
> 
> Second, userspace can use DMA initiated by a device that it controls
> to access the MMIO spaces of other devices in the group. This allows
> userspace to indirectly attack any kernel owned device and it's driver.
> 
> Therefore groups must either be entirely under kernel control or
> userspace control, never a mixture. Unfortunately some systems have
> problems with the granularity of groups and there are a couple of
> important exceptions:
> 
>   - pci_stub allows the admin to block driver binding on a device and
>     make it permanently shared with userspace. Since PCI stub does not
>     do DMA it is safe, however the admin must understand that using
>     pci_stub allows userspace to attack whatever device it was bound
>     it.
> 
>   - PCI bridges are sometimes included in groups. Typically PCI bridges
>     do not use DMA, and generally do not have MMIO regions.
> 
> Generally any device that does not have any MMIO registers is a
> possible candidate for an exception.
> 
> Currently vfio adopts a workaround to detect violations of the above
> restrictions by monitoring the driver core BOUND event, and hardwiring
> the above exceptions. Since there is no way for vfio to reject driver
> binding at this point, BUG_ON() is triggered if a violation is
> captured (kernel driver BOUND event on a group which already has some
> devices assigned to userspace). Aside from the bad user experience
> this opens a way for root userspace to crash the kernel, even in high
> integrity configurations, by manipulating the module binding and
> triggering the BUG_ON.
> 
> This series solves this problem by making the user/kernel ownership a
> core concept at the IOMMU layer. The driver core enforces kernel
> ownership while drivers are bound and violations now result in a error
> codes during probe, not BUG_ON failures.
> 
> Patch partitions:
>    [PATCH 1-7]: Detect DMA ownership conflicts during driver binding;
>    [PATCH 8-10]: Add security context management for assigned devices;
>    [PATCH 11-14]: Various cleanups.
> 
> This is also part one of three initial series for IOMMUFD:
>   * Move IOMMU Group security into the iommu layer
>   - Generic IOMMUFD implementation
>   - VFIO ability to consume IOMMUFD

Thank you very much for your comments. A new version of this series has
been posted here:

https://lore.kernel.org/linux-iommu/20220218005521.172832-1-baolu.lu@linux.intel.com/

Best regards,
baolu

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 00/14] Fix BUG_ON in vfio_iommu_group_notifier()
@ 2022-02-18  1:07   ` Lu Baolu
  0 siblings, 0 replies; 112+ messages in thread
From: Lu Baolu @ 2022-02-18  1:07 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Joerg Roedel, Alex Williamson, Bjorn Helgaas,
	Jason Gunthorpe, Christoph Hellwig, Kevin Tian, Ashok Raj
  Cc: kvm, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Stuart Yoder,
	Jonathan Hunter, Chaitanya Kulkarni, Dan Williams, Cornelia Huck,
	linux-kernel, Li Yang, iommu, Jacob jun Pan, Daniel Vetter,
	Robin Murphy

On 1/4/22 9:56 AM, Lu Baolu wrote:
> Hi folks,
> 
> The iommu group is the minimal isolation boundary for DMA. Devices in
> a group can access each other's MMIO registers via peer to peer DMA
> and also need share the same I/O address space.
> 
> Once the I/O address space is assigned to user control it is no longer
> available to the dma_map* API, which effectively makes the DMA API
> non-working.
> 
> Second, userspace can use DMA initiated by a device that it controls
> to access the MMIO spaces of other devices in the group. This allows
> userspace to indirectly attack any kernel owned device and it's driver.
> 
> Therefore groups must either be entirely under kernel control or
> userspace control, never a mixture. Unfortunately some systems have
> problems with the granularity of groups and there are a couple of
> important exceptions:
> 
>   - pci_stub allows the admin to block driver binding on a device and
>     make it permanently shared with userspace. Since PCI stub does not
>     do DMA it is safe, however the admin must understand that using
>     pci_stub allows userspace to attack whatever device it was bound
>     it.
> 
>   - PCI bridges are sometimes included in groups. Typically PCI bridges
>     do not use DMA, and generally do not have MMIO regions.
> 
> Generally any device that does not have any MMIO registers is a
> possible candidate for an exception.
> 
> Currently vfio adopts a workaround to detect violations of the above
> restrictions by monitoring the driver core BOUND event, and hardwiring
> the above exceptions. Since there is no way for vfio to reject driver
> binding at this point, BUG_ON() is triggered if a violation is
> captured (kernel driver BOUND event on a group which already has some
> devices assigned to userspace). Aside from the bad user experience
> this opens a way for root userspace to crash the kernel, even in high
> integrity configurations, by manipulating the module binding and
> triggering the BUG_ON.
> 
> This series solves this problem by making the user/kernel ownership a
> core concept at the IOMMU layer. The driver core enforces kernel
> ownership while drivers are bound and violations now result in a error
> codes during probe, not BUG_ON failures.
> 
> Patch partitions:
>    [PATCH 1-7]: Detect DMA ownership conflicts during driver binding;
>    [PATCH 8-10]: Add security context management for assigned devices;
>    [PATCH 11-14]: Various cleanups.
> 
> This is also part one of three initial series for IOMMUFD:
>   * Move IOMMU Group security into the iommu layer
>   - Generic IOMMUFD implementation
>   - VFIO ability to consume IOMMUFD

Thank you very much for your comments. A new version of this series has
been posted here:

https://lore.kernel.org/linux-iommu/20220218005521.172832-1-baolu.lu@linux.intel.com/

Best regards,
baolu
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 07/14] PCI: Add driver dma ownership management
  2022-01-04  1:56   ` Lu Baolu
@ 2022-02-23 18:00     ` Bjorn Helgaas
  -1 siblings, 0 replies; 112+ messages in thread
From: Bjorn Helgaas @ 2022-02-23 18:00 UTC (permalink / raw)
  To: Lu Baolu
  Cc: Greg Kroah-Hartman, Joerg Roedel, Alex Williamson, Bjorn Helgaas,
	Jason Gunthorpe, Christoph Hellwig, Kevin Tian, Ashok Raj, kvm,
	rafael, David Airlie, linux-pci, Thierry Reding, Diana Craciun,
	Dmitry Osipenko, Will Deacon, Stuart Yoder, Jonathan Hunter,
	Chaitanya Kulkarni, Dan Williams, Cornelia Huck, linux-kernel,
	Li Yang, iommu, Jacob jun Pan, Daniel Vetter, Robin Murphy

In subject,

s/dma/DMA/ to match the other patches

On Tue, Jan 04, 2022 at 09:56:37AM +0800, Lu Baolu wrote:
> Multiple PCI devices may be placed in the same IOMMU group because
> they cannot be isolated from each other. These devices must either be
> entirely under kernel control or userspace control, never a mixture. This
> checks and sets DMA ownership during driver binding, and release the
> ownership during driver unbinding.
> 
> The device driver may set a new flag (no_kernel_api_dma) to skip calling
> iommu_device_use_dma_api() during the binding process. For instance, the
> userspace framework drivers (vfio etc.) which need to manually claim
> their own dma ownership when assigning the device to userspace.

s/vfio/VFIO/ when used as an acronym (occurs in several patches)

> + * @no_kernel_api_dma: Device driver doesn't use kernel DMA API for DMA.
> + *		Drivers which don't require DMA or want to manually claim the
> + *		owner type (e.g. userspace driver frameworks) could set this
> + *		flag.

s/Drivers which/Drivers that/

>  static int pci_dma_configure(struct device *dev)
>  {
> +	struct pci_driver *driver = to_pci_driver(dev->driver);
>  	struct device *bridge;
>  	int ret = 0;
>  
> +	if (!driver->no_kernel_api_dma) {

Ugh.  Double negative, totally agree this needs a better name that
reverses the sense.  Every place you use it, you negate it again.

> +	if (ret && !driver->no_kernel_api_dma)
> +		iommu_device_unuse_dma_api(dev);

> +static void pci_dma_cleanup(struct device *dev)
> +{
> +	struct pci_driver *driver = to_pci_driver(dev->driver);
> +
> +	if (!driver->no_kernel_api_dma)
> +		iommu_device_unuse_dma_api(dev);

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 07/14] PCI: Add driver dma ownership management
@ 2022-02-23 18:00     ` Bjorn Helgaas
  0 siblings, 0 replies; 112+ messages in thread
From: Bjorn Helgaas @ 2022-02-23 18:00 UTC (permalink / raw)
  To: Lu Baolu
  Cc: kvm, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Ashok Raj,
	Jonathan Hunter, Christoph Hellwig, Stuart Yoder, Kevin Tian,
	Chaitanya Kulkarni, Jason Gunthorpe, Alex Williamson,
	Bjorn Helgaas, Dan Williams, Greg Kroah-Hartman, Cornelia Huck,
	linux-kernel, Li Yang, iommu, Jacob jun Pan, Daniel Vetter,
	Robin Murphy

In subject,

s/dma/DMA/ to match the other patches

On Tue, Jan 04, 2022 at 09:56:37AM +0800, Lu Baolu wrote:
> Multiple PCI devices may be placed in the same IOMMU group because
> they cannot be isolated from each other. These devices must either be
> entirely under kernel control or userspace control, never a mixture. This
> checks and sets DMA ownership during driver binding, and release the
> ownership during driver unbinding.
> 
> The device driver may set a new flag (no_kernel_api_dma) to skip calling
> iommu_device_use_dma_api() during the binding process. For instance, the
> userspace framework drivers (vfio etc.) which need to manually claim
> their own dma ownership when assigning the device to userspace.

s/vfio/VFIO/ when used as an acronym (occurs in several patches)

> + * @no_kernel_api_dma: Device driver doesn't use kernel DMA API for DMA.
> + *		Drivers which don't require DMA or want to manually claim the
> + *		owner type (e.g. userspace driver frameworks) could set this
> + *		flag.

s/Drivers which/Drivers that/

>  static int pci_dma_configure(struct device *dev)
>  {
> +	struct pci_driver *driver = to_pci_driver(dev->driver);
>  	struct device *bridge;
>  	int ret = 0;
>  
> +	if (!driver->no_kernel_api_dma) {

Ugh.  Double negative, totally agree this needs a better name that
reverses the sense.  Every place you use it, you negate it again.

> +	if (ret && !driver->no_kernel_api_dma)
> +		iommu_device_unuse_dma_api(dev);

> +static void pci_dma_cleanup(struct device *dev)
> +{
> +	struct pci_driver *driver = to_pci_driver(dev->driver);
> +
> +	if (!driver->no_kernel_api_dma)
> +		iommu_device_unuse_dma_api(dev);
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 07/14] PCI: Add driver dma ownership management
  2022-02-23 18:00     ` Bjorn Helgaas
@ 2022-02-23 18:07       ` Jason Gunthorpe via iommu
  -1 siblings, 0 replies; 112+ messages in thread
From: Jason Gunthorpe @ 2022-02-23 18:07 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Lu Baolu, Greg Kroah-Hartman, Joerg Roedel, Alex Williamson,
	Bjorn Helgaas, Christoph Hellwig, Kevin Tian, Ashok Raj, kvm,
	rafael, David Airlie, linux-pci, Thierry Reding, Diana Craciun,
	Dmitry Osipenko, Will Deacon, Stuart Yoder, Jonathan Hunter,
	Chaitanya Kulkarni, Dan Williams, Cornelia Huck, linux-kernel,
	Li Yang, iommu, Jacob jun Pan, Daniel Vetter, Robin Murphy

On Wed, Feb 23, 2022 at 12:00:56PM -0600, Bjorn Helgaas wrote:

> >  static int pci_dma_configure(struct device *dev)
> >  {
> > +	struct pci_driver *driver = to_pci_driver(dev->driver);
> >  	struct device *bridge;
> >  	int ret = 0;
> >  
> > +	if (!driver->no_kernel_api_dma) {
> 
> Ugh.  Double negative, totally agree this needs a better name that
> reverses the sense.  Every place you use it, you negate it again.

Greg came up with driver_managed_dma which is in the v6 version:

https://lore.kernel.org/all/20220218005521.172832-5-baolu.lu@linux.intel.com/

Thanks,
Jason

^ permalink raw reply	[flat|nested] 112+ messages in thread

* Re: [PATCH v5 07/14] PCI: Add driver dma ownership management
@ 2022-02-23 18:07       ` Jason Gunthorpe via iommu
  0 siblings, 0 replies; 112+ messages in thread
From: Jason Gunthorpe via iommu @ 2022-02-23 18:07 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: kvm, rafael, David Airlie, linux-pci, Thierry Reding,
	Diana Craciun, Dmitry Osipenko, Will Deacon, Ashok Raj,
	Jonathan Hunter, Christoph Hellwig, Stuart Yoder, Kevin Tian,
	Chaitanya Kulkarni, Alex Williamson, Bjorn Helgaas, Dan Williams,
	Greg Kroah-Hartman, Cornelia Huck, linux-kernel, Li Yang, iommu,
	Jacob jun Pan, Daniel Vetter, Robin Murphy

On Wed, Feb 23, 2022 at 12:00:56PM -0600, Bjorn Helgaas wrote:

> >  static int pci_dma_configure(struct device *dev)
> >  {
> > +	struct pci_driver *driver = to_pci_driver(dev->driver);
> >  	struct device *bridge;
> >  	int ret = 0;
> >  
> > +	if (!driver->no_kernel_api_dma) {
> 
> Ugh.  Double negative, totally agree this needs a better name that
> reverses the sense.  Every place you use it, you negate it again.

Greg came up with driver_managed_dma which is in the v6 version:

https://lore.kernel.org/all/20220218005521.172832-5-baolu.lu@linux.intel.com/

Thanks,
Jason
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 112+ messages in thread

end of thread, other threads:[~2022-02-23 18:08 UTC | newest]

Thread overview: 112+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-04  1:56 [PATCH v5 00/14] Fix BUG_ON in vfio_iommu_group_notifier() Lu Baolu
2022-01-04  1:56 ` Lu Baolu
2022-01-04  1:56 ` [PATCH v5 01/14] iommu: Add dma ownership management interfaces Lu Baolu
2022-01-04  1:56   ` Lu Baolu
2022-01-04 10:08   ` Christoph Hellwig
2022-01-04 10:08     ` Christoph Hellwig
2022-01-04 16:41     ` Bjorn Helgaas
2022-01-04 16:41       ` Bjorn Helgaas
2022-01-04 19:23       ` Jason Gunthorpe
2022-01-04 19:23         ` Jason Gunthorpe via iommu
2022-01-06  3:18         ` Lu Baolu
2022-01-06  3:18           ` Lu Baolu
2022-01-06  3:54         ` Lu Baolu
2022-01-06  3:54           ` Lu Baolu
2022-01-06 15:46           ` Jason Gunthorpe
2022-01-06 15:46             ` Jason Gunthorpe via iommu
2022-01-07  1:50             ` Lu Baolu
2022-01-07  1:50               ` Lu Baolu
2022-01-06  3:43       ` Lu Baolu
2022-01-06  3:43         ` Lu Baolu
2022-01-06  3:47       ` Lu Baolu
2022-01-06  3:47         ` Lu Baolu
2022-01-06  3:51       ` Lu Baolu
2022-01-06  3:51         ` Lu Baolu
2022-01-05  6:57     ` Lu Baolu
2022-01-05  6:57       ` Lu Baolu
2022-01-04  1:56 ` [PATCH v5 02/14] driver core: Add dma_cleanup callback in bus_type Lu Baolu
2022-01-04  1:56   ` Lu Baolu
2022-01-04 10:08   ` Christoph Hellwig
2022-01-04 10:08     ` Christoph Hellwig
2022-01-04 12:39     ` Jason Gunthorpe
2022-01-04 12:39       ` Jason Gunthorpe via iommu
2022-01-04 13:04       ` Greg Kroah-Hartman
2022-01-04 13:04         ` Greg Kroah-Hartman
2022-02-08  5:55         ` Lu Baolu
2022-02-08  5:55           ` Lu Baolu
2022-02-08 11:35           ` Greg Kroah-Hartman
2022-02-08 11:35             ` Greg Kroah-Hartman
2022-02-14 10:01     ` Greg Kroah-Hartman
2022-02-14 10:01       ` Greg Kroah-Hartman
2022-02-14 10:02   ` Greg Kroah-Hartman
2022-02-14 10:02     ` Greg Kroah-Hartman
2022-01-04  1:56 ` [PATCH v5 03/14] amba: Stop sharing platform_dma_configure() Lu Baolu
2022-01-04  1:56   ` Lu Baolu
2022-01-04  1:56 ` [PATCH v5 04/14] driver core: platform: Add driver dma ownership management Lu Baolu
2022-01-04  1:56   ` Lu Baolu
2022-02-14  9:59   ` Greg Kroah-Hartman
2022-02-14  9:59     ` Greg Kroah-Hartman
2022-02-14 13:18     ` Jason Gunthorpe
2022-02-14 13:18       ` Jason Gunthorpe via iommu
2022-02-14 13:37       ` Greg Kroah-Hartman
2022-02-14 13:37         ` Greg Kroah-Hartman
2022-02-14 13:43         ` Jason Gunthorpe
2022-02-14 13:43           ` Jason Gunthorpe via iommu
2022-01-04  1:56 ` [PATCH v5 05/14] amba: " Lu Baolu
2022-01-04  1:56   ` Lu Baolu
2022-01-04  1:56 ` [PATCH v5 06/14] bus: fsl-mc: " Lu Baolu
2022-01-04  1:56   ` Lu Baolu
2022-01-04  1:56 ` [PATCH v5 07/14] PCI: " Lu Baolu
2022-01-04  1:56   ` Lu Baolu
2022-02-14 10:03   ` Greg Kroah-Hartman
2022-02-14 10:03     ` Greg Kroah-Hartman
2022-02-14 12:38     ` Jason Gunthorpe
2022-02-14 12:38       ` Jason Gunthorpe via iommu
2022-02-14 12:51       ` Greg Kroah-Hartman
2022-02-14 12:51         ` Greg Kroah-Hartman
2022-02-14 13:11         ` Jason Gunthorpe
2022-02-14 13:11           ` Jason Gunthorpe via iommu
2022-02-14 13:39           ` Greg Kroah-Hartman
2022-02-14 13:39             ` Greg Kroah-Hartman
2022-02-14 13:43             ` Jason Gunthorpe
2022-02-14 13:43               ` Jason Gunthorpe via iommu
2022-02-15  3:06               ` Lu Baolu
2022-02-15  3:06                 ` Lu Baolu
2022-02-23 18:00   ` Bjorn Helgaas
2022-02-23 18:00     ` Bjorn Helgaas
2022-02-23 18:07     ` Jason Gunthorpe
2022-02-23 18:07       ` Jason Gunthorpe via iommu
2022-01-04  1:56 ` [PATCH v5 08/14] PCI: pci_stub: Suppress kernel DMA ownership auto-claiming Lu Baolu
2022-01-04  1:56   ` Lu Baolu
2022-01-04  1:56 ` [PATCH v5 09/14] PCI: portdrv: " Lu Baolu
2022-01-04  1:56   ` Lu Baolu
2022-01-04 17:06   ` Bjorn Helgaas
2022-01-04 17:06     ` Bjorn Helgaas
2022-01-04 19:26     ` Jason Gunthorpe
2022-01-04 19:26       ` Jason Gunthorpe via iommu
2022-01-04 19:51       ` Bjorn Helgaas
2022-01-04 19:51         ` Bjorn Helgaas
2022-01-05  0:35         ` Jason Gunthorpe
2022-01-05  0:35           ` Jason Gunthorpe via iommu
2022-01-06  4:12     ` Lu Baolu
2022-01-06  4:12       ` Lu Baolu
2022-01-06 18:32       ` Bjorn Helgaas
2022-01-06 18:32         ` Bjorn Helgaas
2022-01-07  1:53         ` Lu Baolu
2022-01-07  1:53           ` Lu Baolu
2022-01-04  1:56 ` [PATCH v5 10/14] vfio: Set DMA ownership for VFIO devices Lu Baolu
2022-01-04  1:56   ` Lu Baolu
2022-01-04  1:56 ` [PATCH v5 11/14] vfio: Remove use of vfio_group_viable() Lu Baolu
2022-01-04  1:56   ` Lu Baolu
2022-01-04  1:56 ` [PATCH v5 12/14] vfio: Delete the unbound_list Lu Baolu
2022-01-04  1:56   ` Lu Baolu
2022-01-04  1:56 ` [PATCH v5 13/14] vfio: Remove iommu group notifier Lu Baolu
2022-01-04  1:56   ` Lu Baolu
2022-01-04  1:56 ` [PATCH v5 14/14] iommu: Remove iommu group changes notifier Lu Baolu
2022-01-04  1:56   ` Lu Baolu
2022-01-04 12:48 ` [PATCH v5 00/14] Fix BUG_ON in vfio_iommu_group_notifier() Jason Gunthorpe
2022-01-04 12:48   ` Jason Gunthorpe via iommu
2022-01-05  6:52   ` Lu Baolu
2022-01-05  6:52     ` Lu Baolu
2022-02-18  1:07 ` Lu Baolu
2022-02-18  1:07   ` Lu Baolu

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.