[PATCH] uml: mconsole fixes
authorAl Viro <viro@ftp.linux.org.uk>
Tue, 24 Oct 2006 10:15:29 +0000 (11:15 +0100)
committerLinus Torvalds <torvalds@g5.osdl.org>
Wed, 25 Oct 2006 05:01:10 +0000 (22:01 -0700)
 * when we have stop/sysrq/go, we get pt_regs of whatever executes
   mc_work_proc().  Would be better to see what we had at the time of
   interrupt that got us stop.

 * stop/stop/stop.....  will give stack overflow.  Shouldn't allow stop
   from mconsole_stop().

 * stop/stop/go leaves us inside mconsole_stop() with
os_set_fd_block(req->originating_fd, 0);
reactivate_fd(req->originating_fd, MCONSOLE_IRQ);
   just done by nested mconsole_stop().  Ditto.

 * once we'd seen stop, there's a period when INTR commands are executed
   out of order (as they should; we might have the things stuck badly
   enough to never reach mconsole_stop(), but still not badly enough to
   block mconsole_interrupt(); in that situation we _want_ things like
   "cad" to be executed immediately).  Once we enter monsole_stop(), all
   INTR commands will be executed in order, mixed with PROC ones.  We'd
   better let user see that such change of behaviour has happened.
   (Suggested by lennert).

 * stack footprint of monsole_interrupt() is an atrocity; AFAICS we can
   safely make struct mc_request req; static in function there.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Acked-by: Jeff Dike <jdike@addtoit.com>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
arch/um/drivers/mconsole_kern.c
arch/um/drivers/mconsole_user.c
arch/um/include/mconsole.h

index d08bd036ccb84268aaab9ad386849ab28b5ffc53..7b172160fe0415375d3e5bc1bbbcb00c6ed71105 100644 (file)
@@ -79,7 +79,7 @@ static irqreturn_t mconsole_interrupt(int irq, void *dev_id)
        /* long to avoid size mismatch warnings from gcc */
        long fd;
        struct mconsole_entry *new;
-       struct mc_request req;
+       static struct mc_request req;   /* that's OK */
 
        fd = (long) dev_id;
        while (mconsole_get_request(fd, &req)){
@@ -91,6 +91,7 @@ static irqreturn_t mconsole_interrupt(int irq, void *dev_id)
                                mconsole_reply(&req, "Out of memory", 1, 0);
                        else {
                                new->request = req;
+                               new->request.regs = get_irq_regs()->regs;
                                list_add(&new->list, &mc_requests);
                        }
                }
@@ -314,9 +315,21 @@ void mconsole_stop(struct mc_request *req)
 {
        deactivate_fd(req->originating_fd, MCONSOLE_IRQ);
        os_set_fd_block(req->originating_fd, 1);
-       mconsole_reply(req, "", 0, 0);
-       while(mconsole_get_request(req->originating_fd, req)){
-               if(req->cmd->handler == mconsole_go) break;
+       mconsole_reply(req, "stopped", 0, 0);
+       while (mconsole_get_request(req->originating_fd, req)) {
+               if (req->cmd->handler == mconsole_go)
+                       break;
+               if (req->cmd->handler == mconsole_stop) {
+                       mconsole_reply(req, "Already stopped", 1, 0);
+                       continue;
+               }
+               if (req->cmd->handler == mconsole_sysrq) {
+                       struct pt_regs *old_regs;
+                       old_regs = set_irq_regs((struct pt_regs *)&req->regs);
+                       mconsole_sysrq(req);
+                       set_irq_regs(old_regs);
+                       continue;
+               }
                (*req->cmd->handler)(req);
        }
        os_set_fd_block(req->originating_fd, 0);
@@ -673,9 +686,7 @@ static void with_console(struct mc_request *req, void (*proc)(void *),
 static void sysrq_proc(void *arg)
 {
        char *op = arg;
-       struct pt_regs *old_regs = set_irq_regs(&current->thread.regs);
        handle_sysrq(*op, NULL);
-       set_irq_regs(old_regs);
 }
 
 void mconsole_sysrq(struct mc_request *req)
index 17068eb746c0bda5204a8ffd49ee0ab5de16c46a..75aef6f7ef6e22dd9669f55f707021cd4f539d10 100644 (file)
@@ -14,6 +14,7 @@
 #include <sys/un.h>
 #include <unistd.h>
 #include "user.h"
+#include "sysdep/ptrace.h"
 #include "mconsole.h"
 #include "umid.h"
 #include "user_util.h"
index 58f67d3911052de522e01fb053edf2cbedd33549..2666815b6af57130cce633c759f0e8d86ebf9d12 100644 (file)
@@ -61,6 +61,7 @@ struct mc_request
 
        struct mconsole_request request;
        struct mconsole_command *cmd;
+       union uml_pt_regs regs;
 };
 
 extern char mconsole_socket_name[];