summaryrefslogtreecommitdiff
path: root/arch/um/kernel/maccess.c
diff options
context:
space:
mode:
authorRichard Weinberger <richard@nod.at>2013-08-17 18:46:00 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-09-26 17:21:58 -0700
commit1e354b6b4b0cb05d1666c0f8c3a13a164aec70c3 (patch)
tree1dffaa1ee156b55039083afdb722c45e1f3a7cb5 /arch/um/kernel/maccess.c
parent61bc17595c5a036931473347856ae5a44f9b01ab (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/maccess.c')
-rw-r--r--arch/um/kernel/maccess.c24
1 files changed, 24 insertions, 0 deletions
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 @@
+/*
+ * Copyright (C) 2013 Richard Weinberger <richrd@nod.at>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/uaccess.h>
+#include <linux/kernel.h>
+#include <os.h>
+
+long probe_kernel_read(void *dst, const void *src, size_t size)
+{
+ void *psrc = (void *)rounddown((unsigned long)src, PAGE_SIZE);
+
+ if ((unsigned long)src < PAGE_SIZE || size <= 0)
+ return -EFAULT;
+
+ if (os_mincore(psrc, size + src - psrc) <= 0)
+ return -EFAULT;
+
+ return __probe_kernel_read(dst, src, size);
+}