Commit 333e581b authored by Vasant Hegde's avatar Vasant Hegde Committed by Joerg Roedel
Browse files

iommu/amd: Introduce per PCI segment irq_lookup_table

parent eda797a2
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -565,6 +565,12 @@ struct amd_iommu_pci_seg {
	 * device id.
	 */
	struct amd_iommu **rlookup_table;

	/*
	 * This table is used to find the irq remapping table for a given
	 * device id quickly.
	 */
	struct irq_remap_table **irq_lookup_table;
};

/*
+27 −0
Original line number Diff line number Diff line
@@ -684,6 +684,26 @@ static inline void free_rlookup_table(struct amd_iommu_pci_seg *pci_seg)
	pci_seg->rlookup_table = NULL;
}

static inline int __init alloc_irq_lookup_table(struct amd_iommu_pci_seg *pci_seg)
{
	pci_seg->irq_lookup_table = (void *)__get_free_pages(
					     GFP_KERNEL | __GFP_ZERO,
					     get_order(rlookup_table_size));
	kmemleak_alloc(pci_seg->irq_lookup_table,
		       rlookup_table_size, 1, GFP_KERNEL);
	if (pci_seg->irq_lookup_table == NULL)
		return -ENOMEM;

	return 0;
}

static inline void free_irq_lookup_table(struct amd_iommu_pci_seg *pci_seg)
{
	kmemleak_free(pci_seg->irq_lookup_table);
	free_pages((unsigned long)pci_seg->irq_lookup_table,
		   get_order(rlookup_table_size));
	pci_seg->irq_lookup_table = NULL;
}

/*
 * Allocates the command buffer. This buffer is per AMD IOMMU. We can
@@ -1535,6 +1555,7 @@ static void __init free_pci_segments(void)

	for_each_pci_segment_safe(pci_seg, next) {
		list_del(&pci_seg->list);
		free_irq_lookup_table(pci_seg);
		free_rlookup_table(pci_seg);
		free_dev_table(pci_seg);
		kfree(pci_seg);
@@ -2900,6 +2921,7 @@ static int __init early_amd_iommu_init(void)
		amd_iommu_irq_remap = check_ioapic_information();

	if (amd_iommu_irq_remap) {
		struct amd_iommu_pci_seg *pci_seg;
		/*
		 * Interrupt remapping enabled, create kmem_cache for the
		 * remapping tables.
@@ -2916,6 +2938,11 @@ static int __init early_amd_iommu_init(void)
		if (!amd_iommu_irq_cache)
			goto out;

		for_each_pci_segment(pci_seg) {
			if (alloc_irq_lookup_table(pci_seg))
				goto out;
		}

		irq_lookup_table = (void *)__get_free_pages(
				GFP_KERNEL | __GFP_ZERO,
				get_order(rlookup_table_size));