@@ -364,7 +364,6 @@ static int iommu_skip_te_disable;
364
364
int intel_iommu_gfx_mapped ;
365
365
EXPORT_SYMBOL_GPL (intel_iommu_gfx_mapped );
366
366
367
- #define DUMMY_DEVICE_DOMAIN_INFO ((struct device_domain_info *)(-1))
368
367
#define DEFER_DEVICE_DOMAIN_INFO ((struct device_domain_info *)(-2))
369
368
struct device_domain_info * get_domain_info (struct device * dev )
370
369
{
@@ -374,8 +373,7 @@ struct device_domain_info *get_domain_info(struct device *dev)
374
373
return NULL ;
375
374
376
375
info = dev_iommu_priv_get (dev );
377
- if (unlikely (info == DUMMY_DEVICE_DOMAIN_INFO ||
378
- info == DEFER_DEVICE_DOMAIN_INFO ))
376
+ if (unlikely (info == DEFER_DEVICE_DOMAIN_INFO ))
379
377
return NULL ;
380
378
381
379
return info ;
@@ -742,11 +740,6 @@ struct context_entry *iommu_context_addr(struct intel_iommu *iommu, u8 bus,
742
740
return & context [devfn ];
743
741
}
744
742
745
- static int iommu_dummy (struct device * dev )
746
- {
747
- return dev_iommu_priv_get (dev ) == DUMMY_DEVICE_DOMAIN_INFO ;
748
- }
749
-
750
743
static bool attach_deferred (struct device * dev )
751
744
{
752
745
return dev_iommu_priv_get (dev ) == DEFER_DEVICE_DOMAIN_INFO ;
@@ -779,6 +772,53 @@ is_downstream_to_pci_bridge(struct device *dev, struct device *bridge)
779
772
return false;
780
773
}
781
774
775
+ static bool quirk_ioat_snb_local_iommu (struct pci_dev * pdev )
776
+ {
777
+ struct dmar_drhd_unit * drhd ;
778
+ u32 vtbar ;
779
+ int rc ;
780
+
781
+ /* We know that this device on this chipset has its own IOMMU.
782
+ * If we find it under a different IOMMU, then the BIOS is lying
783
+ * to us. Hope that the IOMMU for this device is actually
784
+ * disabled, and it needs no translation...
785
+ */
786
+ rc = pci_bus_read_config_dword (pdev -> bus , PCI_DEVFN (0 , 0 ), 0xb0 , & vtbar );
787
+ if (rc ) {
788
+ /* "can't" happen */
789
+ dev_info (& pdev -> dev , "failed to run vt-d quirk\n" );
790
+ return false;
791
+ }
792
+ vtbar &= 0xffff0000 ;
793
+
794
+ /* we know that the this iommu should be at offset 0xa000 from vtbar */
795
+ drhd = dmar_find_matched_drhd_unit (pdev );
796
+ if (!drhd || drhd -> reg_base_addr - vtbar != 0xa000 ) {
797
+ pr_warn_once (FW_BUG "BIOS assigned incorrect VT-d unit for Intel(R) QuickData Technology device\n" );
798
+ add_taint (TAINT_FIRMWARE_WORKAROUND , LOCKDEP_STILL_OK );
799
+ return true;
800
+ }
801
+
802
+ return false;
803
+ }
804
+
805
+ static bool iommu_is_dummy (struct intel_iommu * iommu , struct device * dev )
806
+ {
807
+ if (!iommu || iommu -> drhd -> ignored )
808
+ return true;
809
+
810
+ if (dev_is_pci (dev )) {
811
+ struct pci_dev * pdev = to_pci_dev (dev );
812
+
813
+ if (pdev -> vendor == PCI_VENDOR_ID_INTEL &&
814
+ pdev -> device == PCI_DEVICE_ID_INTEL_IOAT_SNB &&
815
+ quirk_ioat_snb_local_iommu (pdev ))
816
+ return true;
817
+ }
818
+
819
+ return false;
820
+ }
821
+
782
822
struct intel_iommu * device_to_iommu (struct device * dev , u8 * bus , u8 * devfn )
783
823
{
784
824
struct dmar_drhd_unit * drhd = NULL ;
@@ -788,7 +828,7 @@ struct intel_iommu *device_to_iommu(struct device *dev, u8 *bus, u8 *devfn)
788
828
u16 segment = 0 ;
789
829
int i ;
790
830
791
- if (!dev || iommu_dummy ( dev ) )
831
+ if (!dev )
792
832
return NULL ;
793
833
794
834
if (dev_is_pci (dev )) {
@@ -805,7 +845,7 @@ struct intel_iommu *device_to_iommu(struct device *dev, u8 *bus, u8 *devfn)
805
845
dev = & ACPI_COMPANION (dev )-> dev ;
806
846
807
847
rcu_read_lock ();
808
- for_each_active_iommu (iommu , drhd ) {
848
+ for_each_iommu (iommu , drhd ) {
809
849
if (pdev && segment != drhd -> segment )
810
850
continue ;
811
851
@@ -841,6 +881,9 @@ struct intel_iommu *device_to_iommu(struct device *dev, u8 *bus, u8 *devfn)
841
881
}
842
882
iommu = NULL ;
843
883
out :
884
+ if (iommu_is_dummy (iommu , dev ))
885
+ iommu = NULL ;
886
+
844
887
rcu_read_unlock ();
845
888
846
889
return iommu ;
@@ -2447,7 +2490,7 @@ struct dmar_domain *find_domain(struct device *dev)
2447
2490
{
2448
2491
struct device_domain_info * info ;
2449
2492
2450
- if (unlikely (attach_deferred (dev ) || iommu_dummy ( dev ) ))
2493
+ if (unlikely (attach_deferred (dev )))
2451
2494
return NULL ;
2452
2495
2453
2496
/* No lock here, assumes no domain exit in normal case */
@@ -3989,35 +4032,6 @@ static void __init iommu_exit_mempool(void)
3989
4032
iova_cache_put ();
3990
4033
}
3991
4034
3992
- static void quirk_ioat_snb_local_iommu (struct pci_dev * pdev )
3993
- {
3994
- struct dmar_drhd_unit * drhd ;
3995
- u32 vtbar ;
3996
- int rc ;
3997
-
3998
- /* We know that this device on this chipset has its own IOMMU.
3999
- * If we find it under a different IOMMU, then the BIOS is lying
4000
- * to us. Hope that the IOMMU for this device is actually
4001
- * disabled, and it needs no translation...
4002
- */
4003
- rc = pci_bus_read_config_dword (pdev -> bus , PCI_DEVFN (0 , 0 ), 0xb0 , & vtbar );
4004
- if (rc ) {
4005
- /* "can't" happen */
4006
- dev_info (& pdev -> dev , "failed to run vt-d quirk\n" );
4007
- return ;
4008
- }
4009
- vtbar &= 0xffff0000 ;
4010
-
4011
- /* we know that the this iommu should be at offset 0xa000 from vtbar */
4012
- drhd = dmar_find_matched_drhd_unit (pdev );
4013
- if (!drhd || drhd -> reg_base_addr - vtbar != 0xa000 ) {
4014
- pr_warn_once (FW_BUG "BIOS assigned incorrect VT-d unit for Intel(R) QuickData Technology device\n" );
4015
- add_taint (TAINT_FIRMWARE_WORKAROUND , LOCKDEP_STILL_OK );
4016
- dev_iommu_priv_set (& pdev -> dev , DUMMY_DEVICE_DOMAIN_INFO );
4017
- }
4018
- }
4019
- DECLARE_PCI_FIXUP_ENABLE (PCI_VENDOR_ID_INTEL , PCI_DEVICE_ID_INTEL_IOAT_SNB , quirk_ioat_snb_local_iommu );
4020
-
4021
4035
static void __init init_no_remapping_devices (void )
4022
4036
{
4023
4037
struct dmar_drhd_unit * drhd ;
@@ -4049,12 +4063,8 @@ static void __init init_no_remapping_devices(void)
4049
4063
/* This IOMMU has *only* gfx devices. Either bypass it or
4050
4064
set the gfx_mapped flag, as appropriate */
4051
4065
drhd -> gfx_dedicated = 1 ;
4052
- if (!dmar_map_gfx ) {
4066
+ if (!dmar_map_gfx )
4053
4067
drhd -> ignored = 1 ;
4054
- for_each_active_dev_scope (drhd -> devices ,
4055
- drhd -> devices_cnt , i , dev )
4056
- dev_iommu_priv_set (dev , DUMMY_DEVICE_DOMAIN_INFO );
4057
- }
4058
4068
}
4059
4069
}
4060
4070
0 commit comments