RE: [PATCH 1/1] iommu/vt-d: Skip TE disabling on quirky gfx dedicated iommu

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



> -----Original Message-----
> From: iommu <iommu-bounces@xxxxxxxxxxxxxxxxxxxxxxxxxx> On Behalf Of Lu
> Baolu
> Sent: Monday, July 20, 2020 7:17 PM
> To: Joerg Roedel
> Cc: Ashok Raj; linux-kernel@xxxxxxxxxxxxxxx; stable@xxxxxxxxxxxxxxx; Koba
> Ko; iommu@xxxxxxxxxxxxxxxxxxxxxxxxxx
> Subject: [PATCH 1/1] iommu/vt-d: Skip TE disabling on quirky gfx dedicated
> iommu
> 
> The VT-d spec requires (10.4.4 Global Command Register, TE field) that:
> 
> Hardware implementations supporting DMA draining must drain any in-flight
> DMA read/write requests queued within the Root-Complex before completing
> the translation enable command and reflecting the status of the command
> through the TES field in the Global Status register.
> 
> Unfortunately, some integrated graphic devices fail to do so after some
> kind of power state transition. As the result, the system might stuck in
> iommu_disable_translation(), waiting for the completion of TE transition.
> 
> This provides a quirk list for those devices and skips TE disabling if
> the qurik hits.
> 
> Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=208363
That one is for TGL.

I think you also want to add this one for ICL:
Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=206571

> Tested-by: Koba Ko <koba.ko@xxxxxxxxxxxxx>
> Cc: Ashok Raj <ashok.raj@xxxxxxxxx>
> Cc: stable@xxxxxxxxxxxxxxx
> Signed-off-by: Lu Baolu <baolu.lu@xxxxxxxxxxxxxxx>
> ---
>  drivers/iommu/intel/dmar.c  |  1 +
>  drivers/iommu/intel/iommu.c | 27 +++++++++++++++++++++++++++
>  include/linux/dmar.h        |  1 +
>  include/linux/intel-iommu.h |  2 ++
>  4 files changed, 31 insertions(+)
> 
> diff --git a/drivers/iommu/intel/dmar.c b/drivers/iommu/intel/dmar.c
> index 683b812c5c47..16f47041f1bf 100644
> --- a/drivers/iommu/intel/dmar.c
> +++ b/drivers/iommu/intel/dmar.c
> @@ -1102,6 +1102,7 @@ static int alloc_iommu(struct dmar_drhd_unit *drhd)
>  	}
> 
>  	drhd->iommu = iommu;
> +	iommu->drhd = drhd;
> 
>  	return 0;
> 
> diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
> index 98390a6d8113..11418b14cc3f 100644
> --- a/drivers/iommu/intel/iommu.c
> +++ b/drivers/iommu/intel/iommu.c
> @@ -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);
> @@ -4043,6 +4048,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,
> @@ -6160,6 +6166,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
> diff --git a/include/linux/dmar.h b/include/linux/dmar.h
> index d7bf029df737..65565820328a 100644
> --- a/include/linux/dmar.h
> +++ b/include/linux/dmar.h
> @@ -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;
>  };
> 
> diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h
> index bf6009a344f5..329629e1e9de 100644
> --- a/include/linux/intel-iommu.h
> +++ b/include/linux/intel-iommu.h
> @@ -600,6 +600,8 @@ struct intel_iommu {
>  	struct iommu_device iommu;  /* IOMMU core code handle */
>  	int		node;
>  	u32		flags;      /* Software defined flags */
> +
> +	struct dmar_drhd_unit *drhd;
>  };
> 
>  /* PCI domain-device relationship */
> --
> 2.17.1
> 
> _______________________________________________
> iommu mailing list
> iommu@xxxxxxxxxxxxxxxxxxxxxxxxxx
> https://lists.linuxfoundation.org/mailman/listinfo/iommu





[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux