aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/um/drivers/mconsole_kern.c52
-rw-r--r--arch/um/drivers/mconsole_user.c1
-rw-r--r--arch/um/include/mconsole.h1
-rw-r--r--arch/um/kernel/process_kern.c9
-rw-r--r--include/asm-um/processor-generic.h1
5 files changed, 63 insertions, 1 deletions
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
index c190c2414197..12c95368124a 100644
--- a/arch/um/drivers/mconsole_kern.c
+++ b/arch/um/drivers/mconsole_kern.c
@@ -32,6 +32,7 @@
32#include "os.h" 32#include "os.h"
33#include "umid.h" 33#include "umid.h"
34#include "irq_kern.h" 34#include "irq_kern.h"
35#include "choose-mode.h"
35 36
36static int do_unlink_socket(struct notifier_block *notifier, 37static int do_unlink_socket(struct notifier_block *notifier,
37 unsigned long what, void *data) 38 unsigned long what, void *data)
@@ -276,6 +277,7 @@ void mconsole_proc(struct mc_request *req)
276 go - continue the UML after a 'stop' \n\ 277 go - continue the UML after a 'stop' \n\
277 log <string> - make UML enter <string> into the kernel log\n\ 278 log <string> - make UML enter <string> into the kernel log\n\
278 proc <file> - returns the contents of the UML's /proc/<file>\n\ 279 proc <file> - returns the contents of the UML's /proc/<file>\n\
280 stack <pid> - returns the stack of the specified pid\n\
279" 281"
280 282
281void mconsole_help(struct mc_request *req) 283void mconsole_help(struct mc_request *req)
@@ -479,6 +481,56 @@ void mconsole_sysrq(struct mc_request *req)
479} 481}
480#endif 482#endif
481 483
484/* Mconsole stack trace
485 * Added by Allan Graves, Jeff Dike
486 * Dumps a stacks registers to the linux console.
487 * Usage stack <pid>.
488 */
489void do_stack(struct mc_request *req)
490{
491 char *ptr = req->request.data;
492 int pid_requested= -1;
493 struct task_struct *from = NULL;
494 struct task_struct *to = NULL;
495
496 /* Would be nice:
497 * 1) Send showregs output to mconsole.
498 * 2) Add a way to stack dump all pids.
499 */
500
501 ptr += strlen("stack");
502 while(isspace(*ptr)) ptr++;
503
504 /* Should really check for multiple pids or reject bad args here */
505 /* What do the arguments in mconsole_reply mean? */
506 if(sscanf(ptr, "%d", &pid_requested) == 0){
507 mconsole_reply(req, "Please specify a pid", 1, 0);
508 return;
509 }
510
511 from = current;
512 to = find_task_by_pid(pid_requested);
513
514 if((to == NULL) || (pid_requested == 0)) {
515 mconsole_reply(req, "Couldn't find that pid", 1, 0);
516 return;
517 }
518 to->thread.saved_task = current;
519
520 switch_to(from, to, from);
521 mconsole_reply(req, "Stack Dumped to console and message log", 0, 0);
522}
523
524void mconsole_stack(struct mc_request *req)
525{
526 /* This command doesn't work in TT mode, so let's check and then
527 * get out of here
528 */
529 CHOOSE_MODE(mconsole_reply(req, "Sorry, this doesn't work in TT mode",
530 1, 0),
531 do_stack(req));
532}
533
482/* Changed by mconsole_setup, which is __setup, and called before SMP is 534/* Changed by mconsole_setup, which is __setup, and called before SMP is
483 * active. 535 * active.
484 */ 536 */
diff --git a/arch/um/drivers/mconsole_user.c b/arch/um/drivers/mconsole_user.c
index fe5afb13252c..a5b8aeade1c5 100644
--- a/arch/um/drivers/mconsole_user.c
+++ b/arch/um/drivers/mconsole_user.c
@@ -30,6 +30,7 @@ static struct mconsole_command commands[] = {
30 { "go", mconsole_go, MCONSOLE_INTR }, 30 { "go", mconsole_go, MCONSOLE_INTR },
31 { "log", mconsole_log, MCONSOLE_INTR }, 31 { "log", mconsole_log, MCONSOLE_INTR },
32 { "proc", mconsole_proc, MCONSOLE_PROC }, 32 { "proc", mconsole_proc, MCONSOLE_PROC },
33 { "stack", mconsole_stack, MCONSOLE_INTR },
33}; 34};
34 35
35/* Initialized in mconsole_init, which is an initcall */ 36/* Initialized in mconsole_init, which is an initcall */
diff --git a/arch/um/include/mconsole.h b/arch/um/include/mconsole.h
index cfa368e045a5..b1b512f47035 100644
--- a/arch/um/include/mconsole.h
+++ b/arch/um/include/mconsole.h
@@ -81,6 +81,7 @@ extern void mconsole_stop(struct mc_request *req);
81extern void mconsole_go(struct mc_request *req); 81extern void mconsole_go(struct mc_request *req);
82extern void mconsole_log(struct mc_request *req); 82extern void mconsole_log(struct mc_request *req);
83extern void mconsole_proc(struct mc_request *req); 83extern void mconsole_proc(struct mc_request *req);
84extern void mconsole_stack(struct mc_request *req);
84 85
85extern int mconsole_get_request(int fd, struct mc_request *req); 86extern int mconsole_get_request(int fd, struct mc_request *req);
86extern int mconsole_notify(char *sock_name, int type, const void *data, 87extern int mconsole_notify(char *sock_name, int type, const void *data,
diff --git a/arch/um/kernel/process_kern.c b/arch/um/kernel/process_kern.c
index 1143f5e522b2..39cf568ccfaf 100644
--- a/arch/um/kernel/process_kern.c
+++ b/arch/um/kernel/process_kern.c
@@ -119,7 +119,14 @@ void *_switch_to(void *prev, void *next, void *last)
119 to->thread.prev_sched = from; 119 to->thread.prev_sched = from;
120 set_current(to); 120 set_current(to);
121 121
122 CHOOSE_MODE_PROC(switch_to_tt, switch_to_skas, prev, next); 122 do {
123 current->thread.saved_task = NULL ;
124 CHOOSE_MODE_PROC(switch_to_tt, switch_to_skas, prev, next);
125 if(current->thread.saved_task)
126 show_regs(&(current->thread.regs));
127 next= current->thread.saved_task;
128 prev= current;
129 } while(current->thread.saved_task);
123 130
124 return(current->thread.prev_sched); 131 return(current->thread.prev_sched);
125 132
diff --git a/include/asm-um/processor-generic.h b/include/asm-um/processor-generic.h
index b2fc94fbc2d9..2d242360c3d6 100644
--- a/include/asm-um/processor-generic.h
+++ b/include/asm-um/processor-generic.h
@@ -21,6 +21,7 @@ struct thread_struct {
21 * copy_thread) to mark that we are begin called from userspace (fork / 21 * copy_thread) to mark that we are begin called from userspace (fork /
22 * vfork / clone), and reset to 0 after. It is left to 0 when called 22 * vfork / clone), and reset to 0 after. It is left to 0 when called
23 * from kernelspace (i.e. kernel_thread() or fork_idle(), as of 2.6.11). */ 23 * from kernelspace (i.e. kernel_thread() or fork_idle(), as of 2.6.11). */
24 struct task_struct *saved_task;
24 int forking; 25 int forking;
25 int nsyscalls; 26 int nsyscalls;
26 struct pt_regs regs; 27 struct pt_regs regs;