diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-08-01 19:45:02 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-08-01 19:45:02 -0400 |
commit | 1871e845e564c4e17f561ec4e5e4bb6bb8578685 (patch) | |
tree | bcfb62936710321f48bee64153e05f313dc371d0 /arch/um/kernel | |
parent | a6dc77254b3c3eb0307b372b77b861d5cd2ead08 (diff) | |
parent | b070989aeb47ccdfe56d95e046bd317baa47f4fa (diff) |
Merge branch 'for-linus-3.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/uml
Pull UML fixes from Richard Weinberger:
"This patch set contains mostly fixes and cleanups. The UML tty driver
uses now tty_port and is no longer broken like hell :-)"
* 'for-linus-3.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/uml:
um: Add arch/x86/um to MAINTAINERS
um: pass siginfo to guest process
um: fix ubd_file_size for read-only files
um: pull interrupt_end() into userspace()
um: split syscall_trace(), pass pt_regs to it
um: switch UPT_SET_RETURN_VALUE and regs_return_value to pt_regs
um: set BLK_CGROUP=y in defconfig
um: remove count_lock
um: fully use tty_port
um: Remove dead code
um: remove line_ioctl()
TTY: um/line, use tty from tty_port
TTY: um/line, add tty_port
Diffstat (limited to 'arch/um/kernel')
-rw-r--r-- | arch/um/kernel/irq.c | 2 | ||||
-rw-r--r-- | arch/um/kernel/process.c | 13 | ||||
-rw-r--r-- | arch/um/kernel/ptrace.c | 71 | ||||
-rw-r--r-- | arch/um/kernel/skas/syscall.c | 6 | ||||
-rw-r--r-- | arch/um/kernel/time.c | 2 | ||||
-rw-r--r-- | arch/um/kernel/trap.c | 39 |
6 files changed, 71 insertions, 62 deletions
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c index 00506c3d5d6e..9883026f0730 100644 --- a/arch/um/kernel/irq.c +++ b/arch/um/kernel/irq.c | |||
@@ -30,7 +30,7 @@ static struct irq_fd **last_irq_ptr = &active_fds; | |||
30 | 30 | ||
31 | extern void free_irqs(void); | 31 | extern void free_irqs(void); |
32 | 32 | ||
33 | void sigio_handler(int sig, struct uml_pt_regs *regs) | 33 | void sigio_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs) |
34 | { | 34 | { |
35 | struct irq_fd *irq_fd; | 35 | struct irq_fd *irq_fd; |
36 | int n; | 36 | int n; |
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index ccb9a9d283f1..57fc7028714a 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c | |||
@@ -151,12 +151,10 @@ void new_thread_handler(void) | |||
151 | * 0 if it just exits | 151 | * 0 if it just exits |
152 | */ | 152 | */ |
153 | n = run_kernel_thread(fn, arg, ¤t->thread.exec_buf); | 153 | n = run_kernel_thread(fn, arg, ¤t->thread.exec_buf); |
154 | if (n == 1) { | 154 | if (n == 1) |
155 | /* Handle any immediate reschedules or signals */ | ||
156 | interrupt_end(); | ||
157 | userspace(¤t->thread.regs.regs); | 155 | userspace(¤t->thread.regs.regs); |
158 | } | 156 | else |
159 | else do_exit(0); | 157 | do_exit(0); |
160 | } | 158 | } |
161 | 159 | ||
162 | /* Called magically, see new_thread_handler above */ | 160 | /* Called magically, see new_thread_handler above */ |
@@ -175,9 +173,6 @@ void fork_handler(void) | |||
175 | 173 | ||
176 | current->thread.prev_sched = NULL; | 174 | current->thread.prev_sched = NULL; |
177 | 175 | ||
178 | /* Handle any immediate reschedules or signals */ | ||
179 | interrupt_end(); | ||
180 | |||
181 | userspace(¤t->thread.regs.regs); | 176 | userspace(¤t->thread.regs.regs); |
182 | } | 177 | } |
183 | 178 | ||
@@ -193,7 +188,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, | |||
193 | if (current->thread.forking) { | 188 | if (current->thread.forking) { |
194 | memcpy(&p->thread.regs.regs, ®s->regs, | 189 | memcpy(&p->thread.regs.regs, ®s->regs, |
195 | sizeof(p->thread.regs.regs)); | 190 | sizeof(p->thread.regs.regs)); |
196 | UPT_SET_SYSCALL_RETURN(&p->thread.regs.regs, 0); | 191 | PT_REGS_SET_SYSCALL_RETURN(&p->thread.regs, 0); |
197 | if (sp != 0) | 192 | if (sp != 0) |
198 | REGS_SP(p->thread.regs.regs.gp) = sp; | 193 | REGS_SP(p->thread.regs.regs.gp) = sp; |
199 | 194 | ||
diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c index 06b190390505..694d551c8899 100644 --- a/arch/um/kernel/ptrace.c +++ b/arch/um/kernel/ptrace.c | |||
@@ -3,11 +3,12 @@ | |||
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include "linux/audit.h" | 6 | #include <linux/audit.h> |
7 | #include "linux/ptrace.h" | 7 | #include <linux/ptrace.h> |
8 | #include "linux/sched.h" | 8 | #include <linux/sched.h> |
9 | #include "asm/uaccess.h" | 9 | #include <linux/tracehook.h> |
10 | #include "skas_ptrace.h" | 10 | #include <asm/uaccess.h> |
11 | #include <skas_ptrace.h> | ||
11 | 12 | ||
12 | 13 | ||
13 | 14 | ||
@@ -162,48 +163,36 @@ static void send_sigtrap(struct task_struct *tsk, struct uml_pt_regs *regs, | |||
162 | * XXX Check PT_DTRACE vs TIF_SINGLESTEP for singlestepping check and | 163 | * XXX Check PT_DTRACE vs TIF_SINGLESTEP for singlestepping check and |
163 | * PT_PTRACED vs TIF_SYSCALL_TRACE for syscall tracing check | 164 | * PT_PTRACED vs TIF_SYSCALL_TRACE for syscall tracing check |
164 | */ | 165 | */ |
165 | void syscall_trace(struct uml_pt_regs *regs, int entryexit) | 166 | void syscall_trace_enter(struct pt_regs *regs) |
166 | { | 167 | { |
167 | int is_singlestep = (current->ptrace & PT_DTRACE) && entryexit; | 168 | audit_syscall_entry(HOST_AUDIT_ARCH, |
168 | int tracesysgood; | 169 | UPT_SYSCALL_NR(®s->regs), |
169 | 170 | UPT_SYSCALL_ARG1(®s->regs), | |
170 | if (!entryexit) | 171 | UPT_SYSCALL_ARG2(®s->regs), |
171 | audit_syscall_entry(HOST_AUDIT_ARCH, | 172 | UPT_SYSCALL_ARG3(®s->regs), |
172 | UPT_SYSCALL_NR(regs), | 173 | UPT_SYSCALL_ARG4(®s->regs)); |
173 | UPT_SYSCALL_ARG1(regs), | ||
174 | UPT_SYSCALL_ARG2(regs), | ||
175 | UPT_SYSCALL_ARG3(regs), | ||
176 | UPT_SYSCALL_ARG4(regs)); | ||
177 | else | ||
178 | audit_syscall_exit(regs); | ||
179 | |||
180 | /* Fake a debug trap */ | ||
181 | if (is_singlestep) | ||
182 | send_sigtrap(current, regs, 0); | ||
183 | 174 | ||
184 | if (!test_thread_flag(TIF_SYSCALL_TRACE)) | 175 | if (!test_thread_flag(TIF_SYSCALL_TRACE)) |
185 | return; | 176 | return; |
186 | 177 | ||
187 | if (!(current->ptrace & PT_PTRACED)) | 178 | tracehook_report_syscall_entry(regs); |
188 | return; | 179 | } |
189 | 180 | ||
190 | /* | 181 | void syscall_trace_leave(struct pt_regs *regs) |
191 | * the 0x80 provides a way for the tracing parent to distinguish | 182 | { |
192 | * between a syscall stop and SIGTRAP delivery | 183 | int ptraced = current->ptrace; |
193 | */ | ||
194 | tracesysgood = (current->ptrace & PT_TRACESYSGOOD); | ||
195 | ptrace_notify(SIGTRAP | (tracesysgood ? 0x80 : 0)); | ||
196 | 184 | ||
197 | if (entryexit) /* force do_signal() --> is_syscall() */ | 185 | audit_syscall_exit(regs); |
198 | set_thread_flag(TIF_SIGPENDING); | ||
199 | 186 | ||
200 | /* | 187 | /* Fake a debug trap */ |
201 | * this isn't the same as continuing with a signal, but it will do | 188 | if (ptraced & PT_DTRACE) |
202 | * for normal use. strace only continues with a signal if the | 189 | send_sigtrap(current, ®s->regs, 0); |
203 | * stopping signal is not SIGTRAP. -brl | 190 | |
204 | */ | 191 | if (!test_thread_flag(TIF_SYSCALL_TRACE)) |
205 | if (current->exit_code) { | 192 | return; |
206 | send_sig(current->exit_code, current, 1); | 193 | |
207 | current->exit_code = 0; | 194 | tracehook_report_syscall_exit(regs, 0); |
208 | } | 195 | /* force do_signal() --> is_syscall() */ |
196 | if (ptraced & PT_PTRACED) | ||
197 | set_thread_flag(TIF_SIGPENDING); | ||
209 | } | 198 | } |
diff --git a/arch/um/kernel/skas/syscall.c b/arch/um/kernel/skas/syscall.c index 05fbeb480e0b..86368a025a96 100644 --- a/arch/um/kernel/skas/syscall.c +++ b/arch/um/kernel/skas/syscall.c | |||
@@ -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(r, 0); | 21 | syscall_trace_enter(regs); |
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 | UPT_SET_SYSCALL_RETURN(r, result); | 37 | PT_REGS_SET_SYSCALL_RETURN(regs, result); |
38 | 38 | ||
39 | syscall_trace(r, 1); | 39 | syscall_trace_leave(regs); |
40 | } | 40 | } |
diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c index d1a23fb3190d..5f76d4ba151c 100644 --- a/arch/um/kernel/time.c +++ b/arch/um/kernel/time.c | |||
@@ -13,7 +13,7 @@ | |||
13 | #include "kern_util.h" | 13 | #include "kern_util.h" |
14 | #include "os.h" | 14 | #include "os.h" |
15 | 15 | ||
16 | void timer_handler(int sig, struct uml_pt_regs *regs) | 16 | void timer_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs) |
17 | { | 17 | { |
18 | unsigned long flags; | 18 | unsigned long flags; |
19 | 19 | ||
diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c index 3be60765c0e2..0353b98ae35a 100644 --- a/arch/um/kernel/trap.c +++ b/arch/um/kernel/trap.c | |||
@@ -172,7 +172,7 @@ void fatal_sigsegv(void) | |||
172 | os_dump_core(); | 172 | os_dump_core(); |
173 | } | 173 | } |
174 | 174 | ||
175 | void segv_handler(int sig, struct uml_pt_regs *regs) | 175 | void segv_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs) |
176 | { | 176 | { |
177 | struct faultinfo * fi = UPT_FAULTINFO(regs); | 177 | struct faultinfo * fi = UPT_FAULTINFO(regs); |
178 | 178 | ||
@@ -258,8 +258,11 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, | |||
258 | return 0; | 258 | return 0; |
259 | } | 259 | } |
260 | 260 | ||
261 | void relay_signal(int sig, struct uml_pt_regs *regs) | 261 | void relay_signal(int sig, struct siginfo *si, struct uml_pt_regs *regs) |
262 | { | 262 | { |
263 | struct faultinfo *fi; | ||
264 | struct siginfo clean_si; | ||
265 | |||
263 | if (!UPT_IS_USER(regs)) { | 266 | if (!UPT_IS_USER(regs)) { |
264 | if (sig == SIGBUS) | 267 | if (sig == SIGBUS) |
265 | printk(KERN_ERR "Bus error - the host /dev/shm or /tmp " | 268 | printk(KERN_ERR "Bus error - the host /dev/shm or /tmp " |
@@ -269,18 +272,40 @@ void relay_signal(int sig, struct uml_pt_regs *regs) | |||
269 | 272 | ||
270 | arch_examine_signal(sig, regs); | 273 | arch_examine_signal(sig, regs); |
271 | 274 | ||
272 | current->thread.arch.faultinfo = *UPT_FAULTINFO(regs); | 275 | memset(&clean_si, 0, sizeof(clean_si)); |
273 | force_sig(sig, current); | 276 | clean_si.si_signo = si->si_signo; |
277 | clean_si.si_errno = si->si_errno; | ||
278 | clean_si.si_code = si->si_code; | ||
279 | switch (sig) { | ||
280 | case SIGILL: | ||
281 | case SIGFPE: | ||
282 | case SIGSEGV: | ||
283 | case SIGBUS: | ||
284 | case SIGTRAP: | ||
285 | fi = UPT_FAULTINFO(regs); | ||
286 | clean_si.si_addr = (void __user *) FAULT_ADDRESS(*fi); | ||
287 | current->thread.arch.faultinfo = *fi; | ||
288 | #ifdef __ARCH_SI_TRAPNO | ||
289 | clean_si.si_trapno = si->si_trapno; | ||
290 | #endif | ||
291 | break; | ||
292 | default: | ||
293 | printk(KERN_ERR "Attempted to relay unknown signal %d (si_code = %d)\n", | ||
294 | sig, si->si_code); | ||
295 | } | ||
296 | |||
297 | force_sig_info(sig, &clean_si, current); | ||
274 | } | 298 | } |
275 | 299 | ||
276 | void bus_handler(int sig, struct uml_pt_regs *regs) | 300 | void bus_handler(int sig, struct siginfo *si, struct uml_pt_regs *regs) |
277 | { | 301 | { |
278 | if (current->thread.fault_catcher != NULL) | 302 | if (current->thread.fault_catcher != NULL) |
279 | UML_LONGJMP(current->thread.fault_catcher, 1); | 303 | UML_LONGJMP(current->thread.fault_catcher, 1); |
280 | else relay_signal(sig, regs); | 304 | else |
305 | relay_signal(sig, si, regs); | ||
281 | } | 306 | } |
282 | 307 | ||
283 | void winch(int sig, struct uml_pt_regs *regs) | 308 | void winch(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs) |
284 | { | 309 | { |
285 | do_IRQ(WINCH_IRQ, regs); | 310 | do_IRQ(WINCH_IRQ, regs); |
286 | } | 311 | } |