hc
2024-05-10 9999e48639b3cecb08ffb37358bcba3b48161b29
kernel/fs/proc/page.c
....@@ -1,5 +1,5 @@
11 // SPDX-License-Identifier: GPL-2.0
2
-#include <linux/bootmem.h>
2
+#include <linux/memblock.h>
33 #include <linux/compiler.h>
44 #include <linux/fs.h>
55 #include <linux/init.h>
....@@ -21,6 +21,21 @@
2121 #define KPMMASK (KPMSIZE - 1)
2222 #define KPMBITS (KPMSIZE * BITS_PER_BYTE)
2323
24
+static inline unsigned long get_max_dump_pfn(void)
25
+{
26
+#ifdef CONFIG_SPARSEMEM
27
+ /*
28
+ * The memmap of early sections is completely populated and marked
29
+ * online even if max_pfn does not fall on a section boundary -
30
+ * pfn_to_online_page() will succeed on all pages. Allow inspecting
31
+ * these memmaps.
32
+ */
33
+ return round_up(max_pfn, PAGES_PER_SECTION);
34
+#else
35
+ return max_pfn;
36
+#endif
37
+}
38
+
2439 /* /proc/kpagecount - an array exposing page counts
2540 *
2641 * Each entry is a u64 representing the corresponding
....@@ -29,6 +44,7 @@
2944 static ssize_t kpagecount_read(struct file *file, char __user *buf,
3045 size_t count, loff_t *ppos)
3146 {
47
+ const unsigned long max_dump_pfn = get_max_dump_pfn();
3248 u64 __user *out = (u64 __user *)buf;
3349 struct page *ppage;
3450 unsigned long src = *ppos;
....@@ -37,9 +53,11 @@
3753 u64 pcount;
3854
3955 pfn = src / KPMSIZE;
40
- count = min_t(size_t, count, (max_pfn * KPMSIZE) - src);
4156 if (src & KPMMASK || count & KPMMASK)
4257 return -EINVAL;
58
+ if (src >= max_dump_pfn * KPMSIZE)
59
+ return 0;
60
+ count = min_t(unsigned long, count, (max_dump_pfn * KPMSIZE) - src);
4361
4462 while (count > 0) {
4563 /*
....@@ -48,7 +66,7 @@
4866 */
4967 ppage = pfn_to_online_page(pfn);
5068
51
- if (!ppage || PageSlab(ppage))
69
+ if (!ppage || PageSlab(ppage) || page_has_type(ppage))
5270 pcount = 0;
5371 else
5472 pcount = page_mapcount(ppage);
....@@ -71,9 +89,9 @@
7189 return ret;
7290 }
7391
74
-static const struct file_operations proc_kpagecount_operations = {
75
- .llseek = mem_lseek,
76
- .read = kpagecount_read,
92
+static const struct proc_ops kpagecount_proc_ops = {
93
+ .proc_lseek = mem_lseek,
94
+ .proc_read = kpagecount_read,
7795 };
7896
7997 /* /proc/kpageflags - an array exposing page flags
....@@ -154,8 +172,8 @@
154172 else if (page_count(page) == 0 && is_free_buddy_page(page))
155173 u |= 1 << KPF_BUDDY;
156174
157
- if (PageBalloon(page))
158
- u |= 1 << KPF_BALLOON;
175
+ if (PageOffline(page))
176
+ u |= 1 << KPF_OFFLINE;
159177 if (PageTable(page))
160178 u |= 1 << KPF_PGTABLE;
161179
....@@ -199,6 +217,9 @@
199217 u |= kpf_copy_bit(k, KPF_PRIVATE_2, PG_private_2);
200218 u |= kpf_copy_bit(k, KPF_OWNER_PRIVATE, PG_owner_priv_1);
201219 u |= kpf_copy_bit(k, KPF_ARCH, PG_arch_1);
220
+#ifdef CONFIG_64BIT
221
+ u |= kpf_copy_bit(k, KPF_ARCH_2, PG_arch_2);
222
+#endif
202223
203224 return u;
204225 };
....@@ -206,6 +227,7 @@
206227 static ssize_t kpageflags_read(struct file *file, char __user *buf,
207228 size_t count, loff_t *ppos)
208229 {
230
+ const unsigned long max_dump_pfn = get_max_dump_pfn();
209231 u64 __user *out = (u64 __user *)buf;
210232 struct page *ppage;
211233 unsigned long src = *ppos;
....@@ -213,9 +235,11 @@
213235 ssize_t ret = 0;
214236
215237 pfn = src / KPMSIZE;
216
- count = min_t(unsigned long, count, (max_pfn * KPMSIZE) - src);
217238 if (src & KPMMASK || count & KPMMASK)
218239 return -EINVAL;
240
+ if (src >= max_dump_pfn * KPMSIZE)
241
+ return 0;
242
+ count = min_t(unsigned long, count, (max_dump_pfn * KPMSIZE) - src);
219243
220244 while (count > 0) {
221245 /*
....@@ -242,15 +266,16 @@
242266 return ret;
243267 }
244268
245
-static const struct file_operations proc_kpageflags_operations = {
246
- .llseek = mem_lseek,
247
- .read = kpageflags_read,
269
+static const struct proc_ops kpageflags_proc_ops = {
270
+ .proc_lseek = mem_lseek,
271
+ .proc_read = kpageflags_read,
248272 };
249273
250274 #ifdef CONFIG_MEMCG
251275 static ssize_t kpagecgroup_read(struct file *file, char __user *buf,
252276 size_t count, loff_t *ppos)
253277 {
278
+ const unsigned long max_dump_pfn = get_max_dump_pfn();
254279 u64 __user *out = (u64 __user *)buf;
255280 struct page *ppage;
256281 unsigned long src = *ppos;
....@@ -259,9 +284,11 @@
259284 u64 ino;
260285
261286 pfn = src / KPMSIZE;
262
- count = min_t(unsigned long, count, (max_pfn * KPMSIZE) - src);
263287 if (src & KPMMASK || count & KPMMASK)
264288 return -EINVAL;
289
+ if (src >= max_dump_pfn * KPMSIZE)
290
+ return 0;
291
+ count = min_t(unsigned long, count, (max_dump_pfn * KPMSIZE) - src);
265292
266293 while (count > 0) {
267294 /*
....@@ -293,18 +320,18 @@
293320 return ret;
294321 }
295322
296
-static const struct file_operations proc_kpagecgroup_operations = {
297
- .llseek = mem_lseek,
298
- .read = kpagecgroup_read,
323
+static const struct proc_ops kpagecgroup_proc_ops = {
324
+ .proc_lseek = mem_lseek,
325
+ .proc_read = kpagecgroup_read,
299326 };
300327 #endif /* CONFIG_MEMCG */
301328
302329 static int __init proc_page_init(void)
303330 {
304
- proc_create("kpagecount", S_IRUSR, NULL, &proc_kpagecount_operations);
305
- proc_create("kpageflags", S_IRUSR, NULL, &proc_kpageflags_operations);
331
+ proc_create("kpagecount", S_IRUSR, NULL, &kpagecount_proc_ops);
332
+ proc_create("kpageflags", S_IRUSR, NULL, &kpageflags_proc_ops);
306333 #ifdef CONFIG_MEMCG
307
- proc_create("kpagecgroup", S_IRUSR, NULL, &proc_kpagecgroup_operations);
334
+ proc_create("kpagecgroup", S_IRUSR, NULL, &kpagecgroup_proc_ops);
308335 #endif
309336 return 0;
310337 }