This patch is an initial step to replace Intel SVM code with the following IOMMU SVA ops: intel_svm_bind_mm() => iommu_sva_bind_device() intel_svm_unbind_mm() => iommu_sva_unbind_device() intel_svm_is_pasid_valid() => iommu_sva_get_pasid() The features below will continue to work but are not included in this patch in that they are handled mostly within the IOMMU subsystem. - IO page fault - mmu notifier Consolidation of the above will come after merging generic IOMMU sva code[1]. There should not be any changes needed for SVA users such as accelerator device drivers during this time. [1] http://jpbrucker.net/sva/
Showing the changes to include/linux (2 of 4 files). Show all
Unified · Split
| @@ -723,6 +723,10 @@ extern int intel_svm_finish_prq(struct intel_iommu *iommu); · 722 unmodified lines | ||
| 723 | 723 | int intel_svm_bind_gpasid(struct iommu_domain *domain, struct device *dev, |
| 724 | 724 | struct iommu_gpasid_bind_data *data); |
| 725 | 725 | int intel_svm_unbind_gpasid(struct device *dev, int pasid); |
| 726 | +struct iommu_sva *intel_svm_bind(struct device *dev, struct mm_struct *mm, | |
| 727 | + void *drvdata); | |
| 728 | +void intel_svm_unbind(struct iommu_sva *handle); | |
| 729 | +int intel_svm_get_pasid(struct iommu_sva *handle); | |
| 726 | 730 | struct svm_dev_ops; |
| 727 | 731 | |
| 728 | 732 | struct intel_svm_dev { |
| @@ -730,6 +734,8 @@ struct intel_svm_dev { · 1 unmodified line | ||
| 730 | 734 | struct rcu_head rcu; |
| 731 | 735 | struct device *dev; |
| 732 | 736 | struct svm_dev_ops *ops; |
| 737 | + struct iommu_sva sva; | |
| 738 | + int pasid; | |
| 733 | 739 | int users; |
| 734 | 740 | u16 did; |
| 735 | 741 | u16 dev_iotlb:1; |
| @@ -21,7 +21,6 @@ struct svm_dev_ops { · 20 unmodified lines | ||
| 21 | 21 | #define SVM_REQ_EXEC (1<<1) |
| 22 | 22 | #define SVM_REQ_PRIV (1<<0) |
| 23 | 23 | |
| 24 | − | |
| 25 | 24 | /* |
| 26 | 25 | * The SVM_FLAG_PRIVATE_PASID flag requests a PASID which is *not* the "main" |
| 27 | 26 | * PASID for the current process. Even if a PASID already exists, a new one |
| @@ -57,89 +56,4 @@ struct svm_dev_ops { · 29 unmodified lines | ||
| 57 | 56 | */ |
| 58 | 57 | #define SVM_FLAG_GUEST_PASID (1<<3) |
| 59 | 58 | |
| 60 | −#ifdef CONFIG_INTEL_IOMMU_SVM | |
| 61 | − | |
| 62 | −/** | |
| 63 | − * intel_svm_bind_mm() - Bind the current process to a PASID | |
| 64 | − * @dev: Device to be granted access | |
| 65 | − * @pasid: Address for allocated PASID | |
| 66 | − * @flags: Flags. Later for requesting supervisor mode, etc. | |
| 67 | − * @ops: Callbacks to device driver | |
| 68 | − * | |
| 69 | − * This function attempts to enable PASID support for the given device. | |
| 70 | − * If the @pasid argument is non-%NULL, a PASID is allocated for access | |
| 71 | − * to the MM of the current process. | |
| 72 | − * | |
| 73 | − * By using a %NULL value for the @pasid argument, this function can | |
| 74 | − * be used to simply validate that PASID support is available for the | |
| 75 | − * given device — i.e. that it is behind an IOMMU which has the | |
| 76 | − * requisite support, and is enabled. | |
| 77 | − * | |
| 78 | − * Page faults are handled transparently by the IOMMU code, and there | |
| 79 | − * should be no need for the device driver to be involved. If a page | |
| 80 | − * fault cannot be handled (i.e. is an invalid address rather than | |
| 81 | − * just needs paging in), then the page request will be completed by | |
| 82 | − * the core IOMMU code with appropriate status, and the device itself | |
| 83 | − * can then report the resulting fault to its driver via whatever | |
| 84 | − * mechanism is appropriate. | |
| 85 | − * | |
| 86 | − * Multiple calls from the same process may result in the same PASID | |
| 87 | − * being re-used. A reference count is kept. | |
| 88 | − */ | |
| 89 | −extern int intel_svm_bind_mm(struct device *dev, int *pasid, int flags, | |
| 90 | − struct svm_dev_ops *ops); | |
| 91 | − | |
| 92 | −/** | |
| 93 | − * intel_svm_unbind_mm() - Unbind a specified PASID | |
| 94 | − * @dev: Device for which PASID was allocated | |
| 95 | − * @pasid: PASID value to be unbound | |
| 96 | − * | |
| 97 | − * This function allows a PASID to be retired when the device no | |
| 98 | − * longer requires access to the address space of a given process. | |
| 99 | − * | |
| 100 | − * If the use count for the PASID in question reaches zero, the | |
| 101 | − * PASID is revoked and may no longer be used by hardware. | |
| 102 | − * | |
| 103 | − * Device drivers are required to ensure that no access (including | |
| 104 | − * page requests) is currently outstanding for the PASID in question, | |
| 105 | − * before calling this function. | |
| 106 | − */ | |
| 107 | −extern int intel_svm_unbind_mm(struct device *dev, int pasid); | |
| 108 | − | |
| 109 | −/** | |
| 110 | − * intel_svm_is_pasid_valid() - check if pasid is valid | |
| 111 | − * @dev: Device for which PASID was allocated | |
| 112 | − * @pasid: PASID value to be checked | |
| 113 | − * | |
| 114 | − * This function checks if the specified pasid is still valid. A | |
| 115 | − * valid pasid means the backing mm is still having a valid user. | |
| 116 | − * For kernel callers init_mm is always valid. for other mm, if mm->mm_users | |
| 117 | − * is non-zero, it is valid. | |
| 118 | − * | |
| 119 | − * returns -EINVAL if invalid pasid, 0 if pasid ref count is invalid | |
| 120 | − * 1 if pasid is valid. | |
| 121 | − */ | |
| 122 | −extern int intel_svm_is_pasid_valid(struct device *dev, int pasid); | |
| 123 | − | |
| 124 | −#else /* CONFIG_INTEL_IOMMU_SVM */ | |
| 125 | − | |
| 126 | −static inline int intel_svm_bind_mm(struct device *dev, int *pasid, | |
| 127 | − int flags, struct svm_dev_ops *ops) | |
| 128 | −{ | |
| 129 | − return -ENOSYS; | |
| 130 | −} | |
| 131 | − | |
| 132 | −static inline int intel_svm_unbind_mm(struct device *dev, int pasid) | |
| 133 | −{ | |
| 134 | − BUG(); | |
| 135 | −} | |
| 136 | − | |
| 137 | −static inline int intel_svm_is_pasid_valid(struct device *dev, int pasid) | |
| 138 | −{ | |
| 139 | − return -EINVAL; | |
| 140 | −} | |
| 141 | −#endif /* CONFIG_INTEL_IOMMU_SVM */ | |
| 142 | − | |
| 143 | −#define intel_svm_available(dev) (!intel_svm_bind_mm((dev), NULL, 0, NULL)) | |
| 144 | − | |
| 145 | 59 | #endif /* __INTEL_SVM_H__ */ |