1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES 4 */ 5 #include <linux/generic_pt/iommu.h> 6 #include <linux/iommu.h> 7 #include "../iommu-pages.h" 8 #include "iommufd_private.h" 9 10 static const struct iommu_domain_ops noiommu_amdv1_ops; 11 12 struct noiommu_domain { 13 union { 14 struct iommu_domain domain; 15 struct pt_iommu_amdv1 amdv1; 16 }; 17 spinlock_t lock; 18 }; 19 PT_IOMMU_CHECK_DOMAIN(struct noiommu_domain, amdv1.iommu, domain); 20 21 static void noiommu_change_top(struct pt_iommu *iommu_table, 22 phys_addr_t top_paddr, unsigned int top_level) 23 { 24 } 25 26 static spinlock_t *noiommu_get_top_lock(struct pt_iommu *iommupt) 27 { 28 struct noiommu_domain *domain = 29 container_of(iommupt, struct noiommu_domain, amdv1.iommu); 30 31 return &domain->lock; 32 } 33 34 static const struct pt_iommu_driver_ops noiommu_driver_ops = { 35 .get_top_lock = noiommu_get_top_lock, 36 .change_top = noiommu_change_top, 37 }; 38 39 static struct iommu_domain * 40 noiommu_alloc_paging_flags(struct device *dev, u32 flags, 41 const struct iommu_user_data *user_data) 42 { 43 struct pt_iommu_amdv1_cfg cfg = {}; 44 struct noiommu_domain *dom; 45 int rc; 46 47 if (flags || user_data) 48 return ERR_PTR(-EOPNOTSUPP); 49 50 cfg.common.hw_max_vasz_lg2 = 64; 51 cfg.common.hw_max_oasz_lg2 = 52; 52 cfg.starting_level = 2; 53 cfg.common.features = 54 (BIT(PT_FEAT_DYNAMIC_TOP) | BIT(PT_FEAT_AMDV1_ENCRYPT_TABLES) | 55 BIT(PT_FEAT_AMDV1_FORCE_COHERENCE)); 56 57 dom = kzalloc(sizeof(*dom), GFP_KERNEL); 58 if (!dom) 59 return ERR_PTR(-ENOMEM); 60 61 spin_lock_init(&dom->lock); 62 dom->amdv1.iommu.nid = NUMA_NO_NODE; 63 dom->amdv1.iommu.driver_ops = &noiommu_driver_ops; 64 dom->domain.ops = &noiommu_amdv1_ops; 65 66 /* Use SW-only page table which is based on AMDV1 */ 67 rc = pt_iommu_amdv1_init(&dom->amdv1, &cfg, GFP_KERNEL); 68 if (rc) { 69 kfree(dom); 70 return ERR_PTR(rc); 71 } 72 73 return &dom->domain; 74 } 75 76 static void noiommu_domain_free(struct iommu_domain *iommu_domain) 77 { 78 struct noiommu_domain *domain = 79 container_of(iommu_domain, struct noiommu_domain, domain); 80 81 pt_iommu_deinit(&domain->amdv1.iommu); 82 kfree(domain); 83 } 84 85 static void noiommu_iotlb_sync(struct iommu_domain *domain, 86 struct iommu_iotlb_gather *gather) 87 { 88 iommu_put_pages_list(&gather->freelist); 89 } 90 91 /* 92 * Domain ops for iommufd no-IOMMU mode. Uses AMDV1 format as a 93 * SW-only IOPT because it has the best multi-page size options 94 * of all the formats. IOVAs serve only for IOVA-to-PA lookups, 95 * not for hardware DMA translation. 96 */ 97 static const struct iommu_domain_ops noiommu_amdv1_ops = { 98 IOMMU_PT_DOMAIN_OPS(amdv1), 99 .iotlb_sync = noiommu_iotlb_sync, 100 .free = noiommu_domain_free, 101 }; 102 103 const struct iommu_ops iommufd_noiommu_ops = { 104 .domain_alloc_paging_flags = noiommu_alloc_paging_flags, 105 }; 106