1baa489faSSeongJae Park /* SPDX-License-Identifier: GPL-2.0 */
2baa489faSSeongJae Park #include <stdint.h>
3baa489faSSeongJae Park #include <stdbool.h>
4af605d26SPeter Xu #include <sys/mman.h>
5af605d26SPeter Xu #include <err.h>
6*782baf52SEdward Liaw #include <strings.h> /* ffsl() */
7af605d26SPeter Xu #include <unistd.h> /* _SC_PAGESIZE */
8af605d26SPeter Xu 
99f74696bSPeter Xu #define BIT_ULL(nr)                   (1ULL << (nr))
109f74696bSPeter Xu #define PM_SOFT_DIRTY                 BIT_ULL(55)
119f74696bSPeter Xu #define PM_MMAP_EXCLUSIVE             BIT_ULL(56)
129f74696bSPeter Xu #define PM_UFFD_WP                    BIT_ULL(57)
139f74696bSPeter Xu #define PM_FILE                       BIT_ULL(61)
149f74696bSPeter Xu #define PM_SWAP                       BIT_ULL(62)
159f74696bSPeter Xu #define PM_PRESENT                    BIT_ULL(63)
169f74696bSPeter Xu 
17af605d26SPeter Xu extern unsigned int __page_size;
18af605d26SPeter Xu extern unsigned int __page_shift;
19af605d26SPeter Xu 
psize(void)20af605d26SPeter Xu static inline unsigned int psize(void)
21af605d26SPeter Xu {
22af605d26SPeter Xu 	if (!__page_size)
23af605d26SPeter Xu 		__page_size = sysconf(_SC_PAGESIZE);
24af605d26SPeter Xu 	return __page_size;
25af605d26SPeter Xu }
26af605d26SPeter Xu 
pshift(void)27af605d26SPeter Xu static inline unsigned int pshift(void)
28af605d26SPeter Xu {
29af605d26SPeter Xu 	if (!__page_shift)
30af605d26SPeter Xu 		__page_shift = (ffsl(psize()) - 1);
31af605d26SPeter Xu 	return __page_shift;
32af605d26SPeter Xu }
33baa489faSSeongJae Park 
34baa489faSSeongJae Park uint64_t pagemap_get_entry(int fd, char *start);
35baa489faSSeongJae Park bool pagemap_is_softdirty(int fd, char *start);
36baa489faSSeongJae Park bool pagemap_is_swapped(int fd, char *start);
37baa489faSSeongJae Park bool pagemap_is_populated(int fd, char *start);
38baa489faSSeongJae Park unsigned long pagemap_get_pfn(int fd, char *start);
39baa489faSSeongJae Park void clear_softdirty(void);
40baa489faSSeongJae Park bool check_for_pattern(FILE *fp, const char *pattern, char *buf, size_t len);
41baa489faSSeongJae Park uint64_t read_pmd_pagesize(void);
42baa489faSSeongJae Park bool check_huge_anon(void *addr, int nr_hpages, uint64_t hpage_size);
43baa489faSSeongJae Park bool check_huge_file(void *addr, int nr_hpages, uint64_t hpage_size);
44baa489faSSeongJae Park bool check_huge_shmem(void *addr, int nr_hpages, uint64_t hpage_size);
45af605d26SPeter Xu int64_t allocate_transhuge(void *ptr, int pagemap_fd);
46bd4d67e7SPeter Xu unsigned long default_huge_page_size(void);
4781b1e3f9SDavid Hildenbrand int detect_hugetlb_page_sizes(size_t sizes[], int max);
48af605d26SPeter Xu 
49c4277cb6SPeter Xu int uffd_register(int uffd, void *addr, uint64_t len,
50c4277cb6SPeter Xu 		  bool miss, bool wp, bool minor);
51c4277cb6SPeter Xu int uffd_unregister(int uffd, void *addr, uint64_t len);
52c3315502SPeter Xu int uffd_register_with_ioctls(int uffd, void *addr, uint64_t len,
53c3315502SPeter Xu 			      bool miss, bool wp, bool minor, uint64_t *ioctls);
54c4277cb6SPeter Xu 
55af605d26SPeter Xu /*
56af605d26SPeter Xu  * On ppc64 this will only work with radix 2M hugepage size
57af605d26SPeter Xu  */
58af605d26SPeter Xu #define HPAGE_SHIFT 21
59af605d26SPeter Xu #define HPAGE_SIZE (1 << HPAGE_SHIFT)
60af605d26SPeter Xu 
61af605d26SPeter Xu #define PAGEMAP_PRESENT(ent)	(((ent) & (1ull << 63)) != 0)
62af605d26SPeter Xu #define PAGEMAP_PFN(ent)	((ent) & ((1ull << 55) - 1))
63