Skip to content

Commit 660e4b1

Browse files
committed
Merge tag 'mm-hotfixes-stable-2024-08-07-18-32' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
Pull misc fixes from Andrew Morton: "Nine hotfixes. Five are cc:stable, the others either pertain to post-6.10 material or aren't considered necessary for earlier kernels. Five are MM and four are non-MM. No identifiable theme here - please see the individual changelogs" * tag 'mm-hotfixes-stable-2024-08-07-18-32' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm: padata: Fix possible divide-by-0 panic in padata_mt_helper() mailmap: update entry for David Heidelberg memcg: protect concurrent access to mem_cgroup_idr mm: shmem: fix incorrect aligned index when checking conflicts mm: shmem: avoid allocating huge pages larger than MAX_PAGECACHE_ORDER for shmem mm: list_lru: fix UAF for memory cgroup kcov: properly check for softirq context MAINTAINERS: Update LTP members and web selftests: mm: add s390 to ARCH check
2 parents 6a0e382 + 6d45e1c commit 660e4b1

File tree

8 files changed

+71
-22
lines changed

8 files changed

+71
-22
lines changed

.mailmap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ Daniel Borkmann <[email protected]> <[email protected]>
166166
167167
David Brownell <[email protected]>
168168
169+
169170
170171
171172

MAINTAINERS

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13324,14 +13324,16 @@ F: Documentation/devicetree/bindings/i2c/i2c-mux-ltc4306.txt
1332413324
F: drivers/i2c/muxes/i2c-mux-ltc4306.c
1332513325

1332613326
LTP (Linux Test Project)
13327+
M: Andrea Cervesato <[email protected]>
1332713328
M: Cyril Hrubis <[email protected]>
1332813329
M: Jan Stancek <[email protected]>
1332913330
M: Petr Vorel <[email protected]>
1333013331
M: Li Wang <[email protected]>
1333113332
M: Yang Xu <[email protected]>
13333+
M: Xiao Yang <[email protected]>
1333213334
L: [email protected] (subscribers-only)
1333313335
S: Maintained
13334-
W: http://linux-test-project.github.io/
13336+
W: https://linux-test-project.readthedocs.io/
1333513337
T: git https://github.com/linux-test-project/ltp.git
1333613338

1333713339
LTR390 AMBIENT/UV LIGHT SENSOR DRIVER

kernel/kcov.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,15 @@ static void kcov_remote_area_put(struct kcov_remote_area *area,
161161
kmsan_unpoison_memory(&area->list, sizeof(area->list));
162162
}
163163

164+
/*
165+
* Unlike in_serving_softirq(), this function returns false when called during
166+
* a hardirq or an NMI that happened in the softirq context.
167+
*/
168+
static inline bool in_softirq_really(void)
169+
{
170+
return in_serving_softirq() && !in_hardirq() && !in_nmi();
171+
}
172+
164173
static notrace bool check_kcov_mode(enum kcov_mode needed_mode, struct task_struct *t)
165174
{
166175
unsigned int mode;
@@ -170,7 +179,7 @@ static notrace bool check_kcov_mode(enum kcov_mode needed_mode, struct task_stru
170179
* so we ignore code executed in interrupts, unless we are in a remote
171180
* coverage collection section in a softirq.
172181
*/
173-
if (!in_task() && !(in_serving_softirq() && t->kcov_softirq))
182+
if (!in_task() && !(in_softirq_really() && t->kcov_softirq))
174183
return false;
175184
mode = READ_ONCE(t->kcov_mode);
176185
/*
@@ -849,7 +858,7 @@ void kcov_remote_start(u64 handle)
849858

850859
if (WARN_ON(!kcov_check_handle(handle, true, true, true)))
851860
return;
852-
if (!in_task() && !in_serving_softirq())
861+
if (!in_task() && !in_softirq_really())
853862
return;
854863

855864
local_lock_irqsave(&kcov_percpu_data.lock, flags);
@@ -991,7 +1000,7 @@ void kcov_remote_stop(void)
9911000
int sequence;
9921001
unsigned long flags;
9931002

994-
if (!in_task() && !in_serving_softirq())
1003+
if (!in_task() && !in_softirq_really())
9951004
return;
9961005

9971006
local_lock_irqsave(&kcov_percpu_data.lock, flags);

kernel/padata.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,13 @@ void __init padata_do_multithreaded(struct padata_mt_job *job)
517517
ps.chunk_size = max(ps.chunk_size, job->min_chunk);
518518
ps.chunk_size = roundup(ps.chunk_size, job->align);
519519

520+
/*
521+
* chunk_size can be 0 if the caller sets min_chunk to 0. So force it
522+
* to at least 1 to prevent divide-by-0 panic in padata_mt_helper().`
523+
*/
524+
if (!ps.chunk_size)
525+
ps.chunk_size = 1U;
526+
520527
list_for_each_entry(pw, &works, pw_list)
521528
if (job->numa_aware) {
522529
int old_node = atomic_read(&last_used_nid);

mm/list_lru.c

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ list_lru_from_memcg_idx(struct list_lru *lru, int nid, int idx)
8585
}
8686
#endif /* CONFIG_MEMCG */
8787

88+
/* The caller must ensure the memcg lifetime. */
8889
bool list_lru_add(struct list_lru *lru, struct list_head *item, int nid,
8990
struct mem_cgroup *memcg)
9091
{
@@ -109,14 +110,22 @@ EXPORT_SYMBOL_GPL(list_lru_add);
109110

110111
bool list_lru_add_obj(struct list_lru *lru, struct list_head *item)
111112
{
113+
bool ret;
112114
int nid = page_to_nid(virt_to_page(item));
113-
struct mem_cgroup *memcg = list_lru_memcg_aware(lru) ?
114-
mem_cgroup_from_slab_obj(item) : NULL;
115115

116-
return list_lru_add(lru, item, nid, memcg);
116+
if (list_lru_memcg_aware(lru)) {
117+
rcu_read_lock();
118+
ret = list_lru_add(lru, item, nid, mem_cgroup_from_slab_obj(item));
119+
rcu_read_unlock();
120+
} else {
121+
ret = list_lru_add(lru, item, nid, NULL);
122+
}
123+
124+
return ret;
117125
}
118126
EXPORT_SYMBOL_GPL(list_lru_add_obj);
119127

128+
/* The caller must ensure the memcg lifetime. */
120129
bool list_lru_del(struct list_lru *lru, struct list_head *item, int nid,
121130
struct mem_cgroup *memcg)
122131
{
@@ -139,11 +148,18 @@ EXPORT_SYMBOL_GPL(list_lru_del);
139148

140149
bool list_lru_del_obj(struct list_lru *lru, struct list_head *item)
141150
{
151+
bool ret;
142152
int nid = page_to_nid(virt_to_page(item));
143-
struct mem_cgroup *memcg = list_lru_memcg_aware(lru) ?
144-
mem_cgroup_from_slab_obj(item) : NULL;
145153

146-
return list_lru_del(lru, item, nid, memcg);
154+
if (list_lru_memcg_aware(lru)) {
155+
rcu_read_lock();
156+
ret = list_lru_del(lru, item, nid, mem_cgroup_from_slab_obj(item));
157+
rcu_read_unlock();
158+
} else {
159+
ret = list_lru_del(lru, item, nid, NULL);
160+
}
161+
162+
return ret;
147163
}
148164
EXPORT_SYMBOL_GPL(list_lru_del_obj);
149165

mm/memcontrol.c

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3386,11 +3386,28 @@ static void memcg_wb_domain_size_changed(struct mem_cgroup *memcg)
33863386

33873387
#define MEM_CGROUP_ID_MAX ((1UL << MEM_CGROUP_ID_SHIFT) - 1)
33883388
static DEFINE_IDR(mem_cgroup_idr);
3389+
static DEFINE_SPINLOCK(memcg_idr_lock);
3390+
3391+
static int mem_cgroup_alloc_id(void)
3392+
{
3393+
int ret;
3394+
3395+
idr_preload(GFP_KERNEL);
3396+
spin_lock(&memcg_idr_lock);
3397+
ret = idr_alloc(&mem_cgroup_idr, NULL, 1, MEM_CGROUP_ID_MAX + 1,
3398+
GFP_NOWAIT);
3399+
spin_unlock(&memcg_idr_lock);
3400+
idr_preload_end();
3401+
return ret;
3402+
}
33893403

33903404
static void mem_cgroup_id_remove(struct mem_cgroup *memcg)
33913405
{
33923406
if (memcg->id.id > 0) {
3407+
spin_lock(&memcg_idr_lock);
33933408
idr_remove(&mem_cgroup_idr, memcg->id.id);
3409+
spin_unlock(&memcg_idr_lock);
3410+
33943411
memcg->id.id = 0;
33953412
}
33963413
}
@@ -3524,8 +3541,7 @@ static struct mem_cgroup *mem_cgroup_alloc(struct mem_cgroup *parent)
35243541
if (!memcg)
35253542
return ERR_PTR(error);
35263543

3527-
memcg->id.id = idr_alloc(&mem_cgroup_idr, NULL,
3528-
1, MEM_CGROUP_ID_MAX + 1, GFP_KERNEL);
3544+
memcg->id.id = mem_cgroup_alloc_id();
35293545
if (memcg->id.id < 0) {
35303546
error = memcg->id.id;
35313547
goto fail;
@@ -3667,7 +3683,9 @@ static int mem_cgroup_css_online(struct cgroup_subsys_state *css)
36673683
* publish it here at the end of onlining. This matches the
36683684
* regular ID destruction during offlining.
36693685
*/
3686+
spin_lock(&memcg_idr_lock);
36703687
idr_replace(&mem_cgroup_idr, memcg, memcg->id.id);
3688+
spin_unlock(&memcg_idr_lock);
36713689

36723690
return 0;
36733691
offline_kmem:

mm/shmem.c

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1629,11 +1629,6 @@ unsigned long shmem_allowable_huge_orders(struct inode *inode,
16291629
unsigned long mask = READ_ONCE(huge_shmem_orders_always);
16301630
unsigned long within_size_orders = READ_ONCE(huge_shmem_orders_within_size);
16311631
unsigned long vm_flags = vma->vm_flags;
1632-
/*
1633-
* Check all the (large) orders below HPAGE_PMD_ORDER + 1 that
1634-
* are enabled for this vma.
1635-
*/
1636-
unsigned long orders = BIT(PMD_ORDER + 1) - 1;
16371632
loff_t i_size;
16381633
int order;
16391634

@@ -1678,14 +1673,15 @@ unsigned long shmem_allowable_huge_orders(struct inode *inode,
16781673
if (global_huge)
16791674
mask |= READ_ONCE(huge_shmem_orders_inherit);
16801675

1681-
return orders & mask;
1676+
return THP_ORDERS_ALL_FILE_DEFAULT & mask;
16821677
}
16831678

16841679
static unsigned long shmem_suitable_orders(struct inode *inode, struct vm_fault *vmf,
16851680
struct address_space *mapping, pgoff_t index,
16861681
unsigned long orders)
16871682
{
16881683
struct vm_area_struct *vma = vmf->vma;
1684+
pgoff_t aligned_index;
16891685
unsigned long pages;
16901686
int order;
16911687

@@ -1697,9 +1693,9 @@ static unsigned long shmem_suitable_orders(struct inode *inode, struct vm_fault
16971693
order = highest_order(orders);
16981694
while (orders) {
16991695
pages = 1UL << order;
1700-
index = round_down(index, pages);
1701-
if (!xa_find(&mapping->i_pages, &index,
1702-
index + pages - 1, XA_PRESENT))
1696+
aligned_index = round_down(index, pages);
1697+
if (!xa_find(&mapping->i_pages, &aligned_index,
1698+
aligned_index + pages - 1, XA_PRESENT))
17031699
break;
17041700
order = next_order(&orders, order);
17051701
}

tools/testing/selftests/mm/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ endif
110110

111111
endif
112112

113-
ifneq (,$(filter $(ARCH),arm64 ia64 mips64 parisc64 powerpc riscv64 s390x sparc64 x86_64))
113+
ifneq (,$(filter $(ARCH),arm64 ia64 mips64 parisc64 powerpc riscv64 s390x sparc64 x86_64 s390))
114114
TEST_GEN_FILES += va_high_addr_switch
115115
TEST_GEN_FILES += virtual_address_range
116116
TEST_GEN_FILES += write_to_hugetlbfs

0 commit comments

Comments
 (0)