Skip to content

Commit bca1d4d

Browse files
committed
Merge branch 'akpm' (patches from Andrew)
Merge misc mm fixes from Andrew Morton: "15 patches. VM subsystems affected by this patch series: userfaultfd, kfence, highmem, pagealloc, memblock, pagecache, secretmem, pagemap, and hugetlbfs" * akpm: hugetlbfs: fix mount mode command line processing mm: fix the deadlock in finish_fault() mm: mmap_lock: fix disabling preemption directly mm/secretmem: wire up ->set_page_dirty writeback, cgroup: do not reparent dax inodes writeback, cgroup: remove wb from offline list before releasing refcnt memblock: make for_each_mem_range() traverse MEMBLOCK_HOTPLUG regions mm: page_alloc: fix page_poison=1 / INIT_ON_ALLOC_DEFAULT_ON interaction mm: use kmap_local_page in memzero_page mm: call flush_dcache_page() in memcpy_to_page() and memzero_page() kfence: skip all GFP_ZONEMASK allocations kfence: move the size check to the beginning of __kfence_alloc() kfence: defer kfence_test_init to ensure that kunit debugfs is created selftest: use mmap instead of posix_memalign to allocate memory userfaultfd: do not untag user pointers
2 parents f0fddce + e0f7e2b commit bca1d4d

15 files changed

Lines changed: 93 additions & 51 deletions

File tree

Documentation/arm64/tagged-address-abi.rst

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,24 @@ how the user addresses are used by the kernel:
4545

4646
1. User addresses not accessed by the kernel but used for address space
4747
management (e.g. ``mprotect()``, ``madvise()``). The use of valid
48-
tagged pointers in this context is allowed with the exception of
49-
``brk()``, ``mmap()`` and the ``new_address`` argument to
50-
``mremap()`` as these have the potential to alias with existing
51-
user addresses.
52-
53-
NOTE: This behaviour changed in v5.6 and so some earlier kernels may
54-
incorrectly accept valid tagged pointers for the ``brk()``,
55-
``mmap()`` and ``mremap()`` system calls.
48+
tagged pointers in this context is allowed with these exceptions:
49+
50+
- ``brk()``, ``mmap()`` and the ``new_address`` argument to
51+
``mremap()`` as these have the potential to alias with existing
52+
user addresses.
53+
54+
NOTE: This behaviour changed in v5.6 and so some earlier kernels may
55+
incorrectly accept valid tagged pointers for the ``brk()``,
56+
``mmap()`` and ``mremap()`` system calls.
57+
58+
- The ``range.start``, ``start`` and ``dst`` arguments to the
59+
``UFFDIO_*`` ``ioctl()``s used on a file descriptor obtained from
60+
``userfaultfd()``, as fault addresses subsequently obtained by reading
61+
the file descriptor will be untagged, which may otherwise confuse
62+
tag-unaware programs.
63+
64+
NOTE: This behaviour changed in v5.14 and so some earlier kernels may
65+
incorrectly accept valid tagged pointers for this system call.
5666

5767
2. User addresses accessed by the kernel (e.g. ``write()``). This ABI
5868
relaxation is disabled by default and the application thread needs to

fs/fs-writeback.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,9 @@ static bool inode_prepare_wbs_switch(struct inode *inode,
521521
*/
522522
smp_mb();
523523

524+
if (IS_DAX(inode))
525+
return false;
526+
524527
/* while holding I_WB_SWITCH, no one else can update the association */
525528
spin_lock(&inode->i_lock);
526529
if (!(inode->i_sb->s_flags & SB_ACTIVE) ||

fs/hugetlbfs/inode.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ enum hugetlb_param {
7777
static const struct fs_parameter_spec hugetlb_fs_parameters[] = {
7878
fsparam_u32 ("gid", Opt_gid),
7979
fsparam_string("min_size", Opt_min_size),
80-
fsparam_u32 ("mode", Opt_mode),
80+
fsparam_u32oct("mode", Opt_mode),
8181
fsparam_string("nr_inodes", Opt_nr_inodes),
8282
fsparam_string("pagesize", Opt_pagesize),
8383
fsparam_string("size", Opt_size),

fs/userfaultfd.c

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1236,23 +1236,21 @@ static __always_inline void wake_userfault(struct userfaultfd_ctx *ctx,
12361236
}
12371237

12381238
static __always_inline int validate_range(struct mm_struct *mm,
1239-
__u64 *start, __u64 len)
1239+
__u64 start, __u64 len)
12401240
{
12411241
__u64 task_size = mm->task_size;
12421242

1243-
*start = untagged_addr(*start);
1244-
1245-
if (*start & ~PAGE_MASK)
1243+
if (start & ~PAGE_MASK)
12461244
return -EINVAL;
12471245
if (len & ~PAGE_MASK)
12481246
return -EINVAL;
12491247
if (!len)
12501248
return -EINVAL;
1251-
if (*start < mmap_min_addr)
1249+
if (start < mmap_min_addr)
12521250
return -EINVAL;
1253-
if (*start >= task_size)
1251+
if (start >= task_size)
12541252
return -EINVAL;
1255-
if (len > task_size - *start)
1253+
if (len > task_size - start)
12561254
return -EINVAL;
12571255
return 0;
12581256
}
@@ -1316,7 +1314,7 @@ static int userfaultfd_register(struct userfaultfd_ctx *ctx,
13161314
vm_flags |= VM_UFFD_MINOR;
13171315
}
13181316

1319-
ret = validate_range(mm, &uffdio_register.range.start,
1317+
ret = validate_range(mm, uffdio_register.range.start,
13201318
uffdio_register.range.len);
13211319
if (ret)
13221320
goto out;
@@ -1522,7 +1520,7 @@ static int userfaultfd_unregister(struct userfaultfd_ctx *ctx,
15221520
if (copy_from_user(&uffdio_unregister, buf, sizeof(uffdio_unregister)))
15231521
goto out;
15241522

1525-
ret = validate_range(mm, &uffdio_unregister.start,
1523+
ret = validate_range(mm, uffdio_unregister.start,
15261524
uffdio_unregister.len);
15271525
if (ret)
15281526
goto out;
@@ -1671,7 +1669,7 @@ static int userfaultfd_wake(struct userfaultfd_ctx *ctx,
16711669
if (copy_from_user(&uffdio_wake, buf, sizeof(uffdio_wake)))
16721670
goto out;
16731671

1674-
ret = validate_range(ctx->mm, &uffdio_wake.start, uffdio_wake.len);
1672+
ret = validate_range(ctx->mm, uffdio_wake.start, uffdio_wake.len);
16751673
if (ret)
16761674
goto out;
16771675

@@ -1711,7 +1709,7 @@ static int userfaultfd_copy(struct userfaultfd_ctx *ctx,
17111709
sizeof(uffdio_copy)-sizeof(__s64)))
17121710
goto out;
17131711

1714-
ret = validate_range(ctx->mm, &uffdio_copy.dst, uffdio_copy.len);
1712+
ret = validate_range(ctx->mm, uffdio_copy.dst, uffdio_copy.len);
17151713
if (ret)
17161714
goto out;
17171715
/*
@@ -1768,7 +1766,7 @@ static int userfaultfd_zeropage(struct userfaultfd_ctx *ctx,
17681766
sizeof(uffdio_zeropage)-sizeof(__s64)))
17691767
goto out;
17701768

1771-
ret = validate_range(ctx->mm, &uffdio_zeropage.range.start,
1769+
ret = validate_range(ctx->mm, uffdio_zeropage.range.start,
17721770
uffdio_zeropage.range.len);
17731771
if (ret)
17741772
goto out;
@@ -1818,7 +1816,7 @@ static int userfaultfd_writeprotect(struct userfaultfd_ctx *ctx,
18181816
sizeof(struct uffdio_writeprotect)))
18191817
return -EFAULT;
18201818

1821-
ret = validate_range(ctx->mm, &uffdio_wp.range.start,
1819+
ret = validate_range(ctx->mm, uffdio_wp.range.start,
18221820
uffdio_wp.range.len);
18231821
if (ret)
18241822
return ret;
@@ -1866,7 +1864,7 @@ static int userfaultfd_continue(struct userfaultfd_ctx *ctx, unsigned long arg)
18661864
sizeof(uffdio_continue) - (sizeof(__s64))))
18671865
goto out;
18681866

1869-
ret = validate_range(ctx->mm, &uffdio_continue.range.start,
1867+
ret = validate_range(ctx->mm, uffdio_continue.range.start,
18701868
uffdio_continue.range.len);
18711869
if (ret)
18721870
goto out;

include/linux/highmem.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -318,14 +318,16 @@ static inline void memcpy_to_page(struct page *page, size_t offset,
318318

319319
VM_BUG_ON(offset + len > PAGE_SIZE);
320320
memcpy(to + offset, from, len);
321+
flush_dcache_page(page);
321322
kunmap_local(to);
322323
}
323324

324325
static inline void memzero_page(struct page *page, size_t offset, size_t len)
325326
{
326-
char *addr = kmap_atomic(page);
327+
char *addr = kmap_local_page(page);
327328
memset(addr + offset, 0, len);
328-
kunmap_atomic(addr);
329+
flush_dcache_page(page);
330+
kunmap_local(addr);
329331
}
330332

331333
#endif /* _LINUX_HIGHMEM_H */

include/linux/memblock.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ static inline void __next_physmem_range(u64 *idx, struct memblock_type *type,
209209
*/
210210
#define for_each_mem_range(i, p_start, p_end) \
211211
__for_each_mem_range(i, &memblock.memory, NULL, NUMA_NO_NODE, \
212-
MEMBLOCK_NONE, p_start, p_end, NULL)
212+
MEMBLOCK_HOTPLUG, p_start, p_end, NULL)
213213

214214
/**
215215
* for_each_mem_range_rev - reverse iterate through memblock areas from
@@ -220,7 +220,7 @@ static inline void __next_physmem_range(u64 *idx, struct memblock_type *type,
220220
*/
221221
#define for_each_mem_range_rev(i, p_start, p_end) \
222222
__for_each_mem_range_rev(i, &memblock.memory, NULL, NUMA_NO_NODE, \
223-
MEMBLOCK_NONE, p_start, p_end, NULL)
223+
MEMBLOCK_HOTPLUG, p_start, p_end, NULL)
224224

225225
/**
226226
* for_each_reserved_mem_range - iterate over all reserved memblock areas

mm/backing-dev.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,12 +398,12 @@ static void cgwb_release_workfn(struct work_struct *work)
398398
blkcg_unpin_online(blkcg);
399399

400400
fprop_local_destroy_percpu(&wb->memcg_completions);
401-
percpu_ref_exit(&wb->refcnt);
402401

403402
spin_lock_irq(&cgwb_lock);
404403
list_del(&wb->offline_node);
405404
spin_unlock_irq(&cgwb_lock);
406405

406+
percpu_ref_exit(&wb->refcnt);
407407
wb_exit(wb);
408408
WARN_ON_ONCE(!list_empty(&wb->b_attached));
409409
kfree_rcu(wb, rcu);

mm/kfence/core.c

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -733,6 +733,22 @@ void kfence_shutdown_cache(struct kmem_cache *s)
733733

734734
void *__kfence_alloc(struct kmem_cache *s, size_t size, gfp_t flags)
735735
{
736+
/*
737+
* Perform size check before switching kfence_allocation_gate, so that
738+
* we don't disable KFENCE without making an allocation.
739+
*/
740+
if (size > PAGE_SIZE)
741+
return NULL;
742+
743+
/*
744+
* Skip allocations from non-default zones, including DMA. We cannot
745+
* guarantee that pages in the KFENCE pool will have the requested
746+
* properties (e.g. reside in DMAable memory).
747+
*/
748+
if ((flags & GFP_ZONEMASK) ||
749+
(s->flags & (SLAB_CACHE_DMA | SLAB_CACHE_DMA32)))
750+
return NULL;
751+
736752
/*
737753
* allocation_gate only needs to become non-zero, so it doesn't make
738754
* sense to continue writing to it and pay the associated contention
@@ -757,9 +773,6 @@ void *__kfence_alloc(struct kmem_cache *s, size_t size, gfp_t flags)
757773
if (!READ_ONCE(kfence_enabled))
758774
return NULL;
759775

760-
if (size > PAGE_SIZE)
761-
return NULL;
762-
763776
return kfence_guarded_alloc(s, size, flags);
764777
}
765778

mm/kfence/kfence_test.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -852,7 +852,7 @@ static void kfence_test_exit(void)
852852
tracepoint_synchronize_unregister();
853853
}
854854

855-
late_initcall(kfence_test_init);
855+
late_initcall_sync(kfence_test_init);
856856
module_exit(kfence_test_exit);
857857

858858
MODULE_LICENSE("GPL v2");

mm/memblock.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -947,7 +947,8 @@ static bool should_skip_region(struct memblock_type *type,
947947
return true;
948948

949949
/* skip hotpluggable memory regions if needed */
950-
if (movable_node_is_enabled() && memblock_is_hotpluggable(m))
950+
if (movable_node_is_enabled() && memblock_is_hotpluggable(m) &&
951+
!(flags & MEMBLOCK_HOTPLUG))
951952
return true;
952953

953954
/* if we want mirror memory skip non-mirror memory regions */

0 commit comments

Comments
 (0)