Commit 42f0cbb2 authored by Joerg Roedel's avatar Joerg Roedel
Browse files

Merge branches 'intel/vt-d', 'amd/amd-vi' and 'iommufd/arm-smmuv3-nested' into next

Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -1218,6 +1218,17 @@ static bool iort_pci_rc_supports_ats(struct acpi_iort_node *node)
	return pci_rc->ats_attribute & ACPI_IORT_ATS_SUPPORTED;
}

static bool iort_pci_rc_supports_canwbs(struct acpi_iort_node *node)
{
	struct acpi_iort_memory_access *memory_access;
	struct acpi_iort_root_complex *pci_rc;

	pci_rc = (struct acpi_iort_root_complex *)node->node_data;
	memory_access =
		(struct acpi_iort_memory_access *)&pci_rc->memory_properties;
	return memory_access->memory_flags & ACPI_IORT_MF_CANWBS;
}

static int iort_iommu_xlate(struct device *dev, struct acpi_iort_node *node,
			    u32 streamid)
{
@@ -1335,6 +1346,8 @@ int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
		fwspec = dev_iommu_fwspec_get(dev);
		if (fwspec && iort_pci_rc_supports_ats(node))
			fwspec->flags |= IOMMU_FWSPEC_PCI_RC_ATS;
		if (fwspec && iort_pci_rc_supports_canwbs(node))
			fwspec->flags |= IOMMU_FWSPEC_PCI_RC_CANWBS;
	} else {
		node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
				      iort_match_node_callback, dev);
+9 −0
Original line number Diff line number Diff line
@@ -416,6 +416,15 @@ config ARM_SMMU_V3_SVA
	  Say Y here if your system supports SVA extensions such as PCIe PASID
	  and PRI.

config ARM_SMMU_V3_IOMMUFD
	bool "Enable IOMMUFD features for ARM SMMUv3 (EXPERIMENTAL)"
	depends on IOMMUFD
	help
	  Support for IOMMUFD features intended to support virtual machines
	  with accelerated virtual IOMMUs.

	  Say Y here if you are doing development and testing on this feature.

config ARM_SMMU_V3_KUNIT_TEST
	tristate "KUnit tests for arm-smmu-v3 driver"  if !KUNIT_ALL_TESTS
	depends on KUNIT
+2 −1
Original line number Diff line number Diff line
@@ -53,7 +53,8 @@ struct iommu_domain *amd_iommu_domain_alloc_sva(struct device *dev,
						struct mm_struct *mm);
void amd_iommu_domain_free(struct iommu_domain *dom);
int iommu_sva_set_dev_pasid(struct iommu_domain *domain,
			    struct device *dev, ioasid_t pasid);
			    struct device *dev, ioasid_t pasid,
			    struct iommu_domain *old);
void amd_iommu_remove_dev_pasid(struct device *dev, ioasid_t pasid,
				struct iommu_domain *domain);

+11 −12
Original line number Diff line number Diff line
@@ -565,6 +565,12 @@ struct pdom_dev_data {
	struct list_head list;
};

/* Keeps track of the IOMMUs attached to protection domain */
struct pdom_iommu_info {
	struct amd_iommu *iommu; /* IOMMUs attach to protection domain */
	u32 refcnt;	/* Count of attached dev/pasid per domain/IOMMU */
};

/*
 * This structure contains generic data for  IOMMU protection domains
 * independent of their use.
@@ -578,8 +584,7 @@ struct protection_domain {
	u16 id;			/* the domain id written to the device table */
	enum protection_domain_mode pd_mode; /* Track page table type */
	bool dirty_tracking;	/* dirty tracking is enabled in the domain */
	unsigned dev_cnt;	/* devices assigned to this domain */
	unsigned dev_iommu[MAX_IOMMUS]; /* per-IOMMU reference count */
	struct xarray iommu_array;	/* per-IOMMU reference count */

	struct mmu_notifier mn;	/* mmu notifier for the SVA domain */
	struct list_head dev_data_list; /* List of pdom_dev_data */
@@ -831,7 +836,7 @@ struct devid_map {
 */
struct iommu_dev_data {
	/*Protect against attach/detach races */
	spinlock_t lock;
	struct mutex mutex;

	struct list_head list;		  /* For domain->dev_list */
	struct llist_node dev_data_list;  /* For global dev_data_list */
@@ -872,12 +877,6 @@ extern struct list_head amd_iommu_pci_seg_list;
 */
extern struct list_head amd_iommu_list;

/*
 * Array with pointers to each IOMMU struct
 * The indices are referenced in the protection domains
 */
extern struct amd_iommu *amd_iommus[MAX_IOMMUS];

/*
 * Structure defining one entry in the device table
 */
@@ -912,14 +911,14 @@ struct unity_map_entry {
/* size of the dma_ops aperture as power of 2 */
extern unsigned amd_iommu_aperture_order;

/* allocation bitmap for domain ids */
extern unsigned long *amd_iommu_pd_alloc_bitmap;

extern bool amd_iommu_force_isolation;

/* Max levels of glxval supported */
extern int amd_iommu_max_glx_val;

/* IDA to track protection domain IDs */
extern struct ida pdom_ids;

/* Global EFR and EFR2 registers */
extern u64 amd_iommu_efr;
extern u64 amd_iommu_efr2;
+9 −36
Original line number Diff line number Diff line
@@ -177,9 +177,6 @@ LIST_HEAD(amd_iommu_pci_seg_list); /* list of all PCI segments */
LIST_HEAD(amd_iommu_list);		/* list of all AMD IOMMUs in the
					   system */

/* Array to assign indices to IOMMUs*/
struct amd_iommu *amd_iommus[MAX_IOMMUS];

/* Number of IOMMUs present in the system */
static int amd_iommus_present;

@@ -194,12 +191,6 @@ bool amd_iommu_force_isolation __read_mostly;

unsigned long amd_iommu_pgsize_bitmap __ro_after_init = AMD_IOMMU_PGSIZES;

/*
 * AMD IOMMU allows up to 2^16 different protection domains. This is a bitmap
 * to know which ones are already in use.
 */
unsigned long *amd_iommu_pd_alloc_bitmap;

enum iommu_init_state {
	IOMMU_START_STATE,
	IOMMU_IVRS_DETECTED,
@@ -1082,7 +1073,12 @@ static bool __copy_device_table(struct amd_iommu *iommu)
		if (dte_v && dom_id) {
			pci_seg->old_dev_tbl_cpy[devid].data[0] = old_devtb[devid].data[0];
			pci_seg->old_dev_tbl_cpy[devid].data[1] = old_devtb[devid].data[1];
			__set_bit(dom_id, amd_iommu_pd_alloc_bitmap);
			/* Reserve the Domain IDs used by previous kernel */
			if (ida_alloc_range(&pdom_ids, dom_id, dom_id, GFP_ATOMIC) != dom_id) {
				pr_err("Failed to reserve domain ID 0x%x\n", dom_id);
				memunmap(old_devtb);
				return false;
			}
			/* If gcr3 table existed, mask it out */
			if (old_devtb[devid].data[0] & DTE_FLAG_GV) {
				tmp = DTE_GCR3_VAL_B(~0ULL) << DTE_GCR3_SHIFT_B;
@@ -1744,9 +1740,6 @@ static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h,
		return -ENOSYS;
	}

	/* Index is fine - add IOMMU to the array */
	amd_iommus[iommu->index] = iommu;

	/*
	 * Copy data from ACPI table entry to the iommu struct
	 */
@@ -2877,11 +2870,6 @@ static void enable_iommus_vapic(void)
#endif
}

static void enable_iommus(void)
{
	early_enable_iommus();
}

static void disable_iommus(void)
{
	struct amd_iommu *iommu;
@@ -2908,7 +2896,8 @@ static void amd_iommu_resume(void)
		iommu_apply_resume_quirks(iommu);

	/* re-load the hardware */
	enable_iommus();
	for_each_iommu(iommu)
		early_enable_iommu(iommu);

	amd_iommu_enable_interrupts();
}
@@ -2989,9 +2978,7 @@ static bool __init check_ioapic_information(void)

static void __init free_dma_resources(void)
{
	iommu_free_pages(amd_iommu_pd_alloc_bitmap,
			 get_order(MAX_DOMAIN_ID / 8));
	amd_iommu_pd_alloc_bitmap = NULL;
	ida_destroy(&pdom_ids);

	free_unity_maps();
}
@@ -3059,20 +3046,6 @@ static int __init early_amd_iommu_init(void)
	amd_iommu_target_ivhd_type = get_highest_supported_ivhd_type(ivrs_base);
	DUMP_printk("Using IVHD type %#x\n", amd_iommu_target_ivhd_type);

	/* Device table - directly used by all IOMMUs */
	ret = -ENOMEM;

	amd_iommu_pd_alloc_bitmap = iommu_alloc_pages(GFP_KERNEL,
						      get_order(MAX_DOMAIN_ID / 8));
	if (amd_iommu_pd_alloc_bitmap == NULL)
		goto out;

	/*
	 * never allocate domain 0 because its used as the non-allocated and
	 * error value placeholder
	 */
	__set_bit(0, amd_iommu_pd_alloc_bitmap);

	/*
	 * now the data structures are allocated and basically initialized
	 * start the real acpi table scan
Loading