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

Commit 0dc243ae authored by Jon Mason's avatar Jon Mason Committed by Linus Torvalds
Browse files

[PATCH] x86_64: Calgary IOMMU - IOMMU abstractions



This patch creates a new interface for IOMMUs by adding a centralized
location for IOMMU allocation (for translation tables/apertures) and
IOMMU initialization.  In creating these, code was moved around for
abstraction, uniformity, and consiceness.

Take note of the move of the iommu_setup bootarg parsing code to
__setup.  This is enabled by moving back the location of the aperture
allocation/detection to mem init (which while ugly, was already the
location of the swiotlb_init).

While a slight departure from the previous patch, I belive this provides
the true intention of the previous versions of the patch which changed
this code.  It also makes the addition of the upcoming calgary code much
cleaner than previous patches.

[AK: Removed one broken change. iommu_setup still has to be called
early]

Signed-off-by: default avatarMuli Ben-Yehuda <muli@il.ibm.com>
Signed-off-by: default avatarJon Mason <jdmason@us.ibm.com>
Signed-off-by: default avatarAndi Kleen <ak@suse.de>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent a3c042a0
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line
@@ -279,3 +279,32 @@ __init int iommu_setup(char *p)
    }
    return 1;
}
__setup("iommu=", iommu_setup);

void __init pci_iommu_alloc(void)
{
	/*
	 * The order of these functions is important for
	 * fall-back/fail-over reasons
	 */
#ifdef CONFIG_IOMMU
	iommu_hole_init();
#endif

#ifdef CONFIG_SWIOTLB
	pci_swiotlb_init();
#endif
}

static int __init pci_iommu_init(void)
{
#ifdef CONFIG_IOMMU
	gart_iommu_init();
#endif

	no_iommu_init();
	return 0;
}

/* Must execute after PCI subsystem */
fs_initcall(pci_iommu_init);
+6 −7
Original line number Diff line number Diff line
@@ -571,7 +571,7 @@ static struct dma_mapping_ops gart_dma_ops = {
	.unmap_sg = gart_unmap_sg,
};

static int __init pci_iommu_init(void)
void __init gart_iommu_init(void)
{ 
	struct agp_kern_info info;
	unsigned long aper_size;
@@ -581,7 +581,7 @@ static int __init pci_iommu_init(void)

	if (cache_k8_northbridges() < 0 || num_k8_northbridges == 0) {
		printk(KERN_INFO "PCI-GART: No AMD northbridge found.\n");
		return -ENODEV;
		return;
	}

#ifndef CONFIG_AGP_AMD64
@@ -595,11 +595,11 @@ static int __init pci_iommu_init(void)
#endif	

	if (swiotlb)
		return -ENODEV;
		return;

	/* Did we detect a different HW IOMMU? */
	if (iommu_detected && !iommu_aperture)
		return -1;
		return;

	if (no_iommu ||
	    (!force_iommu && end_pfn <= MAX_DMA32_PFN) ||
@@ -611,7 +611,7 @@ static int __init pci_iommu_init(void)
					"but IOMMU not available.\n"
			       KERN_ERR "WARNING 32bit PCI may malfunction.\n");
		}
		return -ENODEV;
		return;
	}

	printk(KERN_INFO "PCI-DMA: using GART IOMMU.\n");
@@ -678,11 +678,10 @@ static int __init pci_iommu_init(void)

	flush_gart();
	dma_ops = &gart_dma_ops;
	return 0;
} 

/* Must execute after PCI subsystem */
fs_initcall(pci_iommu_init);
fs_initcall(gart_iommu_init);

void gart_parse_options(char *p)
{
+0 −5
Original line number Diff line number Diff line
@@ -63,7 +63,6 @@
#include <asm/setup.h>
#include <asm/mach_apic.h>
#include <asm/numa.h>
#include <asm/swiotlb.h>
#include <asm/sections.h>
#include <asm/dmi.h>

@@ -702,10 +701,6 @@ void __init setup_arch(char **cmdline_p)

	e820_setup_gap();

#ifdef CONFIG_IOMMU
	iommu_hole_init();
#endif

#ifdef CONFIG_VT
#if defined(CONFIG_VGA_CONSOLE)
	conswitchp = &vga_con;
+1 −6
Original line number Diff line number Diff line
@@ -41,8 +41,6 @@
#include <asm/proto.h>
#include <asm/smp.h>
#include <asm/sections.h>
#include <asm/dma-mapping.h>
#include <asm/swiotlb.h>

#ifndef Dprintk
#define Dprintk(x...)
@@ -587,10 +585,7 @@ void __init mem_init(void)
{
	long codesize, reservedpages, datasize, initsize;

#ifdef CONFIG_SWIOTLB
	pci_swiotlb_init();
#endif
	no_iommu_init();
	pci_iommu_alloc();

	/* How many end-of-memory variables you have, grandma! */
	max_low_pfn = end_pfn;
+1 −1
Original line number Diff line number Diff line
@@ -39,8 +39,8 @@ int pcibios_set_irq_routing(struct pci_dev *dev, int pin, int irq);
#include <asm/scatterlist.h>
#include <linux/string.h>
#include <asm/page.h>
#include <linux/dma-mapping.h> /* for have_iommu */

extern void pci_iommu_alloc(void);
extern int iommu_setup(char *opt);

/* The PCI address space does equal the physical memory
Loading