Skip to content

Commit 97f2f2c

Browse files
yianchen2018joergroedel
authored andcommitted
iommu/vt-d: Enable ATS for the devices in SATC table
Starting from Intel VT-d v3.2, Intel platform BIOS can provide additional SATC table structure. SATC table includes a list of SoC integrated devices that support ATC (Address translation cache). Enabling ATC (via ATS capability) can be a functional requirement for SATC device operation or optional to enhance device performance/functionality. This is determined by the bit of ATC_REQUIRED in SATC table. When IOMMU is working in scalable mode, software chooses to always enable ATS for every device in SATC table because Intel SoC devices in SATC table are trusted to use ATS. On the other hand, if IOMMU is in legacy mode, ATS of SATC capable devices can work transparently to software and be automatically enabled by IOMMU hardware. As the result, there is no need for software to enable ATS on these devices. This also removes dmar_find_matched_atsr_unit() helper as it becomes dead code now. Signed-off-by: Yian Chen <yian.chen@intel.com> Link: https://lore.kernel.org/r/20220222185416.1722611-1-yian.chen@intel.com Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com> Link: https://lore.kernel.org/r/20220301020159.633356-13-baolu.lu@linux.intel.com Signed-off-by: Joerg Roedel <jroedel@suse.de>
1 parent b897a1b commit 97f2f2c

2 files changed

Lines changed: 38 additions & 3 deletions

File tree

drivers/iommu/intel/iommu.c

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3693,16 +3693,52 @@ static void intel_iommu_free_dmars(void)
36933693
}
36943694
}
36953695

3696-
int dmar_find_matched_atsr_unit(struct pci_dev *dev)
3696+
static struct dmar_satc_unit *dmar_find_matched_satc_unit(struct pci_dev *dev)
3697+
{
3698+
struct dmar_satc_unit *satcu;
3699+
struct acpi_dmar_satc *satc;
3700+
struct device *tmp;
3701+
int i;
3702+
3703+
dev = pci_physfn(dev);
3704+
rcu_read_lock();
3705+
3706+
list_for_each_entry_rcu(satcu, &dmar_satc_units, list) {
3707+
satc = container_of(satcu->hdr, struct acpi_dmar_satc, header);
3708+
if (satc->segment != pci_domain_nr(dev->bus))
3709+
continue;
3710+
for_each_dev_scope(satcu->devices, satcu->devices_cnt, i, tmp)
3711+
if (to_pci_dev(tmp) == dev)
3712+
goto out;
3713+
}
3714+
satcu = NULL;
3715+
out:
3716+
rcu_read_unlock();
3717+
return satcu;
3718+
}
3719+
3720+
static int dmar_ats_supported(struct pci_dev *dev, struct intel_iommu *iommu)
36973721
{
36983722
int i, ret = 1;
36993723
struct pci_bus *bus;
37003724
struct pci_dev *bridge = NULL;
37013725
struct device *tmp;
37023726
struct acpi_dmar_atsr *atsr;
37033727
struct dmar_atsr_unit *atsru;
3728+
struct dmar_satc_unit *satcu;
37043729

37053730
dev = pci_physfn(dev);
3731+
satcu = dmar_find_matched_satc_unit(dev);
3732+
if (satcu)
3733+
/*
3734+
* This device supports ATS as it is in SATC table.
3735+
* When IOMMU is in legacy mode, enabling ATS is done
3736+
* automatically by HW for the device that requires
3737+
* ATS, hence OS should not enable this device ATS
3738+
* to avoid duplicated TLB invalidation.
3739+
*/
3740+
return !(satcu->atc_required && !sm_supported(iommu));
3741+
37063742
for (bus = dev->bus; bus; bus = bus->parent) {
37073743
bridge = bus->self;
37083744
/* If it's an integrated device, allow ATS */
@@ -4550,7 +4586,7 @@ static struct iommu_device *intel_iommu_probe_device(struct device *dev)
45504586
if (dev_is_pci(dev)) {
45514587
if (ecap_dev_iotlb_support(iommu->ecap) &&
45524588
pci_ats_supported(pdev) &&
4553-
dmar_find_matched_atsr_unit(pdev))
4589+
dmar_ats_supported(pdev, iommu))
45544590
info->ats_supported = 1;
45554591

45564592
if (sm_supported(iommu)) {

include/linux/intel-iommu.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -693,7 +693,6 @@ static inline int nr_pte_to_next_page(struct dma_pte *pte)
693693
}
694694

695695
extern struct dmar_drhd_unit * dmar_find_matched_drhd_unit(struct pci_dev *dev);
696-
extern int dmar_find_matched_atsr_unit(struct pci_dev *dev);
697696

698697
extern int dmar_enable_qi(struct intel_iommu *iommu);
699698
extern void dmar_disable_qi(struct intel_iommu *iommu);

0 commit comments

Comments
 (0)