@@ -4244,6 +4244,37 @@ static int intel_iommu_enable_sva(struct device *dev)
4244
4244
return 0 ;
4245
4245
}
4246
4246
4247
+ static int context_flip_pri (struct device_domain_info * info , bool enable )
4248
+ {
4249
+ struct intel_iommu * iommu = info -> iommu ;
4250
+ u8 bus = info -> bus , devfn = info -> devfn ;
4251
+ struct context_entry * context ;
4252
+
4253
+ spin_lock (& iommu -> lock );
4254
+ if (context_copied (iommu , bus , devfn )) {
4255
+ spin_unlock (& iommu -> lock );
4256
+ return - EINVAL ;
4257
+ }
4258
+
4259
+ context = iommu_context_addr (iommu , bus , devfn , false);
4260
+ if (!context || !context_present (context )) {
4261
+ spin_unlock (& iommu -> lock );
4262
+ return - ENODEV ;
4263
+ }
4264
+
4265
+ if (enable )
4266
+ context_set_sm_pre (context );
4267
+ else
4268
+ context_clear_sm_pre (context );
4269
+
4270
+ if (!ecap_coherent (iommu -> ecap ))
4271
+ clflush_cache_range (context , sizeof (* context ));
4272
+ intel_context_flush_present (info , context , true);
4273
+ spin_unlock (& iommu -> lock );
4274
+
4275
+ return 0 ;
4276
+ }
4277
+
4247
4278
static int intel_iommu_enable_iopf (struct device * dev )
4248
4279
{
4249
4280
struct pci_dev * pdev = dev_is_pci (dev ) ? to_pci_dev (dev ) : NULL ;
@@ -4273,15 +4304,23 @@ static int intel_iommu_enable_iopf(struct device *dev)
4273
4304
if (ret )
4274
4305
return ret ;
4275
4306
4307
+ ret = context_flip_pri (info , true);
4308
+ if (ret )
4309
+ goto err_remove_device ;
4310
+
4276
4311
ret = pci_enable_pri (pdev , PRQ_DEPTH );
4277
- if (ret ) {
4278
- iopf_queue_remove_device (iommu -> iopf_queue , dev );
4279
- return ret ;
4280
- }
4312
+ if (ret )
4313
+ goto err_clear_pri ;
4281
4314
4282
4315
info -> pri_enabled = 1 ;
4283
4316
4284
4317
return 0 ;
4318
+ err_clear_pri :
4319
+ context_flip_pri (info , false);
4320
+ err_remove_device :
4321
+ iopf_queue_remove_device (iommu -> iopf_queue , dev );
4322
+
4323
+ return ret ;
4285
4324
}
4286
4325
4287
4326
static int intel_iommu_disable_iopf (struct device * dev )
@@ -4292,6 +4331,15 @@ static int intel_iommu_disable_iopf(struct device *dev)
4292
4331
if (!info -> pri_enabled )
4293
4332
return - EINVAL ;
4294
4333
4334
+ /* Disable new PRI reception: */
4335
+ context_flip_pri (info , false);
4336
+
4337
+ /*
4338
+ * Remove device from fault queue and acknowledge all outstanding
4339
+ * PRQs to the device:
4340
+ */
4341
+ iopf_queue_remove_device (iommu -> iopf_queue , dev );
4342
+
4295
4343
/*
4296
4344
* PCIe spec states that by clearing PRI enable bit, the Page
4297
4345
* Request Interface will not issue new page requests, but has
@@ -4302,7 +4350,6 @@ static int intel_iommu_disable_iopf(struct device *dev)
4302
4350
*/
4303
4351
pci_disable_pri (to_pci_dev (dev ));
4304
4352
info -> pri_enabled = 0 ;
4305
- iopf_queue_remove_device (iommu -> iopf_queue , dev );
4306
4353
4307
4354
return 0 ;
4308
4355
}
0 commit comments