[RFC,10/42] iommu: Add new iommu op to create domains managed by KVM

Message ID 20231202092007.14026-1-yan.y.zhao@intel.com
State New
Headers
Series Sharing KVM TDP to IOMMU |

Commit Message

Yan Zhao Dec. 2, 2023, 9:20 a.m. UTC
  Introduce a new iommu_domain op to create domains managed by KVM through
IOMMUFD.

These domains have a few different properties compares to kernel owned
domains and user owned domains:

- They must not be PAGING domains. Page mapping/unmapping is controlled by
  KVM.

- They must be stage 2 mappings translating GPA to HPA.

- Paging structure allocation/free is not managed by IOMMU driver, but
  by KVM.

- TLBs flushes are notified by KVM.

The new op clearly says the domain is being created by IOMMUFD.
A driver specific structure to the meta data of paging structures from KVM
is passed in via the op param "data".

IOMMU drivers that cannot support VFIO/IOMMUFD should not support this op.

This new op for now is only supposed to be used by IOMMUFD, hence no
wrapper for it. IOMMUFD would call the callback directly. As for domain
free, IOMMUFD would use iommu_domain_free().

Signed-off-by: Yan Zhao <yan.y.zhao@intel.com>
---
 include/linux/iommu.h | 9 +++++++++
 1 file changed, 9 insertions(+)
  

Comments

Jason Gunthorpe Dec. 4, 2023, 3:09 p.m. UTC | #1
On Sat, Dec 02, 2023 at 05:20:07PM +0800, Yan Zhao wrote:
> @@ -522,6 +522,13 @@ __iommu_copy_struct_from_user_array(void *dst_data,
>   * @domain_alloc_paging: Allocate an iommu_domain that can be used for
>   *                       UNMANAGED, DMA, and DMA_FQ domain types.
>   * @domain_alloc_sva: Allocate an iommu_domain for Shared Virtual Addressing.
> + * @domain_alloc_kvm: Allocate an iommu domain with type IOMMU_DOMAIN_KVM.
> + *                    It's called by IOMMUFD and must fully initialize the new
> + *                    domain before return.
> + *                    The @data is of type "const void *" whose format is defined
> + *                    in kvm arch specific header "asm/kvm_exported_tdp.h".
> + *                    Unpon success, domain of type IOMMU_DOMAIN_KVM is returned.
> + *                    Upon failure, ERR_PTR is returned.
>   * @probe_device: Add device to iommu driver handling
>   * @release_device: Remove device from iommu driver handling
>   * @probe_finalize: Do final setup work after the device is added to an IOMMU
> @@ -564,6 +571,8 @@ struct iommu_ops {
>  	struct iommu_domain *(*domain_alloc_paging)(struct device *dev);
>  	struct iommu_domain *(*domain_alloc_sva)(struct device *dev,
>  						 struct mm_struct *mm);
> +	struct iommu_domain *(*domain_alloc_kvm)(struct device *dev, u32 flags,
> +						 const void *data);

This should pass in some kvm related struct here, it should not be
buried in data

Jason
  

Patch

diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 9ecee72e2d6c4..0ce23ee399d35 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -522,6 +522,13 @@  __iommu_copy_struct_from_user_array(void *dst_data,
  * @domain_alloc_paging: Allocate an iommu_domain that can be used for
  *                       UNMANAGED, DMA, and DMA_FQ domain types.
  * @domain_alloc_sva: Allocate an iommu_domain for Shared Virtual Addressing.
+ * @domain_alloc_kvm: Allocate an iommu domain with type IOMMU_DOMAIN_KVM.
+ *                    It's called by IOMMUFD and must fully initialize the new
+ *                    domain before return.
+ *                    The @data is of type "const void *" whose format is defined
+ *                    in kvm arch specific header "asm/kvm_exported_tdp.h".
+ *                    Unpon success, domain of type IOMMU_DOMAIN_KVM is returned.
+ *                    Upon failure, ERR_PTR is returned.
  * @probe_device: Add device to iommu driver handling
  * @release_device: Remove device from iommu driver handling
  * @probe_finalize: Do final setup work after the device is added to an IOMMU
@@ -564,6 +571,8 @@  struct iommu_ops {
 	struct iommu_domain *(*domain_alloc_paging)(struct device *dev);
 	struct iommu_domain *(*domain_alloc_sva)(struct device *dev,
 						 struct mm_struct *mm);
+	struct iommu_domain *(*domain_alloc_kvm)(struct device *dev, u32 flags,
+						 const void *data);
 
 	struct iommu_device *(*probe_device)(struct device *dev);
 	void (*release_device)(struct device *dev);