Merge remote-tracking branch 'sm8350/lineage-20' into lineage-23.0

* sm8350/lineage-20: (841 commits)
  UPSTREAM: fs: prevent out-of-bounds array speculation when closing a file descriptor
  UPSTREAM: file: let pick_file() tell caller it's done
  BACKPORT: rcu-tasks: Add a grace-period start time for throttling and debug
  BACKPORT: maccess: rename probe_user_{read,write} to copy_{from,to}_user_nofault
  BACKPORT: powerpc: use probe_user_read() and probe_user_write()
  BACKPORT: maccess: rename probe_kernel_address to get_kernel_nofault
  BACKPORT: tracing/kprobes: handle mixed kernel/userspace probes better
  BACKPORT: maccess: rename probe_kernel_{read,write} to copy_{from,to}_kernel_nofault
  UPSTREAM: maccess: unexport probe_kernel_write()
  UPSTREAM: maccess: return -ERANGE when probe_kernel_read() fails
  UPSTREAM: maccess: allow architectures to provide kernel probing directly
  BACKPORT: maccess: remove strncpy_from_unsafe
  UPSTREAM: bpf:bpf_seq_printf(): handle potentially unsafe format string better
  UPSTREAM: bpf: Use strncpy_from_unsafe_strict() in bpf_seq_printf() helper
  UPSTREAM: bpf: handle the compat string in bpf_trace_copy_string better
  UPSTREAM: bpf: factor out a bpf_trace_copy_string helper
  BACKPORT: maccess: always use strict semantics for probe_kernel_read
  UPSTREAM: maccess: unify the probe kernel arch hooks
  UPSTREAM: maccess: remove probe_read_common and probe_write_common
  UPSTREAM: maccess: remove duplicate kerneldoc comments
  ...

Change-Id: I22cf7d6fb34826727904effb4f012b0ef459149d
This commit is contained in:
Michael Bestas 2026-01-20 20:47:39 +02:00
commit 2eb0f824a1
No known key found for this signature in database
529 changed files with 40893 additions and 9494 deletions

View file

@ -2453,7 +2453,7 @@ int sysctl_compact_memory;
* /proc/sys/vm/compact_memory
*/
int sysctl_compaction_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *length, loff_t *ppos)
void *buffer, size_t *length, loff_t *ppos)
{
if (write)
compact_nodes();

View file

@ -3145,7 +3145,7 @@ static int proc_hugetlb_doulongvec_minmax(struct ctl_table *table, int write,
static int hugetlb_sysctl_handler_common(bool obey_mempolicy,
struct ctl_table *table, int write,
void __user *buffer, size_t *length, loff_t *ppos)
void *buffer, size_t *length, loff_t *ppos)
{
struct hstate *h = &default_hstate;
unsigned long tmp = h->max_huge_pages;
@ -3167,7 +3167,7 @@ out:
}
int hugetlb_sysctl_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *length, loff_t *ppos)
void *buffer, size_t *length, loff_t *ppos)
{
return hugetlb_sysctl_handler_common(false, table, write,
@ -3176,7 +3176,7 @@ int hugetlb_sysctl_handler(struct ctl_table *table, int write,
#ifdef CONFIG_NUMA
int hugetlb_mempolicy_sysctl_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *length, loff_t *ppos)
void *buffer, size_t *length, loff_t *ppos)
{
return hugetlb_sysctl_handler_common(true, table, write,
buffer, length, ppos);
@ -3184,8 +3184,7 @@ int hugetlb_mempolicy_sysctl_handler(struct ctl_table *table, int write,
#endif /* CONFIG_NUMA */
int hugetlb_overcommit_handler(struct ctl_table *table, int write,
void __user *buffer,
size_t *length, loff_t *ppos)
void *buffer, size_t *length, loff_t *ppos)
{
struct hstate *h = &default_hstate;
unsigned long tmp;

View file

@ -6,63 +6,125 @@
#include <linux/mm.h>
#include <linux/uaccess.h>
static __always_inline long
probe_read_common(void *dst, const void __user *src, size_t size)
bool __weak copy_from_kernel_nofault_allowed(const void *unsafe_src,
size_t size)
{
long ret;
pagefault_disable();
ret = __copy_from_user_inatomic(dst, src, size);
pagefault_enable();
return ret ? -EFAULT : 0;
return true;
}
static __always_inline long
probe_write_common(void __user *dst, const void *src, size_t size)
#ifdef HAVE_GET_KERNEL_NOFAULT
#define copy_from_kernel_nofault_loop(dst, src, len, type, err_label) \
while (len >= sizeof(type)) { \
__get_kernel_nofault(dst, src, type, err_label); \
dst += sizeof(type); \
src += sizeof(type); \
len -= sizeof(type); \
}
long copy_from_kernel_nofault(void *dst, const void *src, size_t size)
{
long ret;
if (!copy_from_kernel_nofault_allowed(src, size))
return -ERANGE;
pagefault_disable();
ret = __copy_to_user_inatomic(dst, src, size);
copy_from_kernel_nofault_loop(dst, src, size, u64, Efault);
copy_from_kernel_nofault_loop(dst, src, size, u32, Efault);
copy_from_kernel_nofault_loop(dst, src, size, u16, Efault);
copy_from_kernel_nofault_loop(dst, src, size, u8, Efault);
pagefault_enable();
return 0;
Efault:
pagefault_enable();
return -EFAULT;
}
EXPORT_SYMBOL_GPL(copy_from_kernel_nofault);
return ret ? -EFAULT : 0;
#define copy_to_kernel_nofault_loop(dst, src, len, type, err_label) \
while (len >= sizeof(type)) { \
__put_kernel_nofault(dst, src, type, err_label); \
dst += sizeof(type); \
src += sizeof(type); \
len -= sizeof(type); \
}
long copy_to_kernel_nofault(void *dst, const void *src, size_t size)
{
pagefault_disable();
copy_to_kernel_nofault_loop(dst, src, size, u64, Efault);
copy_to_kernel_nofault_loop(dst, src, size, u32, Efault);
copy_to_kernel_nofault_loop(dst, src, size, u16, Efault);
copy_to_kernel_nofault_loop(dst, src, size, u8, Efault);
pagefault_enable();
return 0;
Efault:
pagefault_enable();
return -EFAULT;
}
long strncpy_from_kernel_nofault(char *dst, const void *unsafe_addr, long count)
{
const void *src = unsafe_addr;
if (unlikely(count <= 0))
return 0;
if (!copy_from_kernel_nofault_allowed(unsafe_addr, count))
return -ERANGE;
pagefault_disable();
do {
__get_kernel_nofault(dst, src, u8, Efault);
dst++;
src++;
} while (dst[-1] && src - unsafe_addr < count);
pagefault_enable();
dst[-1] = '\0';
return src - unsafe_addr;
Efault:
pagefault_enable();
dst[-1] = '\0';
return -EFAULT;
}
#else /* HAVE_GET_KERNEL_NOFAULT */
/**
* probe_kernel_read(): safely attempt to read from a kernel-space location
* copy_from_kernel_nofault(): safely attempt to read from kernel-space
* @dst: pointer to the buffer that shall take the data
* @src: address to read from
* @size: size of the data chunk
*
* Safely read from address @src to the buffer at @dst. If a kernel fault
* happens, handle that and return -EFAULT.
* Safely read from kernel address @src to the buffer at @dst. If a kernel
* fault happens, handle that and return -EFAULT. If @src is not a valid kernel
* address, return -ERANGE.
*
* We ensure that the copy_from_user is executed in atomic context so that
* do_page_fault() doesn't attempt to take mmap_sem. This makes
* probe_kernel_read() suitable for use within regions where the caller
* copy_from_kernel_nofault() suitable for use within regions where the caller
* already holds mmap_sem, or other locks which nest inside mmap_sem.
*/
long __weak probe_kernel_read(void *dst, const void *src, size_t size)
__attribute__((alias("__probe_kernel_read")));
long __probe_kernel_read(void *dst, const void *src, size_t size)
long copy_from_kernel_nofault(void *dst, const void *src, size_t size)
{
long ret;
mm_segment_t old_fs = get_fs();
if (!copy_from_kernel_nofault_allowed(src, size))
return -ERANGE;
set_fs(KERNEL_DS);
ret = probe_read_common(dst, (__force const void __user *)src, size);
pagefault_disable();
ret = __copy_from_user_inatomic(dst, (__force const void __user *)src,
size);
pagefault_enable();
set_fs(old_fs);
return ret;
if (ret)
return -EFAULT;
return 0;
}
EXPORT_SYMBOL_GPL(probe_kernel_read);
EXPORT_SYMBOL_GPL(copy_from_kernel_nofault);
/**
* probe_user_read(): safely attempt to read from a user-space location
* copy_from_user_nofault(): safely attempt to read from a user-space location
* @dst: pointer to the buffer that shall take the data
* @src: address to read from. This must be a user address.
* @size: size of the data chunk
@ -70,23 +132,24 @@ EXPORT_SYMBOL_GPL(probe_kernel_read);
* Safely read from user address @src to the buffer at @dst. If a kernel fault
* happens, handle that and return -EFAULT.
*/
long __weak probe_user_read(void *dst, const void __user *src, size_t size)
__attribute__((alias("__probe_user_read")));
long __probe_user_read(void *dst, const void __user *src, size_t size)
long copy_from_user_nofault(void *dst, const void __user *src, size_t size)
{
long ret = -EFAULT;
mm_segment_t old_fs = get_fs();
set_fs(USER_DS);
if (access_ok(src, size))
ret = probe_read_common(dst, src, size);
if (access_ok(src, size)) {
pagefault_disable();
ret = __copy_from_user_inatomic(dst, src, size);
pagefault_enable();
}
set_fs(old_fs);
return ret;
if (ret)
return -EFAULT;
return 0;
}
EXPORT_SYMBOL_GPL(probe_user_read);
EXPORT_SYMBOL_GPL(copy_from_user_nofault);
/**
* probe_kernel_write(): safely attempt to write to a location
@ -97,25 +160,24 @@ EXPORT_SYMBOL_GPL(probe_user_read);
* Safely write to address @dst from the buffer at @src. If a kernel fault
* happens, handle that and return -EFAULT.
*/
long __weak probe_kernel_write(void *dst, const void *src, size_t size)
__attribute__((alias("__probe_kernel_write")));
long __probe_kernel_write(void *dst, const void *src, size_t size)
long copy_to_kernel_nofault(void *dst, const void *src, size_t size)
{
long ret;
mm_segment_t old_fs = get_fs();
set_fs(KERNEL_DS);
ret = probe_write_common((__force void __user *)dst, src, size);
pagefault_disable();
ret = __copy_to_user_inatomic((__force void __user *)dst, src, size);
pagefault_enable();
set_fs(old_fs);
return ret;
if (ret)
return -EFAULT;
return 0;
}
EXPORT_SYMBOL_GPL(probe_kernel_write);
/**
* probe_user_write(): safely attempt to write to a user-space location
* copy_to_user_nofault(): safely attempt to write to a user-space location
* @dst: address to write to
* @src: pointer to the data that shall be written
* @size: size of the data chunk
@ -123,26 +185,28 @@ EXPORT_SYMBOL_GPL(probe_kernel_write);
* Safely write to address @dst from the buffer at @src. If a kernel fault
* happens, handle that and return -EFAULT.
*/
long __weak probe_user_write(void __user *dst, const void *src, size_t size)
__attribute__((alias("__probe_user_write")));
long __probe_user_write(void __user *dst, const void *src, size_t size)
long copy_to_user_nofault(void __user *dst, const void *src, size_t size)
{
long ret = -EFAULT;
mm_segment_t old_fs = get_fs();
set_fs(USER_DS);
if (access_ok(dst, size))
ret = probe_write_common(dst, src, size);
if (access_ok(dst, size)) {
pagefault_disable();
ret = __copy_to_user_inatomic(dst, src, size);
pagefault_enable();
}
set_fs(old_fs);
return ret;
if (ret)
return -EFAULT;
return 0;
}
EXPORT_SYMBOL_GPL(probe_user_write);
EXPORT_SYMBOL_GPL(copy_to_user_nofault);
/**
* strncpy_from_unsafe: - Copy a NUL terminated string from unsafe address.
* strncpy_from_kernel_nofault: - Copy a NUL terminated string from unsafe
* address.
* @dst: Destination address, in kernel space. This buffer must be at
* least @count bytes long.
* @unsafe_addr: Unsafe address.
@ -152,13 +216,14 @@ EXPORT_SYMBOL_GPL(probe_user_write);
*
* On success, returns the length of the string INCLUDING the trailing NUL.
*
* If access fails, returns -EFAULT (some data may have been copied
* and the trailing NUL added).
* If access fails, returns -EFAULT (some data may have been copied and the
* trailing NUL added). If @unsafe_addr is not a valid kernel address, return
* -ERANGE.
*
* If @count is smaller than the length of the string, copies @count-1 bytes,
* sets the last byte of @dst buffer to NUL and returns @count.
*/
long strncpy_from_unsafe(char *dst, const void *unsafe_addr, long count)
long strncpy_from_kernel_nofault(char *dst, const void *unsafe_addr, long count)
{
mm_segment_t old_fs = get_fs();
const void *src = unsafe_addr;
@ -166,6 +231,8 @@ long strncpy_from_unsafe(char *dst, const void *unsafe_addr, long count)
if (unlikely(count <= 0))
return 0;
if (!copy_from_kernel_nofault_allowed(unsafe_addr, count))
return -ERANGE;
set_fs(KERNEL_DS);
pagefault_disable();
@ -180,9 +247,10 @@ long strncpy_from_unsafe(char *dst, const void *unsafe_addr, long count)
return ret ? -EFAULT : src - unsafe_addr;
}
#endif /* HAVE_GET_KERNEL_NOFAULT */
/**
* strncpy_from_unsafe_user: - Copy a NUL terminated string from unsafe user
* strncpy_from_user_nofault: - Copy a NUL terminated string from unsafe user
* address.
* @dst: Destination address, in kernel space. This buffer must be at
* least @count bytes long.
@ -199,7 +267,7 @@ long strncpy_from_unsafe(char *dst, const void *unsafe_addr, long count)
* If @count is smaller than the length of the string, copies @count-1 bytes,
* sets the last byte of @dst buffer to NUL and returns @count.
*/
long strncpy_from_unsafe_user(char *dst, const void __user *unsafe_addr,
long strncpy_from_user_nofault(char *dst, const void __user *unsafe_addr,
long count)
{
mm_segment_t old_fs = get_fs();

View file

@ -6405,6 +6405,117 @@ struct cgroup_subsys memory_cgrp_subsys = {
.early_init = 0,
};
/*
* This function calculates an individual cgroup's effective
* protection which is derived from its own memory.min/low, its
* parent's and siblings' settings, as well as the actual memory
* distribution in the tree.
*
* The following rules apply to the effective protection values:
*
* 1. At the first level of reclaim, effective protection is equal to
* the declared protection in memory.min and memory.low.
*
* 2. To enable safe delegation of the protection configuration, at
* subsequent levels the effective protection is capped to the
* parent's effective protection.
*
* 3. To make complex and dynamic subtrees easier to configure, the
* user is allowed to overcommit the declared protection at a given
* level. If that is the case, the parent's effective protection is
* distributed to the children in proportion to how much protection
* they have declared and how much of it they are utilizing.
*
* This makes distribution proportional, but also work-conserving:
* if one cgroup claims much more protection than it uses memory,
* the unused remainder is available to its siblings.
*
* 4. Conversely, when the declared protection is undercommitted at a
* given level, the distribution of the larger parental protection
* budget is NOT proportional. A cgroup's protection from a sibling
* is capped to its own memory.min/low setting.
*
* 5. However, to allow protecting recursive subtrees from each other
* without having to declare each individual cgroup's fixed share
* of the ancestor's claim to protection, any unutilized -
* "floating" - protection from up the tree is distributed in
* proportion to each cgroup's *usage*. This makes the protection
* neutral wrt sibling cgroups and lets them compete freely over
* the shared parental protection budget, but it protects the
* subtree as a whole from neighboring subtrees.
*
* Note that 4. and 5. are not in conflict: 4. is about protecting
* against immediate siblings whereas 5. is about protecting against
* neighboring subtrees.
*/
static unsigned long effective_protection(unsigned long usage,
unsigned long parent_usage,
unsigned long setting,
unsigned long parent_effective,
unsigned long siblings_protected)
{
unsigned long protected;
unsigned long ep;
protected = min(usage, setting);
/*
* If all cgroups at this level combined claim and use more
* protection then what the parent affords them, distribute
* shares in proportion to utilization.
*
* We are using actual utilization rather than the statically
* claimed protection in order to be work-conserving: claimed
* but unused protection is available to siblings that would
* otherwise get a smaller chunk than what they claimed.
*/
if (siblings_protected > parent_effective)
return protected * parent_effective / siblings_protected;
/*
* Ok, utilized protection of all children is within what the
* parent affords them, so we know whatever this child claims
* and utilizes is effectively protected.
*
* If there is unprotected usage beyond this value, reclaim
* will apply pressure in proportion to that amount.
*
* If there is unutilized protection, the cgroup will be fully
* shielded from reclaim, but we do return a smaller value for
* protection than what the group could enjoy in theory. This
* is okay. With the overcommit distribution above, effective
* protection is always dependent on how memory is actually
* consumed among the siblings anyway.
*/
ep = protected;
/*
* If the children aren't claiming (all of) the protection
* afforded to them by the parent, distribute the remainder in
* proportion to the (unprotected) memory of each cgroup. That
* way, cgroups that aren't explicitly prioritized wrt each
* other compete freely over the allowance, but they are
* collectively protected from neighboring trees.
*
* We're using unprotected memory for the weight so that if
* some cgroups DO claim explicit protection, we don't protect
* the same bytes twice.
*/
if (!(cgrp_dfl_root.flags & CGRP_ROOT_MEMORY_RECURSIVE_PROT))
return ep;
if (parent_effective > siblings_protected && usage > protected) {
unsigned long unclaimed;
unclaimed = parent_effective - siblings_protected;
unclaimed *= usage - protected;
unclaimed /= parent_usage - siblings_protected;
ep += unclaimed;
}
return ep;
}
/**
* mem_cgroup_protected - check if memory consumption is in the normal range
* @root: the top ancestor of the sub-tree being checked
@ -6418,70 +6529,12 @@ struct cgroup_subsys memory_cgrp_subsys = {
* MEMCG_PROT_LOW: cgroup memory is protected as long there is
* an unprotected supply of reclaimable memory from other cgroups.
* MEMCG_PROT_MIN: cgroup memory is protected
*
* @root is exclusive; it is never protected when looked at directly
*
* To provide a proper hierarchical behavior, effective memory.min/low values
* are used. Below is the description of how effective memory.low is calculated.
* Effective memory.min values is calculated in the same way.
*
* Effective memory.low is always equal or less than the original memory.low.
* If there is no memory.low overcommittment (which is always true for
* top-level memory cgroups), these two values are equal.
* Otherwise, it's a part of parent's effective memory.low,
* calculated as a cgroup's memory.low usage divided by sum of sibling's
* memory.low usages, where memory.low usage is the size of actually
* protected memory.
*
* low_usage
* elow = min( memory.low, parent->elow * ------------------ ),
* siblings_low_usage
*
* | memory.current, if memory.current < memory.low
* low_usage = |
* | 0, otherwise.
*
*
* Such definition of the effective memory.low provides the expected
* hierarchical behavior: parent's memory.low value is limiting
* children, unprotected memory is reclaimed first and cgroups,
* which are not using their guarantee do not affect actual memory
* distribution.
*
* For example, if there are memcgs A, A/B, A/C, A/D and A/E:
*
* A A/memory.low = 2G, A/memory.current = 6G
* //\\
* BC DE B/memory.low = 3G B/memory.current = 2G
* C/memory.low = 1G C/memory.current = 2G
* D/memory.low = 0 D/memory.current = 2G
* E/memory.low = 10G E/memory.current = 0
*
* and the memory pressure is applied, the following memory distribution
* is expected (approximately):
*
* A/memory.current = 2G
*
* B/memory.current = 1.3G
* C/memory.current = 0.6G
* D/memory.current = 0
* E/memory.current = 0
*
* These calculations require constant tracking of the actual low usages
* (see propagate_protected_usage()), as well as recursive calculation of
* effective memory.low values. But as we do call mem_cgroup_protected()
* path for each memory cgroup top-down from the reclaim,
* it's possible to optimize this part, and save calculated elow
* for next usage. This part is intentionally racy, but it's ok,
* as memory.low is a best-effort mechanism.
*/
enum mem_cgroup_protection mem_cgroup_protected(struct mem_cgroup *root,
struct mem_cgroup *memcg)
{
unsigned long usage, parent_usage;
struct mem_cgroup *parent;
unsigned long emin, parent_emin;
unsigned long elow, parent_elow;
unsigned long usage;
if (mem_cgroup_disabled())
return MEMCG_PROT_NONE;
@ -6503,52 +6556,31 @@ enum mem_cgroup_protection mem_cgroup_protected(struct mem_cgroup *root,
if (!usage)
return MEMCG_PROT_NONE;
emin = memcg->memory.min;
elow = memcg->memory.low;
parent = parent_mem_cgroup(memcg);
/* No parent means a non-hierarchical mode on v1 memcg */
if (!parent)
return MEMCG_PROT_NONE;
if (parent == root)
goto exit;
parent_emin = READ_ONCE(parent->memory.emin);
emin = min(emin, parent_emin);
if (emin && parent_emin) {
unsigned long min_usage, siblings_min_usage;
min_usage = min(usage, memcg->memory.min);
siblings_min_usage = atomic_long_read(
&parent->memory.children_min_usage);
if (min_usage && siblings_min_usage)
emin = min(emin, parent_emin * min_usage /
siblings_min_usage);
if (parent == root) {
memcg->memory.emin = memcg->memory.min;
memcg->memory.elow = memcg->memory.low;
goto out;
}
parent_elow = READ_ONCE(parent->memory.elow);
elow = min(elow, parent_elow);
if (elow && parent_elow) {
unsigned long low_usage, siblings_low_usage;
parent_usage = page_counter_read(&parent->memory);
low_usage = min(usage, memcg->memory.low);
siblings_low_usage = atomic_long_read(
&parent->memory.children_low_usage);
memcg->memory.emin = effective_protection(usage, parent_usage,
memcg->memory.min, READ_ONCE(parent->memory.emin),
atomic_long_read(&parent->memory.children_min_usage));
if (low_usage && siblings_low_usage)
elow = min(elow, parent_elow * low_usage /
siblings_low_usage);
}
memcg->memory.elow = effective_protection(usage, parent_usage,
memcg->memory.low, READ_ONCE(parent->memory.elow),
atomic_long_read(&parent->memory.children_low_usage));
exit:
memcg->memory.emin = emin;
memcg->memory.elow = elow;
if (usage <= emin)
out:
if (usage <= memcg->memory.emin)
return MEMCG_PROT_MIN;
else if (usage <= elow)
else if (usage <= memcg->memory.elow)
return MEMCG_PROT_LOW;
else
return MEMCG_PROT_NONE;

View file

@ -2539,6 +2539,7 @@ static vm_fault_t wp_page_copy(struct vm_fault *vmf)
}
flush_cache_page(vma, vmf->address, pte_pfn(vmf->orig_pte));
entry = mk_pte(new_page, vma->vm_page_prot);
entry = pte_sw_mkyoung(entry);
entry = maybe_mkwrite(pte_mkdirty(entry), vma);
/*
* Clear the pte entry and flush it first, before updating the
@ -3223,6 +3224,7 @@ static vm_fault_t do_anonymous_page(struct vm_fault *vmf)
__SetPageUptodate(page);
entry = mk_pte(page, vma->vm_page_prot);
entry = pte_sw_mkyoung(entry);
if (vma->vm_flags & VM_WRITE)
entry = pte_mkwrite(pte_mkdirty(entry));
@ -3511,6 +3513,7 @@ vm_fault_t alloc_set_pte(struct vm_fault *vmf, struct mem_cgroup *memcg,
flush_icache_page(vma, page);
entry = mk_pte(page, vma->vm_page_prot);
entry = pte_sw_mkyoung(entry);
if (write)
entry = maybe_mkwrite(pte_mkdirty(entry), vma);

View file

@ -140,7 +140,7 @@ void vfree(const void *addr)
}
EXPORT_SYMBOL(vfree);
void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot)
void *__vmalloc(unsigned long size, gfp_t gfp_mask)
{
/*
* You can't specify __GFP_HIGHMEM with kmalloc() since kmalloc()
@ -152,14 +152,14 @@ EXPORT_SYMBOL(__vmalloc);
void *__vmalloc_node_flags(unsigned long size, int node, gfp_t flags)
{
return __vmalloc(size, flags, PAGE_KERNEL);
return __vmalloc(size, flags);
}
void *vmalloc_user(unsigned long size)
{
void *ret;
ret = __vmalloc(size, GFP_KERNEL | __GFP_ZERO, PAGE_KERNEL);
ret = __vmalloc(size, GFP_KERNEL | __GFP_ZERO);
if (ret) {
struct vm_area_struct *vma;
@ -219,7 +219,7 @@ long vwrite(char *buf, char *addr, unsigned long count)
*/
void *vmalloc(unsigned long size)
{
return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL);
return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM);
}
EXPORT_SYMBOL(vmalloc);
@ -237,8 +237,7 @@ EXPORT_SYMBOL(vmalloc);
*/
void *vzalloc(unsigned long size)
{
return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO,
PAGE_KERNEL);
return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO);
}
EXPORT_SYMBOL(vzalloc);
@ -291,7 +290,7 @@ EXPORT_SYMBOL(vzalloc_node);
void *vmalloc_exec(unsigned long size)
{
return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL_EXEC);
return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM);
}
/**
@ -303,7 +302,7 @@ void *vmalloc_exec(unsigned long size)
*/
void *vmalloc_32(unsigned long size)
{
return __vmalloc(size, GFP_KERNEL, PAGE_KERNEL);
return __vmalloc(size, GFP_KERNEL);
}
EXPORT_SYMBOL(vmalloc_32);

View file

@ -523,8 +523,7 @@ bool node_dirty_ok(struct pglist_data *pgdat)
}
int dirty_background_ratio_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp,
loff_t *ppos)
void *buffer, size_t *lenp, loff_t *ppos)
{
int ret;
@ -535,8 +534,7 @@ int dirty_background_ratio_handler(struct ctl_table *table, int write,
}
int dirty_background_bytes_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp,
loff_t *ppos)
void *buffer, size_t *lenp, loff_t *ppos)
{
int ret;
unsigned long old_bytes = dirty_background_bytes;
@ -553,9 +551,8 @@ int dirty_background_bytes_handler(struct ctl_table *table, int write,
return ret;
}
int dirty_ratio_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp,
loff_t *ppos)
int dirty_ratio_handler(struct ctl_table *table, int write, void *buffer,
size_t *lenp, loff_t *ppos)
{
int old_ratio = vm_dirty_ratio;
int ret;
@ -569,8 +566,7 @@ int dirty_ratio_handler(struct ctl_table *table, int write,
}
int dirty_bytes_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp,
loff_t *ppos)
void *buffer, size_t *lenp, loff_t *ppos)
{
unsigned long old_bytes = vm_dirty_bytes;
int ret;
@ -1994,7 +1990,7 @@ bool wb_over_bg_thresh(struct bdi_writeback *wb)
* sysctl handler for /proc/sys/vm/dirty_writeback_centisecs
*/
int dirty_writeback_centisecs_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *length, loff_t *ppos)
void *buffer, size_t *length, loff_t *ppos)
{
unsigned int old_interval = dirty_writeback_interval;
int ret;

View file

@ -5730,21 +5730,11 @@ char numa_zonelist_order[] = "Node";
* sysctl handler for numa_zonelist_order
*/
int numa_zonelist_order_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *length,
loff_t *ppos)
void *buffer, size_t *length, loff_t *ppos)
{
char *str;
int ret;
if (!write)
return proc_dostring(table, write, buffer, length, ppos);
str = memdup_user_nul(buffer, 16);
if (IS_ERR(str))
return PTR_ERR(str);
ret = __parse_numa_zonelist_order(str);
kfree(str);
return ret;
if (write)
return __parse_numa_zonelist_order(buffer);
return proc_dostring(table, write, buffer, length, ppos);
}
@ -8155,7 +8145,7 @@ postcore_initcall(init_per_zone_wmark_min)
* or extra_free_kbytes changes.
*/
int min_free_kbytes_sysctl_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *length, loff_t *ppos)
void *buffer, size_t *length, loff_t *ppos)
{
int rc;
@ -8199,7 +8189,7 @@ int kswapd_threads_sysctl_handler(struct ctl_table *table, int write,
}
#endif
int watermark_scale_factor_sysctl_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *length, loff_t *ppos)
void *buffer, size_t *length, loff_t *ppos)
{
int rc;
@ -8229,7 +8219,7 @@ static void setup_min_unmapped_ratio(void)
int sysctl_min_unmapped_ratio_sysctl_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *length, loff_t *ppos)
void *buffer, size_t *length, loff_t *ppos)
{
int rc;
@ -8256,7 +8246,7 @@ static void setup_min_slab_ratio(void)
}
int sysctl_min_slab_ratio_sysctl_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *length, loff_t *ppos)
void *buffer, size_t *length, loff_t *ppos)
{
int rc;
@ -8280,7 +8270,7 @@ int sysctl_min_slab_ratio_sysctl_handler(struct ctl_table *table, int write,
* if in function of the boot time zone sizes.
*/
int lowmem_reserve_ratio_sysctl_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *length, loff_t *ppos)
void *buffer, size_t *length, loff_t *ppos)
{
proc_dointvec_minmax(table, write, buffer, length, ppos);
setup_per_zone_lowmem_reserve();
@ -8293,7 +8283,7 @@ int lowmem_reserve_ratio_sysctl_handler(struct ctl_table *table, int write,
* pagelist can have before it gets flushed back to buddy allocator.
*/
int percpu_pagelist_fraction_sysctl_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *length, loff_t *ppos)
void *buffer, size_t *length, loff_t *ppos)
{
struct zone *zone;
int old_percpu_pagelist_fraction;
@ -8442,7 +8432,7 @@ void *__init alloc_large_system_hash(const char *tablename,
table = memblock_alloc_raw(size,
SMP_CACHE_BYTES);
} else if (get_order(size) >= MAX_ORDER || hashdist) {
table = __vmalloc(size, gfp_flags, PAGE_KERNEL);
table = __vmalloc(size, gfp_flags);
virt = true;
} else {
/*

View file

@ -508,7 +508,7 @@ static void *pcpu_mem_zalloc(size_t size, gfp_t gfp)
if (size <= PAGE_SIZE)
return kzalloc(size, gfp);
else
return __vmalloc(size, gfp | __GFP_ZERO, PAGE_KERNEL);
return __vmalloc(size, gfp | __GFP_ZERO);
}
/**

View file

@ -25,7 +25,7 @@ void rodata_test(void)
}
/* test 2: write to the variable; this should fault */
if (!probe_kernel_write((void *)&rodata_test_data,
if (!copy_to_kernel_nofault((void *)&rodata_test_data,
(void *)&zero, sizeof(zero))) {
pr_err("test data was not read only\n");
return;

View file

@ -3203,7 +3203,7 @@ static int shmem_xattr_handler_set(const struct xattr_handler *handler,
struct shmem_inode_info *info = SHMEM_I(inode);
name = xattr_full_name(handler, name);
return simple_xattr_set(&info->xattrs, name, value, size, flags);
return simple_xattr_set(&info->xattrs, name, value, size, flags, NULL);
}
static const struct xattr_handler shmem_security_xattr_handler = {

View file

@ -303,7 +303,7 @@ static inline void *get_freepointer_safe(struct kmem_cache *s, void *object)
return get_freepointer(s, object);
freepointer_addr = (unsigned long)object + s->offset;
probe_kernel_read(&p, (void **)freepointer_addr, sizeof(p));
copy_from_kernel_nofault(&p, (void **)freepointer_addr, sizeof(p));
return freelist_ptr(s, p, freepointer_addr);
}

View file

@ -757,9 +757,8 @@ int sysctl_max_map_count __read_mostly = DEFAULT_MAX_MAP_COUNT;
unsigned long sysctl_user_reserve_kbytes __read_mostly = 1UL << 17; /* 128MB */
unsigned long sysctl_admin_reserve_kbytes __read_mostly = 1UL << 13; /* 8MB */
int overcommit_ratio_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp,
loff_t *ppos)
int overcommit_ratio_handler(struct ctl_table *table, int write, void *buffer,
size_t *lenp, loff_t *ppos)
{
int ret;
@ -769,9 +768,8 @@ int overcommit_ratio_handler(struct ctl_table *table, int write,
return ret;
}
int overcommit_kbytes_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp,
loff_t *ppos)
int overcommit_kbytes_handler(struct ctl_table *table, int write, void *buffer,
size_t *lenp, loff_t *ppos)
{
int ret;

View file

@ -2643,9 +2643,9 @@ static void *__vmalloc_node(unsigned long size, unsigned long align,
#endif
}
void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot)
void *__vmalloc(unsigned long size, gfp_t gfp_mask)
{
return __vmalloc_node(size, 1, gfp_mask, prot, NUMA_NO_NODE,
return __vmalloc_node(size, 1, gfp_mask, PAGE_KERNEL, NUMA_NO_NODE,
__builtin_return_address(0));
}
EXPORT_SYMBOL(__vmalloc);
@ -2762,6 +2762,26 @@ void *vzalloc_node(unsigned long size, int node)
}
EXPORT_SYMBOL(vzalloc_node);
/**
* vmalloc_user_node_flags - allocate memory for userspace on a specific node
* @size: allocation size
* @node: numa node
* @flags: flags for the page level allocator
*
* The resulting memory area is zeroed so it can be mapped to userspace
* without leaking data.
*
* Return: pointer to the allocated memory or %NULL on error
*/
void *vmalloc_user_node_flags(unsigned long size, int node, gfp_t flags)
{
return __vmalloc_node_range(size, SHMLBA, VMALLOC_START, VMALLOC_END,
flags | __GFP_ZERO, PAGE_KERNEL,
VM_USERMAP, node,
__builtin_return_address(0));
}
EXPORT_SYMBOL(vmalloc_user_node_flags);
/**
* vmalloc_exec - allocate virtually contiguous, executable memory
* @size: allocation size

View file

@ -76,7 +76,7 @@ static void invalid_numa_statistics(void)
static DEFINE_MUTEX(vm_numa_stat_lock);
int sysctl_vm_numa_stat_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *length, loff_t *ppos)
void *buffer, size_t *length, loff_t *ppos)
{
int ret, oldval;
@ -1761,7 +1761,7 @@ static void refresh_vm_stats(struct work_struct *work)
}
int vmstat_refresh(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos)
void *buffer, size_t *lenp, loff_t *ppos)
{
long val;
int err;