aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/kernel
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-08-01 19:45:02 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-08-01 19:45:02 -0400
commit1871e845e564c4e17f561ec4e5e4bb6bb8578685 (patch)
treebcfb62936710321f48bee64153e05f313dc371d0 /arch/um/kernel
parenta6dc77254b3c3eb0307b372b77b861d5cd2ead08 (diff)
parentb070989aeb47ccdfe56d95e046bd317baa47f4fa (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.c2
-rw-r--r--arch/um/kernel/process.c13
-rw-r--r--arch/um/kernel/ptrace.c71
-rw-r--r--arch/um/kernel/skas/syscall.c6
-rw-r--r--arch/um/kernel/time.c2
-rw-r--r--arch/um/kernel/trap.c39
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
31extern void free_irqs(void); 31extern void free_irqs(void);
32 32
33void sigio_handler(int sig, struct uml_pt_regs *regs) 33void 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, &current->thread.exec_buf); 153 n = run_kernel_thread(fn, arg, &current->thread.exec_buf);
154 if (n == 1) { 154 if (n == 1)
155 /* Handle any immediate reschedules or signals */
156 interrupt_end();
157 userspace(&current->thread.regs.regs); 155 userspace(&current->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(&current->thread.regs.regs); 176 userspace(&current->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, &regs->regs, 189 memcpy(&p->thread.regs.regs, &regs->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 */
165void syscall_trace(struct uml_pt_regs *regs, int entryexit) 166void 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(&regs->regs),
169 170 UPT_SYSCALL_ARG1(&regs->regs),
170 if (!entryexit) 171 UPT_SYSCALL_ARG2(&regs->regs),
171 audit_syscall_entry(HOST_AUDIT_ARCH, 172 UPT_SYSCALL_ARG3(&regs->regs),
172 UPT_SYSCALL_NR(regs), 173 UPT_SYSCALL_ARG4(&regs->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 /* 181void 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, &regs->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
16void timer_handler(int sig, struct uml_pt_regs *regs) 16void 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
175void segv_handler(int sig, struct uml_pt_regs *regs) 175void 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
261void relay_signal(int sig, struct uml_pt_regs *regs) 261void 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
276void bus_handler(int sig, struct uml_pt_regs *regs) 300void 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
283void winch(int sig, struct uml_pt_regs *regs) 308void 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}