xref: /kvm-unit-tests/lib/alloc_page.h (revision 9f0ae3012430ed7072d04247fb674125c616a6b4)
15aca024eSPaolo Bonzini /*
25aca024eSPaolo Bonzini  * This work is licensed under the terms of the GNU LGPL, version 2.
35aca024eSPaolo Bonzini  *
45aca024eSPaolo Bonzini  * This is a simple allocator that provides contiguous physical addresses
55aca024eSPaolo Bonzini  * with byte granularity.
65aca024eSPaolo Bonzini  */
75aca024eSPaolo Bonzini 
8*9f0ae301SCornelia Huck #ifndef _ALLOC_PAGE_H_
9*9f0ae301SCornelia Huck #define _ALLOC_PAGE_H_
105aca024eSPaolo Bonzini 
1101d8952bSClaudio Imbrenda #include <stdbool.h>
128131e91aSClaudio Imbrenda #include <asm/memory_areas.h>
138131e91aSClaudio Imbrenda 
14322cdd64SClaudio Imbrenda #define AREA_ANY_NUMBER	0xff
15322cdd64SClaudio Imbrenda 
16550b4683SClaudio Imbrenda #define AREA_ANY	0x00000
17550b4683SClaudio Imbrenda #define AREA_MASK	0x0ffff
18550b4683SClaudio Imbrenda 
19550b4683SClaudio Imbrenda #define FLAG_DONTZERO	0x10000
20550b4683SClaudio Imbrenda #define FLAG_FRESH	0x20000
21550b4683SClaudio Imbrenda 
228131e91aSClaudio Imbrenda /* Returns true if the page allocator has been initialized */
23bf62a925SAndrew Jones bool page_alloc_initialized(void);
248131e91aSClaudio Imbrenda 
258131e91aSClaudio Imbrenda /*
268131e91aSClaudio Imbrenda  * Initializes a memory area.
278131e91aSClaudio Imbrenda  * n is the number of the area to initialize
288131e91aSClaudio Imbrenda  * base_pfn is the physical frame number of the start of the area to initialize
298131e91aSClaudio Imbrenda  * top_pfn is the physical frame number of the first page immediately after
308131e91aSClaudio Imbrenda  * the end of the area to initialize
318131e91aSClaudio Imbrenda  */
3201d8952bSClaudio Imbrenda void page_alloc_init_area(u8 n, phys_addr_t base_pfn, phys_addr_t top_pfn);
338131e91aSClaudio Imbrenda 
348131e91aSClaudio Imbrenda /* Enables the page allocator. At least one area must have been initialized */
35be60de6fSAndrew Jones void page_alloc_ops_enable(void);
368131e91aSClaudio Imbrenda 
378131e91aSClaudio Imbrenda /*
38550b4683SClaudio Imbrenda  * Allocate aligned memory with the specified flags.
39550b4683SClaudio Imbrenda  * flags is a bitmap of allowed areas and flags.
408131e91aSClaudio Imbrenda  * alignment must be a power of 2
418131e91aSClaudio Imbrenda  */
42550b4683SClaudio Imbrenda void *memalign_pages_flags(size_t alignment, size_t size, unsigned int flags);
438131e91aSClaudio Imbrenda 
448131e91aSClaudio Imbrenda /*
45550b4683SClaudio Imbrenda  * Allocate aligned memory from any area and with default flags.
46550b4683SClaudio Imbrenda  * Equivalent to memalign_pages_flags(alignment, size, AREA_ANY).
478131e91aSClaudio Imbrenda  */
4801d8952bSClaudio Imbrenda static inline void *memalign_pages(size_t alignment, size_t size)
4901d8952bSClaudio Imbrenda {
50550b4683SClaudio Imbrenda 	return memalign_pages_flags(alignment, size, AREA_ANY);
5101d8952bSClaudio Imbrenda }
528131e91aSClaudio Imbrenda 
538131e91aSClaudio Imbrenda /*
54550b4683SClaudio Imbrenda  * Allocate 1ull << order naturally aligned pages with the specified flags.
55550b4683SClaudio Imbrenda  * Equivalent to memalign_pages_flags(1ull << order, 1ull << order, flags).
568131e91aSClaudio Imbrenda  */
57550b4683SClaudio Imbrenda void *alloc_pages_flags(unsigned int order, unsigned int flags);
588131e91aSClaudio Imbrenda 
598131e91aSClaudio Imbrenda /*
60550b4683SClaudio Imbrenda  * Allocate 1ull << order naturally aligned pages from any area and with
61550b4683SClaudio Imbrenda  * default flags.
62550b4683SClaudio Imbrenda  * Equivalent to alloc_pages_flags(order, AREA_ANY);
6301d8952bSClaudio Imbrenda  */
6401d8952bSClaudio Imbrenda static inline void *alloc_pages(unsigned int order)
6501d8952bSClaudio Imbrenda {
66550b4683SClaudio Imbrenda 	return alloc_pages_flags(order, AREA_ANY);
6701d8952bSClaudio Imbrenda }
6801d8952bSClaudio Imbrenda 
6901d8952bSClaudio Imbrenda /*
70550b4683SClaudio Imbrenda  * Allocate one page from any area and with default flags.
718131e91aSClaudio Imbrenda  * Equivalent to alloc_pages(0);
728131e91aSClaudio Imbrenda  */
7301d8952bSClaudio Imbrenda static inline void *alloc_page(void)
7401d8952bSClaudio Imbrenda {
7501d8952bSClaudio Imbrenda 	return alloc_pages(0);
7601d8952bSClaudio Imbrenda }
778131e91aSClaudio Imbrenda 
788131e91aSClaudio Imbrenda /*
798131e91aSClaudio Imbrenda  * Frees a memory block allocated with any of the memalign_pages* or
808131e91aSClaudio Imbrenda  * alloc_pages* functions.
818131e91aSClaudio Imbrenda  * The pointer must point to the start of the block.
828131e91aSClaudio Imbrenda  */
83f90ddba3SClaudio Imbrenda void free_pages(void *mem);
848131e91aSClaudio Imbrenda 
8501d8952bSClaudio Imbrenda /*
8601d8952bSClaudio Imbrenda  * Free one page.
8701d8952bSClaudio Imbrenda  * Equivalent to free_pages(mem).
8801d8952bSClaudio Imbrenda  */
898131e91aSClaudio Imbrenda static inline void free_page(void *mem)
908131e91aSClaudio Imbrenda {
91550b4683SClaudio Imbrenda 	free_pages(mem);
928131e91aSClaudio Imbrenda }
938131e91aSClaudio Imbrenda 
9401d8952bSClaudio Imbrenda /*
9501d8952bSClaudio Imbrenda  * Free pages by order.
9601d8952bSClaudio Imbrenda  * Equivalent to free_pages(mem).
9701d8952bSClaudio Imbrenda  */
988131e91aSClaudio Imbrenda static inline void free_pages_by_order(void *mem, unsigned int order)
998131e91aSClaudio Imbrenda {
100f90ddba3SClaudio Imbrenda 	free_pages(mem);
1018131e91aSClaudio Imbrenda }
1025aca024eSPaolo Bonzini 
10334c95065SClaudio Imbrenda /*
10401d8952bSClaudio Imbrenda  * Reserves the specified physical memory range if possible.
10501d8952bSClaudio Imbrenda  * If the specified range cannot be reserved in its entirety, no action is
10601d8952bSClaudio Imbrenda  * performed and -1 is returned.
10701d8952bSClaudio Imbrenda  *
10801d8952bSClaudio Imbrenda  * Returns 0 in case of success, -1 otherwise.
10934c95065SClaudio Imbrenda  */
11001d8952bSClaudio Imbrenda int reserve_pages(phys_addr_t addr, size_t npages);
11134c95065SClaudio Imbrenda 
11234c95065SClaudio Imbrenda /*
11334c95065SClaudio Imbrenda  * Frees a reserved memory range that had been reserved with
11401d8952bSClaudio Imbrenda  * reserve_pages.
11534c95065SClaudio Imbrenda  * The memory range does not need to match a previous allocation
11634c95065SClaudio Imbrenda  * exactly, it can also be a subset, in which case only the specified
11734c95065SClaudio Imbrenda  * pages will be freed and unreserved.
11834c95065SClaudio Imbrenda  */
11901d8952bSClaudio Imbrenda void unreserve_pages(phys_addr_t addr, size_t npages);
12034c95065SClaudio Imbrenda 
1215aca024eSPaolo Bonzini #endif
122