aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/mm
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-06-12 21:18:05 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-06-12 21:18:05 -0400
commitd645727bdc2aed8e2e0e9496248f735481b5049a (patch)
tree079fa3cf369dbf0dc0663fe1b0a62460c522a8e9 /arch/s390/mm
parentcd166bd0dde265a97dd9aa8e3451a2646d96d04b (diff)
parent310d6b671588dd7695cbc0d09d02e41d94a42bed (diff)
Merge branch 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6
* 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6: (30 commits) [S390] wire up sys_perf_counter_open [S390] wire up sys_rt_tgsigqueueinfo [S390] ftrace: add system call tracer support [S390] ftrace: add function graph tracer support [S390] ftrace: add function trace mcount test support [S390] ftrace: add dynamic ftrace support [S390] kprobes: use probe_kernel_write [S390] maccess: arch specific probe_kernel_write() implementation [S390] maccess: add weak attribute to probe_kernel_write [S390] profile_tick called twice [S390] dasd: forward internal errors to dasd_sleep_on caller [S390] dasd: sync after async probe [S390] dasd: check_characteristics cleanup [S390] dasd: no High Performance FICON in 31-bit mode [S390] dcssblk: revert devt conversion [S390] qdio: fix access beyond ARRAY_SIZE of irq_ptr->{in,out}put_qs [S390] vmalloc: add vmalloc kernel parameter support [S390] uaccess: use might_fault() instead of might_sleep() [S390] 3270: lock dependency fixes [S390] 3270: do not register with tty_register_device ...
Diffstat (limited to 'arch/s390/mm')
-rw-r--r--arch/s390/mm/Makefile2
-rw-r--r--arch/s390/mm/fault.c3
-rw-r--r--arch/s390/mm/maccess.c61
-rw-r--r--arch/s390/mm/mmap.c11
-rw-r--r--arch/s390/mm/pgtable.c16
5 files changed, 82 insertions, 11 deletions
diff --git a/arch/s390/mm/Makefile b/arch/s390/mm/Makefile
index 2a7458134544..db05661ac895 100644
--- a/arch/s390/mm/Makefile
+++ b/arch/s390/mm/Makefile
@@ -2,7 +2,7 @@
2# Makefile for the linux s390-specific parts of the memory manager. 2# Makefile for the linux s390-specific parts of the memory manager.
3# 3#
4 4
5obj-y := init.o fault.o extmem.o mmap.o vmem.o pgtable.o 5obj-y := init.o fault.o extmem.o mmap.o vmem.o pgtable.o maccess.o
6obj-$(CONFIG_CMM) += cmm.o 6obj-$(CONFIG_CMM) += cmm.o
7obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o 7obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
8obj-$(CONFIG_PAGE_STATES) += page-states.o 8obj-$(CONFIG_PAGE_STATES) += page-states.o
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index 833e8366c351..220a152c836c 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -19,6 +19,7 @@
19#include <linux/ptrace.h> 19#include <linux/ptrace.h>
20#include <linux/mman.h> 20#include <linux/mman.h>
21#include <linux/mm.h> 21#include <linux/mm.h>
22#include <linux/compat.h>
22#include <linux/smp.h> 23#include <linux/smp.h>
23#include <linux/kdebug.h> 24#include <linux/kdebug.h>
24#include <linux/smp_lock.h> 25#include <linux/smp_lock.h>
@@ -239,7 +240,7 @@ static int signal_return(struct mm_struct *mm, struct pt_regs *regs,
239 up_read(&mm->mmap_sem); 240 up_read(&mm->mmap_sem);
240 clear_tsk_thread_flag(current, TIF_SINGLE_STEP); 241 clear_tsk_thread_flag(current, TIF_SINGLE_STEP);
241#ifdef CONFIG_COMPAT 242#ifdef CONFIG_COMPAT
242 compat = test_tsk_thread_flag(current, TIF_31BIT); 243 compat = is_compat_task();
243 if (compat && instruction == 0x0a77) 244 if (compat && instruction == 0x0a77)
244 sys32_sigreturn(); 245 sys32_sigreturn();
245 else if (compat && instruction == 0x0aad) 246 else if (compat && instruction == 0x0aad)
diff --git a/arch/s390/mm/maccess.c b/arch/s390/mm/maccess.c
new file mode 100644
index 000000000000..81756271dc44
--- /dev/null
+++ b/arch/s390/mm/maccess.c
@@ -0,0 +1,61 @@
1/*
2 * Access kernel memory without faulting -- s390 specific implementation.
3 *
4 * Copyright IBM Corp. 2009
5 *
6 * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>,
7 *
8 */
9
10#include <linux/uaccess.h>
11#include <linux/kernel.h>
12#include <linux/types.h>
13#include <linux/errno.h>
14#include <asm/system.h>
15
16/*
17 * This function writes to kernel memory bypassing DAT and possible
18 * write protection. It copies one to four bytes from src to dst
19 * using the stura instruction.
20 * Returns the number of bytes copied or -EFAULT.
21 */
22static long probe_kernel_write_odd(void *dst, void *src, size_t size)
23{
24 unsigned long count, aligned;
25 int offset, mask;
26 int rc = -EFAULT;
27
28 aligned = (unsigned long) dst & ~3UL;
29 offset = (unsigned long) dst & 3;
30 count = min_t(unsigned long, 4 - offset, size);
31 mask = (0xf << (4 - count)) & 0xf;
32 mask >>= offset;
33 asm volatile(
34 " bras 1,0f\n"
35 " icm 0,0,0(%3)\n"
36 "0: l 0,0(%1)\n"
37 " lra %1,0(%1)\n"
38 "1: ex %2,0(1)\n"
39 "2: stura 0,%1\n"
40 " la %0,0\n"
41 "3:\n"
42 EX_TABLE(0b,3b) EX_TABLE(1b,3b) EX_TABLE(2b,3b)
43 : "+d" (rc), "+a" (aligned)
44 : "a" (mask), "a" (src) : "cc", "memory", "0", "1");
45 return rc ? rc : count;
46}
47
48long probe_kernel_write(void *dst, void *src, size_t size)
49{
50 long copied = 0;
51
52 while (size) {
53 copied = probe_kernel_write_odd(dst, src, size);
54 if (copied < 0)
55 break;
56 dst += copied;
57 src += copied;
58 size -= copied;
59 }
60 return copied < 0 ? -EFAULT : 0;
61}
diff --git a/arch/s390/mm/mmap.c b/arch/s390/mm/mmap.c
index e008d236cc15..f4558ccf02b9 100644
--- a/arch/s390/mm/mmap.c
+++ b/arch/s390/mm/mmap.c
@@ -28,6 +28,7 @@
28#include <linux/mm.h> 28#include <linux/mm.h>
29#include <linux/module.h> 29#include <linux/module.h>
30#include <asm/pgalloc.h> 30#include <asm/pgalloc.h>
31#include <asm/compat.h>
31 32
32/* 33/*
33 * Top of mmap area (just below the process stack). 34 * Top of mmap area (just below the process stack).
@@ -55,7 +56,7 @@ static inline int mmap_is_legacy(void)
55 /* 56 /*
56 * Force standard allocation for 64 bit programs. 57 * Force standard allocation for 64 bit programs.
57 */ 58 */
58 if (!test_thread_flag(TIF_31BIT)) 59 if (!is_compat_task())
59 return 1; 60 return 1;
60#endif 61#endif
61 return sysctl_legacy_va_layout || 62 return sysctl_legacy_va_layout ||
@@ -91,7 +92,7 @@ EXPORT_SYMBOL_GPL(arch_pick_mmap_layout);
91 92
92int s390_mmap_check(unsigned long addr, unsigned long len) 93int s390_mmap_check(unsigned long addr, unsigned long len)
93{ 94{
94 if (!test_thread_flag(TIF_31BIT) && 95 if (!is_compat_task() &&
95 len >= TASK_SIZE && TASK_SIZE < (1UL << 53)) 96 len >= TASK_SIZE && TASK_SIZE < (1UL << 53))
96 return crst_table_upgrade(current->mm, 1UL << 53); 97 return crst_table_upgrade(current->mm, 1UL << 53);
97 return 0; 98 return 0;
@@ -108,8 +109,7 @@ s390_get_unmapped_area(struct file *filp, unsigned long addr,
108 area = arch_get_unmapped_area(filp, addr, len, pgoff, flags); 109 area = arch_get_unmapped_area(filp, addr, len, pgoff, flags);
109 if (!(area & ~PAGE_MASK)) 110 if (!(area & ~PAGE_MASK))
110 return area; 111 return area;
111 if (area == -ENOMEM && 112 if (area == -ENOMEM && !is_compat_task() && TASK_SIZE < (1UL << 53)) {
112 !test_thread_flag(TIF_31BIT) && TASK_SIZE < (1UL << 53)) {
113 /* Upgrade the page table to 4 levels and retry. */ 113 /* Upgrade the page table to 4 levels and retry. */
114 rc = crst_table_upgrade(mm, 1UL << 53); 114 rc = crst_table_upgrade(mm, 1UL << 53);
115 if (rc) 115 if (rc)
@@ -131,8 +131,7 @@ s390_get_unmapped_area_topdown(struct file *filp, const unsigned long addr,
131 area = arch_get_unmapped_area_topdown(filp, addr, len, pgoff, flags); 131 area = arch_get_unmapped_area_topdown(filp, addr, len, pgoff, flags);
132 if (!(area & ~PAGE_MASK)) 132 if (!(area & ~PAGE_MASK))
133 return area; 133 return area;
134 if (area == -ENOMEM && 134 if (area == -ENOMEM && !is_compat_task() && TASK_SIZE < (1UL << 53)) {
135 !test_thread_flag(TIF_31BIT) && TASK_SIZE < (1UL << 53)) {
136 /* Upgrade the page table to 4 levels and retry. */ 135 /* Upgrade the page table to 4 levels and retry. */
137 rc = crst_table_upgrade(mm, 1UL << 53); 136 rc = crst_table_upgrade(mm, 1UL << 53);
138 if (rc) 137 if (rc)
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c
index be6c1cf4ad5a..4ca8e826bf30 100644
--- a/arch/s390/mm/pgtable.c
+++ b/arch/s390/mm/pgtable.c
@@ -1,7 +1,5 @@
1/* 1/*
2 * arch/s390/mm/pgtable.c 2 * Copyright IBM Corp. 2007,2009
3 *
4 * Copyright IBM Corp. 2007
5 * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com> 3 * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
6 */ 4 */
7 5
@@ -53,6 +51,18 @@ void clear_table_pgstes(unsigned long *table)
53 51
54#endif 52#endif
55 53
54unsigned long VMALLOC_START = VMALLOC_END - VMALLOC_SIZE;
55EXPORT_SYMBOL(VMALLOC_START);
56
57static int __init parse_vmalloc(char *arg)
58{
59 if (!arg)
60 return -EINVAL;
61 VMALLOC_START = (VMALLOC_END - memparse(arg, &arg)) & PAGE_MASK;
62 return 0;
63}
64early_param("vmalloc", parse_vmalloc);
65
56unsigned long *crst_table_alloc(struct mm_struct *mm, int noexec) 66unsigned long *crst_table_alloc(struct mm_struct *mm, int noexec)
57{ 67{
58 struct page *page = alloc_pages(GFP_KERNEL, ALLOC_ORDER); 68 struct page *page = alloc_pages(GFP_KERNEL, ALLOC_ORDER);