xref: /linux-6.15/include/linux/swiotlb.h (revision 02e76569)
1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
21648993fSJoerg Roedel #ifndef __LINUX_SWIOTLB_H
31648993fSJoerg Roedel #define __LINUX_SWIOTLB_H
41648993fSJoerg Roedel 
57fd856aaSClaire Chang #include <linux/device.h>
638674442SThierry Reding #include <linux/dma-direction.h>
738674442SThierry Reding #include <linux/init.h>
81648993fSJoerg Roedel #include <linux/types.h>
9f51778dbSStephen Rothwell #include <linux/limits.h>
1073f62095SClaire Chang #include <linux/spinlock.h>
111aaa7368SPetr Tesarik #include <linux/workqueue.h>
121648993fSJoerg Roedel 
131648993fSJoerg Roedel struct device;
1438674442SThierry Reding struct page;
151648993fSJoerg Roedel struct scatterlist;
161648993fSJoerg Roedel 
17c6af2aa9SChristoph Hellwig #define SWIOTLB_VERBOSE	(1 << 0) /* verbose initialization */
18c6af2aa9SChristoph Hellwig #define SWIOTLB_FORCE	(1 << 1) /* force bounce buffering */
198ba2ed1bSChristoph Hellwig #define SWIOTLB_ANY	(1 << 2) /* allow any memory for the buffer */
20ae7871beSGeert Uytterhoeven 
210016fdeeSIan Campbell /*
220016fdeeSIan Campbell  * Maximum allowable number of contiguous slabs to map,
230016fdeeSIan Campbell  * must be a power of 2.  What is the appropriate value ?
240016fdeeSIan Campbell  * The complexity of {map,unmap}_single is linearly dependent on this value.
250016fdeeSIan Campbell  */
260016fdeeSIan Campbell #define IO_TLB_SEGSIZE	128
270016fdeeSIan Campbell 
280016fdeeSIan Campbell /*
290016fdeeSIan Campbell  * log of the size of each IO TLB slab.  The number of slabs is command line
300016fdeeSIan Campbell  * controllable.
310016fdeeSIan Campbell  */
320016fdeeSIan Campbell #define IO_TLB_SHIFT 11
33b5d7ccb7SChristoph Hellwig #define IO_TLB_SIZE (1 << IO_TLB_SHIFT)
340016fdeeSIan Campbell 
35e998879dSAshish Kalra /* default to 64MB */
36e998879dSAshish Kalra #define IO_TLB_DEFAULT_SIZE (64UL<<20)
37e998879dSAshish Kalra 
38c729de8fSYinghai Lu unsigned long swiotlb_size_or_default(void);
397374153dSChristoph Hellwig void __init swiotlb_init_remap(bool addressing_limit, unsigned int flags,
407374153dSChristoph Hellwig 	int (*remap)(void *tlb, unsigned long nslabs));
417374153dSChristoph Hellwig int swiotlb_init_late(size_t size, gfp_t gfp_mask,
427374153dSChristoph Hellwig 	int (*remap)(void *tlb, unsigned long nslabs));
43c7753208STom Lendacky extern void __init swiotlb_update_mem_attributes(void);
441648993fSJoerg Roedel 
45fc0021aaSChristoph Hellwig phys_addr_t swiotlb_tbl_map_single(struct device *hwdev, phys_addr_t phys,
46fc0021aaSChristoph Hellwig 		size_t mapping_size, size_t alloc_size,
47e81e99baSDavid Stevens 		unsigned int alloc_aligned_mask, enum dma_data_direction dir,
48e81e99baSDavid Stevens 		unsigned long attrs);
49d7ef1533SKonrad Rzeszutek Wilk 
5061ca08c3SAlexander Duyck extern void swiotlb_tbl_unmap_single(struct device *hwdev,
5161ca08c3SAlexander Duyck 				     phys_addr_t tlb_addr,
523fc1ca00SLu Baolu 				     size_t mapping_size,
533fc1ca00SLu Baolu 				     enum dma_data_direction dir,
540443fa00SAlexander Duyck 				     unsigned long attrs);
55d7ef1533SKonrad Rzeszutek Wilk 
5680808d27SChristoph Hellwig void swiotlb_sync_single_for_device(struct device *dev, phys_addr_t tlb_addr,
5780808d27SChristoph Hellwig 		size_t size, enum dma_data_direction dir);
5880808d27SChristoph Hellwig void swiotlb_sync_single_for_cpu(struct device *dev, phys_addr_t tlb_addr,
5980808d27SChristoph Hellwig 		size_t size, enum dma_data_direction dir);
604a47cbaeSChristoph Hellwig dma_addr_t swiotlb_map(struct device *dev, phys_addr_t phys,
614a47cbaeSChristoph Hellwig 		size_t size, enum dma_data_direction dir, unsigned long attrs);
624a47cbaeSChristoph Hellwig 
635740afdbSFUJITA Tomonori #ifdef CONFIG_SWIOTLB
6473f62095SClaire Chang 
6573f62095SClaire Chang /**
66158dbe9cSPetr Tesarik  * struct io_tlb_pool - IO TLB memory pool descriptor
6773f62095SClaire Chang  * @start:	The start address of the swiotlb memory pool. Used to do a quick
6873f62095SClaire Chang  *		range check to see if the memory was in fact allocated by this
6973f62095SClaire Chang  *		API.
7073f62095SClaire Chang  * @end:	The end address of the swiotlb memory pool. Used to do a quick
7173f62095SClaire Chang  *		range check to see if the memory was in fact allocated by this
7273f62095SClaire Chang  *		API.
731a5e91d8STianyu Lan  * @vaddr:	The vaddr of the swiotlb memory pool. The swiotlb memory pool
741a5e91d8STianyu Lan  *		may be remapped in the memory encrypted case and store virtual
751a5e91d8STianyu Lan  *		address for bounce buffer operation.
76158dbe9cSPetr Tesarik  * @nslabs:	The number of IO TLB slots between @start and @end. For the
77158dbe9cSPetr Tesarik  *		default swiotlb, this can be adjusted with a boot parameter,
78158dbe9cSPetr Tesarik  *		see setup_io_tlb_npages().
79158dbe9cSPetr Tesarik  * @late_alloc:	%true if allocated using the page allocator.
80158dbe9cSPetr Tesarik  * @nareas:	Number of areas in the pool.
81158dbe9cSPetr Tesarik  * @area_nslabs: Number of slots in each area.
82158dbe9cSPetr Tesarik  * @areas:	Array of memory area descriptors.
83158dbe9cSPetr Tesarik  * @slots:	Array of slot descriptors.
8479636caaSPetr Tesarik  * @node:	Member of the IO TLB memory pool list.
8579636caaSPetr Tesarik  * @rcu:	RCU head for swiotlb_dyn_free().
8679636caaSPetr Tesarik  * @transient:  %true if transient memory pool.
87158dbe9cSPetr Tesarik  */
88158dbe9cSPetr Tesarik struct io_tlb_pool {
89158dbe9cSPetr Tesarik 	phys_addr_t start;
90158dbe9cSPetr Tesarik 	phys_addr_t end;
91158dbe9cSPetr Tesarik 	void *vaddr;
92158dbe9cSPetr Tesarik 	unsigned long nslabs;
93158dbe9cSPetr Tesarik 	bool late_alloc;
94158dbe9cSPetr Tesarik 	unsigned int nareas;
95158dbe9cSPetr Tesarik 	unsigned int area_nslabs;
96158dbe9cSPetr Tesarik 	struct io_tlb_area *areas;
97158dbe9cSPetr Tesarik 	struct io_tlb_slot *slots;
9879636caaSPetr Tesarik #ifdef CONFIG_SWIOTLB_DYNAMIC
9979636caaSPetr Tesarik 	struct list_head node;
10079636caaSPetr Tesarik 	struct rcu_head rcu;
10179636caaSPetr Tesarik 	bool transient;
10279636caaSPetr Tesarik #endif
103158dbe9cSPetr Tesarik };
104158dbe9cSPetr Tesarik 
105158dbe9cSPetr Tesarik /**
106158dbe9cSPetr Tesarik  * struct io_tlb_mem - Software IO TLB allocator
107158dbe9cSPetr Tesarik  * @defpool:	Default (initial) IO TLB memory pool descriptor.
1081aaa7368SPetr Tesarik  * @pool:	IO TLB memory pool descriptor (if not dynamic).
109158dbe9cSPetr Tesarik  * @nslabs:	Total number of IO TLB slabs in all pools.
11073f62095SClaire Chang  * @debugfs:	The dentry to debugfs.
111903cd0f3SClaire Chang  * @force_bounce: %true if swiotlb bouncing is forced
112f4111e39SClaire Chang  * @for_alloc:  %true if the pool is used for memory allocation
11362708b2bSPetr Tesarik  * @can_grow:	%true if more pools can be allocated dynamically.
114ad96ce32SPetr Tesarik  * @phys_limit:	Maximum allowed physical address.
1151aaa7368SPetr Tesarik  * @lock:	Lock to synchronize changes to the list.
1161aaa7368SPetr Tesarik  * @pools:	List of IO TLB memory pool descriptors (if dynamic).
1171aaa7368SPetr Tesarik  * @dyn_alloc:	Dynamic IO TLB pool allocation work.
1188b0977ecSMichael Kelley  * @total_used:	The total number of slots in the pool that are currently used
1198b0977ecSMichael Kelley  *		across all areas. Used only for calculating used_hiwater in
1208b0977ecSMichael Kelley  *		debugfs.
1218b0977ecSMichael Kelley  * @used_hiwater: The high water mark for total_used.  Used only for reporting
1228b0977ecSMichael Kelley  *		in debugfs.
123*02e76569SZhangPeng  * @transient_nslabs: The total number of slots in all transient pools that
124*02e76569SZhangPeng  *		are currently used across all areas.
12573f62095SClaire Chang  */
12673f62095SClaire Chang struct io_tlb_mem {
127158dbe9cSPetr Tesarik 	struct io_tlb_pool defpool;
12873f62095SClaire Chang 	unsigned long nslabs;
12973f62095SClaire Chang 	struct dentry *debugfs;
130903cd0f3SClaire Chang 	bool force_bounce;
131f4111e39SClaire Chang 	bool for_alloc;
13262708b2bSPetr Tesarik #ifdef CONFIG_SWIOTLB_DYNAMIC
13362708b2bSPetr Tesarik 	bool can_grow;
134ad96ce32SPetr Tesarik 	u64 phys_limit;
1351aaa7368SPetr Tesarik 	spinlock_t lock;
1361aaa7368SPetr Tesarik 	struct list_head pools;
1371aaa7368SPetr Tesarik 	struct work_struct dyn_alloc;
13862708b2bSPetr Tesarik #endif
139ec274affSPetr Tesarik #ifdef CONFIG_DEBUG_FS
1408b0977ecSMichael Kelley 	atomic_long_t total_used;
1418b0977ecSMichael Kelley 	atomic_long_t used_hiwater;
142*02e76569SZhangPeng 	atomic_long_t transient_nslabs;
143ec274affSPetr Tesarik #endif
14473f62095SClaire Chang };
14555897af6SChristoph Hellwig 
14679636caaSPetr Tesarik #ifdef CONFIG_SWIOTLB_DYNAMIC
14779636caaSPetr Tesarik 
14879636caaSPetr Tesarik struct io_tlb_pool *swiotlb_find_pool(struct device *dev, phys_addr_t paddr);
14979636caaSPetr Tesarik 
15079636caaSPetr Tesarik #else
15179636caaSPetr Tesarik 
15279636caaSPetr Tesarik static inline struct io_tlb_pool *swiotlb_find_pool(struct device *dev,
15379636caaSPetr Tesarik 						    phys_addr_t paddr)
15479636caaSPetr Tesarik {
15579636caaSPetr Tesarik 	return &dev->dma_io_tlb_mem->defpool;
15679636caaSPetr Tesarik }
15779636caaSPetr Tesarik 
15879636caaSPetr Tesarik #endif
15979636caaSPetr Tesarik 
160fea18777SPetr Tesarik /**
161fea18777SPetr Tesarik  * is_swiotlb_buffer() - check if a physical address belongs to a swiotlb
162fea18777SPetr Tesarik  * @dev:        Device which has mapped the buffer.
163fea18777SPetr Tesarik  * @paddr:      Physical address within the DMA buffer.
164fea18777SPetr Tesarik  *
165fea18777SPetr Tesarik  * Check if @paddr points into a bounce buffer.
166fea18777SPetr Tesarik  *
167fea18777SPetr Tesarik  * Return:
168fea18777SPetr Tesarik  * * %true if @paddr points into a bounce buffer
169fea18777SPetr Tesarik  * * %false otherwise
170fea18777SPetr Tesarik  */
1717fd856aaSClaire Chang static inline bool is_swiotlb_buffer(struct device *dev, phys_addr_t paddr)
17255897af6SChristoph Hellwig {
1737fd856aaSClaire Chang 	struct io_tlb_mem *mem = dev->dma_io_tlb_mem;
17473f62095SClaire Chang 
17579636caaSPetr Tesarik 	if (!mem)
17679636caaSPetr Tesarik 		return false;
17779636caaSPetr Tesarik 
1782d5780bbSPetr Tesarik #ifdef CONFIG_SWIOTLB_DYNAMIC
1792d5780bbSPetr Tesarik 	/*
1802d5780bbSPetr Tesarik 	 * All SWIOTLB buffer addresses must have been returned by
1812d5780bbSPetr Tesarik 	 * swiotlb_tbl_map_single() and passed to a device driver.
1822d5780bbSPetr Tesarik 	 * If a SWIOTLB address is checked on another CPU, then it was
1832d5780bbSPetr Tesarik 	 * presumably loaded by the device driver from an unspecified private
1842d5780bbSPetr Tesarik 	 * data structure. Make sure that this load is ordered before reading
1852d5780bbSPetr Tesarik 	 * dev->dma_uses_io_tlb here and mem->pools in swiotlb_find_pool().
1862d5780bbSPetr Tesarik 	 *
1872d5780bbSPetr Tesarik 	 * This barrier pairs with smp_mb() in swiotlb_find_slots().
1881395706aSPetr Tesarik 	 */
1891395706aSPetr Tesarik 	smp_rmb();
1902d5780bbSPetr Tesarik 	return READ_ONCE(dev->dma_uses_io_tlb) &&
1912d5780bbSPetr Tesarik 		swiotlb_find_pool(dev, paddr);
1922d5780bbSPetr Tesarik #else
19379636caaSPetr Tesarik 	return paddr >= mem->defpool.start && paddr < mem->defpool.end;
1942d5780bbSPetr Tesarik #endif
19555897af6SChristoph Hellwig }
19655897af6SChristoph Hellwig 
197903cd0f3SClaire Chang static inline bool is_swiotlb_force_bounce(struct device *dev)
198903cd0f3SClaire Chang {
199903cd0f3SClaire Chang 	struct io_tlb_mem *mem = dev->dma_io_tlb_mem;
200903cd0f3SClaire Chang 
201903cd0f3SClaire Chang 	return mem && mem->force_bounce;
202903cd0f3SClaire Chang }
203903cd0f3SClaire Chang 
204c6af2aa9SChristoph Hellwig void swiotlb_init(bool addressing_limited, unsigned int flags);
20555897af6SChristoph Hellwig void __init swiotlb_exit(void);
20605ee7741SPetr Tesarik void swiotlb_dev_init(struct device *dev);
207abe420bfSJoerg Roedel size_t swiotlb_max_mapping_size(struct device *dev);
20805ee7741SPetr Tesarik bool is_swiotlb_allocated(void);
2096f2beb26SClaire Chang bool is_swiotlb_active(struct device *dev);
2102d29960aSChristoph Hellwig void __init swiotlb_adjust_size(unsigned long size);
21105ee7741SPetr Tesarik phys_addr_t default_swiotlb_base(void);
21205ee7741SPetr Tesarik phys_addr_t default_swiotlb_limit(void);
2135740afdbSFUJITA Tomonori #else
214c6af2aa9SChristoph Hellwig static inline void swiotlb_init(bool addressing_limited, unsigned int flags)
215c6af2aa9SChristoph Hellwig {
216c6af2aa9SChristoph Hellwig }
21705ee7741SPetr Tesarik 
21805ee7741SPetr Tesarik static inline void swiotlb_dev_init(struct device *dev)
21905ee7741SPetr Tesarik {
22005ee7741SPetr Tesarik }
22105ee7741SPetr Tesarik 
2227fd856aaSClaire Chang static inline bool is_swiotlb_buffer(struct device *dev, phys_addr_t paddr)
22355897af6SChristoph Hellwig {
22455897af6SChristoph Hellwig 	return false;
22555897af6SChristoph Hellwig }
226903cd0f3SClaire Chang static inline bool is_swiotlb_force_bounce(struct device *dev)
227903cd0f3SClaire Chang {
228903cd0f3SClaire Chang 	return false;
229903cd0f3SClaire Chang }
23055897af6SChristoph Hellwig static inline void swiotlb_exit(void)
23155897af6SChristoph Hellwig {
23255897af6SChristoph Hellwig }
233abe420bfSJoerg Roedel static inline size_t swiotlb_max_mapping_size(struct device *dev)
234abe420bfSJoerg Roedel {
235abe420bfSJoerg Roedel 	return SIZE_MAX;
236abe420bfSJoerg Roedel }
237492366f7SJoerg Roedel 
23805ee7741SPetr Tesarik static inline bool is_swiotlb_allocated(void)
23905ee7741SPetr Tesarik {
24005ee7741SPetr Tesarik 	return false;
24105ee7741SPetr Tesarik }
24205ee7741SPetr Tesarik 
2436f2beb26SClaire Chang static inline bool is_swiotlb_active(struct device *dev)
244492366f7SJoerg Roedel {
245492366f7SJoerg Roedel 	return false;
246492366f7SJoerg Roedel }
247e998879dSAshish Kalra 
2482d29960aSChristoph Hellwig static inline void swiotlb_adjust_size(unsigned long size)
249e998879dSAshish Kalra {
250e998879dSAshish Kalra }
25105ee7741SPetr Tesarik 
25205ee7741SPetr Tesarik static inline phys_addr_t default_swiotlb_base(void)
25305ee7741SPetr Tesarik {
25405ee7741SPetr Tesarik 	return 0;
25505ee7741SPetr Tesarik }
25605ee7741SPetr Tesarik 
25705ee7741SPetr Tesarik static inline phys_addr_t default_swiotlb_limit(void)
25805ee7741SPetr Tesarik {
25905ee7741SPetr Tesarik 	return 0;
26005ee7741SPetr Tesarik }
26155897af6SChristoph Hellwig #endif /* CONFIG_SWIOTLB */
2625740afdbSFUJITA Tomonori 
263ad32e8cbSFUJITA Tomonori extern void swiotlb_print_info(void);
2649c5a3621SAkinobu Mita 
265f4111e39SClaire Chang #ifdef CONFIG_DMA_RESTRICTED_POOL
266f4111e39SClaire Chang struct page *swiotlb_alloc(struct device *dev, size_t size);
267f4111e39SClaire Chang bool swiotlb_free(struct device *dev, struct page *page, size_t size);
268f4111e39SClaire Chang 
269f4111e39SClaire Chang static inline bool is_swiotlb_for_alloc(struct device *dev)
270f4111e39SClaire Chang {
271f4111e39SClaire Chang 	return dev->dma_io_tlb_mem->for_alloc;
272f4111e39SClaire Chang }
273f4111e39SClaire Chang #else
274f4111e39SClaire Chang static inline struct page *swiotlb_alloc(struct device *dev, size_t size)
275f4111e39SClaire Chang {
276f4111e39SClaire Chang 	return NULL;
277f4111e39SClaire Chang }
278f4111e39SClaire Chang static inline bool swiotlb_free(struct device *dev, struct page *page,
279f4111e39SClaire Chang 				size_t size)
280f4111e39SClaire Chang {
281f4111e39SClaire Chang 	return false;
282f4111e39SClaire Chang }
283f4111e39SClaire Chang static inline bool is_swiotlb_for_alloc(struct device *dev)
284f4111e39SClaire Chang {
285f4111e39SClaire Chang 	return false;
286f4111e39SClaire Chang }
287f4111e39SClaire Chang #endif /* CONFIG_DMA_RESTRICTED_POOL */
288f4111e39SClaire Chang 
2891648993fSJoerg Roedel #endif /* __LINUX_SWIOTLB_H */
290