| .. | .. |
|---|
| 1 | +/* SPDX-License-Identifier: GPL-2.0-only */ |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright © 2015 Intel Corporation. |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Authors: David Woodhouse <David.Woodhouse@intel.com> |
|---|
| 5 | | - * |
|---|
| 6 | | - * This program is free software; you can redistribute it and/or modify it |
|---|
| 7 | | - * under the terms and conditions of the GNU General Public License, |
|---|
| 8 | | - * version 2, as published by the Free Software Foundation. |
|---|
| 9 | | - * |
|---|
| 10 | | - * This program is distributed in the hope it will be useful, but WITHOUT |
|---|
| 11 | | - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|---|
| 12 | | - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
|---|
| 13 | | - * more details. |
|---|
| 14 | 6 | */ |
|---|
| 15 | 7 | |
|---|
| 16 | 8 | #ifndef __INTEL_SVM_H__ |
|---|
| .. | .. |
|---|
| 19 | 11 | struct device; |
|---|
| 20 | 12 | |
|---|
| 21 | 13 | struct svm_dev_ops { |
|---|
| 22 | | - void (*fault_cb)(struct device *dev, int pasid, u64 address, |
|---|
| 23 | | - u32 private, int rwxp, int response); |
|---|
| 14 | + void (*fault_cb)(struct device *dev, u32 pasid, u64 address, |
|---|
| 15 | + void *private, int rwxp, int response); |
|---|
| 24 | 16 | }; |
|---|
| 25 | 17 | |
|---|
| 26 | 18 | /* Values for rxwp in fault_cb callback */ |
|---|
| .. | .. |
|---|
| 28 | 20 | #define SVM_REQ_WRITE (1<<2) |
|---|
| 29 | 21 | #define SVM_REQ_EXEC (1<<1) |
|---|
| 30 | 22 | #define SVM_REQ_PRIV (1<<0) |
|---|
| 31 | | - |
|---|
| 32 | 23 | |
|---|
| 33 | 24 | /* |
|---|
| 34 | 25 | * The SVM_FLAG_PRIVATE_PASID flag requests a PASID which is *not* the "main" |
|---|
| .. | .. |
|---|
| 52 | 43 | * do such IOTLB flushes automatically. |
|---|
| 53 | 44 | */ |
|---|
| 54 | 45 | #define SVM_FLAG_SUPERVISOR_MODE (1<<1) |
|---|
| 55 | | - |
|---|
| 56 | | -#ifdef CONFIG_INTEL_IOMMU_SVM |
|---|
| 57 | | - |
|---|
| 58 | | -/** |
|---|
| 59 | | - * intel_svm_bind_mm() - Bind the current process to a PASID |
|---|
| 60 | | - * @dev: Device to be granted acccess |
|---|
| 61 | | - * @pasid: Address for allocated PASID |
|---|
| 62 | | - * @flags: Flags. Later for requesting supervisor mode, etc. |
|---|
| 63 | | - * @ops: Callbacks to device driver |
|---|
| 64 | | - * |
|---|
| 65 | | - * This function attempts to enable PASID support for the given device. |
|---|
| 66 | | - * If the @pasid argument is non-%NULL, a PASID is allocated for access |
|---|
| 67 | | - * to the MM of the current process. |
|---|
| 68 | | - * |
|---|
| 69 | | - * By using a %NULL value for the @pasid argument, this function can |
|---|
| 70 | | - * be used to simply validate that PASID support is available for the |
|---|
| 71 | | - * given device — i.e. that it is behind an IOMMU which has the |
|---|
| 72 | | - * requisite support, and is enabled. |
|---|
| 73 | | - * |
|---|
| 74 | | - * Page faults are handled transparently by the IOMMU code, and there |
|---|
| 75 | | - * should be no need for the device driver to be involved. If a page |
|---|
| 76 | | - * fault cannot be handled (i.e. is an invalid address rather than |
|---|
| 77 | | - * just needs paging in), then the page request will be completed by |
|---|
| 78 | | - * the core IOMMU code with appropriate status, and the device itself |
|---|
| 79 | | - * can then report the resulting fault to its driver via whatever |
|---|
| 80 | | - * mechanism is appropriate. |
|---|
| 81 | | - * |
|---|
| 82 | | - * Multiple calls from the same process may result in the same PASID |
|---|
| 83 | | - * being re-used. A reference count is kept. |
|---|
| 46 | +/* |
|---|
| 47 | + * The SVM_FLAG_GUEST_MODE flag is used when a PASID bind is for guest |
|---|
| 48 | + * processes. Compared to the host bind, the primary differences are: |
|---|
| 49 | + * 1. mm life cycle management |
|---|
| 50 | + * 2. fault reporting |
|---|
| 84 | 51 | */ |
|---|
| 85 | | -extern int intel_svm_bind_mm(struct device *dev, int *pasid, int flags, |
|---|
| 86 | | - struct svm_dev_ops *ops); |
|---|
| 87 | | - |
|---|
| 88 | | -/** |
|---|
| 89 | | - * intel_svm_unbind_mm() - Unbind a specified PASID |
|---|
| 90 | | - * @dev: Device for which PASID was allocated |
|---|
| 91 | | - * @pasid: PASID value to be unbound |
|---|
| 92 | | - * |
|---|
| 93 | | - * This function allows a PASID to be retired when the device no |
|---|
| 94 | | - * longer requires access to the address space of a given process. |
|---|
| 95 | | - * |
|---|
| 96 | | - * If the use count for the PASID in question reaches zero, the |
|---|
| 97 | | - * PASID is revoked and may no longer be used by hardware. |
|---|
| 98 | | - * |
|---|
| 99 | | - * Device drivers are required to ensure that no access (including |
|---|
| 100 | | - * page requests) is currently outstanding for the PASID in question, |
|---|
| 101 | | - * before calling this function. |
|---|
| 52 | +#define SVM_FLAG_GUEST_MODE (1<<2) |
|---|
| 53 | +/* |
|---|
| 54 | + * The SVM_FLAG_GUEST_PASID flag is used when a guest has its own PASID space, |
|---|
| 55 | + * which requires guest and host PASID translation at both directions. |
|---|
| 102 | 56 | */ |
|---|
| 103 | | -extern int intel_svm_unbind_mm(struct device *dev, int pasid); |
|---|
| 104 | | - |
|---|
| 105 | | -/** |
|---|
| 106 | | - * intel_svm_is_pasid_valid() - check if pasid is valid |
|---|
| 107 | | - * @dev: Device for which PASID was allocated |
|---|
| 108 | | - * @pasid: PASID value to be checked |
|---|
| 109 | | - * |
|---|
| 110 | | - * This function checks if the specified pasid is still valid. A |
|---|
| 111 | | - * valid pasid means the backing mm is still having a valid user. |
|---|
| 112 | | - * For kernel callers init_mm is always valid. for other mm, if mm->mm_users |
|---|
| 113 | | - * is non-zero, it is valid. |
|---|
| 114 | | - * |
|---|
| 115 | | - * returns -EINVAL if invalid pasid, 0 if pasid ref count is invalid |
|---|
| 116 | | - * 1 if pasid is valid. |
|---|
| 117 | | - */ |
|---|
| 118 | | -extern int intel_svm_is_pasid_valid(struct device *dev, int pasid); |
|---|
| 119 | | - |
|---|
| 120 | | -#else /* CONFIG_INTEL_IOMMU_SVM */ |
|---|
| 121 | | - |
|---|
| 122 | | -static inline int intel_svm_bind_mm(struct device *dev, int *pasid, |
|---|
| 123 | | - int flags, struct svm_dev_ops *ops) |
|---|
| 124 | | -{ |
|---|
| 125 | | - return -ENOSYS; |
|---|
| 126 | | -} |
|---|
| 127 | | - |
|---|
| 128 | | -static inline int intel_svm_unbind_mm(struct device *dev, int pasid) |
|---|
| 129 | | -{ |
|---|
| 130 | | - BUG(); |
|---|
| 131 | | -} |
|---|
| 132 | | - |
|---|
| 133 | | -static inline int intel_svm_is_pasid_valid(struct device *dev, int pasid) |
|---|
| 134 | | -{ |
|---|
| 135 | | - return -EINVAL; |
|---|
| 136 | | -} |
|---|
| 137 | | -#endif /* CONFIG_INTEL_IOMMU_SVM */ |
|---|
| 138 | | - |
|---|
| 139 | | -#define intel_svm_available(dev) (!intel_svm_bind_mm((dev), NULL, 0, NULL)) |
|---|
| 57 | +#define SVM_FLAG_GUEST_PASID (1<<3) |
|---|
| 140 | 58 | |
|---|
| 141 | 59 | #endif /* __INTEL_SVM_H__ */ |
|---|