Skip to content

Commit bc2dbc5

Browse files
committed
Merge branch 'akpm' (patches from Andrew)
Merge misc fixes from Andrew Morton: "16 fixes" * emailed patches from Andrew Morton <akpm@linux-foundation.org>: kasan: fix memory hotplug during boot kasan: free allocated shadow memory on MEM_CANCEL_ONLINE checkpatch: fix macro argument precedence test init/main.c: include <linux/mem_encrypt.h> kernel/sys.c: fix potential Spectre v1 issue mm/memory_hotplug: fix leftover use of struct page during hotplug proc: fix smaps and meminfo alignment mm: do not warn on offline nodes unless the specific node is explicitly requested mm, memory_hotplug: make has_unmovable_pages more robust mm/kasan: don't vfree() nonexistent vm_area MAINTAINERS: change hugetlbfs maintainer and update files ipc/shm: fix shmat() nil address after round-down when remapping Revert "ipc/shm: Fix shmat mmap nil-page protection" idr: fix invalid ptr dereference on item delete ocfs2: revert "ocfs2/o2hb: check len for bio_add_page() to avoid getting incorrect bio" mm: fix nr_rotate_swap leak in swapon() error case
2 parents 03250e1 + 3f19597 commit bc2dbc5

File tree

16 files changed

+125
-43
lines changed

16 files changed

+125
-43
lines changed

MAINTAINERS

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6503,9 +6503,15 @@ F: Documentation/networking/hinic.txt
65036503
F: drivers/net/ethernet/huawei/hinic/
65046504

65056505
HUGETLB FILESYSTEM
6506-
M: Nadia Yvette Chambers <nyc@holomorphy.com>
6506+
M: Mike Kravetz <mike.kravetz@oracle.com>
6507+
L: linux-mm@kvack.org
65076508
S: Maintained
65086509
F: fs/hugetlbfs/
6510+
F: mm/hugetlb.c
6511+
F: include/linux/hugetlb.h
6512+
F: Documentation/admin-guide/mm/hugetlbpage.rst
6513+
F: Documentation/vm/hugetlbfs_reserv.rst
6514+
F: Documentation/ABI/testing/sysfs-kernel-mm-hugepages
65096515

65106516
HVA ST MEDIA DRIVER
65116517
M: Jean-Christophe Trotin <jean-christophe.trotin@st.com>

drivers/base/node.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -490,7 +490,8 @@ int unregister_mem_sect_under_nodes(struct memory_block *mem_blk,
490490
return 0;
491491
}
492492

493-
int link_mem_sections(int nid, unsigned long start_pfn, unsigned long nr_pages)
493+
int link_mem_sections(int nid, unsigned long start_pfn, unsigned long nr_pages,
494+
bool check_nid)
494495
{
495496
unsigned long end_pfn = start_pfn + nr_pages;
496497
unsigned long pfn;
@@ -514,7 +515,7 @@ int link_mem_sections(int nid, unsigned long start_pfn, unsigned long nr_pages)
514515

515516
mem_blk = find_memory_block_hinted(mem_sect, mem_blk);
516517

517-
ret = register_mem_sect_under_node(mem_blk, nid, true);
518+
ret = register_mem_sect_under_node(mem_blk, nid, check_nid);
518519
if (!err)
519520
err = ret;
520521

fs/ocfs2/cluster/heartbeat.c

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -570,16 +570,7 @@ static struct bio *o2hb_setup_one_bio(struct o2hb_region *reg,
570570
current_page, vec_len, vec_start);
571571

572572
len = bio_add_page(bio, page, vec_len, vec_start);
573-
if (len != vec_len) {
574-
mlog(ML_ERROR, "Adding page[%d] to bio failed, "
575-
"page %p, len %d, vec_len %u, vec_start %u, "
576-
"bi_sector %llu\n", current_page, page, len,
577-
vec_len, vec_start,
578-
(unsigned long long)bio->bi_iter.bi_sector);
579-
bio_put(bio);
580-
bio = ERR_PTR(-EIO);
581-
return bio;
582-
}
573+
if (len != vec_len) break;
583574

584575
cs += vec_len / (PAGE_SIZE/spp);
585576
vec_start = 0;

fs/seq_file.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -709,11 +709,6 @@ void seq_put_decimal_ull_width(struct seq_file *m, const char *delimiter,
709709
if (m->count + width >= m->size)
710710
goto overflow;
711711

712-
if (num < 10) {
713-
m->buf[m->count++] = num + '0';
714-
return;
715-
}
716-
717712
len = num_to_str(m->buf + m->count, m->size - m->count, num, width);
718713
if (!len)
719714
goto overflow;

include/linux/gfp.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,7 @@ static inline struct page *
464464
__alloc_pages_node(int nid, gfp_t gfp_mask, unsigned int order)
465465
{
466466
VM_BUG_ON(nid < 0 || nid >= MAX_NUMNODES);
467-
VM_WARN_ON(!node_online(nid));
467+
VM_WARN_ON((gfp_mask & __GFP_THISNODE) && !node_online(nid));
468468

469469
return __alloc_pages(gfp_mask, order, nid);
470470
}

include/linux/node.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,11 @@ extern struct node *node_devices[];
3232
typedef void (*node_registration_func_t)(struct node *);
3333

3434
#if defined(CONFIG_MEMORY_HOTPLUG_SPARSE) && defined(CONFIG_NUMA)
35-
extern int link_mem_sections(int nid, unsigned long start_pfn, unsigned long nr_pages);
35+
extern int link_mem_sections(int nid, unsigned long start_pfn,
36+
unsigned long nr_pages, bool check_nid);
3637
#else
37-
static inline int link_mem_sections(int nid, unsigned long start_pfn, unsigned long nr_pages)
38+
static inline int link_mem_sections(int nid, unsigned long start_pfn,
39+
unsigned long nr_pages, bool check_nid)
3840
{
3941
return 0;
4042
}
@@ -57,7 +59,7 @@ static inline int register_one_node(int nid)
5759
if (error)
5860
return error;
5961
/* link memory sections under this node */
60-
error = link_mem_sections(nid, pgdat->node_start_pfn, pgdat->node_spanned_pages);
62+
error = link_mem_sections(nid, pgdat->node_start_pfn, pgdat->node_spanned_pages, true);
6163
}
6264

6365
return error;

init/main.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@
9191
#include <linux/cache.h>
9292
#include <linux/rodata_test.h>
9393
#include <linux/jump_label.h>
94+
#include <linux/mem_encrypt.h>
9495

9596
#include <asm/io.h>
9697
#include <asm/bugs.h>

ipc/shm.c

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1363,14 +1363,17 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg,
13631363

13641364
if (addr) {
13651365
if (addr & (shmlba - 1)) {
1366-
/*
1367-
* Round down to the nearest multiple of shmlba.
1368-
* For sane do_mmap_pgoff() parameters, avoid
1369-
* round downs that trigger nil-page and MAP_FIXED.
1370-
*/
1371-
if ((shmflg & SHM_RND) && addr >= shmlba)
1372-
addr &= ~(shmlba - 1);
1373-
else
1366+
if (shmflg & SHM_RND) {
1367+
addr &= ~(shmlba - 1); /* round down */
1368+
1369+
/*
1370+
* Ensure that the round-down is non-nil
1371+
* when remapping. This can happen for
1372+
* cases when addr < shmlba.
1373+
*/
1374+
if (!addr && (shmflg & SHM_REMAP))
1375+
goto out;
1376+
} else
13741377
#ifndef __ARCH_FORCE_SHMLBA
13751378
if (addr & ~PAGE_MASK)
13761379
#endif

kernel/sys.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@
7171
#include <asm/io.h>
7272
#include <asm/unistd.h>
7373

74+
/* Hardening for Spectre-v1 */
75+
#include <linux/nospec.h>
76+
7477
#include "uid16.h"
7578

7679
#ifndef SET_UNALIGN_CTL
@@ -1453,6 +1456,7 @@ SYSCALL_DEFINE2(old_getrlimit, unsigned int, resource,
14531456
if (resource >= RLIM_NLIMITS)
14541457
return -EINVAL;
14551458

1459+
resource = array_index_nospec(resource, RLIM_NLIMITS);
14561460
task_lock(current->group_leader);
14571461
x = current->signal->rlim[resource];
14581462
task_unlock(current->group_leader);
@@ -1472,6 +1476,7 @@ COMPAT_SYSCALL_DEFINE2(old_getrlimit, unsigned int, resource,
14721476
if (resource >= RLIM_NLIMITS)
14731477
return -EINVAL;
14741478

1479+
resource = array_index_nospec(resource, RLIM_NLIMITS);
14751480
task_lock(current->group_leader);
14761481
r = current->signal->rlim[resource];
14771482
task_unlock(current->group_leader);

lib/radix-tree.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2034,10 +2034,12 @@ void *radix_tree_delete_item(struct radix_tree_root *root,
20342034
unsigned long index, void *item)
20352035
{
20362036
struct radix_tree_node *node = NULL;
2037-
void __rcu **slot;
2037+
void __rcu **slot = NULL;
20382038
void *entry;
20392039

20402040
entry = __radix_tree_lookup(root, index, &node, &slot);
2041+
if (!slot)
2042+
return NULL;
20412043
if (!entry && (!is_idr(root) || node_tag_get(root, node, IDR_FREE,
20422044
get_slot_offset(node, slot))))
20432045
return NULL;

mm/kasan/kasan.c

Lines changed: 63 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -792,6 +792,40 @@ DEFINE_ASAN_SET_SHADOW(f5);
792792
DEFINE_ASAN_SET_SHADOW(f8);
793793

794794
#ifdef CONFIG_MEMORY_HOTPLUG
795+
static bool shadow_mapped(unsigned long addr)
796+
{
797+
pgd_t *pgd = pgd_offset_k(addr);
798+
p4d_t *p4d;
799+
pud_t *pud;
800+
pmd_t *pmd;
801+
pte_t *pte;
802+
803+
if (pgd_none(*pgd))
804+
return false;
805+
p4d = p4d_offset(pgd, addr);
806+
if (p4d_none(*p4d))
807+
return false;
808+
pud = pud_offset(p4d, addr);
809+
if (pud_none(*pud))
810+
return false;
811+
812+
/*
813+
* We can't use pud_large() or pud_huge(), the first one is
814+
* arch-specific, the last one depends on HUGETLB_PAGE. So let's abuse
815+
* pud_bad(), if pud is bad then it's bad because it's huge.
816+
*/
817+
if (pud_bad(*pud))
818+
return true;
819+
pmd = pmd_offset(pud, addr);
820+
if (pmd_none(*pmd))
821+
return false;
822+
823+
if (pmd_bad(*pmd))
824+
return true;
825+
pte = pte_offset_kernel(pmd, addr);
826+
return !pte_none(*pte);
827+
}
828+
795829
static int __meminit kasan_mem_notifier(struct notifier_block *nb,
796830
unsigned long action, void *data)
797831
{
@@ -813,6 +847,14 @@ static int __meminit kasan_mem_notifier(struct notifier_block *nb,
813847
case MEM_GOING_ONLINE: {
814848
void *ret;
815849

850+
/*
851+
* If shadow is mapped already than it must have been mapped
852+
* during the boot. This could happen if we onlining previously
853+
* offlined memory.
854+
*/
855+
if (shadow_mapped(shadow_start))
856+
return NOTIFY_OK;
857+
816858
ret = __vmalloc_node_range(shadow_size, PAGE_SIZE, shadow_start,
817859
shadow_end, GFP_KERNEL,
818860
PAGE_KERNEL, VM_NO_GUARD,
@@ -824,8 +866,26 @@ static int __meminit kasan_mem_notifier(struct notifier_block *nb,
824866
kmemleak_ignore(ret);
825867
return NOTIFY_OK;
826868
}
827-
case MEM_OFFLINE:
828-
vfree((void *)shadow_start);
869+
case MEM_CANCEL_ONLINE:
870+
case MEM_OFFLINE: {
871+
struct vm_struct *vm;
872+
873+
/*
874+
* shadow_start was either mapped during boot by kasan_init()
875+
* or during memory online by __vmalloc_node_range().
876+
* In the latter case we can use vfree() to free shadow.
877+
* Non-NULL result of the find_vm_area() will tell us if
878+
* that was the second case.
879+
*
880+
* Currently it's not possible to free shadow mapped
881+
* during boot by kasan_init(). It's because the code
882+
* to do that hasn't been written yet. So we'll just
883+
* leak the memory.
884+
*/
885+
vm = find_vm_area((void *)shadow_start);
886+
if (vm)
887+
vfree((void *)shadow_start);
888+
}
829889
}
830890

831891
return NOTIFY_OK;
@@ -838,5 +898,5 @@ static int __init kasan_memhotplug_init(void)
838898
return 0;
839899
}
840900

841-
module_init(kasan_memhotplug_init);
901+
core_initcall(kasan_memhotplug_init);
842902
#endif

mm/memory_hotplug.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1158,7 +1158,7 @@ int __ref add_memory_resource(int nid, struct resource *res, bool online)
11581158
* nodes have to go through register_node.
11591159
* TODO clean up this mess.
11601160
*/
1161-
ret = link_mem_sections(nid, start_pfn, nr_pages);
1161+
ret = link_mem_sections(nid, start_pfn, nr_pages, false);
11621162
register_fail:
11631163
/*
11641164
* If sysfs file of new node can't create, cpu on the node

mm/page_alloc.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7598,11 +7598,12 @@ bool has_unmovable_pages(struct zone *zone, struct page *page, int count,
75987598
unsigned long pfn, iter, found;
75997599

76007600
/*
7601-
* For avoiding noise data, lru_add_drain_all() should be called
7602-
* If ZONE_MOVABLE, the zone never contains unmovable pages
7601+
* TODO we could make this much more efficient by not checking every
7602+
* page in the range if we know all of them are in MOVABLE_ZONE and
7603+
* that the movable zone guarantees that pages are migratable but
7604+
* the later is not the case right now unfortunatelly. E.g. movablecore
7605+
* can still lead to having bootmem allocations in zone_movable.
76037606
*/
7604-
if (zone_idx(zone) == ZONE_MOVABLE)
7605-
return false;
76067607

76077608
/*
76087609
* CMA allocations (alloc_contig_range) really need to mark isolate
@@ -7623,7 +7624,7 @@ bool has_unmovable_pages(struct zone *zone, struct page *page, int count,
76237624
page = pfn_to_page(check);
76247625

76257626
if (PageReserved(page))
7626-
return true;
7627+
goto unmovable;
76277628

76287629
/*
76297630
* Hugepages are not in LRU lists, but they're movable.
@@ -7673,9 +7674,12 @@ bool has_unmovable_pages(struct zone *zone, struct page *page, int count,
76737674
* page at boot.
76747675
*/
76757676
if (found > count)
7676-
return true;
7677+
goto unmovable;
76777678
}
76787679
return false;
7680+
unmovable:
7681+
WARN_ON_ONCE(zone_idx(zone) == ZONE_MOVABLE);
7682+
return true;
76797683
}
76807684

76817685
bool is_pageblock_removable_nolock(struct page *page)

mm/swapfile.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3112,6 +3112,7 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
31123112
unsigned long *frontswap_map = NULL;
31133113
struct page *page = NULL;
31143114
struct inode *inode = NULL;
3115+
bool inced_nr_rotate_swap = false;
31153116

31163117
if (swap_flags & ~SWAP_FLAGS_VALID)
31173118
return -EINVAL;
@@ -3215,8 +3216,10 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
32153216
cluster = per_cpu_ptr(p->percpu_cluster, cpu);
32163217
cluster_set_null(&cluster->index);
32173218
}
3218-
} else
3219+
} else {
32193220
atomic_inc(&nr_rotate_swap);
3221+
inced_nr_rotate_swap = true;
3222+
}
32203223

32213224
error = swap_cgroup_swapon(p->type, maxpages);
32223225
if (error)
@@ -3307,6 +3310,8 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
33073310
vfree(swap_map);
33083311
kvfree(cluster_info);
33093312
kvfree(frontswap_map);
3313+
if (inced_nr_rotate_swap)
3314+
atomic_dec(&nr_rotate_swap);
33103315
if (swap_file) {
33113316
if (inode && S_ISREG(inode->i_mode)) {
33123317
inode_unlock(inode);

scripts/checkpatch.pl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5041,7 +5041,7 @@ sub process {
50415041
$tmp_stmt =~ s/\b(typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g;
50425042
$tmp_stmt =~ s/\#+\s*$arg\b//g;
50435043
$tmp_stmt =~ s/\b$arg\s*\#\#//g;
5044-
my $use_cnt = $tmp_stmt =~ s/\b$arg\b//g;
5044+
my $use_cnt = () = $tmp_stmt =~ /\b$arg\b/g;
50455045
if ($use_cnt > 1) {
50465046
CHK("MACRO_ARG_REUSE",
50475047
"Macro argument reuse '$arg' - possible side-effects?\n" . "$herectx");

tools/testing/radix-tree/idr-test.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,13 @@ void idr_checks(void)
252252
idr_remove(&idr, 3);
253253
idr_remove(&idr, 0);
254254

255+
assert(idr_alloc(&idr, DUMMY_PTR, 0, 0, GFP_KERNEL) == 0);
256+
idr_remove(&idr, 1);
257+
for (i = 1; i < RADIX_TREE_MAP_SIZE; i++)
258+
assert(idr_alloc(&idr, DUMMY_PTR, 0, 0, GFP_KERNEL) == i);
259+
idr_remove(&idr, 1 << 30);
260+
idr_destroy(&idr);
261+
255262
for (i = INT_MAX - 3UL; i < INT_MAX + 1UL; i++) {
256263
struct item *item = item_create(i, 0);
257264
assert(idr_alloc(&idr, item, i, i + 10, GFP_KERNEL) == i);

0 commit comments

Comments
 (0)