diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-12 21:18:05 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-12 21:18:05 -0400 |
commit | d645727bdc2aed8e2e0e9496248f735481b5049a (patch) | |
tree | 079fa3cf369dbf0dc0663fe1b0a62460c522a8e9 /arch/s390/mm | |
parent | cd166bd0dde265a97dd9aa8e3451a2646d96d04b (diff) | |
parent | 310d6b671588dd7695cbc0d09d02e41d94a42bed (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/Makefile | 2 | ||||
-rw-r--r-- | arch/s390/mm/fault.c | 3 | ||||
-rw-r--r-- | arch/s390/mm/maccess.c | 61 | ||||
-rw-r--r-- | arch/s390/mm/mmap.c | 11 | ||||
-rw-r--r-- | arch/s390/mm/pgtable.c | 16 |
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 | ||
5 | obj-y := init.o fault.o extmem.o mmap.o vmem.o pgtable.o | 5 | obj-y := init.o fault.o extmem.o mmap.o vmem.o pgtable.o maccess.o |
6 | obj-$(CONFIG_CMM) += cmm.o | 6 | obj-$(CONFIG_CMM) += cmm.o |
7 | obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o | 7 | obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o |
8 | obj-$(CONFIG_PAGE_STATES) += page-states.o | 8 | obj-$(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 | */ | ||
22 | static 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 | |||
48 | long 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 | ||
92 | int s390_mmap_check(unsigned long addr, unsigned long len) | 93 | int 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 | ||
54 | unsigned long VMALLOC_START = VMALLOC_END - VMALLOC_SIZE; | ||
55 | EXPORT_SYMBOL(VMALLOC_START); | ||
56 | |||
57 | static 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 | } | ||
64 | early_param("vmalloc", parse_vmalloc); | ||
65 | |||
56 | unsigned long *crst_table_alloc(struct mm_struct *mm, int noexec) | 66 | unsigned 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); |