Skip to content

Commit

Permalink
Merge branch 'mm-hotfixes-stable' into mm-stable
Browse files Browse the repository at this point in the history
To pick up depended-upon changes
  • Loading branch information
akpm00 committed Feb 10, 2023
2 parents 223ec6a + ce4d9a1 commit f67d6b2
Show file tree
Hide file tree
Showing 18 changed files with 102 additions and 45 deletions.
2 changes: 2 additions & 0 deletions .mailmap
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ Aleksey Gorelov <[email protected]>
Alexander Lobakin <[email protected]> <[email protected]>
Alexander Lobakin <[email protected]> <[email protected]>
Alexander Lobakin <[email protected]> <[email protected]>
Alexander Mikhalitsyn <[email protected]> <[email protected]>
Alexander Mikhalitsyn <[email protected]> <[email protected]>
Alexandre Belloni <[email protected]> <[email protected]>
Alexei Starovoitov <[email protected]> <[email protected]>
Alexei Starovoitov <[email protected]> <[email protected]>
Expand Down
3 changes: 2 additions & 1 deletion drivers/of/of_reserved_mem.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,10 @@ static int __init early_init_dt_alloc_reserved_memory_arch(phys_addr_t size,
err = memblock_mark_nomap(base, size);
if (err)
memblock_phys_free(base, size);
kmemleak_ignore_phys(base);
}

kmemleak_ignore_phys(base);

return err;
}

Expand Down
4 changes: 4 additions & 0 deletions fs/aio.c
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,9 @@ static int aio_ring_mremap(struct vm_area_struct *vma)
spin_lock(&mm->ioctx_lock);
rcu_read_lock();
table = rcu_dereference(mm->ioctx_table);
if (!table)
goto out_unlock;

for (i = 0; i < table->nr; i++) {
struct kioctx *ctx;

Expand All @@ -374,6 +377,7 @@ static int aio_ring_mremap(struct vm_area_struct *vma)
}
}

out_unlock:
rcu_read_unlock();
spin_unlock(&mm->ioctx_lock);
return res;
Expand Down
5 changes: 3 additions & 2 deletions fs/dax.c
Original file line number Diff line number Diff line change
Expand Up @@ -1271,8 +1271,9 @@ static s64 dax_unshare_iter(struct iomap_iter *iter)
if (ret < 0)
goto out_unlock;

ret = copy_mc_to_kernel(daddr, saddr, length);
if (ret)
if (copy_mc_to_kernel(daddr, saddr, length) == 0)
ret = length;
else
ret = -EIO;

out_unlock:
Expand Down
2 changes: 1 addition & 1 deletion fs/squashfs/xattr_id.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ __le64 *squashfs_read_xattr_id_table(struct super_block *sb, u64 table_start,
/* Sanity check values */

/* there is always at least one xattr id */
if (*xattr_ids <= 0)
if (*xattr_ids == 0)
return ERR_PTR(-EINVAL);

len = SQUASHFS_XATTR_BLOCK_BYTES(*xattr_ids);
Expand Down
12 changes: 9 additions & 3 deletions include/linux/mm.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ extern int mmap_rnd_compat_bits __read_mostly;
* define their own version of this macro in <asm/pgtable.h>
*/
#if BITS_PER_LONG == 64
/* This function must be updated when the size of struct page grows above 80
/* This function must be updated when the size of struct page grows above 96
* or reduces below 56. The idea that compiler optimizes out switch()
* statement, and only leaves move/store instructions. Also the compiler can
* combine write statements if they are both assignments and can be reordered,
Expand All @@ -148,12 +148,18 @@ static inline void __mm_zero_struct_page(struct page *page)
{
unsigned long *_pp = (void *)page;

/* Check that struct page is either 56, 64, 72, or 80 bytes */
/* Check that struct page is either 56, 64, 72, 80, 88 or 96 bytes */
BUILD_BUG_ON(sizeof(struct page) & 7);
BUILD_BUG_ON(sizeof(struct page) < 56);
BUILD_BUG_ON(sizeof(struct page) > 80);
BUILD_BUG_ON(sizeof(struct page) > 96);

switch (sizeof(struct page)) {
case 96:
_pp[11] = 0;
fallthrough;
case 88:
_pp[10] = 0;
fallthrough;
case 80:
_pp[9] = 0;
fallthrough;
Expand Down
5 changes: 3 additions & 2 deletions include/linux/shrinker.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,16 +107,17 @@ extern void synchronize_shrinkers(void);

#ifdef CONFIG_SHRINKER_DEBUG
extern int shrinker_debugfs_add(struct shrinker *shrinker);
extern void shrinker_debugfs_remove(struct shrinker *shrinker);
extern struct dentry *shrinker_debugfs_remove(struct shrinker *shrinker);
extern int __printf(2, 3) shrinker_debugfs_rename(struct shrinker *shrinker,
const char *fmt, ...);
#else /* CONFIG_SHRINKER_DEBUG */
static inline int shrinker_debugfs_add(struct shrinker *shrinker)
{
return 0;
}
static inline void shrinker_debugfs_remove(struct shrinker *shrinker)
static inline struct dentry *shrinker_debugfs_remove(struct shrinker *shrinker)
{
return NULL;
}
static inline __printf(2, 3)
int shrinker_debugfs_rename(struct shrinker *shrinker, const char *fmt, ...)
Expand Down
39 changes: 20 additions & 19 deletions lib/parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,15 @@
#include <linux/slab.h>
#include <linux/string.h>

/*
* max size needed by different bases to express U64
* HEX: "0xFFFFFFFFFFFFFFFF" --> 18
* DEC: "18446744073709551615" --> 20
* OCT: "01777777777777777777777" --> 23
* pick the max one to define NUMBER_BUF_LEN
*/
#define NUMBER_BUF_LEN 24

/**
* match_one - Determines if a string matches a simple pattern
* @s: the string to examine for presence of the pattern
Expand Down Expand Up @@ -129,14 +138,12 @@ EXPORT_SYMBOL(match_token);
static int match_number(substring_t *s, int *result, int base)
{
char *endp;
char *buf;
char buf[NUMBER_BUF_LEN];
int ret;
long val;

buf = match_strdup(s);
if (!buf)
return -ENOMEM;

if (match_strlcpy(buf, s, NUMBER_BUF_LEN) >= NUMBER_BUF_LEN)
return -ERANGE;
ret = 0;
val = simple_strtol(buf, &endp, base);
if (endp == buf)
Expand All @@ -145,7 +152,6 @@ static int match_number(substring_t *s, int *result, int base)
ret = -ERANGE;
else
*result = (int) val;
kfree(buf);
return ret;
}

Expand All @@ -163,18 +169,15 @@ static int match_number(substring_t *s, int *result, int base)
*/
static int match_u64int(substring_t *s, u64 *result, int base)
{
char *buf;
char buf[NUMBER_BUF_LEN];
int ret;
u64 val;

buf = match_strdup(s);
if (!buf)
return -ENOMEM;

if (match_strlcpy(buf, s, NUMBER_BUF_LEN) >= NUMBER_BUF_LEN)
return -ERANGE;
ret = kstrtoull(buf, base, &val);
if (!ret)
*result = val;
kfree(buf);
return ret;
}

Expand Down Expand Up @@ -206,14 +209,12 @@ EXPORT_SYMBOL(match_int);
*/
int match_uint(substring_t *s, unsigned int *result)
{
int err = -ENOMEM;
char *buf = match_strdup(s);
char buf[NUMBER_BUF_LEN];

if (buf) {
err = kstrtouint(buf, 10, result);
kfree(buf);
}
return err;
if (match_strlcpy(buf, s, NUMBER_BUF_LEN) >= NUMBER_BUF_LEN)
return -ERANGE;

return kstrtouint(buf, 10, result);
}
EXPORT_SYMBOL(match_uint);

Expand Down
2 changes: 1 addition & 1 deletion mm/gup.c
Original file line number Diff line number Diff line change
Expand Up @@ -1939,7 +1939,7 @@ static unsigned long collect_longterm_unpinnable_pages(
drain_allow = false;
}

if (!folio_isolate_lru(folio))
if (folio_isolate_lru(folio))
continue;

list_add_tail(&folio->lru, movable_page_list);
Expand Down
3 changes: 3 additions & 0 deletions mm/kasan/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,9 @@ bool __kasan_slab_free(struct kmem_cache *cache, void *object,

static inline bool ____kasan_kfree_large(void *ptr, unsigned long ip)
{
if (!kasan_arch_is_ready())
return false;

if (ptr != page_address(virt_to_head_page(ptr))) {
kasan_report_invalid_free(ptr, ip, KASAN_REPORT_INVALID_FREE);
return true;
Expand Down
7 changes: 6 additions & 1 deletion mm/kasan/generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,12 @@ bool kasan_check_range(unsigned long addr, size_t size, bool write,

bool kasan_byte_accessible(const void *addr)
{
s8 shadow_byte = READ_ONCE(*(s8 *)kasan_mem_to_shadow(addr));
s8 shadow_byte;

if (!kasan_arch_is_ready())
return true;

shadow_byte = READ_ONCE(*(s8 *)kasan_mem_to_shadow(addr));

return shadow_byte >= 0 && shadow_byte < KASAN_GRANULE_SIZE;
}
Expand Down
12 changes: 12 additions & 0 deletions mm/kasan/shadow.c
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,9 @@ int kasan_populate_vmalloc(unsigned long addr, unsigned long size)
unsigned long shadow_start, shadow_end;
int ret;

if (!kasan_arch_is_ready())
return 0;

if (!is_vmalloc_or_module_addr((void *)addr))
return 0;

Expand Down Expand Up @@ -459,6 +462,9 @@ void kasan_release_vmalloc(unsigned long start, unsigned long end,
unsigned long region_start, region_end;
unsigned long size;

if (!kasan_arch_is_ready())
return;

region_start = ALIGN(start, KASAN_MEMORY_PER_SHADOW_PAGE);
region_end = ALIGN_DOWN(end, KASAN_MEMORY_PER_SHADOW_PAGE);

Expand Down Expand Up @@ -502,6 +508,9 @@ void *__kasan_unpoison_vmalloc(const void *start, unsigned long size,
* with setting memory tags, so the KASAN_VMALLOC_INIT flag is ignored.
*/

if (!kasan_arch_is_ready())
return (void *)start;

if (!is_vmalloc_or_module_addr(start))
return (void *)start;

Expand All @@ -524,6 +533,9 @@ void *__kasan_unpoison_vmalloc(const void *start, unsigned long size,
*/
void __kasan_poison_vmalloc(const void *start, unsigned long size)
{
if (!kasan_arch_is_ready())
return;

if (!is_vmalloc_or_module_addr(start))
return;

Expand Down
7 changes: 5 additions & 2 deletions mm/ksm.c
Original file line number Diff line number Diff line change
Expand Up @@ -2628,8 +2628,11 @@ struct page *ksm_might_need_to_copy(struct page *page,
new_page = NULL;
}
if (new_page) {
copy_user_highpage(new_page, page, address, vma);

if (copy_mc_user_highpage(new_page, page, address, vma)) {
put_page(new_page);
memory_failure_queue(page_to_pfn(page), 0);
return ERR_PTR(-EHWPOISON);
}
SetPageDirty(new_page);
__SetPageUptodate(new_page);
__SetPageLocked(new_page);
Expand Down
3 changes: 3 additions & 0 deletions mm/memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -3823,6 +3823,9 @@ vm_fault_t do_swap_page(struct vm_fault *vmf)
if (unlikely(!page)) {
ret = VM_FAULT_OOM;
goto out_page;
} else if (unlikely(PTR_ERR(page) == -EHWPOISON)) {
ret = VM_FAULT_HWPOISON;
goto out_page;
}
folio = page_folio(page);

Expand Down
13 changes: 8 additions & 5 deletions mm/shrinker_debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -246,18 +246,21 @@ int shrinker_debugfs_rename(struct shrinker *shrinker, const char *fmt, ...)
}
EXPORT_SYMBOL(shrinker_debugfs_rename);

void shrinker_debugfs_remove(struct shrinker *shrinker)
struct dentry *shrinker_debugfs_remove(struct shrinker *shrinker)
{
struct dentry *entry = shrinker->debugfs_entry;

lockdep_assert_held(&shrinker_rwsem);

kfree_const(shrinker->name);
shrinker->name = NULL;

if (!shrinker->debugfs_entry)
return;
if (entry) {
ida_free(&shrinker_debugfs_ida, shrinker->debugfs_id);
shrinker->debugfs_entry = NULL;
}

debugfs_remove_recursive(shrinker->debugfs_entry);
ida_free(&shrinker_debugfs_ida, shrinker->debugfs_id);
return entry;
}

static int __init shrinker_debugfs_init(void)
Expand Down
20 changes: 14 additions & 6 deletions mm/swapfile.c
Original file line number Diff line number Diff line change
Expand Up @@ -1762,28 +1762,35 @@ static int unuse_pte(struct vm_area_struct *vma, pmd_t *pmd,
struct page *swapcache;
spinlock_t *ptl;
pte_t *pte, new_pte;
bool hwposioned = false;
int ret = 1;

swapcache = page;
page = ksm_might_need_to_copy(page, vma, addr);
if (unlikely(!page))
return -ENOMEM;
else if (unlikely(PTR_ERR(page) == -EHWPOISON))
hwposioned = true;

pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl);
if (unlikely(!pte_same_as_swp(*pte, swp_entry_to_pte(entry)))) {
ret = 0;
goto out;
}

if (unlikely(!PageUptodate(page))) {
pte_t pteval;
if (unlikely(hwposioned || !PageUptodate(page))) {
swp_entry_t swp_entry;

dec_mm_counter(vma->vm_mm, MM_SWAPENTS);
pteval = swp_entry_to_pte(make_swapin_error_entry());
set_pte_at(vma->vm_mm, addr, pte, pteval);
swap_free(entry);
if (hwposioned) {
swp_entry = make_hwpoison_entry(swapcache);
page = swapcache;
} else {
swp_entry = make_swapin_error_entry();
}
new_pte = swp_entry_to_pte(swp_entry);
ret = 0;
goto out;
goto setpte;
}

/* See do_swap_page() */
Expand Down Expand Up @@ -1815,6 +1822,7 @@ static int unuse_pte(struct vm_area_struct *vma, pmd_t *pmd,
new_pte = pte_mksoft_dirty(new_pte);
if (pte_swp_uffd_wp(*pte))
new_pte = pte_mkuffd_wp(new_pte);
setpte:
set_pte_at(vma->vm_mm, addr, pte, new_pte);
swap_free(entry);
out:
Expand Down
6 changes: 5 additions & 1 deletion mm/vmscan.c
Original file line number Diff line number Diff line change
Expand Up @@ -747,6 +747,8 @@ EXPORT_SYMBOL(register_shrinker);
*/
void unregister_shrinker(struct shrinker *shrinker)
{
struct dentry *debugfs_entry;

if (!(shrinker->flags & SHRINKER_REGISTERED))
return;

Expand All @@ -755,9 +757,11 @@ void unregister_shrinker(struct shrinker *shrinker)
shrinker->flags &= ~SHRINKER_REGISTERED;
if (shrinker->flags & SHRINKER_MEMCG_AWARE)
unregister_memcg_shrinker(shrinker);
shrinker_debugfs_remove(shrinker);
debugfs_entry = shrinker_debugfs_remove(shrinker);
up_write(&shrinker_rwsem);

debugfs_remove_recursive(debugfs_entry);

kfree(shrinker->nr_deferred);
shrinker->nr_deferred = NULL;
}
Expand Down
2 changes: 1 addition & 1 deletion scripts/gdb/linux/cpus.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ def get_current_task(cpu):
task_ptr_type = task_type.get_type().pointer()

if utils.is_target_arch("x86"):
var_ptr = gdb.parse_and_eval("&current_task")
var_ptr = gdb.parse_and_eval("&pcpu_hot.current_task")
return per_cpu(var_ptr, cpu).dereference()
elif utils.is_target_arch("aarch64"):
current_task_addr = gdb.parse_and_eval("$SP_EL0")
Expand Down

0 comments on commit f67d6b2

Please sign in to comment.