blob: 6674d63fc0df27395f73a27d5e27669fcc09207c [file] [log] [blame]
From f0f2e1ff8a7b24c56879fa9302f98a3f81474e9c Mon Sep 17 00:00:00 2001
From: Bingbu Cao <bingbu.cao@intel.com>
Date: Thu, 5 Jan 2023 16:28:57 +0800
Subject: [PATCH] FROMLIST: iommu/vt-d: Use passthrough mode for the Intel IPUs
Intel IPU(Image Processing Unit) has its own (IO)MMU hardware,
The IPU driver allocates its own page table that is not mapped
via the DMA, and thus the Intel IOMMU driver blocks access giving
this error:
DMAR: DRHD: handling fault status reg 3
DMAR: [DMA Read] Request device [00:05.0] PASID ffffffff
fault addr 76406000 [fault reason 06] PTE Read access is not set
As IPU is not an external facing device which is not risky, so use
IOMMU passthrough mode for Intel IPUs.
Fixes: 26f5689592e2 ("media: staging/intel-ipu3: mmu: Implement driver")
Signed-off-by: Bingbu Cao <bingbu.cao@intel.com>
(am from https://patchwork.kernel.org/patch/13089529/)
(also found at https://lore.kernel.org/r/20230105082857.4180299-1-bingbu.cao@intel.com)
UPSTREAM-TASK=b:149068439
UPSTREAM-TASK=b:149068672
BUG=b:264596409
TEST=Sanity checked basic camera functions on Skolas and Brya
Change-Id: Icb203e1a958f3998536f16f50138918a800e9192
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/4153367
Tested-by: Tian Shu Qiu <tian.shu.qiu@intel.corp-partner.google.com>
Reviewed-by: Sergey Senozhatsky <senozhatsky@chromium.org>
Reviewed-by: Sean Paul <sean@poorly.run>
Commit-Queue: Sergey Senozhatsky <senozhatsky@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/4169799
Commit-Queue: Guenter Roeck <groeck@chromium.org>
Reviewed-by: Guenter Roeck <groeck@chromium.org>
Tested-by: Guenter Roeck <groeck@chromium.org>
---
drivers/iommu/intel/iommu.c | 33 +++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index 2e9811bf2a4e5573aa364ba11ed05f3dda474ce9..cffbd2b93c9dbc8dd7da6acaf734c9d9b38584f8 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -38,6 +38,15 @@
#define IS_GFX_DEVICE(pdev) ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY)
#define IS_USB_DEVICE(pdev) ((pdev->class >> 8) == PCI_CLASS_SERIAL_USB)
#define IS_ISA_DEVICE(pdev) ((pdev->class >> 8) == PCI_CLASS_BRIDGE_ISA)
+#define IS_INTEL_IPU(pdev) ((pdev)->vendor == PCI_VENDOR_ID_INTEL && \
+ ((pdev)->device == 0x9a19 || \
+ (pdev)->device == 0x9a39 || \
+ (pdev)->device == 0x4e19 || \
+ (pdev)->device == 0x465d || \
+ (pdev)->device == 0x462e || \
+ (pdev)->device == 0xa75d || \
+ (pdev)->device == 0x7d19 || \
+ (pdev)->device == 0x1919))
#define IS_AZALIA(pdev) ((pdev)->vendor == 0x8086 && (pdev)->device == 0x3a3e)
#define IOAPIC_RANGE_START (0xfee00000)
@@ -217,12 +226,14 @@ int intel_iommu_sm = IS_ENABLED(CONFIG_INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON);
int intel_iommu_enabled = 0;
EXPORT_SYMBOL_GPL(intel_iommu_enabled);
+static int dmar_map_ipu = 1;
static int intel_iommu_superpage = 1;
static int iommu_identity_mapping;
static int iommu_skip_te_disable;
static int disable_igfx_iommu;
#define IDENTMAP_AZALIA 4
+#define IDENTMAP_IPU 8
const struct iommu_ops intel_iommu_ops;
static const struct iommu_dirty_ops intel_dirty_ops;
@@ -2195,6 +2206,9 @@ static int device_def_domain_type(struct device *dev)
if ((iommu_identity_mapping & IDENTMAP_AZALIA) && IS_AZALIA(pdev))
return IOMMU_DOMAIN_IDENTITY;
+
+ if ((iommu_identity_mapping & IDENTMAP_IPU) && IS_INTEL_IPU(pdev))
+ return IOMMU_DOMAIN_IDENTITY;
}
return 0;
@@ -2495,6 +2509,10 @@ static int __init init_dmars(void)
iommu_set_root_entry(iommu);
}
+ if (!dmar_map_ipu)
+ iommu_identity_mapping |= IDENTMAP_IPU;
+
+
check_tylersburg_isoch();
ret = si_domain_init(hw_pass_through);
@@ -4617,6 +4635,18 @@ static void quirk_iommu_igfx(struct pci_dev *dev)
disable_igfx_iommu = 1;
}
+static void quirk_iommu_ipu(struct pci_dev *dev)
+{
+ if (!IS_INTEL_IPU(dev))
+ return;
+
+ if (risky_device(dev))
+ return;
+
+ pci_info(dev, "Passthrough IOMMU for integrated Intel IPU\n");
+ dmar_map_ipu = 0;
+}
+
/* G4x/GM45 integrated gfx dmar support is totally busted. */
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_igfx);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e00, quirk_iommu_igfx);
@@ -4652,6 +4682,9 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1632, quirk_iommu_igfx);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x163A, quirk_iommu_igfx);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x163D, quirk_iommu_igfx);
+/* make IPU dmar use identity mapping */
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, quirk_iommu_ipu);
+
static void quirk_iommu_rwbf(struct pci_dev *dev)
{
if (risky_device(dev))
--
2.45.1.288.g0e0cd299f1-goog