Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,7 @@ ForEachMacros:
- 'for_each_prop_dlc_cpus'
- 'for_each_prop_dlc_platforms'
- 'for_each_property_of_node'
- 'for_each_pt_level_entry'
- 'for_each_rdt_resource'
- 'for_each_reg'
- 'for_each_reg_filtered'
Expand Down
89 changes: 87 additions & 2 deletions Documentation/driver-api/vfio.rst
Original file line number Diff line number Diff line change
Expand Up @@ -275,8 +275,6 @@ in a VFIO group.
With CONFIG_VFIO_DEVICE_CDEV=y the user can now acquire a device fd
by directly opening a character device /dev/vfio/devices/vfioX where
"X" is the number allocated uniquely by VFIO for registered devices.
cdev interface does not support noiommu devices, so user should use
the legacy group interface if noiommu is wanted.

The cdev only works with IOMMUFD. Both VFIO drivers and applications
must adapt to the new cdev security model which requires using
Expand Down Expand Up @@ -370,6 +368,93 @@ IOMMUFD IOAS/HWPT to enable userspace DMA::

/* Other device operations as stated in "VFIO Usage Example" */

VFIO NOIOMMU mode
-------------------------------------------------------------------------------
VFIO also supports a no-IOMMU mode, intended for usages where unsafe DMA can
be performed by userspace drivers w/o physical IOMMU protection. This mode
is controlled by the parameter:

/sys/module/vfio/parameters/enable_unsafe_noiommu_mode

Upon enabling this mode, with an assigned device, the user will be presented
with a VFIO group and device file, e.g.::

/dev/vfio/
|-- devices
| `-- noiommu-vfioX /* VFIO device cdev */
|-- noiommu-Y /* VFIO group */
`-- vfio

The capabilities vary depending on the device programming interface and kernel
configuration used. The following table summarizes the differences ("Yes" means
the UAPI is accessible and functional in noiommu mode, "No" means the UAPI is
not supported):

+-------------------+---------------------+----------------------+
| Feature | VFIO group | VFIO device cdev |
+===================+=====================+======================+
| VFIO device UAPI | Yes | Yes |
+-------------------+---------------------+----------------------+
| VFIO container | No | No |
+-------------------+---------------------+----------------------+
| IOMMUFD IOAS | No | Yes* |
+-------------------+---------------------+----------------------+

Note that the VFIO container case includes IOMMUFD provided VFIO compatibility
interfaces when either CONFIG_VFIO_CONTAINER or CONFIG_IOMMUFD_VFIO_CONTAINER is
enabled.

* IOMMUFD UAPI is available for VFIO device cdev to pin and map user memory with
the ability to retrieve physical addresses for DMA command submission.

Kconfig Support Matrix
^^^^^^^^^^^^^^^^^^^^^^

The visibility of CONFIG_VFIO_NOIOMMU depends on the combination of
CONFIG_VFIO_GROUP, CONFIG_VFIO_DEVICE_CDEV, and whether a container backend
(CONFIG_VFIO_CONTAINER or CONFIG_IOMMUFD_VFIO_CONTAINER) is configured. The
Kconfig dependencies enforce the following constraints:

- At least one access path (group or cdev) must be available.
- If VFIO_GROUP is enabled, a container backend is required; otherwise the
group node would be unusable in noiommu mode.
- The cdev noiommu path requires CONFIG_GENERIC_ATOMIC64=n because it depends
on CONFIG_IOMMUFD_NOIOMMU.

The resulting support matrix:

+------+-------+-----------+------+---------+---------------------------+
| Case | GROUP | Container | CDEV | NOIOMMU | Notes |
+======+=======+===========+======+=========+===========================+
| 1 | y | y | n | yes | Group noiommu works |
+------+-------+-----------+------+---------+---------------------------+
| 2 | y | n | n | no | Blocked - no container |
+------+-------+-----------+------+---------+---------------------------+
| 3 | y | y | y | yes | Both paths work [#cdev]_ |
+------+-------+-----------+------+---------+---------------------------+
| 4 | y | n | y | no | Blocked - no container |
+------+-------+-----------+------+---------+---------------------------+
| 5 | n | - | y | yes | Cdev-only works [#cdev]_ |
+------+-------+-----------+------+---------+---------------------------+
| 6 | n | - | n | no | No access path |
+------+-------+-----------+------+---------+---------------------------+

Container = CONFIG_VFIO_CONTAINER or CONFIG_IOMMUFD_VFIO_CONTAINER (either
suffices). Case 4 is intentionally blocked: allowing NOIOMMU with GROUP
enabled but no container would create unusable group nodes. Users who want
cdev-only noiommu should set CONFIG_VFIO_GROUP=n (case 5).

.. [#cdev] The cdev noiommu path requires CONFIG_GENERIC_ATOMIC64=n. When
CONFIG_VFIO_GROUP=y, CONFIG_VFIO_DEVICE_CDEV=y, and
CONFIG_GENERIC_ATOMIC64=y, CONFIG_VFIO_NOIOMMU remains selectable for the
group path, but no noiommu device cdev is registered. Cdev-only noiommu is
not selectable on those platforms.

A new IOMMUFD ioctl IOMMU_IOAS_NOIOMMU_GET_PA is added to retrieve the physical
address for a given IOVA. Although there is no physical DMA remapping hardware,
IOMMU_IOAS_MAP_FIXED_IOVA is still used to establish IOVA-to-PA mappings in the
software page table for later IOMMU_IOAS_NOIOMMU_GET_PA lookups.

VFIO User API
-------------------------------------------------------------------------------

Expand Down
30 changes: 29 additions & 1 deletion Microsoft/hcl-arm64.config
Original file line number Diff line number Diff line change
Expand Up @@ -1521,6 +1521,7 @@ CONFIG_UIO=y
# CONFIG_UIO_MF624 is not set
CONFIG_UIO_HV_GENERIC=y
CONFIG_VFIO=y
CONFIG_VFIO_DEVICE_CDEV=y
CONFIG_VFIO_GROUP=y
CONFIG_VFIO_CONTAINER=y
CONFIG_VFIO_IOMMU_TYPE1=y
Expand Down Expand Up @@ -1612,8 +1613,33 @@ CONFIG_ARM_ARCH_TIMER=y
# end of Clock Source drivers

# CONFIG_MAILBOX is not set
CONFIG_IOMMU_IOVA=y
CONFIG_IOMMU_API=y
# CONFIG_IOMMU_SUPPORT is not set
CONFIG_IOMMU_SUPPORT=y

#
# Generic IOMMU Pagetable Support
#
# CONFIG_IOMMU_IO_PGTABLE_LPAE is not set
# CONFIG_IOMMU_IO_PGTABLE_ARMV7S is not set
# CONFIG_IOMMU_IO_PGTABLE_DART is not set
# end of Generic IOMMU Pagetable Support

CONFIG_IOMMU_DEFAULT_DMA_STRICT=y
# CONFIG_IOMMU_DEFAULT_DMA_LAZY is not set
# CONFIG_IOMMU_DEFAULT_PASSTHROUGH is not set
CONFIG_OF_IOMMU=y
CONFIG_IOMMU_DMA=y
# CONFIG_ARM_SMMU is not set
# CONFIG_ARM_SMMU_V3 is not set
CONFIG_IOMMUFD_DRIVER_CORE=y
CONFIG_IOMMUFD=y
CONFIG_IOMMUFD_NOIOMMU=y
# CONFIG_VIRTIO_IOMMU is not set
CONFIG_GENERIC_PT=y
# CONFIG_DEBUG_GENERIC_PT is not set
CONFIG_IOMMU_PT=y
CONFIG_IOMMU_PT_AMDV1=y

#
# Remoteproc drivers
Expand Down Expand Up @@ -2195,11 +2221,13 @@ CONFIG_ZLIB_INFLATE=y
CONFIG_DECOMPRESS_GZIP=y
CONFIG_GENERIC_ALLOCATOR=y
CONFIG_INTERVAL_TREE=y
CONFIG_INTERVAL_TREE_SPAN_ITER=y
CONFIG_XARRAY_MULTI=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_IOPORT_MAP=y
CONFIG_HAS_DMA=y
CONFIG_DMA_OPS_HELPERS=y
CONFIG_NEED_SG_DMA_FLAGS=y
CONFIG_NEED_SG_DMA_LENGTH=y
CONFIG_NEED_DMA_MAP_STATE=y
Expand Down
29 changes: 27 additions & 2 deletions Microsoft/hcl-x64.config
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# Automatically generated file; DO NOT EDIT.
# Linux/x86_64 6.18.37 Kernel Configuration
#
CONFIG_CC_VERSION_TEXT="gcc (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0"
CONFIG_CC_VERSION_TEXT="gcc (Ubuntu 13.3.0-6ubuntu2~24.04.1) 13.3.0"
CONFIG_CC_IS_GCC=y
CONFIG_GCC_VERSION=130300
CONFIG_CLANG_VERSION=0
Expand Down Expand Up @@ -1501,6 +1501,7 @@ CONFIG_UIO=y
# CONFIG_UIO_MF624 is not set
CONFIG_UIO_HV_GENERIC=y
CONFIG_VFIO=y
CONFIG_VFIO_DEVICE_CDEV=y
CONFIG_VFIO_GROUP=y
CONFIG_VFIO_CONTAINER=y
CONFIG_VFIO_IOMMU_TYPE1=y
Expand Down Expand Up @@ -1574,8 +1575,29 @@ CONFIG_CLKBLD_I8253=y
# end of Clock Source drivers

# CONFIG_MAILBOX is not set
CONFIG_IOMMU_IOVA=y
CONFIG_IOMMU_API=y
# CONFIG_IOMMU_SUPPORT is not set
CONFIG_IOMMU_SUPPORT=y

#
# Generic IOMMU Pagetable Support
#
# end of Generic IOMMU Pagetable Support

# CONFIG_IOMMU_DEFAULT_DMA_STRICT is not set
CONFIG_IOMMU_DEFAULT_DMA_LAZY=y
# CONFIG_IOMMU_DEFAULT_PASSTHROUGH is not set
CONFIG_OF_IOMMU=y
CONFIG_IOMMU_DMA=y
CONFIG_IOMMUFD_DRIVER_CORE=y
CONFIG_IOMMUFD=y
CONFIG_IOMMUFD_NOIOMMU=y
CONFIG_HYPERV_IOMMU=y
# CONFIG_VIRTIO_IOMMU is not set
CONFIG_GENERIC_PT=y
# CONFIG_DEBUG_GENERIC_PT is not set
CONFIG_IOMMU_PT=y
CONFIG_IOMMU_PT_AMDV1=y

#
# Remoteproc drivers
Expand Down Expand Up @@ -2142,11 +2164,14 @@ CONFIG_ZLIB_INFLATE=y
# CONFIG_XZ_DEC is not set
CONFIG_DECOMPRESS_GZIP=y
CONFIG_INTERVAL_TREE=y
CONFIG_INTERVAL_TREE_SPAN_ITER=y
CONFIG_XARRAY_MULTI=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_IOPORT_MAP=y
CONFIG_HAS_DMA=y
CONFIG_DMA_OPS_HELPERS=y
CONFIG_NEED_SG_DMA_FLAGS=y
CONFIG_NEED_SG_DMA_LENGTH=y
CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_ARCH_DMA_ADDR_T_64BIT=y
Expand Down
2 changes: 2 additions & 0 deletions drivers/iommu/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -384,3 +384,5 @@ config SPRD_IOMMU
Say Y here if you want to use the multimedia devices listed above.

endif # IOMMU_SUPPORT

source "drivers/iommu/generic_pt/Kconfig"
1 change: 1 addition & 0 deletions drivers/iommu/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ obj-y += arm/ iommufd/
obj-$(CONFIG_AMD_IOMMU) += amd/
obj-$(CONFIG_INTEL_IOMMU) += intel/
obj-$(CONFIG_RISCV_IOMMU) += riscv/
obj-$(CONFIG_GENERIC_PT) += generic_pt/fmt/
obj-$(CONFIG_IOMMU_API) += iommu.o
obj-$(CONFIG_IOMMU_SUPPORT) += iommu-pages.o
obj-$(CONFIG_IOMMU_API) += iommu-traces.o
Expand Down
45 changes: 45 additions & 0 deletions drivers/iommu/generic_pt/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# SPDX-License-Identifier: GPL-2.0-only

menuconfig GENERIC_PT
bool "Generic Radix Page Table"
help
Generic library for building radix tree page tables.

Generic PT provides a set of HW page table formats and a common
set of APIs to work with them.

if GENERIC_PT
config DEBUG_GENERIC_PT
bool "Extra debugging checks for GENERIC_PT"
help
Enable extra run time debugging checks for GENERIC_PT code. This
incurs a runtime cost and should not be enabled for production
kernels.

The kunit tests require this to be enabled to get full coverage.

config IOMMU_PT
tristate "IOMMU Page Tables"
select IOMMU_API
depends on IOMMU_SUPPORT
depends on GENERIC_PT
help
Generic library for building IOMMU page tables

IOMMU_PT provides an implementation of the page table operations
related to struct iommu_domain using GENERIC_PT. It provides a single
implementation of the page table operations that can be shared by
multiple drivers.

if IOMMU_PT
config IOMMU_PT_AMDV1
tristate "IOMMU page table for 64-bit AMD IOMMU v1"
depends on !GENERIC_ATOMIC64 # for cmpxchg64
help
iommu_domain implementation for the AMD v1 page table. AMDv1 is the
"host" page table. It supports granular page sizes of almost every
power of 2 and decodes an full 64-bit IOVA space.

Selected automatically by an IOMMU driver that uses this format.
endif
endif
11 changes: 11 additions & 0 deletions drivers/iommu/generic_pt/fmt/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# SPDX-License-Identifier: GPL-2.0

iommu_pt_fmt-$(CONFIG_IOMMU_PT_AMDV1) += amdv1

define create_format
obj-$(2) += iommu_$(1).o

endef

$(eval $(foreach fmt,$(iommu_pt_fmt-y),$(call create_format,$(fmt),y)))
$(eval $(foreach fmt,$(iommu_pt_fmt-m),$(call create_format,$(fmt),m)))
Loading
Loading