PCI/ATS: Add pci_pri_supported() to check device or associated PF
commit3f9a7a13fe
upstream. For SR-IOV, the PF PRI is shared between the PF and any associated VFs, and the PRI Capability is allowed for PFs but not for VFs. Searching for the PRI Capability on a VF always fails, even if its associated PF supports PRI. Add pci_pri_supported() to check whether device or its associated PF supports PRI. [bhelgaas: commit log, avoid "!!"] Fixes:b16d0cb9e2
("iommu/vt-d: Always enable PASID/PRI PCI capabilities before ATS") Link: https://lore.kernel.org/r/1595543849-19692-1-git-send-email-ashok.raj@intel.com Signed-off-by: Ashok Raj <ashok.raj@intel.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com> Acked-by: Joerg Roedel <jroedel@suse.de> Cc: stable@vger.kernel.org # v4.4+ Signed-off-by: Chen Zhuo <sagazchen@tencent.com> Signed-off-by: Xinghui Li <korantli@tencent.com>
This commit is contained in:
parent
8f212a1fc3
commit
bb83178d2c
|
@ -356,6 +356,7 @@ static int intel_iommu_strict;
|
|||
static int intel_iommu_superpage = 1;
|
||||
static int iommu_identity_mapping;
|
||||
static int intel_no_bounce;
|
||||
static int iommu_skip_te_disable;
|
||||
|
||||
#define IDENTMAP_GFX 2
|
||||
#define IDENTMAP_AZALIA 4
|
||||
|
@ -1633,6 +1634,10 @@ static void iommu_disable_translation(struct intel_iommu *iommu)
|
|||
u32 sts;
|
||||
unsigned long flag;
|
||||
|
||||
if (iommu_skip_te_disable && iommu->drhd->gfx_dedicated &&
|
||||
(cap_read_drain(iommu->cap) || cap_write_drain(iommu->cap)))
|
||||
return;
|
||||
|
||||
raw_spin_lock_irqsave(&iommu->register_lock, flag);
|
||||
iommu->gcmd &= ~DMA_GCMD_TE;
|
||||
writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG);
|
||||
|
@ -2564,7 +2569,7 @@ static struct dmar_domain *dmar_insert_one_dev_info(struct intel_iommu *iommu,
|
|||
}
|
||||
|
||||
if (info->ats_supported && ecap_prs(iommu->ecap) &&
|
||||
pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI))
|
||||
pci_pri_supported(pdev))
|
||||
info->pri_supported = 1;
|
||||
}
|
||||
}
|
||||
|
@ -4048,6 +4053,7 @@ static void __init init_no_remapping_devices(void)
|
|||
|
||||
/* This IOMMU has *only* gfx devices. Either bypass it or
|
||||
set the gfx_mapped flag, as appropriate */
|
||||
drhd->gfx_dedicated = 1;
|
||||
if (!dmar_map_gfx) {
|
||||
drhd->ignored = 1;
|
||||
for_each_active_dev_scope(drhd->devices,
|
||||
|
@ -6177,6 +6183,27 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0044, quirk_calpella_no_shadow_g
|
|||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0062, quirk_calpella_no_shadow_gtt);
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x006a, quirk_calpella_no_shadow_gtt);
|
||||
|
||||
static void quirk_igfx_skip_te_disable(struct pci_dev *dev)
|
||||
{
|
||||
unsigned short ver;
|
||||
|
||||
if (!IS_GFX_DEVICE(dev))
|
||||
return;
|
||||
|
||||
ver = (dev->device >> 8) & 0xff;
|
||||
if (ver != 0x45 && ver != 0x46 && ver != 0x4c &&
|
||||
ver != 0x4e && ver != 0x8a && ver != 0x98 &&
|
||||
ver != 0x9a)
|
||||
return;
|
||||
|
||||
if (risky_device(dev))
|
||||
return;
|
||||
|
||||
pci_info(dev, "Skip IOMMU disabling for graphics\n");
|
||||
iommu_skip_te_disable = 1;
|
||||
}
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, quirk_igfx_skip_te_disable);
|
||||
|
||||
/* On Tylersburg chipsets, some BIOSes have been known to enable the
|
||||
ISOCH DMAR unit for the Azalia sound device, but not give it any
|
||||
TLB entries, which causes it to deadlock. Check for that. We do
|
||||
|
|
|
@ -296,6 +296,21 @@ int pci_reset_pri(struct pci_dev *pdev)
|
|||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pci_reset_pri);
|
||||
|
||||
/**
|
||||
* pci_pri_supported - Check if PRI is supported.
|
||||
* @pdev: PCI device structure
|
||||
*
|
||||
* Returns true if PRI capability is present, false otherwise.
|
||||
*/
|
||||
bool pci_pri_supported(struct pci_dev *pdev)
|
||||
{
|
||||
/* VFs share the PF PRI */
|
||||
if (pci_physfn(pdev)->pri_cap)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pci_pri_supported);
|
||||
#endif /* CONFIG_PCI_PRI */
|
||||
|
||||
#ifdef CONFIG_PCI_PASID
|
||||
|
|
|
@ -48,6 +48,7 @@ struct dmar_drhd_unit {
|
|||
u16 segment; /* PCI domain */
|
||||
u8 ignored:1; /* ignore drhd */
|
||||
u8 include_all:1;
|
||||
u8 gfx_dedicated:1; /* graphic dedicated */
|
||||
struct intel_iommu *iommu;
|
||||
};
|
||||
|
||||
|
|
|
@ -10,9 +10,10 @@ int pci_enable_pri(struct pci_dev *pdev, u32 reqs);
|
|||
void pci_disable_pri(struct pci_dev *pdev);
|
||||
void pci_restore_pri_state(struct pci_dev *pdev);
|
||||
int pci_reset_pri(struct pci_dev *pdev);
|
||||
|
||||
bool pci_pri_supported(struct pci_dev *pdev);
|
||||
#else /* CONFIG_PCI_PRI */
|
||||
|
||||
static inline bool pci_pri_supported(struct pci_dev *pdev)
|
||||
{ return false; }
|
||||
static inline int pci_enable_pri(struct pci_dev *pdev, u32 reqs)
|
||||
{
|
||||
return -ENODEV;
|
||||
|
|
Loading…
Reference in New Issue