diff options
author | Richard Weinberger <richard@nod.at> | 2013-08-17 12:46:00 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-09-26 20:18:29 -0400 |
commit | 4fdaa3d47985338f80d7262de700533a9e630d29 (patch) | |
tree | e0b5561831e3336af764f5c5d1472e405a8ab470 /arch/um/kernel | |
parent | 579db19eca10b594acd9d4516814b599eb4486ec (diff) |
um: Implement probe_kernel_read()
commit f75b1b1bedfb498cc43a992ce4d7ed8df3b1e770 upstream.
UML needs it's own probe_kernel_read() to handle kernel
mode faults correctly.
The implementation uses mincore() on the host side to detect
whether a page is owned by the UML kernel process.
This fixes also a possible crash when sysrq-t is used.
Starting with 3.10 sysrq-t calls probe_kernel_read() to
read details from the kernel workers. As kernel worker are
completely async pointers may turn NULL while reading them.
Signed-off-by: Richard Weinberger <richard@nod.at>
Cc: <stian@nixia.no>
Cc: <tj@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'arch/um/kernel')
-rw-r--r-- | arch/um/kernel/Makefile | 2 | ||||
-rw-r--r-- | arch/um/kernel/maccess.c | 24 |
2 files changed, 25 insertions, 1 deletions
diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile index babe21826e3e..d8b78a03855c 100644 --- a/arch/um/kernel/Makefile +++ b/arch/um/kernel/Makefile | |||
@@ -13,7 +13,7 @@ clean-files := | |||
13 | obj-y = config.o exec.o exitcode.o irq.o ksyms.o mem.o \ | 13 | obj-y = config.o exec.o exitcode.o irq.o ksyms.o mem.o \ |
14 | physmem.o process.o ptrace.o reboot.o sigio.o \ | 14 | physmem.o process.o ptrace.o reboot.o sigio.o \ |
15 | signal.o smp.o syscall.o sysrq.o time.o tlb.o trap.o \ | 15 | signal.o smp.o syscall.o sysrq.o time.o tlb.o trap.o \ |
16 | um_arch.o umid.o skas/ | 16 | um_arch.o umid.o maccess.o skas/ |
17 | 17 | ||
18 | obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o | 18 | obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o |
19 | obj-$(CONFIG_GPROF) += gprof_syms.o | 19 | obj-$(CONFIG_GPROF) += gprof_syms.o |
diff --git a/arch/um/kernel/maccess.c b/arch/um/kernel/maccess.c new file mode 100644 index 000000000000..1f3d5c4910d1 --- /dev/null +++ b/arch/um/kernel/maccess.c | |||
@@ -0,0 +1,24 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 Richard Weinberger <richrd@nod.at> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | |||
9 | #include <linux/uaccess.h> | ||
10 | #include <linux/kernel.h> | ||
11 | #include <os.h> | ||
12 | |||
13 | long probe_kernel_read(void *dst, const void *src, size_t size) | ||
14 | { | ||
15 | void *psrc = (void *)rounddown((unsigned long)src, PAGE_SIZE); | ||
16 | |||
17 | if ((unsigned long)src < PAGE_SIZE || size <= 0) | ||
18 | return -EFAULT; | ||
19 | |||
20 | if (os_mincore(psrc, size + src - psrc) <= 0) | ||
21 | return -EFAULT; | ||
22 | |||
23 | return __probe_kernel_read(dst, src, size); | ||
24 | } | ||