Commit 380173ff authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'akpm' (patches from Andrew)

Merge fixes from Andrew Morton:
 "13 fixes"

* emailed patches from Andrew Morton <akpm@linux-foundation.org>:
  dma-mapping: avoid oops when parameter cpu_addr is null
  mm/hugetlb: use EOPNOTSUPP in hugetlb sysctl handlers
  memremap: check pfn validity before passing to pfn_to_page()
  mm, thp: fix migration of PTE-mapped transparent huge pages
  dax: check return value of dax_radix_entry()
  ocfs2: fix return value from ocfs2_page_mkwrite()
  arm64: kasan: clear stale stack poison
  sched/kasan: remove stale KASAN poison after hotplug
  kasan: add functions to clear stack poison
  mm: fix mixed zone detection in devm_memremap_pages
  list: kill list_force_poison()
  mm: __delete_from_page_cache show Bad page if mapped
  mm/hugetlb: hugetlb_no_page: rate-limit warning message
parents 2f0d94ea d6b7eaeb
...@@ -145,6 +145,10 @@ ENTRY(cpu_resume_mmu) ...@@ -145,6 +145,10 @@ ENTRY(cpu_resume_mmu)
ENDPROC(cpu_resume_mmu) ENDPROC(cpu_resume_mmu)
.popsection .popsection
cpu_resume_after_mmu: cpu_resume_after_mmu:
#ifdef CONFIG_KASAN
mov x0, sp
bl kasan_unpoison_remaining_stack
#endif
mov x0, #0 // return zero on success mov x0, #0 // return zero on success
ldp x19, x20, [sp, #16] ldp x19, x20, [sp, #16]
ldp x21, x22, [sp, #32] ldp x21, x22, [sp, #32]
......
...@@ -1056,6 +1056,7 @@ EXPORT_SYMBOL_GPL(dax_pmd_fault); ...@@ -1056,6 +1056,7 @@ EXPORT_SYMBOL_GPL(dax_pmd_fault);
int dax_pfn_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) int dax_pfn_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
{ {
struct file *file = vma->vm_file; struct file *file = vma->vm_file;
int error;
/* /*
* We pass NO_SECTOR to dax_radix_entry() because we expect that a * We pass NO_SECTOR to dax_radix_entry() because we expect that a
...@@ -1065,7 +1066,13 @@ int dax_pfn_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) ...@@ -1065,7 +1066,13 @@ int dax_pfn_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
* saves us from having to make a call to get_block() here to look * saves us from having to make a call to get_block() here to look
* up the sector. * up the sector.
*/ */
dax_radix_entry(file->f_mapping, vmf->pgoff, NO_SECTOR, false, true); error = dax_radix_entry(file->f_mapping, vmf->pgoff, NO_SECTOR, false,
true);
if (error == -ENOMEM)
return VM_FAULT_OOM;
if (error)
return VM_FAULT_SIGBUS;
return VM_FAULT_NOPAGE; return VM_FAULT_NOPAGE;
} }
EXPORT_SYMBOL_GPL(dax_pfn_mkwrite); EXPORT_SYMBOL_GPL(dax_pfn_mkwrite);
......
...@@ -147,6 +147,10 @@ static int ocfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) ...@@ -147,6 +147,10 @@ static int ocfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
ret = ocfs2_inode_lock(inode, &di_bh, 1); ret = ocfs2_inode_lock(inode, &di_bh, 1);
if (ret < 0) { if (ret < 0) {
mlog_errno(ret); mlog_errno(ret);
if (ret == -ENOMEM)
ret = VM_FAULT_OOM;
else
ret = VM_FAULT_SIGBUS;
goto out; goto out;
} }
......
...@@ -386,7 +386,7 @@ static inline void dma_free_attrs(struct device *dev, size_t size, ...@@ -386,7 +386,7 @@ static inline void dma_free_attrs(struct device *dev, size_t size,
if (dma_release_from_coherent(dev, get_order(size), cpu_addr)) if (dma_release_from_coherent(dev, get_order(size), cpu_addr))
return; return;
if (!ops->free) if (!ops->free || !cpu_addr)
return; return;
debug_dma_free_coherent(dev, size, cpu_addr, dma_handle); debug_dma_free_coherent(dev, size, cpu_addr, dma_handle);
......
#ifndef _LINUX_KASAN_H #ifndef _LINUX_KASAN_H
#define _LINUX_KASAN_H #define _LINUX_KASAN_H
#include <linux/sched.h>
#include <linux/types.h> #include <linux/types.h>
struct kmem_cache; struct kmem_cache;
...@@ -13,7 +14,6 @@ struct vm_struct; ...@@ -13,7 +14,6 @@ struct vm_struct;
#include <asm/kasan.h> #include <asm/kasan.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>
#include <linux/sched.h>
extern unsigned char kasan_zero_page[PAGE_SIZE]; extern unsigned char kasan_zero_page[PAGE_SIZE];
extern pte_t kasan_zero_pte[PTRS_PER_PTE]; extern pte_t kasan_zero_pte[PTRS_PER_PTE];
...@@ -43,6 +43,8 @@ static inline void kasan_disable_current(void) ...@@ -43,6 +43,8 @@ static inline void kasan_disable_current(void)
void kasan_unpoison_shadow(const void *address, size_t size); void kasan_unpoison_shadow(const void *address, size_t size);
void kasan_unpoison_task_stack(struct task_struct *task);
void kasan_alloc_pages(struct page *page, unsigned int order); void kasan_alloc_pages(struct page *page, unsigned int order);
void kasan_free_pages(struct page *page, unsigned int order); void kasan_free_pages(struct page *page, unsigned int order);
...@@ -66,6 +68,8 @@ void kasan_free_shadow(const struct vm_struct *vm); ...@@ -66,6 +68,8 @@ void kasan_free_shadow(const struct vm_struct *vm);
static inline void kasan_unpoison_shadow(const void *address, size_t size) {} static inline void kasan_unpoison_shadow(const void *address, size_t size) {}
static inline void kasan_unpoison_task_stack(struct task_struct *task) {}
static inline void kasan_enable_current(void) {} static inline void kasan_enable_current(void) {}
static inline void kasan_disable_current(void) {} static inline void kasan_disable_current(void) {}
......
...@@ -113,17 +113,6 @@ extern void __list_del_entry(struct list_head *entry); ...@@ -113,17 +113,6 @@ extern void __list_del_entry(struct list_head *entry);
extern void list_del(struct list_head *entry); extern void list_del(struct list_head *entry);
#endif #endif
#ifdef CONFIG_DEBUG_LIST
/*
* See devm_memremap_pages() which wants DEBUG_LIST=y to assert if one
* of the pages it allocates is ever passed to list_add()
*/
extern void list_force_poison(struct list_head *entry);
#else
/* fallback to the less strict LIST_POISON* definitions */
#define list_force_poison list_del
#endif
/** /**
* list_replace - replace old entry by new one * list_replace - replace old entry by new one
* @old : the element to be replaced * @old : the element to be replaced
......
...@@ -29,10 +29,10 @@ __weak void __iomem *ioremap_cache(resource_size_t offset, unsigned long size) ...@@ -29,10 +29,10 @@ __weak void __iomem *ioremap_cache(resource_size_t offset, unsigned long size)
static void *try_ram_remap(resource_size_t offset, size_t size) static void *try_ram_remap(resource_size_t offset, size_t size)
{ {
struct page *page = pfn_to_page(offset >> PAGE_SHIFT); unsigned long pfn = PHYS_PFN(offset);
/* In the simple case just return the existing linear address */ /* In the simple case just return the existing linear address */
if (!PageHighMem(page)) if (pfn_valid(pfn) && !PageHighMem(pfn_to_page(pfn)))
return __va(offset); return __va(offset);
return NULL; /* fallback to ioremap_cache */ return NULL; /* fallback to ioremap_cache */
} }
...@@ -270,13 +270,16 @@ struct dev_pagemap *find_dev_pagemap(resource_size_t phys) ...@@ -270,13 +270,16 @@ struct dev_pagemap *find_dev_pagemap(resource_size_t phys)
void *devm_memremap_pages(struct device *dev, struct resource *res, void *devm_memremap_pages(struct device *dev, struct resource *res,
struct percpu_ref *ref, struct vmem_altmap *altmap) struct percpu_ref *ref, struct vmem_altmap *altmap)
{ {
int is_ram = region_intersects(res->start, resource_size(res),
"System RAM");
resource_size_t key, align_start, align_size, align_end; resource_size_t key, align_start, align_size, align_end;
struct dev_pagemap *pgmap; struct dev_pagemap *pgmap;
struct page_map *page_map; struct page_map *page_map;
int error, nid, is_ram;
unsigned long pfn; unsigned long pfn;
int error, nid;
align_start = res->start & ~(SECTION_SIZE - 1);
align_size = ALIGN(res->start + resource_size(res), SECTION_SIZE)
- align_start;
is_ram = region_intersects(align_start, align_size, "System RAM");
if (is_ram == REGION_MIXED) { if (is_ram == REGION_MIXED) {
WARN_ONCE(1, "%s attempted on mixed region %pr\n", WARN_ONCE(1, "%s attempted on mixed region %pr\n",
...@@ -314,8 +317,6 @@ void *devm_memremap_pages(struct device *dev, struct resource *res, ...@@ -314,8 +317,6 @@ void *devm_memremap_pages(struct device *dev, struct resource *res,
mutex_lock(&pgmap_lock); mutex_lock(&pgmap_lock);
error = 0; error = 0;
align_start = res->start & ~(SECTION_SIZE - 1);
align_size = ALIGN(resource_size(res), SECTION_SIZE);
align_end = align_start + align_size - 1; align_end = align_start + align_size - 1;
for (key = align_start; key <= align_end; key += SECTION_SIZE) { for (key = align_start; key <= align_end; key += SECTION_SIZE) {
struct dev_pagemap *dup; struct dev_pagemap *dup;
...@@ -351,8 +352,13 @@ void *devm_memremap_pages(struct device *dev, struct resource *res, ...@@ -351,8 +352,13 @@ void *devm_memremap_pages(struct device *dev, struct resource *res,
for_each_device_pfn(pfn, page_map) { for_each_device_pfn(pfn, page_map) {
struct page *page = pfn_to_page(pfn); struct page *page = pfn_to_page(pfn);
/* ZONE_DEVICE pages must never appear on a slab lru */ /*
list_force_poison(&page->lru); * ZONE_DEVICE pages union ->lru with a ->pgmap back
* pointer. It is a bug if a ZONE_DEVICE page is ever
* freed or placed on a driver-private list. Seed the
* storage with LIST_POISON* values.
*/
list_del(&page->lru);
page->pgmap = pgmap; page->pgmap = pgmap;
} }
devres_add(dev, page_map); devres_add(dev, page_map);
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
* Thomas Gleixner, Mike Kravetz * Thomas Gleixner, Mike Kravetz
*/ */
#include <linux/kasan.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/nmi.h> #include <linux/nmi.h>
...@@ -5096,6 +5097,8 @@ void init_idle(struct task_struct *idle, int cpu) ...@@ -5096,6 +5097,8 @@ void init_idle(struct task_struct *idle, int cpu)
idle->state = TASK_RUNNING; idle->state = TASK_RUNNING;
idle->se.exec_start = sched_clock(); idle->se.exec_start = sched_clock();
kasan_unpoison_task_stack(idle);
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
/* /*
* Its possible that init_idle() gets called multiple times on a task, * Its possible that init_idle() gets called multiple times on a task,
......
...@@ -12,13 +12,6 @@ ...@@ -12,13 +12,6 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/rculist.h> #include <linux/rculist.h>
static struct list_head force_poison;
void list_force_poison(struct list_head *entry)
{
entry->next = &force_poison;
entry->prev = &force_poison;
}
/* /*
* Insert a new entry between two known consecutive entries. * Insert a new entry between two known consecutive entries.
* *
...@@ -30,8 +23,6 @@ void __list_add(struct list_head *new, ...@@ -30,8 +23,6 @@ void __list_add(struct list_head *new,
struct list_head *prev, struct list_head *prev,
struct list_head *next) struct list_head *next)
{ {
WARN(new->next == &force_poison || new->prev == &force_poison,
"list_add attempted on force-poisoned entry\n");
WARN(next->prev != prev, WARN(next->prev != prev,
"list_add corruption. next->prev should be " "list_add corruption. next->prev should be "
"prev (%p), but was %p. (next=%p).\n", "prev (%p), but was %p. (next=%p).\n",
......
...@@ -195,6 +195,30 @@ void __delete_from_page_cache(struct page *page, void *shadow, ...@@ -195,6 +195,30 @@ void __delete_from_page_cache(struct page *page, void *shadow,
else else
cleancache_invalidate_page(mapping, page); cleancache_invalidate_page(mapping, page);
VM_BUG_ON_PAGE(page_mapped(page), page);
if (!IS_ENABLED(CONFIG_DEBUG_VM) && unlikely(page_mapped(page))) {
int mapcount;
pr_alert("BUG: Bad page cache in process %s pfn:%05lx\n",
current->comm, page_to_pfn(page));
dump_page(page, "still mapped when deleted");
dump_stack();
add_taint(TAINT_BAD_PAGE, LOCKDEP_NOW_UNRELIABLE);
mapcount = page_mapcount(page);
if (mapping_exiting(mapping) &&
page_count(page) >= mapcount + 2) {
/*
* All vmas have already been torn down, so it's
* a good bet that actually the page is unmapped,
* and we'd prefer not to leak it: if we're wrong,
* some other bad page check should catch it later.
*/
page_mapcount_reset(page);
atomic_sub(mapcount, &page->_count);
}
}
page_cache_tree_delete(mapping, page, shadow); page_cache_tree_delete(mapping, page, shadow);
page->mapping = NULL; page->mapping = NULL;
...@@ -205,7 +229,6 @@ void __delete_from_page_cache(struct page *page, void *shadow, ...@@ -205,7 +229,6 @@ void __delete_from_page_cache(struct page *page, void *shadow,
__dec_zone_page_state(page, NR_FILE_PAGES); __dec_zone_page_state(page, NR_FILE_PAGES);
if (PageSwapBacked(page)) if (PageSwapBacked(page))
__dec_zone_page_state(page, NR_SHMEM); __dec_zone_page_state(page, NR_SHMEM);
VM_BUG_ON_PAGE(page_mapped(page), page);
/* /*
* At this point page must be either written or cleaned by truncate. * At this point page must be either written or cleaned by truncate.
......
...@@ -2751,7 +2751,7 @@ static int hugetlb_sysctl_handler_common(bool obey_mempolicy, ...@@ -2751,7 +2751,7 @@ static int hugetlb_sysctl_handler_common(bool obey_mempolicy,
int ret; int ret;
if (!hugepages_supported()) if (!hugepages_supported())
return -ENOTSUPP; return -EOPNOTSUPP;
table->data = &tmp; table->data = &tmp;
table->maxlen = sizeof(unsigned long); table->maxlen = sizeof(unsigned long);
...@@ -2792,7 +2792,7 @@ int hugetlb_overcommit_handler(struct ctl_table *table, int write, ...@@ -2792,7 +2792,7 @@ int hugetlb_overcommit_handler(struct ctl_table *table, int write,
int ret; int ret;
if (!hugepages_supported()) if (!hugepages_supported())
return -ENOTSUPP; return -EOPNOTSUPP;
tmp = h->nr_overcommit_huge_pages; tmp = h->nr_overcommit_huge_pages;
...@@ -3502,7 +3502,7 @@ static int hugetlb_no_page(struct mm_struct *mm, struct vm_area_struct *vma, ...@@ -3502,7 +3502,7 @@ static int hugetlb_no_page(struct mm_struct *mm, struct vm_area_struct *vma,
* COW. Warn that such a situation has occurred as it may not be obvious * COW. Warn that such a situation has occurred as it may not be obvious
*/ */
if (is_vma_resv_set(vma, HPAGE_RESV_UNMAPPED)) { if (is_vma_resv_set(vma, HPAGE_RESV_UNMAPPED)) {
pr_warning("PID %d killed due to inadequate hugepage pool\n", pr_warn_ratelimited("PID %d killed due to inadequate hugepage pool\n",
current->pid); current->pid);
return ret; return ret;
} }
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/kmemleak.h> #include <linux/kmemleak.h>
#include <linux/linkage.h>
#include <linux/memblock.h> #include <linux/memblock.h>
#include <linux/memory.h> #include <linux/memory.h>
#include <linux/mm.h> #include <linux/mm.h>
...@@ -60,6 +61,25 @@ void kasan_unpoison_shadow(const void *address, size_t size) ...@@ -60,6 +61,25 @@ void kasan_unpoison_shadow(const void *address, size_t size)
} }
} }
static void __kasan_unpoison_stack(struct task_struct *task, void *sp)
{
void *base = task_stack_page(task);
size_t size = sp - base;
kasan_unpoison_shadow(base, size);
}
/* Unpoison the entire stack for a task. */
void kasan_unpoison_task_stack(struct task_struct *task)
{
__kasan_unpoison_stack(task, task_stack_page(task) + THREAD_SIZE);
}
/* Unpoison the stack for the current task beyond a watermark sp value. */
asmlinkage void kasan_unpoison_remaining_stack(void *sp)
{
__kasan_unpoison_stack(current, sp);
}
/* /*
* All functions below always inlined so compiler could * All functions below always inlined so compiler could
......
...@@ -532,7 +532,7 @@ static int queue_pages_pte_range(pmd_t *pmd, unsigned long addr, ...@@ -532,7 +532,7 @@ static int queue_pages_pte_range(pmd_t *pmd, unsigned long addr,
nid = page_to_nid(page); nid = page_to_nid(page);
if (node_isset(nid, *qp->nmask) == !!(flags & MPOL_MF_INVERT)) if (node_isset(nid, *qp->nmask) == !!(flags & MPOL_MF_INVERT))
continue; continue;
if (PageTail(page) && PageAnon(page)) { if (PageTransCompound(page) && PageAnon(page)) {
get_page(page); get_page(page);
pte_unmap_unlock(pte, ptl); pte_unmap_unlock(pte, ptl);
lock_page(page); lock_page(page);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment