late_initcall(stdio_init);
-static void console_write(struct console *console, const char *string,
+static void uml_console_write(struct console *console, const char *string,
unsigned len)
{
struct line *line = &vts[console->index];
up(&line->sem);
}
-static struct tty_driver *um_console_device(struct console *c, int *index)
+static struct tty_driver *uml_console_device(struct console *c, int *index)
{
*index = c->index;
return console_driver;
}
-static int console_setup(struct console *co, char *options)
+static int uml_console_setup(struct console *co, char *options)
{
return(0);
}
static struct console stdiocons = {
name: "tty",
- write: console_write,
- device: um_console_device,
- setup: console_setup,
+ write: uml_console_write,
+ device: uml_console_device,
+ setup: uml_console_setup,
flags: CON_PRINTBUFFER,
index: -1,
};
" are 'xterm=gnome-terminal,-t,-x'.\n\n"
);
+/* XXX This badly needs some cleaning up in the error paths */
int xterm_open(int input, int output, int primary, void *d, char **dev_out)
{
struct xterm_chan *data = d;
return(arg.pid);
}
-void suspend_new_thread(int fd)
-{
- char c;
-
- os_stop_process(os_getpid());
-
- if(os_read_file(fd, &c, sizeof(c)) != sizeof(c))
- panic("read failed in suspend_new_thread");
-}
-
static int ptrace_child(void *arg)
{
int pid = os_getpid();
/* Protected by sigio_lock() called from write_sigio_workaround */
static int sigio_irq_fd = -1;
-irqreturn_t sigio_interrupt(int irq, void *data, struct pt_regs *unused)
+static irqreturn_t sigio_interrupt(int irq, void *data, struct pt_regs *unused)
{
read_sigio_fd(sigio_irq_fd);
reactivate_fd(sigio_irq_fd, SIGIO_WRITE_IRQ);
int write_sigio_irq(int fd)
{
- if(um_request_irq(SIGIO_WRITE_IRQ, fd, IRQ_READ, sigio_interrupt,
+ int err;
+
+ err = um_request_irq(SIGIO_WRITE_IRQ, fd, IRQ_READ, sigio_interrupt,
SA_INTERRUPT | SA_SAMPLE_RANDOM, "write sigio",
- NULL)){
- printk("write_sigio_irq : um_request_irq failed\n");
+ NULL);
+ if(err){
+ printk("write_sigio_irq : um_request_irq failed, err = %d\n",
+ err);
return(-1);
}
sigio_irq_fd = fd;
siglongjmp(initial_jmpbuf, 4);
}
-int new_mm(int from)
-{
- struct proc_mm_op copy;
- int n, fd = os_open_file("/proc/mm",
- of_cloexec(of_write(OPENFLAGS())), 0);
-
- if(fd < 0)
- return(fd);
-
- if(from != -1){
- copy = ((struct proc_mm_op) { .op = MM_COPY_SEGMENTS,
- .u =
- { .copy_segments = from } } );
- n = os_write_file(fd, ©, sizeof(copy));
- if(n != sizeof(copy))
- printk("new_mm : /proc/mm copy_segments failed, "
- "err = %d\n", -n);
- }
-
- return(fd);
-}
-
void switch_mm_skas(int mm_fd)
{
int err;
#include "frame.h"
#include "kern.h"
#include "mode.h"
+#include "proc_mm.h"
static atomic_t using_sysemu;
int sysemu_supported;
return(0);
}
+int new_mm(int from)
+{
+ struct proc_mm_op copy;
+ int n, fd;
+
+ fd = os_open_file("/proc/mm", of_cloexec(of_write(OPENFLAGS())), 0);
+ if(fd < 0)
+ return(fd);
+
+ if(from != -1){
+ copy = ((struct proc_mm_op) { .op = MM_COPY_SEGMENTS,
+ .u =
+ { .copy_segments = from } } );
+ n = os_write_file(fd, ©, sizeof(copy));
+ if(n != sizeof(copy))
+ printk("new_mm : /proc/mm copy_segments failed, "
+ "err = %d\n", -n);
+ }
+
+ return(fd);
+}
+
void init_idle_skas(void)
{
cpu_tasks[current_thread->cpu].pid = os_getpid();
os_close_file(current->thread.mode.tt.switch_pipe[1]);
}
+void suspend_new_thread(int fd)
+{
+ int err;
+ char c;
+
+ os_stop_process(os_getpid());
+ err = os_read_file(fd, &c, sizeof(c));
+ if(err != sizeof(c))
+ panic("read failed in suspend_new_thread, err = %d", -err);
+}
+
void schedule_tail(task_t *prev);
static void new_thread_handler(int sig)
local_irq_enable();
if(!run_kernel_thread(fn, arg, ¤t->thread.exec_buf))
do_exit(0);
+
+ /* XXX No set_user_mode here because a newly execed process will
+ * immediately segfault on its non-existent IP, coming straight back
+ * to the signal handler, which will call set_user_mode on its way
+ * out. This should probably change since it's confusing.
+ */
}
static int new_thread_proc(void *stack)
continue;
}
tracing = 0;
- if(do_syscall(task, pid)) sig = SIGUSR2;
+ if(do_syscall(task, pid))
+ sig = SIGUSR2;
else clear_singlestep(task);
break;
case SIGPROF:
}
if(strlen(name) > UMID_LEN - 1)
- (*printer)("Unique machine name is being truncated to %s "
+ (*printer)("Unique machine name is being truncated to %d "
"characters\n", UMID_LEN);
strlcpy(umid, name, sizeof(umid));
static int __init set_uml_dir(char *name, int *add)
{
if((strlen(name) > 0) && (name[strlen(name) - 1] != '/')){
- uml_dir = malloc(strlen(name) + 1);
+ uml_dir = malloc(strlen(name) + 2);
if(uml_dir == NULL){
printf("Failed to malloc uml_dir - error = %d\n",
errno);
uml_dir = name;
+ /* Return 0 here because do_initcalls doesn't look at
+ * the return value.
+ */
return(0);
}
sprintf(uml_dir, "%s/", name);
}
else uml_dir = name;
- return 0;
+ return(0);
}
static int __init make_uml_dir(void)
errno);
}
else if(WIFEXITED(status))
- printk("process exited with status %d\n",
- WEXITSTATUS(status));
+ printk("process %d exited with status %d\n",
+ pid, WEXITSTATUS(status));
else if(WIFSIGNALED(status))
- printk("process exited with signal %d\n",
- WTERMSIG(status));
+ printk("process %d exited with signal %d\n",
+ pid, WTERMSIG(status));
else if((WSTOPSIG(status) == SIGVTALRM) ||
(WSTOPSIG(status) == SIGALRM) ||
(WSTOPSIG(status) == SIGIO) ||
ptrace(cont_type, pid, 0, WSTOPSIG(status));
continue;
}
- else printk("process stopped with signal %d\n",
- WSTOPSIG(status));
+ else printk("process %d stopped with signal %d\n",
+ pid, WSTOPSIG(status));
panic("wait_for_stop failed to wait for %d to stop "
"with %d\n", pid, sig);
}
if((fcntl(master, F_SETFL, flags | O_NONBLOCK | O_ASYNC) < 0) ||
(fcntl(master, F_SETOWN, os_getpid()) < 0)){
- printk("fcntl F_SETFL or F_SETOWN failed, errno = %d\n", errno);
+ printk("fcntl F_SETFL or F_SETOWN failed, errno = %d\n",
+ errno);
return(-errno);
}
}
os_close_file(fd);
pc = ARBITRARY_ADDR;
- if(sscanf(buf, "%*d " COMM_SCANF " %*c %*d %*d %*d %*d %*d %*d %*d %*d "
+ if(sscanf(buf, "%*d " COMM_SCANF " %*c %*d %*d %*d %*d %*d %*d %*d "
"%*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d "
- "%*d %*d %*d %*d %lu", &pc) != 1){
+ "%*d %*d %*d %*d %*d %lu", &pc) != 1){
printk("os_process_pc - couldn't find pc in '%s'\n", buf);
}
return(pc);
if(ptrace(PTRACE_POKEUSER, pid, &dummy->u_debugreg[i],
regs[i]) < 0)
printk("write_debugregs - ptrace failed on "
- "register %d, errno = %d\n", errno);
+ "register %d, value = 0x%x, errno = %d\n", i,
+ regs[i], errno);
}
}