diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2018-05-19 13:55:40 +0200 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2018-05-19 13:55:40 +0200 |
commit | b563ea676a46f3a297b1e64b6ece25b934aafba5 (patch) | |
tree | 7b18cca93a853b253375d0a3f1cb5af242771768 /fs/proc/kcore.c | |
parent | 4fe581d7f114d56f31f392448477cff5a4394065 (diff) | |
parent | 73fcb1a370c76b202d406e95d9dabb76eaccf484 (diff) | |
download | linux-b563ea676a46f3a297b1e64b6ece25b934aafba5.tar.bz2 |
Merge branch 'linus' into timers/2038
Merge upstream to pick up changes on which pending patches depend on.
Diffstat (limited to 'fs/proc/kcore.c')
-rw-r--r-- | fs/proc/kcore.c | 23 |
1 files changed, 16 insertions, 7 deletions
diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c index d1e82761de81..e64ecb9f2720 100644 --- a/fs/proc/kcore.c +++ b/fs/proc/kcore.c @@ -209,25 +209,34 @@ kclist_add_private(unsigned long pfn, unsigned long nr_pages, void *arg) { struct list_head *head = (struct list_head *)arg; struct kcore_list *ent; + struct page *p; + + if (!pfn_valid(pfn)) + return 1; + + p = pfn_to_page(pfn); + if (!memmap_valid_within(pfn, p, page_zone(p))) + return 1; ent = kmalloc(sizeof(*ent), GFP_KERNEL); if (!ent) return -ENOMEM; - ent->addr = (unsigned long)__va((pfn << PAGE_SHIFT)); + ent->addr = (unsigned long)page_to_virt(p); ent->size = nr_pages << PAGE_SHIFT; - /* Sanity check: Can happen in 32bit arch...maybe */ - if (ent->addr < (unsigned long) __va(0)) + if (!virt_addr_valid(ent->addr)) goto free_out; /* cut not-mapped area. ....from ppc-32 code. */ if (ULONG_MAX - ent->addr < ent->size) ent->size = ULONG_MAX - ent->addr; - /* cut when vmalloc() area is higher than direct-map area */ - if (VMALLOC_START > (unsigned long)__va(0)) { - if (ent->addr > VMALLOC_START) - goto free_out; + /* + * We've already checked virt_addr_valid so we know this address + * is a valid pointer, therefore we can check against it to determine + * if we need to trim + */ + if (VMALLOC_START > ent->addr) { if (VMALLOC_START - ent->addr < ent->size) ent->size = VMALLOC_START - ent->addr; } |