Skip to content

Commit c22c3e0

Browse files
committed
Merge tag 'mm-hotfixes-stable-2024-05-10-13-14' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
Pull MM fixes from Andrew Morton: "18 hotfixes, 7 of which are cc:stable. More fixups for this cycle's page_owner updates. And a few userfaultfd fixes. Otherwise, random singletons - see the individual changelogs for details" * tag 'mm-hotfixes-stable-2024-05-10-13-14' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm: mailmap: add entry for Barry Song selftests/mm: fix powerpc ARCH check mailmap: add entry for John Garry XArray: set the marks correctly when splitting an entry selftests/vDSO: fix runtime errors on LoongArch selftests/vDSO: fix building errors on LoongArch mm,page_owner: don't remove __GFP_NOLOCKDEP in add_stack_record_to_list fs/proc/task_mmu: fix uffd-wp confusion in pagemap_scan_pmd_entry() fs/proc/task_mmu: fix loss of young/dirty bits during pagemap scan mm/vmalloc: fix return value of vb_alloc if size is 0 mm: use memalloc_nofs_save() in page_cache_ra_order() kmsan: compiler_types: declare __no_sanitize_or_inline lib/test_xarray.c: fix error assumptions on check_xa_multi_store_adv_add() tools: fix userspace compilation with new test_xarray changes MAINTAINERS: update URL's for KEYS/KEYRINGS_INTEGRITY and TPM DEVICE DRIVER mm: page_owner: fix wrong information in dump_page_owner maple_tree: fix mas_empty_area_rev() null pointer dereference mm/userfaultfd: reset ptes when close() for wr-protected ones
2 parents cfb4be1 + 672614a commit c22c3e0

File tree

16 files changed

+116
-64
lines changed

16 files changed

+116
-64
lines changed

.mailmap

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,11 @@ Baolin Wang <[email protected]> <[email protected]>
9797
9898
9999
100+
101+
102+
103+
104+
100105
101106
102107
Bartosz Golaszewski <[email protected]> <[email protected]>
@@ -304,6 +309,7 @@ Johan Hovold <[email protected]> <[email protected]>
304309
305310
306311
312+
307313
308314
309315
John Paul Adrian Glaubitz <[email protected]>

MAINTAINERS

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12041,6 +12041,7 @@ M: Mimi Zohar <[email protected]>
1204112041
1204212042
1204312043
S: Supported
12044+
W: https://kernsec.org/wiki/index.php/Linux_Kernel_Integrity
1204412045
F: security/integrity/platform_certs
1204512046

1204612047
KFENCE
@@ -22409,7 +22410,7 @@ M: Jarkko Sakkinen <[email protected]>
2240922410
R: Jason Gunthorpe <[email protected]>
2241022411
2241122412
S: Maintained
22412-
W: https://kernsec.org/wiki/index.php/Linux_Kernel_Integrity
22413+
W: https://gitlab.com/jarkkojs/linux-tpmdd-test
2241322414
Q: https://patchwork.kernel.org/project/linux-integrity/list/
2241422415
T: git git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd.git
2241522416
F: Documentation/devicetree/bindings/tpm/

fs/proc/task_mmu.c

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1817,15 +1817,13 @@ static unsigned long pagemap_page_category(struct pagemap_scan_private *p,
18171817
}
18181818

18191819
static void make_uffd_wp_pte(struct vm_area_struct *vma,
1820-
unsigned long addr, pte_t *pte)
1820+
unsigned long addr, pte_t *pte, pte_t ptent)
18211821
{
1822-
pte_t ptent = ptep_get(pte);
1823-
18241822
if (pte_present(ptent)) {
18251823
pte_t old_pte;
18261824

18271825
old_pte = ptep_modify_prot_start(vma, addr, pte);
1828-
ptent = pte_mkuffd_wp(ptent);
1826+
ptent = pte_mkuffd_wp(old_pte);
18291827
ptep_modify_prot_commit(vma, addr, pte, old_pte, ptent);
18301828
} else if (is_swap_pte(ptent)) {
18311829
ptent = pte_swp_mkuffd_wp(ptent);
@@ -2175,9 +2173,12 @@ static int pagemap_scan_pmd_entry(pmd_t *pmd, unsigned long start,
21752173
if ((p->arg.flags & PM_SCAN_WP_MATCHING) && !p->vec_out) {
21762174
/* Fast path for performing exclusive WP */
21772175
for (addr = start; addr != end; pte++, addr += PAGE_SIZE) {
2178-
if (pte_uffd_wp(ptep_get(pte)))
2176+
pte_t ptent = ptep_get(pte);
2177+
2178+
if ((pte_present(ptent) && pte_uffd_wp(ptent)) ||
2179+
pte_swp_uffd_wp_any(ptent))
21792180
continue;
2180-
make_uffd_wp_pte(vma, addr, pte);
2181+
make_uffd_wp_pte(vma, addr, pte, ptent);
21812182
if (!flush_end)
21822183
start = addr;
21832184
flush_end = addr + PAGE_SIZE;
@@ -2190,16 +2191,18 @@ static int pagemap_scan_pmd_entry(pmd_t *pmd, unsigned long start,
21902191
p->arg.return_mask == PAGE_IS_WRITTEN) {
21912192
for (addr = start; addr < end; pte++, addr += PAGE_SIZE) {
21922193
unsigned long next = addr + PAGE_SIZE;
2194+
pte_t ptent = ptep_get(pte);
21932195

2194-
if (pte_uffd_wp(ptep_get(pte)))
2196+
if ((pte_present(ptent) && pte_uffd_wp(ptent)) ||
2197+
pte_swp_uffd_wp_any(ptent))
21952198
continue;
21962199
ret = pagemap_scan_output(p->cur_vma_category | PAGE_IS_WRITTEN,
21972200
p, addr, &next);
21982201
if (next == addr)
21992202
break;
22002203
if (~p->arg.flags & PM_SCAN_WP_MATCHING)
22012204
continue;
2202-
make_uffd_wp_pte(vma, addr, pte);
2205+
make_uffd_wp_pte(vma, addr, pte, ptent);
22032206
if (!flush_end)
22042207
start = addr;
22052208
flush_end = next;
@@ -2208,8 +2211,9 @@ static int pagemap_scan_pmd_entry(pmd_t *pmd, unsigned long start,
22082211
}
22092212

22102213
for (addr = start; addr != end; pte++, addr += PAGE_SIZE) {
2214+
pte_t ptent = ptep_get(pte);
22112215
unsigned long categories = p->cur_vma_category |
2212-
pagemap_page_category(p, vma, addr, ptep_get(pte));
2216+
pagemap_page_category(p, vma, addr, ptent);
22132217
unsigned long next = addr + PAGE_SIZE;
22142218

22152219
if (!pagemap_scan_is_interesting_page(categories, p))
@@ -2224,7 +2228,7 @@ static int pagemap_scan_pmd_entry(pmd_t *pmd, unsigned long start,
22242228
if (~categories & PAGE_IS_WRITTEN)
22252229
continue;
22262230

2227-
make_uffd_wp_pte(vma, addr, pte);
2231+
make_uffd_wp_pte(vma, addr, pte, ptent);
22282232
if (!flush_end)
22292233
start = addr;
22302234
flush_end = next;

fs/userfaultfd.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -895,6 +895,10 @@ static int userfaultfd_release(struct inode *inode, struct file *file)
895895
prev = vma;
896896
continue;
897897
}
898+
/* Reset ptes for the whole vma range if wr-protected */
899+
if (userfaultfd_wp(vma))
900+
uffd_wp_range(vma, vma->vm_start,
901+
vma->vm_end - vma->vm_start, false);
898902
new_flags = vma->vm_flags & ~__VM_UFFD_FLAGS;
899903
vma = vma_modify_flags_uffd(&vmi, prev, vma, vma->vm_start,
900904
vma->vm_end, new_flags,

include/linux/compiler_types.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,17 @@ struct ftrace_likely_data {
278278
# define __no_kcsan
279279
#endif
280280

281+
#ifdef __SANITIZE_MEMORY__
282+
/*
283+
* Similarly to KASAN and KCSAN, KMSAN loses function attributes of inlined
284+
* functions, therefore disabling KMSAN checks also requires disabling inlining.
285+
*
286+
* __no_sanitize_or_inline effectively prevents KMSAN from reporting errors
287+
* within the function and marks all its outputs as initialized.
288+
*/
289+
# define __no_sanitize_or_inline __no_kmsan_checks notrace __maybe_unused
290+
#endif
291+
281292
#ifndef __no_sanitize_or_inline
282293
#define __no_sanitize_or_inline __always_inline
283294
#endif

lib/maple_tree.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5109,18 +5109,18 @@ int mas_empty_area_rev(struct ma_state *mas, unsigned long min,
51095109
if (size == 0 || max - min < size - 1)
51105110
return -EINVAL;
51115111

5112-
if (mas_is_start(mas)) {
5112+
if (mas_is_start(mas))
51135113
mas_start(mas);
5114-
mas->offset = mas_data_end(mas);
5115-
} else if (mas->offset >= 2) {
5116-
mas->offset -= 2;
5117-
} else if (!mas_rewind_node(mas)) {
5114+
else if ((mas->offset < 2) && (!mas_rewind_node(mas)))
51185115
return -EBUSY;
5119-
}
51205116

5121-
/* Empty set. */
5122-
if (mas_is_none(mas) || mas_is_ptr(mas))
5117+
if (unlikely(mas_is_none(mas) || mas_is_ptr(mas)))
51235118
return mas_sparse_area(mas, min, max, size, false);
5119+
else if (mas->offset >= 2)
5120+
mas->offset -= 2;
5121+
else
5122+
mas->offset = mas_data_end(mas);
5123+
51245124

51255125
/* The start of the window can only be within these values. */
51265126
mas->index = min;

lib/test_xarray.c

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -744,15 +744,20 @@ static noinline void check_xa_multi_store_adv_add(struct xarray *xa,
744744

745745
do {
746746
xas_lock_irq(&xas);
747-
748747
xas_store(&xas, p);
749-
XA_BUG_ON(xa, xas_error(&xas));
750-
XA_BUG_ON(xa, xa_load(xa, index) != p);
751-
752748
xas_unlock_irq(&xas);
749+
/*
750+
* In our selftest case the only failure we can expect is for
751+
* there not to be enough memory as we're not mimicking the
752+
* entire page cache, so verify that's the only error we can run
753+
* into here. The xas_nomem() which follows will ensure to fix
754+
* that condition for us so to chug on on the loop.
755+
*/
756+
XA_BUG_ON(xa, xas_error(&xas) && xas_error(&xas) != -ENOMEM);
753757
} while (xas_nomem(&xas, GFP_KERNEL));
754758

755759
XA_BUG_ON(xa, xas_error(&xas));
760+
XA_BUG_ON(xa, xa_load(xa, index) != p);
756761
}
757762

758763
/* mimics page_cache_delete() */
@@ -1783,9 +1788,11 @@ static void check_split_1(struct xarray *xa, unsigned long index,
17831788
unsigned int order, unsigned int new_order)
17841789
{
17851790
XA_STATE_ORDER(xas, xa, index, new_order);
1786-
unsigned int i;
1791+
unsigned int i, found;
1792+
void *entry;
17871793

17881794
xa_store_order(xa, index, order, xa, GFP_KERNEL);
1795+
xa_set_mark(xa, index, XA_MARK_1);
17891796

17901797
xas_split_alloc(&xas, xa, order, GFP_KERNEL);
17911798
xas_lock(&xas);
@@ -1802,6 +1809,16 @@ static void check_split_1(struct xarray *xa, unsigned long index,
18021809
xa_set_mark(xa, index, XA_MARK_0);
18031810
XA_BUG_ON(xa, !xa_get_mark(xa, index, XA_MARK_0));
18041811

1812+
xas_set_order(&xas, index, 0);
1813+
found = 0;
1814+
rcu_read_lock();
1815+
xas_for_each_marked(&xas, entry, ULONG_MAX, XA_MARK_1) {
1816+
found++;
1817+
XA_BUG_ON(xa, xa_is_internal(entry));
1818+
}
1819+
rcu_read_unlock();
1820+
XA_BUG_ON(xa, found != 1 << (order - new_order));
1821+
18051822
xa_destroy(xa);
18061823
}
18071824

lib/xarray.c

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -969,16 +969,30 @@ static unsigned int node_get_marks(struct xa_node *node, unsigned int offset)
969969
return marks;
970970
}
971971

972+
static inline void node_mark_slots(struct xa_node *node, unsigned int sibs,
973+
xa_mark_t mark)
974+
{
975+
int i;
976+
977+
if (sibs == 0)
978+
node_mark_all(node, mark);
979+
else {
980+
for (i = 0; i < XA_CHUNK_SIZE; i += sibs + 1)
981+
node_set_mark(node, i, mark);
982+
}
983+
}
984+
972985
static void node_set_marks(struct xa_node *node, unsigned int offset,
973-
struct xa_node *child, unsigned int marks)
986+
struct xa_node *child, unsigned int sibs,
987+
unsigned int marks)
974988
{
975989
xa_mark_t mark = XA_MARK_0;
976990

977991
for (;;) {
978992
if (marks & (1 << (__force unsigned int)mark)) {
979993
node_set_mark(node, offset, mark);
980994
if (child)
981-
node_mark_all(child, mark);
995+
node_mark_slots(child, sibs, mark);
982996
}
983997
if (mark == XA_MARK_MAX)
984998
break;
@@ -1077,7 +1091,8 @@ void xas_split(struct xa_state *xas, void *entry, unsigned int order)
10771091
child->nr_values = xa_is_value(entry) ?
10781092
XA_CHUNK_SIZE : 0;
10791093
RCU_INIT_POINTER(child->parent, node);
1080-
node_set_marks(node, offset, child, marks);
1094+
node_set_marks(node, offset, child, xas->xa_sibs,
1095+
marks);
10811096
rcu_assign_pointer(node->slots[offset],
10821097
xa_mk_node(child));
10831098
if (xa_is_value(curr))
@@ -1086,7 +1101,7 @@ void xas_split(struct xa_state *xas, void *entry, unsigned int order)
10861101
} else {
10871102
unsigned int canon = offset - xas->xa_sibs;
10881103

1089-
node_set_marks(node, canon, NULL, marks);
1104+
node_set_marks(node, canon, NULL, 0, marks);
10901105
rcu_assign_pointer(node->slots[canon], entry);
10911106
while (offset > canon)
10921107
rcu_assign_pointer(node->slots[offset--],

mm/page_owner.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ static void add_stack_record_to_list(struct stack_record *stack_record,
170170

171171
/* Filter gfp_mask the same way stackdepot does, for consistency */
172172
gfp_mask &= ~GFP_ZONEMASK;
173-
gfp_mask &= (GFP_ATOMIC | GFP_KERNEL);
173+
gfp_mask &= (GFP_ATOMIC | GFP_KERNEL | __GFP_NOLOCKDEP);
174174
gfp_mask |= __GFP_NOWARN;
175175

176176
set_current_in_page_owner();
@@ -328,7 +328,7 @@ noinline void __set_page_owner(struct page *page, unsigned short order,
328328
if (unlikely(!page_ext))
329329
return;
330330
__update_page_owner_handle(page_ext, handle, order, gfp_mask, -1,
331-
current->pid, current->tgid, ts_nsec,
331+
ts_nsec, current->pid, current->tgid,
332332
current->comm);
333333
page_ext_put(page_ext);
334334
inc_stack_record_count(handle, gfp_mask, 1 << order);

mm/readahead.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,7 @@ void page_cache_ra_order(struct readahead_control *ractl,
490490
pgoff_t index = readahead_index(ractl);
491491
pgoff_t limit = (i_size_read(mapping->host) - 1) >> PAGE_SHIFT;
492492
pgoff_t mark = index + ra->size - ra->async_size;
493+
unsigned int nofs;
493494
int err = 0;
494495
gfp_t gfp = readahead_gfp_mask(mapping);
495496

@@ -504,6 +505,8 @@ void page_cache_ra_order(struct readahead_control *ractl,
504505
new_order = min_t(unsigned int, new_order, ilog2(ra->size));
505506
}
506507

508+
/* See comment in page_cache_ra_unbounded() */
509+
nofs = memalloc_nofs_save();
507510
filemap_invalidate_lock_shared(mapping);
508511
while (index <= limit) {
509512
unsigned int order = new_order;
@@ -527,6 +530,7 @@ void page_cache_ra_order(struct readahead_control *ractl,
527530

528531
read_pages(ractl);
529532
filemap_invalidate_unlock_shared(mapping);
533+
memalloc_nofs_restore(nofs);
530534

531535
/*
532536
* If there were already pages in the page cache, then we may have

mm/vmalloc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2710,7 +2710,7 @@ static void *vb_alloc(unsigned long size, gfp_t gfp_mask)
27102710
* get_order(0) returns funny result. Just warn and terminate
27112711
* early.
27122712
*/
2713-
return NULL;
2713+
return ERR_PTR(-EINVAL);
27142714
}
27152715
order = get_order(size);
27162716

tools/testing/radix-tree/linux/kernel.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#define pr_info printk
1919
#define pr_debug printk
2020
#define pr_cont printk
21+
#define schedule()
22+
#define PAGE_SHIFT 12
2123

2224
#define __acquires(x)
2325
#define __releases(x)

tools/testing/selftests/mm/Makefile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ uname_M := $(shell uname -m 2>/dev/null || echo not)
1212
else
1313
uname_M := $(shell echo $(CROSS_COMPILE) | grep -o '^[a-z0-9]\+')
1414
endif
15-
ARCH ?= $(shell echo $(uname_M) | sed -e 's/aarch64.*/arm64/' -e 's/ppc64.*/ppc64/')
15+
ARCH ?= $(shell echo $(uname_M) | sed -e 's/aarch64.*/arm64/' -e 's/ppc64.*/powerpc/')
1616
endif
1717

1818
# Without this, failed build products remain, with up-to-date timestamps,
@@ -98,13 +98,13 @@ TEST_GEN_FILES += $(BINARIES_64)
9898
endif
9999
else
100100

101-
ifneq (,$(findstring $(ARCH),ppc64))
101+
ifneq (,$(findstring $(ARCH),powerpc))
102102
TEST_GEN_FILES += protection_keys
103103
endif
104104

105105
endif
106106

107-
ifneq (,$(filter $(ARCH),arm64 ia64 mips64 parisc64 ppc64 riscv64 s390x sparc64 x86_64))
107+
ifneq (,$(filter $(ARCH),arm64 ia64 mips64 parisc64 powerpc riscv64 s390x sparc64 x86_64))
108108
TEST_GEN_FILES += va_high_addr_switch
109109
TEST_GEN_FILES += virtual_address_range
110110
TEST_GEN_FILES += write_to_hugetlbfs

tools/testing/selftests/vDSO/vdso_config.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,15 +53,19 @@
5353
#if __riscv_xlen == 32
5454
#define VDSO_32BIT 1
5555
#endif
56+
#elif defined(__loongarch__)
57+
#define VDSO_VERSION 6
58+
#define VDSO_NAMES 1
5659
#endif
5760

58-
static const char *versions[6] = {
61+
static const char *versions[7] = {
5962
"LINUX_2.6",
6063
"LINUX_2.6.15",
6164
"LINUX_2.6.29",
6265
"LINUX_2.6.39",
6366
"LINUX_4",
6467
"LINUX_4.15",
68+
"LINUX_5.10"
6569
};
6670

6771
static const char *names[2][6] = {

0 commit comments

Comments
 (0)