| 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 |
| |