Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c42d9f32 authored by Suresh Siddha's avatar Suresh Siddha Committed by Ingo Molnar
Browse files

x64, x2apic/intr-remap: fix the need for sequential array allocation of iommus



Clean up the intel-iommu code related to deferred iommu flush logic. There is
no need to allocate all the iommu's as a sequential array.

This will be used later in the interrupt-remapping patch series to
allocate iommu much early and individually for each device remapping
hardware unit.

Signed-off-by: default avatarSuresh Siddha <suresh.b.siddha@intel.com>
Cc: akpm@linux-foundation.org
Cc: arjan@linux.intel.com
Cc: andi@firstfloor.org
Cc: ebiederm@xmission.com
Cc: jbarnes@virtuousgeek.org
Cc: steiner@sgi.com
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent e61d98d8
Loading
Loading
Loading
Loading
+9 −2
Original line number Diff line number Diff line
@@ -377,11 +377,18 @@ int __init early_dmar_detect(void)
	return (ACPI_SUCCESS(status) ? 1 : 0);
}

struct intel_iommu *alloc_iommu(struct intel_iommu *iommu,
				struct dmar_drhd_unit *drhd)
struct intel_iommu *alloc_iommu(struct dmar_drhd_unit *drhd)
{
	struct intel_iommu *iommu;
	int map_size;
	u32 ver;
	static int iommu_allocated = 0;

	iommu = kzalloc(sizeof(*iommu), GFP_KERNEL);
	if (!iommu)
		return NULL;

	iommu->seq_id = iommu_allocated++;

	iommu->reg = ioremap(drhd->reg_base_addr, PAGE_SIZE_4K);
	if (!iommu->reg) {
+7 −17
Original line number Diff line number Diff line
@@ -58,8 +58,6 @@ static void flush_unmaps_timeout(unsigned long data);

DEFINE_TIMER(unmap_timer,  flush_unmaps_timeout, 0, 0);

static struct intel_iommu *g_iommus;

#define HIGH_WATER_MARK 250
struct deferred_flush_tables {
	int next;
@@ -1649,8 +1647,6 @@ int __init init_dmars(void)
	 * endfor
	 */
	for_each_drhd_unit(drhd) {
		if (drhd->ignored)
			continue;
		g_num_of_iommus++;
		/*
		 * lock not needed as this is only incremented in the single
@@ -1659,26 +1655,17 @@ int __init init_dmars(void)
		 */
	}

	g_iommus = kzalloc(g_num_of_iommus * sizeof(*iommu), GFP_KERNEL);
	if (!g_iommus) {
		ret = -ENOMEM;
		goto error;
	}

	deferred_flush = kzalloc(g_num_of_iommus *
		sizeof(struct deferred_flush_tables), GFP_KERNEL);
	if (!deferred_flush) {
		kfree(g_iommus);
		ret = -ENOMEM;
		goto error;
	}

	i = 0;
	for_each_drhd_unit(drhd) {
		if (drhd->ignored)
			continue;
		iommu = alloc_iommu(&g_iommus[i], drhd);
		i++;
		iommu = alloc_iommu(drhd);
		if (!iommu) {
			ret = -ENOMEM;
			goto error;
@@ -1770,7 +1757,6 @@ error:
		iommu = drhd->iommu;
		free_iommu(iommu);
	}
	kfree(g_iommus);
	return ret;
}

@@ -1927,7 +1913,10 @@ static void flush_unmaps(void)
	/* just flush them all */
	for (i = 0; i < g_num_of_iommus; i++) {
		if (deferred_flush[i].next) {
			iommu_flush_iotlb_global(&g_iommus[i], 0);
			struct intel_iommu *iommu =
				deferred_flush[i].domain[0]->iommu;

			iommu_flush_iotlb_global(iommu, 0);
			for (j = 0; j < deferred_flush[i].next; j++) {
				__free_iova(&deferred_flush[i].domain[j]->iovad,
						deferred_flush[i].iova[j]);
@@ -1957,7 +1946,8 @@ static void add_unmap(struct dmar_domain *dom, struct iova *iova)
	if (list_size == HIGH_WATER_MARK)
		flush_unmaps();

	iommu_id = dom->iommu - g_iommus;
	iommu_id = dom->iommu->seq_id;

	next = deferred_flush[iommu_id].next;
	deferred_flush[iommu_id].domain[next] = dom;
	deferred_flush[iommu_id].iova[next] = iova;
+2 −2
Original line number Diff line number Diff line
@@ -182,6 +182,7 @@ struct intel_iommu {
	int		seg;
	u32		gcmd; /* Holds TE, EAFL. Don't need SRTP, SFL, WBF */
	spinlock_t	register_lock; /* protect register handling */
	int		seq_id;	/* sequence id of the iommu */

#ifdef CONFIG_DMAR
	unsigned long 	*domain_ids; /* bitmap of domains */
@@ -198,8 +199,7 @@ struct intel_iommu {

extern struct dmar_drhd_unit * dmar_find_matched_drhd_unit(struct pci_dev *dev);

extern struct intel_iommu *alloc_iommu(struct intel_iommu *iommu,
				       struct dmar_drhd_unit *drhd);
extern struct intel_iommu *alloc_iommu(struct dmar_drhd_unit *drhd);
extern void free_iommu(struct intel_iommu *iommu);

#endif