mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-28 17:19:41 -04:00
Concurrent reads and writes of sysctl_max_map_count are possible, so we should READ_ONCE() and WRITE_ONCE(). The sysctl procfs logic already enforces WRITE_ONCE(), so abstract the read side with get_sysctl_max_map_count(). While we're here, also move the field to mm/internal.h and add the getter there since only mm interacts with it, there's no need for anybody else to have access. Finally, update the VMA userland tests to reflect the change. Link: https://lkml.kernel.org/r/0715259eb37cbdfde4f9e5db92a20ec7110a1ce5.1773249037.git.ljs@kernel.org Signed-off-by: Lorenzo Stoakes (Oracle) <ljs@kernel.org> Reviewed-by: Pedro Falcato <pfalcato@suse.de> Cc: Jann Horn <jannh@google.com> Cc: Jianzhou Zhao <luckd0g@163.com> Cc: Liam Howlett <liam.howlett@oracle.com> Cc: Michal Hocko <mhocko@suse.com> Cc: Mike Rapoport <rppt@kernel.org> Cc: Oscar Salvador <osalvador@suse.de> Cc: Suren Baghdasaryan <surenb@google.com> Cc: Vlastimil Babka <vbabka@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
123 lines
2.7 KiB
C
123 lines
2.7 KiB
C
/* SPDX-License-Identifier: GPL-2.0+ */
|
|
|
|
#pragma once
|
|
|
|
/*
|
|
* Contains declarations that exist in the kernel which have been CUSTOMISED for
|
|
* testing purposes to faciliate userland VMA testing.
|
|
*/
|
|
|
|
#ifdef CONFIG_MMU
|
|
extern unsigned long mmap_min_addr;
|
|
extern unsigned long dac_mmap_min_addr;
|
|
#else
|
|
#define mmap_min_addr 0UL
|
|
#define dac_mmap_min_addr 0UL
|
|
#endif
|
|
|
|
#define VM_WARN_ON(_expr) (WARN_ON(_expr))
|
|
#define VM_WARN_ON_ONCE(_expr) (WARN_ON_ONCE(_expr))
|
|
#define VM_WARN_ON_VMG(_expr, _vmg) (WARN_ON(_expr))
|
|
#define VM_BUG_ON(_expr) (BUG_ON(_expr))
|
|
#define VM_BUG_ON_VMA(_expr, _vma) (BUG_ON(_expr))
|
|
|
|
#define TASK_SIZE ((1ul << 47)-PAGE_SIZE)
|
|
|
|
/*
|
|
* The shared stubs do not implement this, it amounts to an fprintf(STDERR,...)
|
|
* either way :)
|
|
*/
|
|
#define pr_warn_once pr_err
|
|
|
|
#define pgtable_supports_soft_dirty() 1
|
|
|
|
struct anon_vma {
|
|
struct anon_vma *root;
|
|
struct rb_root_cached rb_root;
|
|
|
|
/* Test fields. */
|
|
bool was_cloned;
|
|
bool was_unlinked;
|
|
};
|
|
|
|
static inline void unlink_anon_vmas(struct vm_area_struct *vma)
|
|
{
|
|
/* For testing purposes, indicate that the anon_vma was unlinked. */
|
|
vma->anon_vma->was_unlinked = true;
|
|
}
|
|
|
|
static inline void vma_start_write(struct vm_area_struct *vma)
|
|
{
|
|
/* Used to indicate to tests that a write operation has begun. */
|
|
vma->vm_lock_seq++;
|
|
}
|
|
|
|
static inline __must_check
|
|
int vma_start_write_killable(struct vm_area_struct *vma)
|
|
{
|
|
/* Used to indicate to tests that a write operation has begun. */
|
|
vma->vm_lock_seq++;
|
|
return 0;
|
|
}
|
|
|
|
static inline int anon_vma_clone(struct vm_area_struct *dst, struct vm_area_struct *src,
|
|
enum vma_operation operation)
|
|
{
|
|
/* For testing purposes. We indicate that an anon_vma has been cloned. */
|
|
if (src->anon_vma != NULL) {
|
|
dst->anon_vma = src->anon_vma;
|
|
dst->anon_vma->was_cloned = true;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static inline int __anon_vma_prepare(struct vm_area_struct *vma)
|
|
{
|
|
struct anon_vma *anon_vma = calloc(1, sizeof(struct anon_vma));
|
|
|
|
if (!anon_vma)
|
|
return -ENOMEM;
|
|
|
|
anon_vma->root = anon_vma;
|
|
vma->anon_vma = anon_vma;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static inline int anon_vma_prepare(struct vm_area_struct *vma)
|
|
{
|
|
if (likely(vma->anon_vma))
|
|
return 0;
|
|
|
|
return __anon_vma_prepare(vma);
|
|
}
|
|
|
|
static inline void vma_lock_init(struct vm_area_struct *vma, bool reset_refcnt)
|
|
{
|
|
if (reset_refcnt)
|
|
refcount_set(&vma->vm_refcnt, 0);
|
|
}
|
|
|
|
static __always_inline vma_flags_t __mk_vma_flags(size_t count,
|
|
const vma_flag_t *bits)
|
|
{
|
|
vma_flags_t flags;
|
|
int i;
|
|
|
|
/*
|
|
* For testing purposes: allow invalid bit specification so we can
|
|
* easily test.
|
|
*/
|
|
vma_flags_clear_all(&flags);
|
|
for (i = 0; i < count; i++)
|
|
if (bits[i] < NUM_VMA_FLAG_BITS)
|
|
vma_flags_set_flag(&flags, bits[i]);
|
|
return flags;
|
|
}
|
|
|
|
static inline unsigned long vma_kernel_pagesize(struct vm_area_struct *vma)
|
|
{
|
|
return PAGE_SIZE;
|
|
}
|