linux/kernel/dma/swiotlb.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Dynamic DMA mapping support.
 *
 * This implementation is a fallback for platforms that do not support
 * I/O TLBs (aka DMA address translation hardware).
 * Copyright (C) 2000 Asit Mallick <[email protected]>
 * Copyright (C) 2000 Goutham Rao <[email protected]>
 * Copyright (C) 2000, 2003 Hewlett-Packard Co
 *	David Mosberger-Tang <[email protected]>
 *
 * 03/05/07 davidm	Switch from PCI-DMA to generic device DMA API.
 * 00/12/13 davidm	Rename to swiotlb.c and add mark_clean() to avoid
 *			unnecessary i-cache flushing.
 * 04/07/.. ak		Better overflow handling. Assorted fixes.
 * 05/09/10 linville	Add support for syncing ranges, support syncing for
 *			DMA_BIDIRECTIONAL mappings, miscellaneous cleanup.
 * 08/12/11 beckyb	Add highmem support
 */

#define pr_fmt(fmt)

#include <linux/cache.h>
#include <linux/cc_platform.h>
#include <linux/ctype.h>
#include <linux/debugfs.h>
#include <linux/dma-direct.h>
#include <linux/dma-map-ops.h>
#include <linux/export.h>
#include <linux/gfp.h>
#include <linux/highmem.h>
#include <linux/io.h>
#include <linux/iommu-helper.h>
#include <linux/init.h>
#include <linux/memblock.h>
#include <linux/mm.h>
#include <linux/pfn.h>
#include <linux/rculist.h>
#include <linux/scatterlist.h>
#include <linux/set_memory.h>
#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/swiotlb.h>
#include <linux/types.h>
#ifdef CONFIG_DMA_RESTRICTED_POOL
#include <linux/of.h>
#include <linux/of_fdt.h>
#include <linux/of_reserved_mem.h>
#include <linux/slab.h>
#endif

#define CREATE_TRACE_POINTS
#include <trace/events/swiotlb.h>

#define SLABS_PER_PAGE

/*
 * Minimum IO TLB size to bother booting with.  Systems with mainly
 * 64bit capable cards will only lightly use the swiotlb.  If we can't
 * allocate a contiguous 1MB, we're probably in trouble anyway.
 */
#define IO_TLB_MIN_SLABS

#define INVALID_PHYS_ADDR

/**
 * struct io_tlb_slot - IO TLB slot descriptor
 * @orig_addr:	The original address corresponding to a mapped entry.
 * @alloc_size:	Size of the allocated buffer.
 * @list:	The free list describing the number of free entries available
 *		from each index.
 * @pad_slots:	Number of preceding padding slots. Valid only in the first
 *		allocated non-padding slot.
 */
struct io_tlb_slot {};

static bool swiotlb_force_bounce;
static bool swiotlb_force_disable;

#ifdef CONFIG_SWIOTLB_DYNAMIC

static void swiotlb_dyn_alloc(struct work_struct *work);

static struct io_tlb_mem io_tlb_default_mem =;

#else  /* !CONFIG_SWIOTLB_DYNAMIC */

static struct io_tlb_mem io_tlb_default_mem;

#endif	/* CONFIG_SWIOTLB_DYNAMIC */

static unsigned long default_nslabs =;
static unsigned long default_nareas;

/**
 * struct io_tlb_area - IO TLB memory area descriptor
 *
 * This is a single area with a single lock.
 *
 * @used:	The number of used IO TLB block.
 * @index:	The slot index to start searching in this area for next round.
 * @lock:	The lock to protect the above data structures in the map and
 *		unmap calls.
 */
struct io_tlb_area {};

/*
 * Round up number of slabs to the next power of 2. The last area is going
 * be smaller than the rest if default_nslabs is not power of two.
 * The number of slot in an area should be a multiple of IO_TLB_SEGSIZE,
 * otherwise a segment may span two or more areas. It conflicts with free
 * contiguous slots tracking: free slots are treated contiguous no matter
 * whether they cross an area boundary.
 *
 * Return true if default_nslabs is rounded up.
 */
static bool round_up_default_nslabs(void)
{}

/**
 * swiotlb_adjust_nareas() - adjust the number of areas and slots
 * @nareas:	Desired number of areas. Zero is treated as 1.
 *
 * Adjust the default number of areas in a memory pool.
 * The default size of the memory pool may also change to meet minimum area
 * size requirements.
 */
static void swiotlb_adjust_nareas(unsigned int nareas)
{}

/**
 * limit_nareas() - get the maximum number of areas for a given memory pool size
 * @nareas:	Desired number of areas.
 * @nslots:	Total number of slots in the memory pool.
 *
 * Limit the number of areas to the maximum possible number of areas in
 * a memory pool of the given size.
 *
 * Return: Maximum possible number of areas.
 */
static unsigned int limit_nareas(unsigned int nareas, unsigned long nslots)
{}

static int __init
setup_io_tlb_npages(char *str)
{}
early_param();

unsigned long swiotlb_size_or_default(void)
{}

void __init swiotlb_adjust_size(unsigned long size)
{}

void swiotlb_print_info(void)
{}

static inline unsigned long io_tlb_offset(unsigned long val)
{}

static inline unsigned long nr_slots(u64 val)
{}

/*
 * Early SWIOTLB allocation may be too early to allow an architecture to
 * perform the desired operations.  This function allows the architecture to
 * call SWIOTLB when the operations are possible.  It needs to be called
 * before the SWIOTLB memory is used.
 */
void __init swiotlb_update_mem_attributes(void)
{}

static void swiotlb_init_io_tlb_pool(struct io_tlb_pool *mem, phys_addr_t start,
		unsigned long nslabs, bool late_alloc, unsigned int nareas)
{}

/**
 * add_mem_pool() - add a memory pool to the allocator
 * @mem:	Software IO TLB allocator.
 * @pool:	Memory pool to be added.
 */
static void add_mem_pool(struct io_tlb_mem *mem, struct io_tlb_pool *pool)
{}

static void __init *swiotlb_memblock_alloc(unsigned long nslabs,
		unsigned int flags,
		int (*remap)(void *tlb, unsigned long nslabs))
{}

/*
 * Statically reserve bounce buffer space and initialize bounce buffer data
 * structures for the software IO TLB used to implement the DMA API.
 */
void __init swiotlb_init_remap(bool addressing_limit, unsigned int flags,
		int (*remap)(void *tlb, unsigned long nslabs))
{}

void __init swiotlb_init(bool addressing_limit, unsigned int flags)
{}

/*
 * Systems with larger DMA zones (those that don't support ISA) can
 * initialize the swiotlb later using the slab allocator if needed.
 * This should be just like above, but with some error catching.
 */
int swiotlb_init_late(size_t size, gfp_t gfp_mask,
		int (*remap)(void *tlb, unsigned long nslabs))
{}

void __init swiotlb_exit(void)
{}

#ifdef CONFIG_SWIOTLB_DYNAMIC

/**
 * alloc_dma_pages() - allocate pages to be used for DMA
 * @gfp:	GFP flags for the allocation.
 * @bytes:	Size of the buffer.
 * @phys_limit:	Maximum allowed physical address of the buffer.
 *
 * Allocate pages from the buddy allocator. If successful, make the allocated
 * pages decrypted that they can be used for DMA.
 *
 * Return: Decrypted pages, %NULL on allocation failure, or ERR_PTR(-EAGAIN)
 * if the allocated physical address was above @phys_limit.
 */
static struct page *alloc_dma_pages(gfp_t gfp, size_t bytes, u64 phys_limit)
{}

/**
 * swiotlb_alloc_tlb() - allocate a dynamic IO TLB buffer
 * @dev:	Device for which a memory pool is allocated.
 * @bytes:	Size of the buffer.
 * @phys_limit:	Maximum allowed physical address of the buffer.
 * @gfp:	GFP flags for the allocation.
 *
 * Return: Allocated pages, or %NULL on allocation failure.
 */
static struct page *swiotlb_alloc_tlb(struct device *dev, size_t bytes,
		u64 phys_limit, gfp_t gfp)
{}

/**
 * swiotlb_free_tlb() - free a dynamically allocated IO TLB buffer
 * @vaddr:	Virtual address of the buffer.
 * @bytes:	Size of the buffer.
 */
static void swiotlb_free_tlb(void *vaddr, size_t bytes)
{}

/**
 * swiotlb_alloc_pool() - allocate a new IO TLB memory pool
 * @dev:	Device for which a memory pool is allocated.
 * @minslabs:	Minimum number of slabs.
 * @nslabs:	Desired (maximum) number of slabs.
 * @nareas:	Number of areas.
 * @phys_limit:	Maximum DMA buffer physical address.
 * @gfp:	GFP flags for the allocations.
 *
 * Allocate and initialize a new IO TLB memory pool. The actual number of
 * slabs may be reduced if allocation of @nslabs fails. If even
 * @minslabs cannot be allocated, this function fails.
 *
 * Return: New memory pool, or %NULL on allocation failure.
 */
static struct io_tlb_pool *swiotlb_alloc_pool(struct device *dev,
		unsigned long minslabs, unsigned long nslabs,
		unsigned int nareas, u64 phys_limit, gfp_t gfp)
{}

/**
 * swiotlb_dyn_alloc() - dynamic memory pool allocation worker
 * @work:	Pointer to dyn_alloc in struct io_tlb_mem.
 */
static void swiotlb_dyn_alloc(struct work_struct *work)
{}

/**
 * swiotlb_dyn_free() - RCU callback to free a memory pool
 * @rcu:	RCU head in the corresponding struct io_tlb_pool.
 */
static void swiotlb_dyn_free(struct rcu_head *rcu)
{}

/**
 * __swiotlb_find_pool() - find the IO TLB pool for a physical address
 * @dev:        Device which has mapped the DMA buffer.
 * @paddr:      Physical address within the DMA buffer.
 *
 * Find the IO TLB memory pool descriptor which contains the given physical
 * address, if any. This function is for use only when the dev is known to
 * be using swiotlb. Use swiotlb_find_pool() for the more general case
 * when this condition is not met.
 *
 * Return: Memory pool which contains @paddr, or %NULL if none.
 */
struct io_tlb_pool *__swiotlb_find_pool(struct device *dev, phys_addr_t paddr)
{}

/**
 * swiotlb_del_pool() - remove an IO TLB pool from a device
 * @dev:	Owning device.
 * @pool:	Memory pool to be removed.
 */
static void swiotlb_del_pool(struct device *dev, struct io_tlb_pool *pool)
{}

#endif	/* CONFIG_SWIOTLB_DYNAMIC */

/**
 * swiotlb_dev_init() - initialize swiotlb fields in &struct device
 * @dev:	Device to be initialized.
 */
void swiotlb_dev_init(struct device *dev)
{}

/**
 * swiotlb_align_offset() - Get required offset into an IO TLB allocation.
 * @dev:         Owning device.
 * @align_mask:  Allocation alignment mask.
 * @addr:        DMA address.
 *
 * Return the minimum offset from the start of an IO TLB allocation which is
 * required for a given buffer address and allocation alignment to keep the
 * device happy.
 *
 * First, the address bits covered by min_align_mask must be identical in the
 * original address and the bounce buffer address. High bits are preserved by
 * choosing a suitable IO TLB slot, but bits below IO_TLB_SHIFT require extra
 * padding bytes before the bounce buffer.
 *
 * Second, @align_mask specifies which bits of the first allocated slot must
 * be zero. This may require allocating additional padding slots, and then the
 * offset (in bytes) from the first such padding slot is returned.
 */
static unsigned int swiotlb_align_offset(struct device *dev,
					 unsigned int align_mask, u64 addr)
{}

/*
 * Bounce: copy the swiotlb buffer from or back to the original dma location
 */
static void swiotlb_bounce(struct device *dev, phys_addr_t tlb_addr, size_t size,
			   enum dma_data_direction dir, struct io_tlb_pool *mem)
{}

static inline phys_addr_t slot_addr(phys_addr_t start, phys_addr_t idx)
{}

/*
 * Carefully handle integer overflow which can occur when boundary_mask == ~0UL.
 */
static inline unsigned long get_max_slots(unsigned long boundary_mask)
{}

static unsigned int wrap_area_index(struct io_tlb_pool *mem, unsigned int index)
{}

/*
 * Track the total used slots with a global atomic value in order to have
 * correct information to determine the high water mark. The mem_used()
 * function gives imprecise results because there's no locking across
 * multiple areas.
 */
#ifdef CONFIG_DEBUG_FS
static void inc_used_and_hiwater(struct io_tlb_mem *mem, unsigned int nslots)
{}

static void dec_used(struct io_tlb_mem *mem, unsigned int nslots)
{}

#else /* !CONFIG_DEBUG_FS */
static void inc_used_and_hiwater(struct io_tlb_mem *mem, unsigned int nslots)
{
}
static void dec_used(struct io_tlb_mem *mem, unsigned int nslots)
{
}
#endif /* CONFIG_DEBUG_FS */

#ifdef CONFIG_SWIOTLB_DYNAMIC
#ifdef CONFIG_DEBUG_FS
static void inc_transient_used(struct io_tlb_mem *mem, unsigned int nslots)
{}

static void dec_transient_used(struct io_tlb_mem *mem, unsigned int nslots)
{}

#else /* !CONFIG_DEBUG_FS */
static void inc_transient_used(struct io_tlb_mem *mem, unsigned int nslots)
{
}
static void dec_transient_used(struct io_tlb_mem *mem, unsigned int nslots)
{
}
#endif /* CONFIG_DEBUG_FS */
#endif /* CONFIG_SWIOTLB_DYNAMIC */

/**
 * swiotlb_search_pool_area() - search one memory area in one pool
 * @dev:	Device which maps the buffer.
 * @pool:	Memory pool to be searched.
 * @area_index:	Index of the IO TLB memory area to be searched.
 * @orig_addr:	Original (non-bounced) IO buffer address.
 * @alloc_size: Total requested size of the bounce buffer,
 *		including initial alignment padding.
 * @alloc_align_mask:	Required alignment of the allocated buffer.
 *
 * Find a suitable sequence of IO TLB entries for the request and allocate
 * a buffer from the given IO TLB memory area.
 * This function takes care of locking.
 *
 * Return: Index of the first allocated slot, or -1 on error.
 */
static int swiotlb_search_pool_area(struct device *dev, struct io_tlb_pool *pool,
		int area_index, phys_addr_t orig_addr, size_t alloc_size,
		unsigned int alloc_align_mask)
{}

#ifdef CONFIG_SWIOTLB_DYNAMIC

/**
 * swiotlb_search_area() - search one memory area in all pools
 * @dev:	Device which maps the buffer.
 * @start_cpu:	Start CPU number.
 * @cpu_offset:	Offset from @start_cpu.
 * @orig_addr:	Original (non-bounced) IO buffer address.
 * @alloc_size: Total requested size of the bounce buffer,
 *		including initial alignment padding.
 * @alloc_align_mask:	Required alignment of the allocated buffer.
 * @retpool:	Used memory pool, updated on return.
 *
 * Search one memory area in all pools for a sequence of slots that match the
 * allocation constraints.
 *
 * Return: Index of the first allocated slot, or -1 on error.
 */
static int swiotlb_search_area(struct device *dev, int start_cpu,
		int cpu_offset, phys_addr_t orig_addr, size_t alloc_size,
		unsigned int alloc_align_mask, struct io_tlb_pool **retpool)
{}

/**
 * swiotlb_find_slots() - search for slots in the whole swiotlb
 * @dev:	Device which maps the buffer.
 * @orig_addr:	Original (non-bounced) IO buffer address.
 * @alloc_size: Total requested size of the bounce buffer,
 *		including initial alignment padding.
 * @alloc_align_mask:	Required alignment of the allocated buffer.
 * @retpool:	Used memory pool, updated on return.
 *
 * Search through the whole software IO TLB to find a sequence of slots that
 * match the allocation constraints.
 *
 * Return: Index of the first allocated slot, or -1 on error.
 */
static int swiotlb_find_slots(struct device *dev, phys_addr_t orig_addr,
		size_t alloc_size, unsigned int alloc_align_mask,
		struct io_tlb_pool **retpool)
{}

#else  /* !CONFIG_SWIOTLB_DYNAMIC */

static int swiotlb_find_slots(struct device *dev, phys_addr_t orig_addr,
		size_t alloc_size, unsigned int alloc_align_mask,
		struct io_tlb_pool **retpool)
{
	struct io_tlb_pool *pool;
	int start, i;
	int index;

	*retpool = pool = &dev->dma_io_tlb_mem->defpool;
	i = start = raw_smp_processor_id() & (pool->nareas - 1);
	do {
		index = swiotlb_search_pool_area(dev, pool, i, orig_addr,
						 alloc_size, alloc_align_mask);
		if (index >= 0)
			return index;
		if (++i >= pool->nareas)
			i = 0;
	} while (i != start);
	return -1;
}

#endif /* CONFIG_SWIOTLB_DYNAMIC */

#ifdef CONFIG_DEBUG_FS

/**
 * mem_used() - get number of used slots in an allocator
 * @mem:	Software IO TLB allocator.
 *
 * The result is accurate in this version of the function, because an atomic
 * counter is available if CONFIG_DEBUG_FS is set.
 *
 * Return: Number of used slots.
 */
static unsigned long mem_used(struct io_tlb_mem *mem)
{}

#else /* !CONFIG_DEBUG_FS */

/**
 * mem_pool_used() - get number of used slots in a memory pool
 * @pool:	Software IO TLB memory pool.
 *
 * The result is not accurate, see mem_used().
 *
 * Return: Approximate number of used slots.
 */
static unsigned long mem_pool_used(struct io_tlb_pool *pool)
{
	int i;
	unsigned long used = 0;

	for (i = 0; i < pool->nareas; i++)
		used += pool->areas[i].used;
	return used;
}

/**
 * mem_used() - get number of used slots in an allocator
 * @mem:	Software IO TLB allocator.
 *
 * The result is not accurate, because there is no locking of individual
 * areas.
 *
 * Return: Approximate number of used slots.
 */
static unsigned long mem_used(struct io_tlb_mem *mem)
{
#ifdef CONFIG_SWIOTLB_DYNAMIC
	struct io_tlb_pool *pool;
	unsigned long used = 0;

	rcu_read_lock();
	list_for_each_entry_rcu(pool, &mem->pools, node)
		used += mem_pool_used(pool);
	rcu_read_unlock();

	return used;
#else
	return mem_pool_used(&mem->defpool);
#endif
}

#endif /* CONFIG_DEBUG_FS */

/**
 * swiotlb_tbl_map_single() - bounce buffer map a single contiguous physical area
 * @dev:		Device which maps the buffer.
 * @orig_addr:		Original (non-bounced) physical IO buffer address
 * @mapping_size:	Requested size of the actual bounce buffer, excluding
 *			any pre- or post-padding for alignment
 * @alloc_align_mask:	Required start and end alignment of the allocated buffer
 * @dir:		DMA direction
 * @attrs:		Optional DMA attributes for the map operation
 *
 * Find and allocate a suitable sequence of IO TLB slots for the request.
 * The allocated space starts at an alignment specified by alloc_align_mask,
 * and the size of the allocated space is rounded up so that the total amount
 * of allocated space is a multiple of (alloc_align_mask + 1). If
 * alloc_align_mask is zero, the allocated space may be at any alignment and
 * the size is not rounded up.
 *
 * The returned address is within the allocated space and matches the bits
 * of orig_addr that are specified in the DMA min_align_mask for the device. As
 * such, this returned address may be offset from the beginning of the allocated
 * space. The bounce buffer space starting at the returned address for
 * mapping_size bytes is initialized to the contents of the original IO buffer
 * area. Any pre-padding (due to an offset) and any post-padding (due to
 * rounding-up the size) is not initialized.
 */
phys_addr_t swiotlb_tbl_map_single(struct device *dev, phys_addr_t orig_addr,
		size_t mapping_size, unsigned int alloc_align_mask,
		enum dma_data_direction dir, unsigned long attrs)
{}

static void swiotlb_release_slots(struct device *dev, phys_addr_t tlb_addr,
				  struct io_tlb_pool *mem)
{}

#ifdef CONFIG_SWIOTLB_DYNAMIC

/**
 * swiotlb_del_transient() - delete a transient memory pool
 * @dev:	Device which mapped the buffer.
 * @tlb_addr:	Physical address within a bounce buffer.
 * @pool:       Pointer to the transient memory pool to be checked and deleted.
 *
 * Check whether the address belongs to a transient SWIOTLB memory pool.
 * If yes, then delete the pool.
 *
 * Return: %true if @tlb_addr belonged to a transient pool that was released.
 */
static bool swiotlb_del_transient(struct device *dev, phys_addr_t tlb_addr,
		struct io_tlb_pool *pool)
{}

#else  /* !CONFIG_SWIOTLB_DYNAMIC */

static inline bool swiotlb_del_transient(struct device *dev,
		phys_addr_t tlb_addr, struct io_tlb_pool *pool)
{
	return false;
}

#endif	/* CONFIG_SWIOTLB_DYNAMIC */

/*
 * tlb_addr is the physical address of the bounce buffer to unmap.
 */
void __swiotlb_tbl_unmap_single(struct device *dev, phys_addr_t tlb_addr,
		size_t mapping_size, enum dma_data_direction dir,
		unsigned long attrs, struct io_tlb_pool *pool)
{}

void __swiotlb_sync_single_for_device(struct device *dev, phys_addr_t tlb_addr,
		size_t size, enum dma_data_direction dir,
		struct io_tlb_pool *pool)
{}

void __swiotlb_sync_single_for_cpu(struct device *dev, phys_addr_t tlb_addr,
		size_t size, enum dma_data_direction dir,
		struct io_tlb_pool *pool)
{}

/*
 * Create a swiotlb mapping for the buffer at @paddr, and in case of DMAing
 * to the device copy the data into it as well.
 */
dma_addr_t swiotlb_map(struct device *dev, phys_addr_t paddr, size_t size,
		enum dma_data_direction dir, unsigned long attrs)
{}

size_t swiotlb_max_mapping_size(struct device *dev)
{}

/**
 * is_swiotlb_allocated() - check if the default software IO TLB is initialized
 */
bool is_swiotlb_allocated(void)
{}

bool is_swiotlb_active(struct device *dev)
{}

/**
 * default_swiotlb_base() - get the base address of the default SWIOTLB
 *
 * Get the lowest physical address used by the default software IO TLB pool.
 */
phys_addr_t default_swiotlb_base(void)
{}

/**
 * default_swiotlb_limit() - get the address limit of the default SWIOTLB
 *
 * Get the highest physical address used by the default software IO TLB pool.
 */
phys_addr_t default_swiotlb_limit(void)
{}

#ifdef CONFIG_DEBUG_FS
#ifdef CONFIG_SWIOTLB_DYNAMIC
static unsigned long mem_transient_used(struct io_tlb_mem *mem)
{}

static int io_tlb_transient_used_get(void *data, u64 *val)
{}

DEFINE_DEBUGFS_ATTRIBUTE();
#endif /* CONFIG_SWIOTLB_DYNAMIC */

static int io_tlb_used_get(void *data, u64 *val)
{}

static int io_tlb_hiwater_get(void *data, u64 *val)
{}

static int io_tlb_hiwater_set(void *data, u64 val)
{}

DEFINE_DEBUGFS_ATTRIBUTE();
DEFINE_DEBUGFS_ATTRIBUTE();

static void swiotlb_create_debugfs_files(struct io_tlb_mem *mem,
					 const char *dirname)
{}

static int __init swiotlb_create_default_debugfs(void)
{}

late_initcall(swiotlb_create_default_debugfs);

#else  /* !CONFIG_DEBUG_FS */

static inline void swiotlb_create_debugfs_files(struct io_tlb_mem *mem,
						const char *dirname)
{
}

#endif	/* CONFIG_DEBUG_FS */

#ifdef CONFIG_DMA_RESTRICTED_POOL

struct page *swiotlb_alloc(struct device *dev, size_t size)
{}

bool swiotlb_free(struct device *dev, struct page *page, size_t size)
{}

static int rmem_swiotlb_device_init(struct reserved_mem *rmem,
				    struct device *dev)
{}

static void rmem_swiotlb_device_release(struct reserved_mem *rmem,
					struct device *dev)
{}

static const struct reserved_mem_ops rmem_swiotlb_ops =;

static int __init rmem_swiotlb_setup(struct reserved_mem *rmem)
{}

RESERVEDMEM_OF_DECLARE(dma, "restricted-dma-pool", rmem_swiotlb_setup);
#endif /* CONFIG_DMA_RESTRICTED_POOL */