Commit 2ccdd9f8 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'iommu-fixes-v5.9-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu

Pull iommu fixes from Joerg Roedel:

 - three Intel VT-d fixes to fix address handling on 32bit, fix a NULL
   pointer dereference bug and serialize a hardware register access as
   required by the VT-d spec.

 - two patches for AMD IOMMU to force AMD GPUs into translation mode
   when memory encryption is active and disallow using IOMMUv2
   functionality.  This makes the AMDGPU driver work when memory
   encryption is active.

 - two more fixes for AMD IOMMU to fix updating the Interrupt Remapping
   Table Entries.

 - MAINTAINERS file update for the Qualcom IOMMU driver.

* tag 'iommu-fixes-v5.9-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu:
  iommu/vt-d: Handle 36bit addressing for x86-32
  iommu/amd: Do not use IOMMUv2 functionality when SME is active
  iommu/amd: Do not force direct mapping when SME is active
  iommu/amd: Use cmpxchg_double() when updating 128-bit IRTE
  iommu/amd: Restore IRTE.RemapEn bit after programming IRTE
  iommu/vt-d: Fix NULL pointer dereference in dev_iommu_priv_set()
  iommu/vt-d: Serialize IOMMU GCMD register modifications
  MAINTAINERS: Update QUALCOMM IOMMU after Arm SMMU drivers move
parents 015b3155 29aaebbc
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -14388,7 +14388,7 @@ M: Rob Clark <robdclark@gmail.com>
L:	iommu@lists.linux-foundation.org
L:	linux-arm-msm@vger.kernel.org
S:	Maintained
F:	drivers/iommu/qcom_iommu.c
F:	drivers/iommu/arm/arm-smmu/qcom_iommu.c
QUALCOMM IPCC MAILBOX DRIVER
M:	Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+1 −1
Original line number Diff line number Diff line
@@ -10,7 +10,7 @@ config AMD_IOMMU
	select IOMMU_API
	select IOMMU_IOVA
	select IOMMU_DMA
	depends on X86_64 && PCI && ACPI
	depends on X86_64 && PCI && ACPI && HAVE_CMPXCHG_DOUBLE
	help
	  With this option you can enable support for AMD IOMMU hardware in
	  your system. An IOMMU is a hardware component which provides
+19 −2
Original line number Diff line number Diff line
@@ -1511,7 +1511,14 @@ static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h)
			iommu->mmio_phys_end = MMIO_REG_END_OFFSET;
		else
			iommu->mmio_phys_end = MMIO_CNTR_CONF_OFFSET;
		if (((h->efr_attr & (0x1 << IOMMU_FEAT_GASUP_SHIFT)) == 0))

		/*
		 * Note: GA (128-bit IRTE) mode requires cmpxchg16b supports.
		 * GAM also requires GA mode. Therefore, we need to
		 * check cmpxchg16b support before enabling it.
		 */
		if (!boot_cpu_has(X86_FEATURE_CX16) ||
		    ((h->efr_attr & (0x1 << IOMMU_FEAT_GASUP_SHIFT)) == 0))
			amd_iommu_guest_ir = AMD_IOMMU_GUEST_IR_LEGACY;
		break;
	case 0x11:
@@ -1520,8 +1527,18 @@ static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h)
			iommu->mmio_phys_end = MMIO_REG_END_OFFSET;
		else
			iommu->mmio_phys_end = MMIO_CNTR_CONF_OFFSET;
		if (((h->efr_reg & (0x1 << IOMMU_EFR_GASUP_SHIFT)) == 0))

		/*
		 * Note: GA (128-bit IRTE) mode requires cmpxchg16b supports.
		 * XT, GAM also requires GA mode. Therefore, we need to
		 * check cmpxchg16b support before enabling them.
		 */
		if (!boot_cpu_has(X86_FEATURE_CX16) ||
		    ((h->efr_reg & (0x1 << IOMMU_EFR_GASUP_SHIFT)) == 0)) {
			amd_iommu_guest_ir = AMD_IOMMU_GUEST_IR_LEGACY;
			break;
		}

		/*
		 * Note: Since iommu_update_intcapxt() leverages
		 * the IOMMU MMIO access to MSI capability block registers
+21 −5
Original line number Diff line number Diff line
@@ -2659,7 +2659,12 @@ static int amd_iommu_def_domain_type(struct device *dev)
	if (!dev_data)
		return 0;

	if (dev_data->iommu_v2)
	/*
	 * Do not identity map IOMMUv2 capable devices when memory encryption is
	 * active, because some of those devices (AMD GPUs) don't have the
	 * encryption bit in their DMA-mask and require remapping.
	 */
	if (!mem_encrypt_active() && dev_data->iommu_v2)
		return IOMMU_DOMAIN_IDENTITY;

	return 0;
@@ -3292,6 +3297,7 @@ out:
static int modify_irte_ga(u16 devid, int index, struct irte_ga *irte,
			  struct amd_ir_data *data)
{
	bool ret;
	struct irq_remap_table *table;
	struct amd_iommu *iommu;
	unsigned long flags;
@@ -3309,10 +3315,18 @@ static int modify_irte_ga(u16 devid, int index, struct irte_ga *irte,

	entry = (struct irte_ga *)table->table;
	entry = &entry[index];
	entry->lo.fields_remap.valid = 0;
	entry->hi.val = irte->hi.val;
	entry->lo.val = irte->lo.val;
	entry->lo.fields_remap.valid = 1;

	ret = cmpxchg_double(&entry->lo.val, &entry->hi.val,
			     entry->lo.val, entry->hi.val,
			     irte->lo.val, irte->hi.val);
	/*
	 * We use cmpxchg16 to atomically update the 128-bit IRTE,
	 * and it cannot be updated by the hardware or other processors
	 * behind us, so the return value of cmpxchg16 should be the
	 * same as the old value.
	 */
	WARN_ON(!ret);

	if (data)
		data->ref = entry;

@@ -3850,6 +3864,7 @@ int amd_iommu_deactivate_guest_mode(void *data)
	struct amd_ir_data *ir_data = (struct amd_ir_data *)data;
	struct irte_ga *entry = (struct irte_ga *) ir_data->entry;
	struct irq_cfg *cfg = ir_data->cfg;
	u64 valid = entry->lo.fields_remap.valid;

	if (!AMD_IOMMU_GUEST_IR_VAPIC(amd_iommu_guest_ir) ||
	    !entry || !entry->lo.fields_vapic.guest_mode)
@@ -3858,6 +3873,7 @@ int amd_iommu_deactivate_guest_mode(void *data)
	entry->lo.val = 0;
	entry->hi.val = 0;

	entry->lo.fields_remap.valid       = valid;
	entry->lo.fields_remap.dm          = apic->irq_dest_mode;
	entry->lo.fields_remap.int_type    = apic->irq_delivery_mode;
	entry->hi.fields.vector            = cfg->vector;
+7 −0
Original line number Diff line number Diff line
@@ -737,6 +737,13 @@ int amd_iommu_init_device(struct pci_dev *pdev, int pasids)

	might_sleep();

	/*
	 * When memory encryption is active the device is likely not in a
	 * direct-mapped domain. Forbid using IOMMUv2 functionality for now.
	 */
	if (mem_encrypt_active())
		return -ENODEV;

	if (!amd_iommu_v2_supported())
		return -ENODEV;

Loading