arch/x86/kernel/amd_gart_64.c

Source file repositories/reference/linux-study-clean/arch/x86/kernel/amd_gart_64.c

File Facts

System
Linux kernel
Corpus path
arch/x86/kernel/amd_gart_64.c
Extension
.c
Size
21747 bytes
Lines
848
Domain
Architecture Layer
Bucket
arch/x86
Inferred role
Architecture Layer: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

if (next_bit >= iommu_pages) {
			next_bit = 0;
			need_flush = true;
		}
	}
	if (iommu_fullflush)
		need_flush = true;
	spin_unlock_irqrestore(&iommu_bitmap_lock, flags);

	return offset;
}

static void free_iommu(unsigned long offset, int size)
{
	unsigned long flags;

	spin_lock_irqsave(&iommu_bitmap_lock, flags);
	bitmap_clear(iommu_gart_bitmap, offset, size);
	if (offset >= next_bit)
		next_bit = offset + size;
	spin_unlock_irqrestore(&iommu_bitmap_lock, flags);
}

/*
 * Use global flush state to avoid races with multiple flushers.
 */
static void flush_gart(void)
{
	unsigned long flags;

	spin_lock_irqsave(&iommu_bitmap_lock, flags);
	if (need_flush) {
		amd_flush_garts();
		need_flush = false;
	}
	spin_unlock_irqrestore(&iommu_bitmap_lock, flags);
}

#ifdef CONFIG_IOMMU_LEAK
/* Debugging aid for drivers that don't free their IOMMU tables */
static void dump_leak(void)
{
	static int dump;

	if (dump)
		return;
	dump = 1;

	show_stack(NULL, NULL, KERN_ERR);
	debug_dma_dump_mappings(NULL);
}
#endif

static void iommu_full(struct device *dev, size_t size, int dir)
{
	/*
	 * Ran out of IOMMU space for this operation. This is very bad.
	 * Unfortunately the drivers cannot handle this operation properly.
	 * Return some non mapped prereserved space in the aperture and
	 * let the Northbridge deal with it. This will result in garbage
	 * in the IO operation. When the size exceeds the prereserved space
	 * memory corruption will occur or random memory will be DMAed
	 * out. Hopefully no network devices use single mappings that big.
	 */

	dev_err(dev, "PCI-DMA: Out of IOMMU space for %lu bytes\n", size);
#ifdef CONFIG_IOMMU_LEAK
	dump_leak();
#endif
}

static inline int
need_iommu(struct device *dev, unsigned long addr, size_t size)
{
	return force_iommu || !dma_capable(dev, addr, size, true);
}

static inline int
nonforced_iommu(struct device *dev, unsigned long addr, size_t size)
{
	return !dma_capable(dev, addr, size, true);
}

/* Map a single continuous physical area into the IOMMU.
 * Caller needs to check if the iommu is needed and flush.
 */
static dma_addr_t dma_map_area(struct device *dev, dma_addr_t phys_mem,
				size_t size, int dir, unsigned long align_mask)
{
	unsigned long npages = iommu_num_pages(phys_mem, size, PAGE_SIZE);

Annotation

Implementation Notes