11
11
#include <linux/slab.h>
12
12
#include <linux/workqueue.h>
13
13
14
- #include "iommu-sva .h"
14
+ #include "iommu-priv .h"
15
15
16
- enum iommu_page_response_code
17
- iommu_sva_handle_mm (struct iommu_fault * fault , struct mm_struct * mm );
18
-
19
- static void iopf_free_group (struct iopf_group * group )
16
+ void iopf_free_group (struct iopf_group * group )
20
17
{
21
18
struct iopf_fault * iopf , * next ;
22
19
@@ -27,44 +24,7 @@ static void iopf_free_group(struct iopf_group *group)
27
24
28
25
kfree (group );
29
26
}
30
-
31
- static int iopf_complete_group (struct device * dev , struct iopf_fault * iopf ,
32
- enum iommu_page_response_code status )
33
- {
34
- struct iommu_page_response resp = {
35
- .pasid = iopf -> fault .prm .pasid ,
36
- .grpid = iopf -> fault .prm .grpid ,
37
- .code = status ,
38
- };
39
-
40
- if ((iopf -> fault .prm .flags & IOMMU_FAULT_PAGE_REQUEST_PASID_VALID ) &&
41
- (iopf -> fault .prm .flags & IOMMU_FAULT_PAGE_RESPONSE_NEEDS_PASID ))
42
- resp .flags = IOMMU_PAGE_RESP_PASID_VALID ;
43
-
44
- return iommu_page_response (dev , & resp );
45
- }
46
-
47
- static void iopf_handler (struct work_struct * work )
48
- {
49
- struct iopf_fault * iopf ;
50
- struct iopf_group * group ;
51
- enum iommu_page_response_code status = IOMMU_PAGE_RESP_SUCCESS ;
52
-
53
- group = container_of (work , struct iopf_group , work );
54
- list_for_each_entry (iopf , & group -> faults , list ) {
55
- /*
56
- * For the moment, errors are sticky: don't handle subsequent
57
- * faults in the group if there is an error.
58
- */
59
- if (status != IOMMU_PAGE_RESP_SUCCESS )
60
- break ;
61
-
62
- status = iommu_sva_handle_mm (& iopf -> fault , group -> domain -> mm );
63
- }
64
-
65
- iopf_complete_group (group -> dev , & group -> last_fault , status );
66
- iopf_free_group (group );
67
- }
27
+ EXPORT_SYMBOL_GPL (iopf_free_group );
68
28
69
29
static struct iommu_domain * get_domain_for_iopf (struct device * dev ,
70
30
struct iommu_fault * fault )
@@ -91,7 +51,7 @@ static struct iommu_domain *get_domain_for_iopf(struct device *dev,
91
51
}
92
52
93
53
/**
94
- * iommu_queue_iopf - IO Page Fault handler
54
+ * iommu_handle_iopf - IO Page Fault handler
95
55
* @fault: fault event
96
56
* @dev: struct device.
97
57
*
@@ -130,7 +90,7 @@ static struct iommu_domain *get_domain_for_iopf(struct device *dev,
130
90
*
131
91
* Return: 0 on success and <0 on error.
132
92
*/
133
- int iommu_queue_iopf (struct iommu_fault * fault , struct device * dev )
93
+ static int iommu_handle_iopf (struct iommu_fault * fault , struct device * dev )
134
94
{
135
95
int ret ;
136
96
struct iopf_group * group ;
@@ -212,18 +172,117 @@ int iommu_queue_iopf(struct iommu_fault *fault, struct device *dev)
212
172
}
213
173
return ret ;
214
174
}
215
- EXPORT_SYMBOL_GPL (iommu_queue_iopf );
216
175
217
- int iommu_sva_handle_iopf (struct iopf_group * group )
176
+ /**
177
+ * iommu_report_device_fault() - Report fault event to device driver
178
+ * @dev: the device
179
+ * @evt: fault event data
180
+ *
181
+ * Called by IOMMU drivers when a fault is detected, typically in a threaded IRQ
182
+ * handler. When this function fails and the fault is recoverable, it is the
183
+ * caller's responsibility to complete the fault.
184
+ *
185
+ * Return 0 on success, or an error.
186
+ */
187
+ int iommu_report_device_fault (struct device * dev , struct iopf_fault * evt )
218
188
{
219
- struct iommu_fault_param * fault_param = group -> dev -> iommu -> fault_param ;
189
+ struct dev_iommu * param = dev -> iommu ;
190
+ struct iopf_fault * evt_pending = NULL ;
191
+ struct iommu_fault_param * fparam ;
192
+ int ret = 0 ;
220
193
221
- INIT_WORK (& group -> work , iopf_handler );
222
- if (!queue_work (fault_param -> queue -> wq , & group -> work ))
223
- return - EBUSY ;
194
+ if (!param || !evt )
195
+ return - EINVAL ;
224
196
225
- return 0 ;
197
+ /* we only report device fault if there is a handler registered */
198
+ mutex_lock (& param -> lock );
199
+ fparam = param -> fault_param ;
200
+
201
+ if (evt -> fault .type == IOMMU_FAULT_PAGE_REQ &&
202
+ (evt -> fault .prm .flags & IOMMU_FAULT_PAGE_REQUEST_LAST_PAGE )) {
203
+ evt_pending = kmemdup (evt , sizeof (struct iopf_fault ),
204
+ GFP_KERNEL );
205
+ if (!evt_pending ) {
206
+ ret = - ENOMEM ;
207
+ goto done_unlock ;
208
+ }
209
+ mutex_lock (& fparam -> lock );
210
+ list_add_tail (& evt_pending -> list , & fparam -> faults );
211
+ mutex_unlock (& fparam -> lock );
212
+ }
213
+
214
+ ret = iommu_handle_iopf (& evt -> fault , dev );
215
+ if (ret && evt_pending ) {
216
+ mutex_lock (& fparam -> lock );
217
+ list_del (& evt_pending -> list );
218
+ mutex_unlock (& fparam -> lock );
219
+ kfree (evt_pending );
220
+ }
221
+ done_unlock :
222
+ mutex_unlock (& param -> lock );
223
+ return ret ;
224
+ }
225
+ EXPORT_SYMBOL_GPL (iommu_report_device_fault );
226
+
227
+ int iommu_page_response (struct device * dev ,
228
+ struct iommu_page_response * msg )
229
+ {
230
+ bool needs_pasid ;
231
+ int ret = - EINVAL ;
232
+ struct iopf_fault * evt ;
233
+ struct iommu_fault_page_request * prm ;
234
+ struct dev_iommu * param = dev -> iommu ;
235
+ const struct iommu_ops * ops = dev_iommu_ops (dev );
236
+ bool has_pasid = msg -> flags & IOMMU_PAGE_RESP_PASID_VALID ;
237
+
238
+ if (!ops -> page_response )
239
+ return - ENODEV ;
240
+
241
+ if (!param || !param -> fault_param )
242
+ return - EINVAL ;
243
+
244
+ /* Only send response if there is a fault report pending */
245
+ mutex_lock (& param -> fault_param -> lock );
246
+ if (list_empty (& param -> fault_param -> faults )) {
247
+ dev_warn_ratelimited (dev , "no pending PRQ, drop response\n" );
248
+ goto done_unlock ;
249
+ }
250
+ /*
251
+ * Check if we have a matching page request pending to respond,
252
+ * otherwise return -EINVAL
253
+ */
254
+ list_for_each_entry (evt , & param -> fault_param -> faults , list ) {
255
+ prm = & evt -> fault .prm ;
256
+ if (prm -> grpid != msg -> grpid )
257
+ continue ;
258
+
259
+ /*
260
+ * If the PASID is required, the corresponding request is
261
+ * matched using the group ID, the PASID valid bit and the PASID
262
+ * value. Otherwise only the group ID matches request and
263
+ * response.
264
+ */
265
+ needs_pasid = prm -> flags & IOMMU_FAULT_PAGE_RESPONSE_NEEDS_PASID ;
266
+ if (needs_pasid && (!has_pasid || msg -> pasid != prm -> pasid ))
267
+ continue ;
268
+
269
+ if (!needs_pasid && has_pasid ) {
270
+ /* No big deal, just clear it. */
271
+ msg -> flags &= ~IOMMU_PAGE_RESP_PASID_VALID ;
272
+ msg -> pasid = 0 ;
273
+ }
274
+
275
+ ret = ops -> page_response (dev , evt , msg );
276
+ list_del (& evt -> list );
277
+ kfree (evt );
278
+ break ;
279
+ }
280
+
281
+ done_unlock :
282
+ mutex_unlock (& param -> fault_param -> lock );
283
+ return ret ;
226
284
}
285
+ EXPORT_SYMBOL_GPL (iommu_page_response );
227
286
228
287
/**
229
288
* iopf_queue_flush_dev - Ensure that all queued faults have been processed
@@ -258,6 +317,31 @@ int iopf_queue_flush_dev(struct device *dev)
258
317
}
259
318
EXPORT_SYMBOL_GPL (iopf_queue_flush_dev );
260
319
320
+ /**
321
+ * iopf_group_response - Respond a group of page faults
322
+ * @group: the group of faults with the same group id
323
+ * @status: the response code
324
+ *
325
+ * Return 0 on success and <0 on error.
326
+ */
327
+ int iopf_group_response (struct iopf_group * group ,
328
+ enum iommu_page_response_code status )
329
+ {
330
+ struct iopf_fault * iopf = & group -> last_fault ;
331
+ struct iommu_page_response resp = {
332
+ .pasid = iopf -> fault .prm .pasid ,
333
+ .grpid = iopf -> fault .prm .grpid ,
334
+ .code = status ,
335
+ };
336
+
337
+ if ((iopf -> fault .prm .flags & IOMMU_FAULT_PAGE_REQUEST_PASID_VALID ) &&
338
+ (iopf -> fault .prm .flags & IOMMU_FAULT_PAGE_RESPONSE_NEEDS_PASID ))
339
+ resp .flags = IOMMU_PAGE_RESP_PASID_VALID ;
340
+
341
+ return iommu_page_response (group -> dev , & resp );
342
+ }
343
+ EXPORT_SYMBOL_GPL (iopf_group_response );
344
+
261
345
/**
262
346
* iopf_queue_discard_partial - Remove all pending partial fault
263
347
* @queue: the queue whose partial faults need to be discarded
0 commit comments