1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) 2025 Advanced Micro Devices, Inc. 4 */ 5 6 #include <linux/iommu.h> 7 8 #include "iommufd.h" 9 #include "amd_iommu.h" 10 #include "amd_iommu_types.h" 11 12 static const struct iommufd_viommu_ops amd_viommu_ops; 13 14 void *amd_iommufd_hw_info(struct device *dev, u32 *length, enum iommu_hw_info_type *type) 15 { 16 struct iommu_hw_info_amd *hwinfo; 17 18 if (*type != IOMMU_HW_INFO_TYPE_DEFAULT && 19 *type != IOMMU_HW_INFO_TYPE_AMD) 20 return ERR_PTR(-EOPNOTSUPP); 21 22 hwinfo = kzalloc_obj(*hwinfo); 23 if (!hwinfo) 24 return ERR_PTR(-ENOMEM); 25 26 *length = sizeof(*hwinfo); 27 *type = IOMMU_HW_INFO_TYPE_AMD; 28 29 hwinfo->efr = amd_iommu_efr; 30 hwinfo->efr2 = amd_iommu_efr2; 31 32 return hwinfo; 33 } 34 35 size_t amd_iommufd_get_viommu_size(struct device *dev, enum iommu_viommu_type viommu_type) 36 { 37 return VIOMMU_STRUCT_SIZE(struct amd_iommu_viommu, core); 38 } 39 40 int amd_iommufd_viommu_init(struct iommufd_viommu *viommu, struct iommu_domain *parent, 41 const struct iommu_user_data *user_data) 42 { 43 unsigned long flags; 44 struct protection_domain *pdom = to_pdomain(parent); 45 struct amd_iommu_viommu *aviommu = container_of(viommu, struct amd_iommu_viommu, core); 46 47 xa_init_flags(&aviommu->gdomid_array, XA_FLAGS_ALLOC1); 48 aviommu->parent = pdom; 49 50 viommu->ops = &amd_viommu_ops; 51 52 spin_lock_irqsave(&pdom->lock, flags); 53 list_add(&aviommu->pdom_list, &pdom->viommu_list); 54 spin_unlock_irqrestore(&pdom->lock, flags); 55 56 return 0; 57 } 58 59 static void amd_iommufd_viommu_destroy(struct iommufd_viommu *viommu) 60 { 61 unsigned long flags; 62 struct amd_iommu_viommu *aviommu = container_of(viommu, struct amd_iommu_viommu, core); 63 struct protection_domain *pdom = aviommu->parent; 64 65 spin_lock_irqsave(&pdom->lock, flags); 66 list_del(&aviommu->pdom_list); 67 spin_unlock_irqrestore(&pdom->lock, flags); 68 xa_destroy(&aviommu->gdomid_array); 69 } 70 71 /* 72 * See include/linux/iommufd.h 73 * struct iommufd_viommu_ops - vIOMMU specific operations 74 */ 75 static const struct iommufd_viommu_ops amd_viommu_ops = { 76 .destroy = amd_iommufd_viommu_destroy, 77 }; 78