1 // SPDX-License-Identifier: GPL-2.0 2 #include <linux/memblock.h> 3 #include <linux/compiler.h> 4 #include <linux/fs.h> 5 #include <linux/init.h> 6 #include <linux/ksm.h> 7 #include <linux/mm.h> 8 #include <linux/mmzone.h> 9 #include <linux/huge_mm.h> 10 #include <linux/proc_fs.h> 11 #include <linux/seq_file.h> 12 #include <linux/hugetlb.h> 13 #include <linux/memcontrol.h> 14 #include <linux/mmu_notifier.h> 15 #include <linux/page_idle.h> 16 #include <linux/kernel-page-flags.h> 17 #include <linux/uaccess.h> 18 #include "internal.h" 19 20 #define KPMSIZE sizeof(u64) 21 #define KPMMASK (KPMSIZE - 1) 22 #define KPMBITS (KPMSIZE * BITS_PER_BYTE) 23 24 /* /proc/kpagecount - an array exposing page counts 25 * 26 * Each entry is a u64 representing the corresponding 27 * physical page count. 28 */ 29 static ssize_t kpagecount_read(struct file *file, char __user *buf, 30 size_t count, loff_t *ppos) 31 { 32 u64 __user *out = (u64 __user *)buf; 33 struct page *ppage; 34 unsigned long src = *ppos; 35 unsigned long pfn; 36 ssize_t ret = 0; 37 u64 pcount; 38 39 pfn = src / KPMSIZE; 40 count = min_t(size_t, count, (max_pfn * KPMSIZE) - src); 41 if (src & KPMMASK || count & KPMMASK) 42 return -EINVAL; 43 44 while (count > 0) { 45 /* 46 * TODO: ZONE_DEVICE support requires to identify 47 * memmaps that were actually initialized. 48 */ 49 ppage = pfn_to_online_page(pfn); 50 51 if (!ppage || PageSlab(ppage) || page_has_type(ppage)) 52 pcount = 0; 53 else 54 pcount = page_mapcount(ppage); 55 56 if (put_user(pcount, out)) { 57 ret = -EFAULT; 58 break; 59 } 60 61 pfn++; 62 out++; 63 count -= KPMSIZE; 64 65 cond_resched(); 66 } 67 68 *ppos += (char __user *)out - buf; 69 if (!ret) 70 ret = (char __user *)out - buf; 71 return ret; 72 } 73 74 static const struct file_operations proc_kpagecount_operations = { 75 .llseek = mem_lseek, 76 .read = kpagecount_read, 77 }; 78 79 /* /proc/kpageflags - an array exposing page flags 80 * 81 * Each entry is a u64 representing the corresponding 82 * physical page flags. 83 */ 84 85 static inline u64 kpf_copy_bit(u64 kflags, int ubit, int kbit) 86 { 87 return ((kflags >> kbit) & 1) << ubit; 88 } 89 90 u64 stable_page_flags(struct page *page) 91 { 92 u64 k; 93 u64 u; 94 95 /* 96 * pseudo flag: KPF_NOPAGE 97 * it differentiates a memory hole from a page with no flags 98 */ 99 if (!page) 100 return 1 << KPF_NOPAGE; 101 102 k = page->flags; 103 u = 0; 104 105 /* 106 * pseudo flags for the well known (anonymous) memory mapped pages 107 * 108 * Note that page->_mapcount is overloaded in SLOB/SLUB/SLQB, so the 109 * simple test in page_mapped() is not enough. 110 */ 111 if (!PageSlab(page) && page_mapped(page)) 112 u |= 1 << KPF_MMAP; 113 if (PageAnon(page)) 114 u |= 1 << KPF_ANON; 115 if (PageKsm(page)) 116 u |= 1 << KPF_KSM; 117 118 /* 119 * compound pages: export both head/tail info 120 * they together define a compound page's start/end pos and order 121 */ 122 if (PageHead(page)) 123 u |= 1 << KPF_COMPOUND_HEAD; 124 if (PageTail(page)) 125 u |= 1 << KPF_COMPOUND_TAIL; 126 if (PageHuge(page)) 127 u |= 1 << KPF_HUGE; 128 /* 129 * PageTransCompound can be true for non-huge compound pages (slab 130 * pages or pages allocated by drivers with __GFP_COMP) because it 131 * just checks PG_head/PG_tail, so we need to check PageLRU/PageAnon 132 * to make sure a given page is a thp, not a non-huge compound page. 133 */ 134 else if (PageTransCompound(page)) { 135 struct page *head = compound_head(page); 136 137 if (PageLRU(head) || PageAnon(head)) 138 u |= 1 << KPF_THP; 139 else if (is_huge_zero_page(head)) { 140 u |= 1 << KPF_ZERO_PAGE; 141 u |= 1 << KPF_THP; 142 } 143 } else if (is_zero_pfn(page_to_pfn(page))) 144 u |= 1 << KPF_ZERO_PAGE; 145 146 147 /* 148 * Caveats on high order pages: page->_refcount will only be set 149 * -1 on the head page; SLUB/SLQB do the same for PG_slab; 150 * SLOB won't set PG_slab at all on compound pages. 151 */ 152 if (PageBuddy(page)) 153 u |= 1 << KPF_BUDDY; 154 else if (page_count(page) == 0 && is_free_buddy_page(page)) 155 u |= 1 << KPF_BUDDY; 156 157 if (PageOffline(page)) 158 u |= 1 << KPF_OFFLINE; 159 if (PageTable(page)) 160 u |= 1 << KPF_PGTABLE; 161 162 if (page_is_idle(page)) 163 u |= 1 << KPF_IDLE; 164 165 u |= kpf_copy_bit(k, KPF_LOCKED, PG_locked); 166 167 u |= kpf_copy_bit(k, KPF_SLAB, PG_slab); 168 if (PageTail(page) && PageSlab(compound_head(page))) 169 u |= 1 << KPF_SLAB; 170 171 u |= kpf_copy_bit(k, KPF_ERROR, PG_error); 172 u |= kpf_copy_bit(k, KPF_DIRTY, PG_dirty); 173 u |= kpf_copy_bit(k, KPF_UPTODATE, PG_uptodate); 174 u |= kpf_copy_bit(k, KPF_WRITEBACK, PG_writeback); 175 176 u |= kpf_copy_bit(k, KPF_LRU, PG_lru); 177 u |= kpf_copy_bit(k, KPF_REFERENCED, PG_referenced); 178 u |= kpf_copy_bit(k, KPF_ACTIVE, PG_active); 179 u |= kpf_copy_bit(k, KPF_RECLAIM, PG_reclaim); 180 181 if (PageSwapCache(page)) 182 u |= 1 << KPF_SWAPCACHE; 183 u |= kpf_copy_bit(k, KPF_SWAPBACKED, PG_swapbacked); 184 185 u |= kpf_copy_bit(k, KPF_UNEVICTABLE, PG_unevictable); 186 u |= kpf_copy_bit(k, KPF_MLOCKED, PG_mlocked); 187 188 #ifdef CONFIG_MEMORY_FAILURE 189 u |= kpf_copy_bit(k, KPF_HWPOISON, PG_hwpoison); 190 #endif 191 192 #ifdef CONFIG_ARCH_USES_PG_UNCACHED 193 u |= kpf_copy_bit(k, KPF_UNCACHED, PG_uncached); 194 #endif 195 196 u |= kpf_copy_bit(k, KPF_RESERVED, PG_reserved); 197 u |= kpf_copy_bit(k, KPF_MAPPEDTODISK, PG_mappedtodisk); 198 u |= kpf_copy_bit(k, KPF_PRIVATE, PG_private); 199 u |= kpf_copy_bit(k, KPF_PRIVATE_2, PG_private_2); 200 u |= kpf_copy_bit(k, KPF_OWNER_PRIVATE, PG_owner_priv_1); 201 u |= kpf_copy_bit(k, KPF_ARCH, PG_arch_1); 202 203 return u; 204 }; 205 206 static ssize_t kpageflags_read(struct file *file, char __user *buf, 207 size_t count, loff_t *ppos) 208 { 209 u64 __user *out = (u64 __user *)buf; 210 struct page *ppage; 211 unsigned long src = *ppos; 212 unsigned long pfn; 213 ssize_t ret = 0; 214 215 pfn = src / KPMSIZE; 216 count = min_t(unsigned long, count, (max_pfn * KPMSIZE) - src); 217 if (src & KPMMASK || count & KPMMASK) 218 return -EINVAL; 219 220 while (count > 0) { 221 /* 222 * TODO: ZONE_DEVICE support requires to identify 223 * memmaps that were actually initialized. 224 */ 225 ppage = pfn_to_online_page(pfn); 226 227 if (put_user(stable_page_flags(ppage), out)) { 228 ret = -EFAULT; 229 break; 230 } 231 232 pfn++; 233 out++; 234 count -= KPMSIZE; 235 236 cond_resched(); 237 } 238 239 *ppos += (char __user *)out - buf; 240 if (!ret) 241 ret = (char __user *)out - buf; 242 return ret; 243 } 244 245 static const struct file_operations proc_kpageflags_operations = { 246 .llseek = mem_lseek, 247 .read = kpageflags_read, 248 }; 249 250 #ifdef CONFIG_MEMCG 251 static ssize_t kpagecgroup_read(struct file *file, char __user *buf, 252 size_t count, loff_t *ppos) 253 { 254 u64 __user *out = (u64 __user *)buf; 255 struct page *ppage; 256 unsigned long src = *ppos; 257 unsigned long pfn; 258 ssize_t ret = 0; 259 u64 ino; 260 261 pfn = src / KPMSIZE; 262 count = min_t(unsigned long, count, (max_pfn * KPMSIZE) - src); 263 if (src & KPMMASK || count & KPMMASK) 264 return -EINVAL; 265 266 while (count > 0) { 267 /* 268 * TODO: ZONE_DEVICE support requires to identify 269 * memmaps that were actually initialized. 270 */ 271 ppage = pfn_to_online_page(pfn); 272 273 if (ppage) 274 ino = page_cgroup_ino(ppage); 275 else 276 ino = 0; 277 278 if (put_user(ino, out)) { 279 ret = -EFAULT; 280 break; 281 } 282 283 pfn++; 284 out++; 285 count -= KPMSIZE; 286 287 cond_resched(); 288 } 289 290 *ppos += (char __user *)out - buf; 291 if (!ret) 292 ret = (char __user *)out - buf; 293 return ret; 294 } 295 296 static const struct file_operations proc_kpagecgroup_operations = { 297 .llseek = mem_lseek, 298 .read = kpagecgroup_read, 299 }; 300 #endif /* CONFIG_MEMCG */ 301 302 static int __init proc_page_init(void) 303 { 304 proc_create("kpagecount", S_IRUSR, NULL, &proc_kpagecount_operations); 305 proc_create("kpageflags", S_IRUSR, NULL, &proc_kpageflags_operations); 306 #ifdef CONFIG_MEMCG 307 proc_create("kpagecgroup", S_IRUSR, NULL, &proc_kpagecgroup_operations); 308 #endif 309 return 0; 310 } 311 fs_initcall(proc_page_init); 312