@@ -221,7 +221,6 @@ struct iommufd_device *iommufd_device_bind(struct iommufd_ctx *ictx,
221
221
refcount_inc (& idev -> obj .users );
222
222
/* igroup refcount moves into iommufd_device */
223
223
idev -> igroup = igroup ;
224
- mutex_init (& idev -> iopf_lock );
225
224
226
225
/*
227
226
* If the caller fails after this success it must call
@@ -425,13 +424,35 @@ static int iommufd_hwpt_pasid_compat(struct iommufd_hw_pagetable *hwpt,
425
424
return 0 ;
426
425
}
427
426
427
+ static bool iommufd_hwpt_compatible_device (struct iommufd_hw_pagetable * hwpt ,
428
+ struct iommufd_device * idev )
429
+ {
430
+ struct pci_dev * pdev ;
431
+
432
+ if (!hwpt -> fault || !dev_is_pci (idev -> dev ))
433
+ return true;
434
+
435
+ /*
436
+ * Once we turn on PCI/PRI support for VF, the response failure code
437
+ * should not be forwarded to the hardware due to PRI being a shared
438
+ * resource between PF and VFs. There is no coordination for this
439
+ * shared capability. This waits for a vPRI reset to recover.
440
+ */
441
+ pdev = to_pci_dev (idev -> dev );
442
+
443
+ return (!pdev -> is_virtfn || !pci_pri_supported (pdev ));
444
+ }
445
+
428
446
static int iommufd_hwpt_attach_device (struct iommufd_hw_pagetable * hwpt ,
429
447
struct iommufd_device * idev ,
430
448
ioasid_t pasid )
431
449
{
432
450
struct iommufd_attach_handle * handle ;
433
451
int rc ;
434
452
453
+ if (!iommufd_hwpt_compatible_device (hwpt , idev ))
454
+ return - EINVAL ;
455
+
435
456
rc = iommufd_hwpt_pasid_compat (hwpt , idev , pasid );
436
457
if (rc )
437
458
return rc ;
@@ -440,12 +461,6 @@ static int iommufd_hwpt_attach_device(struct iommufd_hw_pagetable *hwpt,
440
461
if (!handle )
441
462
return - ENOMEM ;
442
463
443
- if (hwpt -> fault ) {
444
- rc = iommufd_fault_iopf_enable (idev );
445
- if (rc )
446
- goto out_free_handle ;
447
- }
448
-
449
464
handle -> idev = idev ;
450
465
if (pasid == IOMMU_NO_PASID )
451
466
rc = iommu_attach_group_handle (hwpt -> domain , idev -> igroup -> group ,
@@ -454,13 +469,10 @@ static int iommufd_hwpt_attach_device(struct iommufd_hw_pagetable *hwpt,
454
469
rc = iommu_attach_device_pasid (hwpt -> domain , idev -> dev , pasid ,
455
470
& handle -> handle );
456
471
if (rc )
457
- goto out_disable_iopf ;
472
+ goto out_free_handle ;
458
473
459
474
return 0 ;
460
475
461
- out_disable_iopf :
462
- if (hwpt -> fault )
463
- iommufd_fault_iopf_disable (idev );
464
476
out_free_handle :
465
477
kfree (handle );
466
478
return rc ;
@@ -492,10 +504,7 @@ static void iommufd_hwpt_detach_device(struct iommufd_hw_pagetable *hwpt,
492
504
else
493
505
iommu_detach_device_pasid (hwpt -> domain , idev -> dev , pasid );
494
506
495
- if (hwpt -> fault ) {
496
- iommufd_auto_response_faults (hwpt , handle );
497
- iommufd_fault_iopf_disable (idev );
498
- }
507
+ iommufd_auto_response_faults (hwpt , handle );
499
508
kfree (handle );
500
509
}
501
510
@@ -507,6 +516,9 @@ static int iommufd_hwpt_replace_device(struct iommufd_device *idev,
507
516
struct iommufd_attach_handle * handle , * old_handle ;
508
517
int rc ;
509
518
519
+ if (!iommufd_hwpt_compatible_device (hwpt , idev ))
520
+ return - EINVAL ;
521
+
510
522
rc = iommufd_hwpt_pasid_compat (hwpt , idev , pasid );
511
523
if (rc )
512
524
return rc ;
@@ -517,12 +529,6 @@ static int iommufd_hwpt_replace_device(struct iommufd_device *idev,
517
529
if (!handle )
518
530
return - ENOMEM ;
519
531
520
- if (hwpt -> fault && !old -> fault ) {
521
- rc = iommufd_fault_iopf_enable (idev );
522
- if (rc )
523
- goto out_free_handle ;
524
- }
525
-
526
532
handle -> idev = idev ;
527
533
if (pasid == IOMMU_NO_PASID )
528
534
rc = iommu_replace_group_handle (idev -> igroup -> group ,
@@ -531,20 +537,13 @@ static int iommufd_hwpt_replace_device(struct iommufd_device *idev,
531
537
rc = iommu_replace_device_pasid (hwpt -> domain , idev -> dev ,
532
538
pasid , & handle -> handle );
533
539
if (rc )
534
- goto out_disable_iopf ;
540
+ goto out_free_handle ;
535
541
536
- if (old -> fault ) {
537
- iommufd_auto_response_faults (hwpt , old_handle );
538
- if (!hwpt -> fault )
539
- iommufd_fault_iopf_disable (idev );
540
- }
542
+ iommufd_auto_response_faults (hwpt , old_handle );
541
543
kfree (old_handle );
542
544
543
545
return 0 ;
544
546
545
- out_disable_iopf :
546
- if (hwpt -> fault && !old -> fault )
547
- iommufd_fault_iopf_disable (idev );
548
547
out_free_handle :
549
548
kfree (handle );
550
549
return rc ;
0 commit comments