diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
commit | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch) | |
tree | a8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /arch/um/kernel/skas | |
parent | 406089d01562f1e2bf9f089fd7637009ebaad589 (diff) |
Patched in Tegra support.
Diffstat (limited to 'arch/um/kernel/skas')
-rw-r--r-- | arch/um/kernel/skas/clone.c | 9 | ||||
-rw-r--r-- | arch/um/kernel/skas/mmu.c | 42 | ||||
-rw-r--r-- | arch/um/kernel/skas/process.c | 14 | ||||
-rw-r--r-- | arch/um/kernel/skas/syscall.c | 16 | ||||
-rw-r--r-- | arch/um/kernel/skas/uaccess.c | 14 |
5 files changed, 52 insertions, 43 deletions
diff --git a/arch/um/kernel/skas/clone.c b/arch/um/kernel/skas/clone.c index 289771dadf8..2c8583c1a34 100644 --- a/arch/um/kernel/skas/clone.c +++ b/arch/um/kernel/skas/clone.c | |||
@@ -7,10 +7,11 @@ | |||
7 | #include <sched.h> | 7 | #include <sched.h> |
8 | #include <asm/unistd.h> | 8 | #include <asm/unistd.h> |
9 | #include <sys/time.h> | 9 | #include <sys/time.h> |
10 | #include <as-layout.h> | 10 | #include "as-layout.h" |
11 | #include <ptrace_user.h> | 11 | #include "kern_constants.h" |
12 | #include <stub-data.h> | 12 | #include "ptrace_user.h" |
13 | #include <sysdep/stub.h> | 13 | #include "stub-data.h" |
14 | #include "sysdep/stub.h" | ||
14 | 15 | ||
15 | /* | 16 | /* |
16 | * This is in a separate file because it needs to be compiled with any | 17 | * This is in a separate file because it needs to be compiled with any |
diff --git a/arch/um/kernel/skas/mmu.c b/arch/um/kernel/skas/mmu.c index ff03067a3b1..1aee587e9c5 100644 --- a/arch/um/kernel/skas/mmu.c +++ b/arch/um/kernel/skas/mmu.c | |||
@@ -3,14 +3,14 @@ | |||
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include <linux/mm.h> | 6 | #include "linux/mm.h" |
7 | #include <linux/sched.h> | 7 | #include "linux/sched.h" |
8 | #include <linux/slab.h> | 8 | #include "linux/slab.h" |
9 | #include <asm/pgalloc.h> | 9 | #include "asm/pgalloc.h" |
10 | #include <asm/pgtable.h> | 10 | #include "asm/pgtable.h" |
11 | #include <as-layout.h> | 11 | #include "as-layout.h" |
12 | #include <os.h> | 12 | #include "os.h" |
13 | #include <skas.h> | 13 | #include "skas.h" |
14 | 14 | ||
15 | extern int __syscall_stub_start; | 15 | extern int __syscall_stub_start; |
16 | 16 | ||
@@ -92,6 +92,8 @@ int init_new_context(struct task_struct *task, struct mm_struct *mm) | |||
92 | goto out_free; | 92 | goto out_free; |
93 | } | 93 | } |
94 | 94 | ||
95 | to_mm->stub_pages = NULL; | ||
96 | |||
95 | return 0; | 97 | return 0; |
96 | 98 | ||
97 | out_free: | 99 | out_free: |
@@ -101,8 +103,9 @@ int init_new_context(struct task_struct *task, struct mm_struct *mm) | |||
101 | return ret; | 103 | return ret; |
102 | } | 104 | } |
103 | 105 | ||
104 | void uml_setup_stubs(struct mm_struct *mm) | 106 | void arch_dup_mmap(struct mm_struct *oldmm, struct mm_struct *mm) |
105 | { | 107 | { |
108 | struct page **pages; | ||
106 | int err, ret; | 109 | int err, ret; |
107 | 110 | ||
108 | if (!skas_needs_stub) | 111 | if (!skas_needs_stub) |
@@ -117,20 +120,29 @@ void uml_setup_stubs(struct mm_struct *mm) | |||
117 | if (ret) | 120 | if (ret) |
118 | goto out; | 121 | goto out; |
119 | 122 | ||
120 | mm->context.stub_pages[0] = virt_to_page(&__syscall_stub_start); | 123 | pages = kmalloc(2 * sizeof(struct page *), GFP_KERNEL); |
121 | mm->context.stub_pages[1] = virt_to_page(mm->context.id.stack); | 124 | if (pages == NULL) { |
125 | printk(KERN_ERR "arch_dup_mmap failed to allocate 2 page " | ||
126 | "pointers\n"); | ||
127 | goto out; | ||
128 | } | ||
129 | |||
130 | pages[0] = virt_to_page(&__syscall_stub_start); | ||
131 | pages[1] = virt_to_page(mm->context.id.stack); | ||
132 | mm->context.stub_pages = pages; | ||
122 | 133 | ||
123 | /* dup_mmap already holds mmap_sem */ | 134 | /* dup_mmap already holds mmap_sem */ |
124 | err = install_special_mapping(mm, STUB_START, STUB_END - STUB_START, | 135 | err = install_special_mapping(mm, STUB_START, STUB_END - STUB_START, |
125 | VM_READ | VM_MAYREAD | VM_EXEC | | 136 | VM_READ | VM_MAYREAD | VM_EXEC | |
126 | VM_MAYEXEC | VM_DONTCOPY, | 137 | VM_MAYEXEC | VM_DONTCOPY, pages); |
127 | mm->context.stub_pages); | ||
128 | if (err) { | 138 | if (err) { |
129 | printk(KERN_ERR "install_special_mapping returned %d\n", err); | 139 | printk(KERN_ERR "install_special_mapping returned %d\n", err); |
130 | goto out; | 140 | goto out_free; |
131 | } | 141 | } |
132 | return; | 142 | return; |
133 | 143 | ||
144 | out_free: | ||
145 | kfree(pages); | ||
134 | out: | 146 | out: |
135 | force_sigsegv(SIGSEGV, current); | 147 | force_sigsegv(SIGSEGV, current); |
136 | } | 148 | } |
@@ -139,6 +151,8 @@ void arch_exit_mmap(struct mm_struct *mm) | |||
139 | { | 151 | { |
140 | pte_t *pte; | 152 | pte_t *pte; |
141 | 153 | ||
154 | if (mm->context.stub_pages != NULL) | ||
155 | kfree(mm->context.stub_pages); | ||
142 | pte = virt_to_pte(mm, STUB_CODE); | 156 | pte = virt_to_pte(mm, STUB_CODE); |
143 | if (pte != NULL) | 157 | if (pte != NULL) |
144 | pte_clear(mm, STUB_CODE, pte); | 158 | pte_clear(mm, STUB_CODE, pte); |
diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c index 4da11b3c8dd..2e9852c0d48 100644 --- a/arch/um/kernel/skas/process.c +++ b/arch/um/kernel/skas/process.c | |||
@@ -3,12 +3,12 @@ | |||
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include <linux/init.h> | 6 | #include "linux/init.h" |
7 | #include <linux/sched.h> | 7 | #include "linux/sched.h" |
8 | #include <as-layout.h> | 8 | #include "as-layout.h" |
9 | #include <kern.h> | 9 | #include "kern.h" |
10 | #include <os.h> | 10 | #include "os.h" |
11 | #include <skas.h> | 11 | #include "skas.h" |
12 | 12 | ||
13 | int new_mm(unsigned long stack) | 13 | int new_mm(unsigned long stack) |
14 | { | 14 | { |
@@ -41,7 +41,7 @@ static int __init start_kernel_proc(void *unused) | |||
41 | cpu_tasks[0].pid = pid; | 41 | cpu_tasks[0].pid = pid; |
42 | cpu_tasks[0].task = current; | 42 | cpu_tasks[0].task = current; |
43 | #ifdef CONFIG_SMP | 43 | #ifdef CONFIG_SMP |
44 | init_cpu_online(get_cpu_mask(0)); | 44 | cpu_online_map = cpumask_of_cpu(0); |
45 | #endif | 45 | #endif |
46 | start_kernel(); | 46 | start_kernel(); |
47 | return 0; | 47 | return 0; |
diff --git a/arch/um/kernel/skas/syscall.c b/arch/um/kernel/skas/syscall.c index c0681e09743..f5173e1ec3a 100644 --- a/arch/um/kernel/skas/syscall.c +++ b/arch/um/kernel/skas/syscall.c | |||
@@ -3,11 +3,11 @@ | |||
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include <linux/kernel.h> | 6 | #include "linux/kernel.h" |
7 | #include <linux/ptrace.h> | 7 | #include "linux/ptrace.h" |
8 | #include <kern_util.h> | 8 | #include "kern_util.h" |
9 | #include <sysdep/ptrace.h> | 9 | #include "sysdep/ptrace.h" |
10 | #include <sysdep/syscalls.h> | 10 | #include "sysdep/syscalls.h" |
11 | 11 | ||
12 | extern int syscall_table_size; | 12 | extern int syscall_table_size; |
13 | #define NR_SYSCALLS (syscall_table_size / sizeof(void *)) | 13 | #define NR_SYSCALLS (syscall_table_size / sizeof(void *)) |
@@ -18,7 +18,7 @@ void handle_syscall(struct uml_pt_regs *r) | |||
18 | long result; | 18 | long result; |
19 | int syscall; | 19 | int syscall; |
20 | 20 | ||
21 | syscall_trace_enter(regs); | 21 | syscall_trace(r, 0); |
22 | 22 | ||
23 | /* | 23 | /* |
24 | * This should go in the declaration of syscall, but when I do that, | 24 | * This should go in the declaration of syscall, but when I do that, |
@@ -34,7 +34,7 @@ void handle_syscall(struct uml_pt_regs *r) | |||
34 | result = -ENOSYS; | 34 | result = -ENOSYS; |
35 | else result = EXECUTE_SYSCALL(syscall, regs); | 35 | else result = EXECUTE_SYSCALL(syscall, regs); |
36 | 36 | ||
37 | PT_REGS_SET_SYSCALL_RETURN(regs, result); | 37 | REGS_SET_SYSCALL_RETURN(r->gp, result); |
38 | 38 | ||
39 | syscall_trace_leave(regs); | 39 | syscall_trace(r, 1); |
40 | } | 40 | } |
diff --git a/arch/um/kernel/skas/uaccess.c b/arch/um/kernel/skas/uaccess.c index 1d3e0c17340..696634214dc 100644 --- a/arch/um/kernel/skas/uaccess.c +++ b/arch/um/kernel/skas/uaccess.c | |||
@@ -6,13 +6,12 @@ | |||
6 | #include <linux/err.h> | 6 | #include <linux/err.h> |
7 | #include <linux/highmem.h> | 7 | #include <linux/highmem.h> |
8 | #include <linux/mm.h> | 8 | #include <linux/mm.h> |
9 | #include <linux/module.h> | ||
10 | #include <linux/sched.h> | 9 | #include <linux/sched.h> |
11 | #include <asm/current.h> | 10 | #include <asm/current.h> |
12 | #include <asm/page.h> | 11 | #include <asm/page.h> |
13 | #include <asm/pgtable.h> | 12 | #include <asm/pgtable.h> |
14 | #include <kern_util.h> | 13 | #include "kern_util.h" |
15 | #include <os.h> | 14 | #include "os.h" |
16 | 15 | ||
17 | pte_t *virt_to_pte(struct mm_struct *mm, unsigned long addr) | 16 | pte_t *virt_to_pte(struct mm_struct *mm, unsigned long addr) |
18 | { | 17 | { |
@@ -69,7 +68,7 @@ static int do_op_one_page(unsigned long addr, int len, int is_write, | |||
69 | return -1; | 68 | return -1; |
70 | 69 | ||
71 | page = pte_page(*pte); | 70 | page = pte_page(*pte); |
72 | addr = (unsigned long) kmap_atomic(page) + | 71 | addr = (unsigned long) kmap_atomic(page, KM_UML_USERCOPY) + |
73 | (addr & ~PAGE_MASK); | 72 | (addr & ~PAGE_MASK); |
74 | 73 | ||
75 | current->thread.fault_catcher = &buf; | 74 | current->thread.fault_catcher = &buf; |
@@ -82,7 +81,7 @@ static int do_op_one_page(unsigned long addr, int len, int is_write, | |||
82 | 81 | ||
83 | current->thread.fault_catcher = NULL; | 82 | current->thread.fault_catcher = NULL; |
84 | 83 | ||
85 | kunmap_atomic((void *)addr); | 84 | kunmap_atomic((void *)addr, KM_UML_USERCOPY); |
86 | 85 | ||
87 | return n; | 86 | return n; |
88 | } | 87 | } |
@@ -150,7 +149,6 @@ int copy_from_user(void *to, const void __user *from, int n) | |||
150 | buffer_op((unsigned long) from, n, 0, copy_chunk_from_user, &to): | 149 | buffer_op((unsigned long) from, n, 0, copy_chunk_from_user, &to): |
151 | n; | 150 | n; |
152 | } | 151 | } |
153 | EXPORT_SYMBOL(copy_from_user); | ||
154 | 152 | ||
155 | static int copy_chunk_to_user(unsigned long to, int len, void *arg) | 153 | static int copy_chunk_to_user(unsigned long to, int len, void *arg) |
156 | { | 154 | { |
@@ -172,7 +170,6 @@ int copy_to_user(void __user *to, const void *from, int n) | |||
172 | buffer_op((unsigned long) to, n, 1, copy_chunk_to_user, &from) : | 170 | buffer_op((unsigned long) to, n, 1, copy_chunk_to_user, &from) : |
173 | n; | 171 | n; |
174 | } | 172 | } |
175 | EXPORT_SYMBOL(copy_to_user); | ||
176 | 173 | ||
177 | static int strncpy_chunk_from_user(unsigned long from, int len, void *arg) | 174 | static int strncpy_chunk_from_user(unsigned long from, int len, void *arg) |
178 | { | 175 | { |
@@ -207,7 +204,6 @@ int strncpy_from_user(char *dst, const char __user *src, int count) | |||
207 | return -EFAULT; | 204 | return -EFAULT; |
208 | return strnlen(dst, count); | 205 | return strnlen(dst, count); |
209 | } | 206 | } |
210 | EXPORT_SYMBOL(strncpy_from_user); | ||
211 | 207 | ||
212 | static int clear_chunk(unsigned long addr, int len, void *unused) | 208 | static int clear_chunk(unsigned long addr, int len, void *unused) |
213 | { | 209 | { |
@@ -230,7 +226,6 @@ int clear_user(void __user *mem, int len) | |||
230 | return access_ok(VERIFY_WRITE, mem, len) ? | 226 | return access_ok(VERIFY_WRITE, mem, len) ? |
231 | buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL) : len; | 227 | buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL) : len; |
232 | } | 228 | } |
233 | EXPORT_SYMBOL(clear_user); | ||
234 | 229 | ||
235 | static int strnlen_chunk(unsigned long str, int len, void *arg) | 230 | static int strnlen_chunk(unsigned long str, int len, void *arg) |
236 | { | 231 | { |
@@ -256,4 +251,3 @@ int strnlen_user(const void __user *str, int len) | |||
256 | return count + 1; | 251 | return count + 1; |
257 | return -EFAULT; | 252 | return -EFAULT; |
258 | } | 253 | } |
259 | EXPORT_SYMBOL(strnlen_user); | ||