mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 18:51:56 -04:00
Linus 5.3-rc1
-----BEGIN PGP SIGNATURE----- iQFSBAABCAA8FiEEq68RxlopcLEwq+PEeb4+QwBBGIYFAl0006weHHRvcnZhbGRz QGxpbnV4LWZvdW5kYXRpb24ub3JnAAoJEHm+PkMAQRiGaDUIAJ4oTyVWpMRZkfG6 vVY8qVMU3zlzEqRiyLYjkXoe/mGpuU/UVTyyStllxZ+Gg9da0mGwlugScKriPJof 4KRUDDTGX5DrfEOo+0brKvM+PYh9uGViPgKXzyv7i6BrnX2z3JdBR4bKNuEYlAJ9 N93Qg7v05SBHIq2Gfp3klrdWbsTTW2EaDTLbcgifXLnfKyFr47kwsmXAHPlTFP0p dYsZHHmf14Y9n1+ToZeVINgjQFr6mFn6ygY/PqTnd6vCgEEfP9eENJ4BZCtN1ZL/ V0BO9MyJ5iZV0AfwSEKydk+kDEvO16TG/nyDrECVuur7AXsBx18ZplVc787f6GK+ dyCQJ3U= =XLAF -----END PGP SIGNATURE----- Merge 5.3.0-rc1 into android-mainline Linus 5.3-rc1 release Signed-off-by: Greg Kroah-Hartman <[email protected]> Change-Id: Ic171e37d4c21ffa495240c5538852bbb5a9dcce8
This commit is contained in:
commit
37766c2946
12773 changed files with 1016107 additions and 433463 deletions
|
|
@ -58,7 +58,8 @@ config PROC_VMCORE_DEVICE_DUMP
|
|||
snapshot.
|
||||
|
||||
If you say Y here, the collected device dumps will be added
|
||||
as ELF notes to /proc/vmcore.
|
||||
as ELF notes to /proc/vmcore. You can still disable device
|
||||
dump using the kernel command line option 'novmcoredd'.
|
||||
|
||||
config PROC_SYSCTL
|
||||
bool "Sysctl support (/proc/sys)" if EXPERT
|
||||
|
|
@ -72,7 +73,7 @@ config PROC_SYSCTL
|
|||
interface is through /proc/sys. If you say Y here a tree of
|
||||
modifiable sysctl entries will be generated beneath the
|
||||
/proc/sys directory. They are explained in the files
|
||||
in <file:Documentation/sysctl/>. Note that enabling this
|
||||
in <file:Documentation/admin-guide/sysctl/>. Note that enabling this
|
||||
option will enlarge the kernel by at least 8 KB.
|
||||
|
||||
As it is generally a good thing, you should say Y here unless
|
||||
|
|
@ -99,6 +100,10 @@ config PROC_CHILDREN
|
|||
Say Y if you are running any user-space software which takes benefit from
|
||||
this interface. For example, rkt is such a piece of software.
|
||||
|
||||
config PROC_PID_ARCH_STATUS
|
||||
def_bool n
|
||||
depends on PROC_FS
|
||||
|
||||
config PROC_UID
|
||||
bool "Include /proc/uid/ files"
|
||||
depends on PROC_FS && RT_MUTEXES
|
||||
|
|
|
|||
|
|
@ -381,9 +381,9 @@ static inline void task_context_switch_counts(struct seq_file *m,
|
|||
static void task_cpus_allowed(struct seq_file *m, struct task_struct *task)
|
||||
{
|
||||
seq_printf(m, "Cpus_allowed:\t%*pb\n",
|
||||
cpumask_pr_args(&task->cpus_allowed));
|
||||
cpumask_pr_args(task->cpus_ptr));
|
||||
seq_printf(m, "Cpus_allowed_list:\t%*pbl\n",
|
||||
cpumask_pr_args(&task->cpus_allowed));
|
||||
cpumask_pr_args(task->cpus_ptr));
|
||||
}
|
||||
|
||||
static inline void task_core_dumping(struct seq_file *m, struct mm_struct *mm)
|
||||
|
|
|
|||
169
fs/proc/base.c
169
fs/proc/base.c
|
|
@ -210,12 +210,53 @@ static int proc_root_link(struct dentry *dentry, struct path *path)
|
|||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the user used setproctitle(), we just get the string from
|
||||
* user space at arg_start, and limit it to a maximum of one page.
|
||||
*/
|
||||
static ssize_t get_mm_proctitle(struct mm_struct *mm, char __user *buf,
|
||||
size_t count, unsigned long pos,
|
||||
unsigned long arg_start)
|
||||
{
|
||||
char *page;
|
||||
int ret, got;
|
||||
|
||||
if (pos >= PAGE_SIZE)
|
||||
return 0;
|
||||
|
||||
page = (char *)__get_free_page(GFP_KERNEL);
|
||||
if (!page)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = 0;
|
||||
got = access_remote_vm(mm, arg_start, page, PAGE_SIZE, FOLL_ANON);
|
||||
if (got > 0) {
|
||||
int len = strnlen(page, got);
|
||||
|
||||
/* Include the NUL character if it was found */
|
||||
if (len < got)
|
||||
len++;
|
||||
|
||||
if (len > pos) {
|
||||
len -= pos;
|
||||
if (len > count)
|
||||
len = count;
|
||||
len -= copy_to_user(buf, page+pos, len);
|
||||
if (!len)
|
||||
len = -EFAULT;
|
||||
ret = len;
|
||||
}
|
||||
}
|
||||
free_page((unsigned long)page);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t get_mm_cmdline(struct mm_struct *mm, char __user *buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
unsigned long arg_start, arg_end, env_start, env_end;
|
||||
unsigned long pos, len;
|
||||
char *page;
|
||||
char *page, c;
|
||||
|
||||
/* Check if process spawned far enough to have cmdline. */
|
||||
if (!mm->env_end)
|
||||
|
|
@ -232,28 +273,42 @@ static ssize_t get_mm_cmdline(struct mm_struct *mm, char __user *buf,
|
|||
return 0;
|
||||
|
||||
/*
|
||||
* We have traditionally allowed the user to re-write
|
||||
* the argument strings and overflow the end result
|
||||
* into the environment section. But only do that if
|
||||
* the environment area is contiguous to the arguments.
|
||||
* We allow setproctitle() to overwrite the argument
|
||||
* strings, and overflow past the original end. But
|
||||
* only when it overflows into the environment area.
|
||||
*/
|
||||
if (env_start != arg_end || env_start >= env_end)
|
||||
if (env_start != arg_end || env_end < env_start)
|
||||
env_start = env_end = arg_end;
|
||||
|
||||
/* .. and limit it to a maximum of one page of slop */
|
||||
if (env_end >= arg_end + PAGE_SIZE)
|
||||
env_end = arg_end + PAGE_SIZE - 1;
|
||||
len = env_end - arg_start;
|
||||
|
||||
/* We're not going to care if "*ppos" has high bits set */
|
||||
pos = arg_start + *ppos;
|
||||
|
||||
/* .. but we do check the result is in the proper range */
|
||||
if (pos < arg_start || pos >= env_end)
|
||||
pos = *ppos;
|
||||
if (pos >= len)
|
||||
return 0;
|
||||
if (count > len - pos)
|
||||
count = len - pos;
|
||||
if (!count)
|
||||
return 0;
|
||||
|
||||
/* .. and we never go past env_end */
|
||||
if (env_end - pos < count)
|
||||
count = env_end - pos;
|
||||
/*
|
||||
* Magical special case: if the argv[] end byte is not
|
||||
* zero, the user has overwritten it with setproctitle(3).
|
||||
*
|
||||
* Possible future enhancement: do this only once when
|
||||
* pos is 0, and set a flag in the 'struct file'.
|
||||
*/
|
||||
if (access_remote_vm(mm, arg_end-1, &c, 1, FOLL_ANON) == 1 && c)
|
||||
return get_mm_proctitle(mm, buf, count, pos, arg_start);
|
||||
|
||||
/*
|
||||
* For the non-setproctitle() case we limit things strictly
|
||||
* to the [arg_start, arg_end[ range.
|
||||
*/
|
||||
pos += arg_start;
|
||||
if (pos < arg_start || pos >= arg_end)
|
||||
return 0;
|
||||
if (count > arg_end - pos)
|
||||
count = arg_end - pos;
|
||||
|
||||
page = (char *)__get_free_page(GFP_KERNEL);
|
||||
if (!page)
|
||||
|
|
@ -263,48 +318,11 @@ static ssize_t get_mm_cmdline(struct mm_struct *mm, char __user *buf,
|
|||
while (count) {
|
||||
int got;
|
||||
size_t size = min_t(size_t, PAGE_SIZE, count);
|
||||
long offset;
|
||||
|
||||
/*
|
||||
* Are we already starting past the official end?
|
||||
* We always include the last byte that is *supposed*
|
||||
* to be NUL
|
||||
*/
|
||||
offset = (pos >= arg_end) ? pos - arg_end + 1 : 0;
|
||||
|
||||
got = access_remote_vm(mm, pos - offset, page, size + offset, FOLL_ANON);
|
||||
if (got <= offset)
|
||||
got = access_remote_vm(mm, pos, page, size, FOLL_ANON);
|
||||
if (got <= 0)
|
||||
break;
|
||||
got -= offset;
|
||||
|
||||
/* Don't walk past a NUL character once you hit arg_end */
|
||||
if (pos + got >= arg_end) {
|
||||
int n = 0;
|
||||
|
||||
/*
|
||||
* If we started before 'arg_end' but ended up
|
||||
* at or after it, we start the NUL character
|
||||
* check at arg_end-1 (where we expect the normal
|
||||
* EOF to be).
|
||||
*
|
||||
* NOTE! This is smaller than 'got', because
|
||||
* pos + got >= arg_end
|
||||
*/
|
||||
if (pos < arg_end)
|
||||
n = arg_end - pos - 1;
|
||||
|
||||
/* Cut off at first NUL after 'n' */
|
||||
got = n + strnlen(page+n, offset+got-n);
|
||||
if (got < offset)
|
||||
break;
|
||||
got -= offset;
|
||||
|
||||
/* Include the NUL if it existed */
|
||||
if (got < size)
|
||||
got++;
|
||||
}
|
||||
|
||||
got -= copy_to_user(buf, page+offset, got);
|
||||
got -= copy_to_user(buf, page, got);
|
||||
if (unlikely(!got)) {
|
||||
if (!len)
|
||||
len = -EFAULT;
|
||||
|
|
@ -533,8 +551,7 @@ static int proc_oom_score(struct seq_file *m, struct pid_namespace *ns,
|
|||
unsigned long totalpages = totalram_pages() + total_swap_pages;
|
||||
unsigned long points = 0;
|
||||
|
||||
points = oom_badness(task, NULL, NULL, totalpages) *
|
||||
1000 / totalpages;
|
||||
points = oom_badness(task, totalpages) * 1000 / totalpages;
|
||||
seq_printf(m, "%lu\n", points);
|
||||
|
||||
return 0;
|
||||
|
|
@ -1963,9 +1980,12 @@ static int map_files_d_revalidate(struct dentry *dentry, unsigned int flags)
|
|||
goto out;
|
||||
|
||||
if (!dname_to_vma_addr(dentry, &vm_start, &vm_end)) {
|
||||
down_read(&mm->mmap_sem);
|
||||
exact_vma_exists = !!find_exact_vma(mm, vm_start, vm_end);
|
||||
up_read(&mm->mmap_sem);
|
||||
status = down_read_killable(&mm->mmap_sem);
|
||||
if (!status) {
|
||||
exact_vma_exists = !!find_exact_vma(mm, vm_start,
|
||||
vm_end);
|
||||
up_read(&mm->mmap_sem);
|
||||
}
|
||||
}
|
||||
|
||||
mmput(mm);
|
||||
|
|
@ -2011,8 +2031,11 @@ static int map_files_get_link(struct dentry *dentry, struct path *path)
|
|||
if (rc)
|
||||
goto out_mmput;
|
||||
|
||||
rc = down_read_killable(&mm->mmap_sem);
|
||||
if (rc)
|
||||
goto out_mmput;
|
||||
|
||||
rc = -ENOENT;
|
||||
down_read(&mm->mmap_sem);
|
||||
vma = find_exact_vma(mm, vm_start, vm_end);
|
||||
if (vma && vma->vm_file) {
|
||||
*path = vma->vm_file->f_path;
|
||||
|
|
@ -2108,7 +2131,11 @@ static struct dentry *proc_map_files_lookup(struct inode *dir,
|
|||
if (!mm)
|
||||
goto out_put_task;
|
||||
|
||||
down_read(&mm->mmap_sem);
|
||||
result = ERR_PTR(-EINTR);
|
||||
if (down_read_killable(&mm->mmap_sem))
|
||||
goto out_put_mm;
|
||||
|
||||
result = ERR_PTR(-ENOENT);
|
||||
vma = find_exact_vma(mm, vm_start, vm_end);
|
||||
if (!vma)
|
||||
goto out_no_vma;
|
||||
|
|
@ -2119,6 +2146,7 @@ static struct dentry *proc_map_files_lookup(struct inode *dir,
|
|||
|
||||
out_no_vma:
|
||||
up_read(&mm->mmap_sem);
|
||||
out_put_mm:
|
||||
mmput(mm);
|
||||
out_put_task:
|
||||
put_task_struct(task);
|
||||
|
|
@ -2161,7 +2189,12 @@ proc_map_files_readdir(struct file *file, struct dir_context *ctx)
|
|||
mm = get_task_mm(task);
|
||||
if (!mm)
|
||||
goto out_put_task;
|
||||
down_read(&mm->mmap_sem);
|
||||
|
||||
ret = down_read_killable(&mm->mmap_sem);
|
||||
if (ret) {
|
||||
mmput(mm);
|
||||
goto out_put_task;
|
||||
}
|
||||
|
||||
nr_files = 0;
|
||||
|
||||
|
|
@ -3065,6 +3098,9 @@ static const struct pid_entry tgid_base_stuff[] = {
|
|||
#ifdef CONFIG_STACKLEAK_METRICS
|
||||
ONE("stack_depth", S_IRUGO, proc_stack_depth),
|
||||
#endif
|
||||
#ifdef CONFIG_PROC_PID_ARCH_STATUS
|
||||
ONE("arch_status", S_IRUGO, proc_pid_arch_status),
|
||||
#endif
|
||||
};
|
||||
|
||||
static int proc_tgid_base_readdir(struct file *file, struct dir_context *ctx)
|
||||
|
|
@ -3452,6 +3488,9 @@ static const struct pid_entry tid_base_stuff[] = {
|
|||
#ifdef CONFIG_LIVEPATCH
|
||||
ONE("patch_state", S_IRUSR, proc_pid_patch_state),
|
||||
#endif
|
||||
#ifdef CONFIG_PROC_PID_ARCH_STATUS
|
||||
ONE("arch_status", S_IRUGO, proc_pid_arch_status),
|
||||
#endif
|
||||
#ifdef CONFIG_CPU_FREQ_TIMES
|
||||
ONE("time_in_state", 0444, proc_time_in_state_show),
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -200,7 +200,8 @@ static loff_t proc_reg_llseek(struct file *file, loff_t offset, int whence)
|
|||
struct proc_dir_entry *pde = PDE(file_inode(file));
|
||||
loff_t rv = -EINVAL;
|
||||
if (use_pde(pde)) {
|
||||
loff_t (*llseek)(struct file *, loff_t, int);
|
||||
typeof_member(struct file_operations, llseek) llseek;
|
||||
|
||||
llseek = pde->proc_fops->llseek;
|
||||
if (!llseek)
|
||||
llseek = default_llseek;
|
||||
|
|
@ -212,10 +213,11 @@ static loff_t proc_reg_llseek(struct file *file, loff_t offset, int whence)
|
|||
|
||||
static ssize_t proc_reg_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
|
||||
{
|
||||
ssize_t (*read)(struct file *, char __user *, size_t, loff_t *);
|
||||
struct proc_dir_entry *pde = PDE(file_inode(file));
|
||||
ssize_t rv = -EIO;
|
||||
if (use_pde(pde)) {
|
||||
typeof_member(struct file_operations, read) read;
|
||||
|
||||
read = pde->proc_fops->read;
|
||||
if (read)
|
||||
rv = read(file, buf, count, ppos);
|
||||
|
|
@ -226,10 +228,11 @@ static ssize_t proc_reg_read(struct file *file, char __user *buf, size_t count,
|
|||
|
||||
static ssize_t proc_reg_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
|
||||
{
|
||||
ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *);
|
||||
struct proc_dir_entry *pde = PDE(file_inode(file));
|
||||
ssize_t rv = -EIO;
|
||||
if (use_pde(pde)) {
|
||||
typeof_member(struct file_operations, write) write;
|
||||
|
||||
write = pde->proc_fops->write;
|
||||
if (write)
|
||||
rv = write(file, buf, count, ppos);
|
||||
|
|
@ -242,8 +245,9 @@ static __poll_t proc_reg_poll(struct file *file, struct poll_table_struct *pts)
|
|||
{
|
||||
struct proc_dir_entry *pde = PDE(file_inode(file));
|
||||
__poll_t rv = DEFAULT_POLLMASK;
|
||||
__poll_t (*poll)(struct file *, struct poll_table_struct *);
|
||||
if (use_pde(pde)) {
|
||||
typeof_member(struct file_operations, poll) poll;
|
||||
|
||||
poll = pde->proc_fops->poll;
|
||||
if (poll)
|
||||
rv = poll(file, pts);
|
||||
|
|
@ -256,8 +260,9 @@ static long proc_reg_unlocked_ioctl(struct file *file, unsigned int cmd, unsigne
|
|||
{
|
||||
struct proc_dir_entry *pde = PDE(file_inode(file));
|
||||
long rv = -ENOTTY;
|
||||
long (*ioctl)(struct file *, unsigned int, unsigned long);
|
||||
if (use_pde(pde)) {
|
||||
typeof_member(struct file_operations, unlocked_ioctl) ioctl;
|
||||
|
||||
ioctl = pde->proc_fops->unlocked_ioctl;
|
||||
if (ioctl)
|
||||
rv = ioctl(file, cmd, arg);
|
||||
|
|
@ -271,8 +276,9 @@ static long proc_reg_compat_ioctl(struct file *file, unsigned int cmd, unsigned
|
|||
{
|
||||
struct proc_dir_entry *pde = PDE(file_inode(file));
|
||||
long rv = -ENOTTY;
|
||||
long (*compat_ioctl)(struct file *, unsigned int, unsigned long);
|
||||
if (use_pde(pde)) {
|
||||
typeof_member(struct file_operations, compat_ioctl) compat_ioctl;
|
||||
|
||||
compat_ioctl = pde->proc_fops->compat_ioctl;
|
||||
if (compat_ioctl)
|
||||
rv = compat_ioctl(file, cmd, arg);
|
||||
|
|
@ -286,8 +292,9 @@ static int proc_reg_mmap(struct file *file, struct vm_area_struct *vma)
|
|||
{
|
||||
struct proc_dir_entry *pde = PDE(file_inode(file));
|
||||
int rv = -EIO;
|
||||
int (*mmap)(struct file *, struct vm_area_struct *);
|
||||
if (use_pde(pde)) {
|
||||
typeof_member(struct file_operations, mmap) mmap;
|
||||
|
||||
mmap = pde->proc_fops->mmap;
|
||||
if (mmap)
|
||||
rv = mmap(file, vma);
|
||||
|
|
@ -305,7 +312,7 @@ proc_reg_get_unmapped_area(struct file *file, unsigned long orig_addr,
|
|||
unsigned long rv = -EIO;
|
||||
|
||||
if (use_pde(pde)) {
|
||||
typeof(proc_reg_get_unmapped_area) *get_area;
|
||||
typeof_member(struct file_operations, get_unmapped_area) get_area;
|
||||
|
||||
get_area = pde->proc_fops->get_unmapped_area;
|
||||
#ifdef CONFIG_MMU
|
||||
|
|
@ -326,8 +333,8 @@ static int proc_reg_open(struct inode *inode, struct file *file)
|
|||
{
|
||||
struct proc_dir_entry *pde = PDE(inode);
|
||||
int rv = 0;
|
||||
int (*open)(struct inode *, struct file *);
|
||||
int (*release)(struct inode *, struct file *);
|
||||
typeof_member(struct file_operations, open) open;
|
||||
typeof_member(struct file_operations, release) release;
|
||||
struct pde_opener *pdeo;
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ static int meminfo_proc_show(struct seq_file *m, void *v)
|
|||
show_val_kb(m, "Committed_AS: ", committed);
|
||||
seq_printf(m, "VmallocTotal: %8lu kB\n",
|
||||
(unsigned long)VMALLOC_TOTAL >> 10);
|
||||
show_val_kb(m, "VmallocUsed: ", 0ul);
|
||||
show_val_kb(m, "VmallocUsed: ", vmalloc_nr_pages());
|
||||
show_val_kb(m, "VmallocChunk: ", 0ul);
|
||||
show_val_kb(m, "Percpu: ", pcpu_nr_pages());
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,10 @@ static const struct inode_operations proc_sys_inode_operations;
|
|||
static const struct file_operations proc_sys_dir_file_operations;
|
||||
static const struct inode_operations proc_sys_dir_operations;
|
||||
|
||||
/* shared constants to be used in various sysctls */
|
||||
const int sysctl_vals[] = { 0, 1, INT_MAX };
|
||||
EXPORT_SYMBOL(sysctl_vals);
|
||||
|
||||
/* Support for permanently empty directories */
|
||||
|
||||
struct ctl_table sysctl_mount_point[] = {
|
||||
|
|
@ -499,6 +503,10 @@ static struct inode *proc_sys_make_inode(struct super_block *sb,
|
|||
|
||||
if (root->set_ownership)
|
||||
root->set_ownership(head, table, &inode->i_uid, &inode->i_gid);
|
||||
else {
|
||||
inode->i_uid = GLOBAL_ROOT_UID;
|
||||
inode->i_gid = GLOBAL_ROOT_GID;
|
||||
}
|
||||
|
||||
return inode;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -157,8 +157,6 @@ static int proc_get_tree(struct fs_context *fc)
|
|||
{
|
||||
struct proc_fs_context *ctx = fc->fs_private;
|
||||
|
||||
put_user_ns(fc->user_ns);
|
||||
fc->user_ns = get_user_ns(ctx->pid_ns->user_ns);
|
||||
fc->s_fs_info = ctx->pid_ns;
|
||||
return vfs_get_super(fc, vfs_get_keyed_super, proc_fill_super);
|
||||
}
|
||||
|
|
@ -167,8 +165,7 @@ static void proc_fs_context_free(struct fs_context *fc)
|
|||
{
|
||||
struct proc_fs_context *ctx = fc->fs_private;
|
||||
|
||||
if (ctx->pid_ns)
|
||||
put_pid_ns(ctx->pid_ns);
|
||||
put_pid_ns(ctx->pid_ns);
|
||||
kfree(ctx);
|
||||
}
|
||||
|
||||
|
|
@ -188,6 +185,8 @@ static int proc_init_fs_context(struct fs_context *fc)
|
|||
return -ENOMEM;
|
||||
|
||||
ctx->pid_ns = get_pid_ns(task_active_pid_ns(current));
|
||||
put_user_ns(fc->user_ns);
|
||||
fc->user_ns = get_user_ns(ctx->pid_ns->user_ns);
|
||||
fc->fs_private = ctx;
|
||||
fc->ops = &proc_fs_context_ops;
|
||||
return 0;
|
||||
|
|
@ -211,7 +210,7 @@ static struct file_system_type proc_fs_type = {
|
|||
.init_fs_context = proc_init_fs_context,
|
||||
.parameters = &proc_fs_parameters,
|
||||
.kill_sb = proc_kill_sb,
|
||||
.fs_flags = FS_USERNS_MOUNT,
|
||||
.fs_flags = FS_USERNS_MOUNT | FS_DISALLOW_NOTIFY_PERM,
|
||||
};
|
||||
|
||||
void __init proc_root_init(void)
|
||||
|
|
|
|||
|
|
@ -216,7 +216,11 @@ static void *m_start(struct seq_file *m, loff_t *ppos)
|
|||
if (!mm || !mmget_not_zero(mm))
|
||||
return NULL;
|
||||
|
||||
down_read(&mm->mmap_sem);
|
||||
if (down_read_killable(&mm->mmap_sem)) {
|
||||
mmput(mm);
|
||||
return ERR_PTR(-EINTR);
|
||||
}
|
||||
|
||||
hold_task_mempolicy(priv);
|
||||
priv->tail_vma = get_gate_vma(mm);
|
||||
|
||||
|
|
@ -474,17 +478,53 @@ struct mem_size_stats {
|
|||
unsigned long shared_hugetlb;
|
||||
unsigned long private_hugetlb;
|
||||
u64 pss;
|
||||
u64 pss_anon;
|
||||
u64 pss_file;
|
||||
u64 pss_shmem;
|
||||
u64 pss_locked;
|
||||
u64 swap_pss;
|
||||
bool check_shmem_swap;
|
||||
};
|
||||
|
||||
static void smaps_page_accumulate(struct mem_size_stats *mss,
|
||||
struct page *page, unsigned long size, unsigned long pss,
|
||||
bool dirty, bool locked, bool private)
|
||||
{
|
||||
mss->pss += pss;
|
||||
|
||||
if (PageAnon(page))
|
||||
mss->pss_anon += pss;
|
||||
else if (PageSwapBacked(page))
|
||||
mss->pss_shmem += pss;
|
||||
else
|
||||
mss->pss_file += pss;
|
||||
|
||||
if (locked)
|
||||
mss->pss_locked += pss;
|
||||
|
||||
if (dirty || PageDirty(page)) {
|
||||
if (private)
|
||||
mss->private_dirty += size;
|
||||
else
|
||||
mss->shared_dirty += size;
|
||||
} else {
|
||||
if (private)
|
||||
mss->private_clean += size;
|
||||
else
|
||||
mss->shared_clean += size;
|
||||
}
|
||||
}
|
||||
|
||||
static void smaps_account(struct mem_size_stats *mss, struct page *page,
|
||||
bool compound, bool young, bool dirty, bool locked)
|
||||
{
|
||||
int i, nr = compound ? 1 << compound_order(page) : 1;
|
||||
unsigned long size = nr * PAGE_SIZE;
|
||||
|
||||
/*
|
||||
* First accumulate quantities that depend only on |size| and the type
|
||||
* of the compound page.
|
||||
*/
|
||||
if (PageAnon(page)) {
|
||||
mss->anonymous += size;
|
||||
if (!PageSwapBacked(page) && !dirty && !PageDirty(page))
|
||||
|
|
@ -497,42 +537,25 @@ static void smaps_account(struct mem_size_stats *mss, struct page *page,
|
|||
mss->referenced += size;
|
||||
|
||||
/*
|
||||
* Then accumulate quantities that may depend on sharing, or that may
|
||||
* differ page-by-page.
|
||||
*
|
||||
* page_count(page) == 1 guarantees the page is mapped exactly once.
|
||||
* If any subpage of the compound page mapped with PTE it would elevate
|
||||
* page_count().
|
||||
*/
|
||||
if (page_count(page) == 1) {
|
||||
if (dirty || PageDirty(page))
|
||||
mss->private_dirty += size;
|
||||
else
|
||||
mss->private_clean += size;
|
||||
mss->pss += (u64)size << PSS_SHIFT;
|
||||
if (locked)
|
||||
mss->pss_locked += (u64)size << PSS_SHIFT;
|
||||
smaps_page_accumulate(mss, page, size, size << PSS_SHIFT, dirty,
|
||||
locked, true);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < nr; i++, page++) {
|
||||
int mapcount = page_mapcount(page);
|
||||
unsigned long pss = (PAGE_SIZE << PSS_SHIFT);
|
||||
|
||||
if (mapcount >= 2) {
|
||||
if (dirty || PageDirty(page))
|
||||
mss->shared_dirty += PAGE_SIZE;
|
||||
else
|
||||
mss->shared_clean += PAGE_SIZE;
|
||||
mss->pss += pss / mapcount;
|
||||
if (locked)
|
||||
mss->pss_locked += pss / mapcount;
|
||||
} else {
|
||||
if (dirty || PageDirty(page))
|
||||
mss->private_dirty += PAGE_SIZE;
|
||||
else
|
||||
mss->private_clean += PAGE_SIZE;
|
||||
mss->pss += pss;
|
||||
if (locked)
|
||||
mss->pss_locked += pss;
|
||||
}
|
||||
unsigned long pss = PAGE_SIZE << PSS_SHIFT;
|
||||
if (mapcount >= 2)
|
||||
pss /= mapcount;
|
||||
smaps_page_accumulate(mss, page, PAGE_SIZE, pss, dirty, locked,
|
||||
mapcount < 2);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -811,10 +834,23 @@ static void smap_gather_stats(struct vm_area_struct *vma,
|
|||
seq_put_decimal_ull_width(m, str, (val) >> 10, 8)
|
||||
|
||||
/* Show the contents common for smaps and smaps_rollup */
|
||||
static void __show_smap(struct seq_file *m, const struct mem_size_stats *mss)
|
||||
static void __show_smap(struct seq_file *m, const struct mem_size_stats *mss,
|
||||
bool rollup_mode)
|
||||
{
|
||||
SEQ_PUT_DEC("Rss: ", mss->resident);
|
||||
SEQ_PUT_DEC(" kB\nPss: ", mss->pss >> PSS_SHIFT);
|
||||
if (rollup_mode) {
|
||||
/*
|
||||
* These are meaningful only for smaps_rollup, otherwise two of
|
||||
* them are zero, and the other one is the same as Pss.
|
||||
*/
|
||||
SEQ_PUT_DEC(" kB\nPss_Anon: ",
|
||||
mss->pss_anon >> PSS_SHIFT);
|
||||
SEQ_PUT_DEC(" kB\nPss_File: ",
|
||||
mss->pss_file >> PSS_SHIFT);
|
||||
SEQ_PUT_DEC(" kB\nPss_Shmem: ",
|
||||
mss->pss_shmem >> PSS_SHIFT);
|
||||
}
|
||||
SEQ_PUT_DEC(" kB\nShared_Clean: ", mss->shared_clean);
|
||||
SEQ_PUT_DEC(" kB\nShared_Dirty: ", mss->shared_dirty);
|
||||
SEQ_PUT_DEC(" kB\nPrivate_Clean: ", mss->private_clean);
|
||||
|
|
@ -856,9 +892,10 @@ static int show_smap(struct seq_file *m, void *v)
|
|||
SEQ_PUT_DEC(" kB\nMMUPageSize: ", vma_mmu_pagesize(vma));
|
||||
seq_puts(m, " kB\n");
|
||||
|
||||
__show_smap(m, &mss);
|
||||
__show_smap(m, &mss, false);
|
||||
|
||||
seq_printf(m, "THPeligible: %d\n", transparent_hugepage_enabled(vma));
|
||||
seq_printf(m, "THPeligible: %d\n",
|
||||
transparent_hugepage_enabled(vma));
|
||||
|
||||
if (arch_pkeys_enabled())
|
||||
seq_printf(m, "ProtectionKey: %8u\n", vma_pkey(vma));
|
||||
|
|
@ -890,7 +927,10 @@ static int show_smaps_rollup(struct seq_file *m, void *v)
|
|||
|
||||
memset(&mss, 0, sizeof(mss));
|
||||
|
||||
down_read(&mm->mmap_sem);
|
||||
ret = down_read_killable(&mm->mmap_sem);
|
||||
if (ret)
|
||||
goto out_put_mm;
|
||||
|
||||
hold_task_mempolicy(priv);
|
||||
|
||||
for (vma = priv->mm->mmap; vma; vma = vma->vm_next) {
|
||||
|
|
@ -903,12 +943,13 @@ static int show_smaps_rollup(struct seq_file *m, void *v)
|
|||
seq_pad(m, ' ');
|
||||
seq_puts(m, "[rollup]\n");
|
||||
|
||||
__show_smap(m, &mss);
|
||||
__show_smap(m, &mss, true);
|
||||
|
||||
release_task_mempolicy(priv);
|
||||
up_read(&mm->mmap_sem);
|
||||
mmput(mm);
|
||||
|
||||
out_put_mm:
|
||||
mmput(mm);
|
||||
out_put_task:
|
||||
put_task_struct(priv->task);
|
||||
priv->task = NULL;
|
||||
|
|
@ -1194,7 +1235,10 @@ static ssize_t clear_refs_write(struct file *file, const char __user *buf,
|
|||
goto out_mm;
|
||||
}
|
||||
|
||||
down_read(&mm->mmap_sem);
|
||||
if (down_read_killable(&mm->mmap_sem)) {
|
||||
count = -EINTR;
|
||||
goto out_mm;
|
||||
}
|
||||
tlb_gather_mmu(&tlb, mm, 0, -1);
|
||||
if (type == CLEAR_REFS_SOFT_DIRTY) {
|
||||
for (vma = mm->mmap; vma; vma = vma->vm_next) {
|
||||
|
|
@ -1341,7 +1385,7 @@ static pagemap_entry_t pte_to_pagemap_entry(struct pagemapread *pm,
|
|||
if (pm->show_pfn)
|
||||
frame = pte_pfn(pte);
|
||||
flags |= PM_PRESENT;
|
||||
page = _vm_normal_page(vma, addr, pte, true);
|
||||
page = vm_normal_page(vma, addr, pte);
|
||||
if (pte_soft_dirty(pte))
|
||||
flags |= PM_SOFT_DIRTY;
|
||||
} else if (is_swap_pte(pte)) {
|
||||
|
|
@ -1601,7 +1645,9 @@ static ssize_t pagemap_read(struct file *file, char __user *buf,
|
|||
/* overflow ? */
|
||||
if (end < start_vaddr || end > end_vaddr)
|
||||
end = end_vaddr;
|
||||
down_read(&mm->mmap_sem);
|
||||
ret = down_read_killable(&mm->mmap_sem);
|
||||
if (ret)
|
||||
goto out_free;
|
||||
ret = walk_page_range(start_vaddr, end, &pagemap_walk);
|
||||
up_read(&mm->mmap_sem);
|
||||
start_vaddr = end;
|
||||
|
|
|
|||
|
|
@ -211,7 +211,11 @@ static void *m_start(struct seq_file *m, loff_t *pos)
|
|||
if (!mm || !mmget_not_zero(mm))
|
||||
return NULL;
|
||||
|
||||
down_read(&mm->mmap_sem);
|
||||
if (down_read_killable(&mm->mmap_sem)) {
|
||||
mmput(mm);
|
||||
return ERR_PTR(-EINTR);
|
||||
}
|
||||
|
||||
/* start from the Nth VMA */
|
||||
for (p = rb_first(&mm->mm_rb); p; p = rb_next(p))
|
||||
if (n-- == 0)
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#include <linux/init.h>
|
||||
#include <linux/crash_dump.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/pagemap.h>
|
||||
|
|
@ -54,6 +55,9 @@ static struct proc_dir_entry *proc_vmcore;
|
|||
/* Device Dump list and mutex to synchronize access to list */
|
||||
static LIST_HEAD(vmcoredd_list);
|
||||
static DEFINE_MUTEX(vmcoredd_mutex);
|
||||
|
||||
static bool vmcoredd_disabled;
|
||||
core_param(novmcoredd, vmcoredd_disabled, bool, 0);
|
||||
#endif /* CONFIG_PROC_VMCORE_DEVICE_DUMP */
|
||||
|
||||
/* Device Dump Size */
|
||||
|
|
@ -166,7 +170,7 @@ void __weak elfcorehdr_free(unsigned long long addr)
|
|||
*/
|
||||
ssize_t __weak elfcorehdr_read(char *buf, size_t count, u64 *ppos)
|
||||
{
|
||||
return read_from_oldmem(buf, count, ppos, 0, false);
|
||||
return read_from_oldmem(buf, count, ppos, 0, sev_active());
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -174,7 +178,7 @@ ssize_t __weak elfcorehdr_read(char *buf, size_t count, u64 *ppos)
|
|||
*/
|
||||
ssize_t __weak elfcorehdr_read_notes(char *buf, size_t count, u64 *ppos)
|
||||
{
|
||||
return read_from_oldmem(buf, count, ppos, 0, sme_active());
|
||||
return read_from_oldmem(buf, count, ppos, 0, mem_encrypt_active());
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -374,7 +378,7 @@ static ssize_t __read_vmcore(char *buffer, size_t buflen, loff_t *fpos,
|
|||
buflen);
|
||||
start = m->paddr + *fpos - m->offset;
|
||||
tmp = read_from_oldmem(buffer, tsz, &start,
|
||||
userbuf, sme_active());
|
||||
userbuf, mem_encrypt_active());
|
||||
if (tmp < 0)
|
||||
return tmp;
|
||||
buflen -= tsz;
|
||||
|
|
@ -1452,6 +1456,11 @@ int vmcore_add_device_dump(struct vmcoredd_data *data)
|
|||
size_t data_size;
|
||||
int ret;
|
||||
|
||||
if (vmcoredd_disabled) {
|
||||
pr_err_once("Device dump is disabled\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!data || !strlen(data->dump_name) ||
|
||||
!data->vmcoredd_callback || !data->size)
|
||||
return -EINVAL;
|
||||
|
|
|
|||
Loading…
Reference in a new issue