@@ -192,7 +192,6 @@ static void vhost_kernel_iotlb_read(void *opaque)
192
192
ssize_t len ;
193
193
194
194
while ((len = read ((uintptr_t )dev -> opaque , & msg , sizeof msg )) > 0 ) {
195
- struct vhost_iotlb_msg * imsg = & msg .iotlb ;
196
195
if (len < sizeof msg ) {
197
196
error_report ("Wrong vhost message len: %d" , (int )len );
198
197
break ;
@@ -201,70 +200,21 @@ static void vhost_kernel_iotlb_read(void *opaque)
201
200
error_report ("Unknown vhost iotlb message type" );
202
201
break ;
203
202
}
204
- switch (imsg -> type ) {
205
- case VHOST_IOTLB_MISS :
206
- vhost_device_iotlb_miss (dev , imsg -> iova ,
207
- imsg -> perm != VHOST_ACCESS_RO );
208
- break ;
209
- case VHOST_IOTLB_UPDATE :
210
- case VHOST_IOTLB_INVALIDATE :
211
- error_report ("Unexpected IOTLB message type" );
212
- break ;
213
- case VHOST_IOTLB_ACCESS_FAIL :
214
- /* FIXME: report device iotlb error */
215
- break ;
216
- default :
217
- break ;
218
- }
219
- }
220
- }
221
203
222
- static int vhost_kernel_update_device_iotlb (struct vhost_dev * dev ,
223
- uint64_t iova , uint64_t uaddr ,
224
- uint64_t len ,
225
- IOMMUAccessFlags perm )
226
- {
227
- struct vhost_msg msg ;
228
- msg .type = VHOST_IOTLB_MSG ;
229
- msg .iotlb .iova = iova ;
230
- msg .iotlb .uaddr = uaddr ;
231
- msg .iotlb .size = len ;
232
- msg .iotlb .type = VHOST_IOTLB_UPDATE ;
233
-
234
- switch (perm ) {
235
- case IOMMU_RO :
236
- msg .iotlb .perm = VHOST_ACCESS_RO ;
237
- break ;
238
- case IOMMU_WO :
239
- msg .iotlb .perm = VHOST_ACCESS_WO ;
240
- break ;
241
- case IOMMU_RW :
242
- msg .iotlb .perm = VHOST_ACCESS_RW ;
243
- break ;
244
- default :
245
- g_assert_not_reached ();
246
- }
247
-
248
- if (write ((uintptr_t )dev -> opaque , & msg , sizeof msg ) != sizeof msg ) {
249
- error_report ("Fail to update device iotlb" );
250
- return - EFAULT ;
204
+ vhost_backend_handle_iotlb_msg (dev , & msg .iotlb );
251
205
}
252
-
253
- return 0 ;
254
206
}
255
207
256
- static int vhost_kernel_invalidate_device_iotlb (struct vhost_dev * dev ,
257
- uint64_t iova , uint64_t len )
208
+ static int vhost_kernel_send_device_iotlb_msg (struct vhost_dev * dev ,
209
+ struct vhost_iotlb_msg * imsg )
258
210
{
259
211
struct vhost_msg msg ;
260
212
261
213
msg .type = VHOST_IOTLB_MSG ;
262
- msg .iotlb .iova = iova ;
263
- msg .iotlb .size = len ;
264
- msg .iotlb .type = VHOST_IOTLB_INVALIDATE ;
214
+ msg .iotlb = * imsg ;
265
215
266
216
if (write ((uintptr_t )dev -> opaque , & msg , sizeof msg ) != sizeof msg ) {
267
- error_report ("Fail to invalidate device iotlb" );
217
+ error_report ("Fail to update device iotlb" );
268
218
return - EFAULT ;
269
219
}
270
220
@@ -311,8 +261,7 @@ static const VhostOps kernel_ops = {
311
261
.vhost_vsock_set_running = vhost_kernel_vsock_set_running ,
312
262
#endif /* CONFIG_VHOST_VSOCK */
313
263
.vhost_set_iotlb_callback = vhost_kernel_set_iotlb_callback ,
314
- .vhost_update_device_iotlb = vhost_kernel_update_device_iotlb ,
315
- .vhost_invalidate_device_iotlb = vhost_kernel_invalidate_device_iotlb ,
264
+ .vhost_send_device_iotlb_msg = vhost_kernel_send_device_iotlb_msg ,
316
265
};
317
266
318
267
int vhost_set_backend_type (struct vhost_dev * dev , VhostBackendType backend_type )
@@ -333,3 +282,70 @@ int vhost_set_backend_type(struct vhost_dev *dev, VhostBackendType backend_type)
333
282
334
283
return r ;
335
284
}
285
+
286
+ int vhost_backend_update_device_iotlb (struct vhost_dev * dev ,
287
+ uint64_t iova , uint64_t uaddr ,
288
+ uint64_t len ,
289
+ IOMMUAccessFlags perm )
290
+ {
291
+ struct vhost_iotlb_msg imsg ;
292
+
293
+ imsg .iova = iova ;
294
+ imsg .uaddr = uaddr ;
295
+ imsg .size = len ;
296
+ imsg .type = VHOST_IOTLB_UPDATE ;
297
+
298
+ switch (perm ) {
299
+ case IOMMU_RO :
300
+ imsg .perm = VHOST_ACCESS_RO ;
301
+ break ;
302
+ case IOMMU_WO :
303
+ imsg .perm = VHOST_ACCESS_WO ;
304
+ break ;
305
+ case IOMMU_RW :
306
+ imsg .perm = VHOST_ACCESS_RW ;
307
+ break ;
308
+ default :
309
+ return - EINVAL ;
310
+ }
311
+
312
+ return dev -> vhost_ops -> vhost_send_device_iotlb_msg (dev , & imsg );
313
+ }
314
+
315
+ int vhost_backend_invalidate_device_iotlb (struct vhost_dev * dev ,
316
+ uint64_t iova , uint64_t len )
317
+ {
318
+ struct vhost_iotlb_msg imsg ;
319
+
320
+ imsg .iova = iova ;
321
+ imsg .size = len ;
322
+ imsg .type = VHOST_IOTLB_INVALIDATE ;
323
+
324
+ return dev -> vhost_ops -> vhost_send_device_iotlb_msg (dev , & imsg );
325
+ }
326
+
327
+ int vhost_backend_handle_iotlb_msg (struct vhost_dev * dev ,
328
+ struct vhost_iotlb_msg * imsg )
329
+ {
330
+ int ret = 0 ;
331
+
332
+ switch (imsg -> type ) {
333
+ case VHOST_IOTLB_MISS :
334
+ ret = vhost_device_iotlb_miss (dev , imsg -> iova ,
335
+ imsg -> perm != VHOST_ACCESS_RO );
336
+ break ;
337
+ case VHOST_IOTLB_ACCESS_FAIL :
338
+ /* FIXME: report device iotlb error */
339
+ error_report ("Access failure IOTLB message type not supported" );
340
+ ret = - ENOTSUP ;
341
+ break ;
342
+ case VHOST_IOTLB_UPDATE :
343
+ case VHOST_IOTLB_INVALIDATE :
344
+ default :
345
+ error_report ("Unexpected IOTLB message type" );
346
+ ret = - EINVAL ;
347
+ break ;
348
+ }
349
+
350
+ return ret ;
351
+ }
0 commit comments