Commit ba180fd4 authored by Jeff Dike's avatar Jeff Dike Committed by Linus Torvalds

uml: style fixes pass 3

Formatting changes in the files which have been changed in the course
of folding foo_skas functions into their callers.  These include:
	copyright updates
	header file trimming
	style fixes
	adding severity to printks

These changes should be entirely non-functional.
Signed-off-by: default avatarJeff Dike <jdike@linux.intel.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 77bf4400
/* /*
* Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL * Licensed under the GPL
*/ */
#ifndef __IRQ_USER_H__ #ifndef __IRQ_USER_H__
#define __IRQ_USER_H__ #define __IRQ_USER_H__
#include "uml-config.h" #include "sysdep/ptrace.h"
struct irq_fd { struct irq_fd {
struct irq_fd *next; struct irq_fd *next;
......
/* /*
* Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL * Licensed under the GPL
*/ */
...@@ -8,7 +8,6 @@ ...@@ -8,7 +8,6 @@
#include "sysdep/ptrace.h" #include "sysdep/ptrace.h"
#include "sysdep/faultinfo.h" #include "sysdep/faultinfo.h"
#include "uml-config.h"
typedef void (*kern_hndl)(int, struct uml_pt_regs *); typedef void (*kern_hndl)(int, struct uml_pt_regs *);
......
/* /*
* Copyright (C) 2002 Jeff Dike (jdike@karaya.com) * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL * Licensed under the GPL
*/ */
#ifndef __OS_H__ #ifndef __OS_H__
#define __OS_H__ #define __OS_H__
#include "uml-config.h" #include <stdarg.h>
#include "asm/types.h"
#include "../os/include/file.h"
#include "sysdep/ptrace.h"
#include "kern_util.h"
#include "skas/mm_id.h"
#include "irq_user.h" #include "irq_user.h"
#include "kern_util.h"
#include "longjmp.h"
#include "mm_id.h"
#include "sysdep/tls.h" #include "sysdep/tls.h"
#include "sysdep/archsetjmp.h" #include "../os/include/file.h"
#define CATCH_EINTR(expr) while ((errno = 0, ((expr) < 0)) && (errno == EINTR)) #define CATCH_EINTR(expr) while ((errno = 0, ((expr) < 0)) && (errno == EINTR))
...@@ -140,7 +138,7 @@ extern int os_set_slip(int fd); ...@@ -140,7 +138,7 @@ extern int os_set_slip(int fd);
extern int os_set_owner(int fd, int pid); extern int os_set_owner(int fd, int pid);
extern int os_mode_fd(int fd, int mode); extern int os_mode_fd(int fd, int mode);
extern int os_seek_file(int fd, __u64 offset); extern int os_seek_file(int fd, unsigned long long offset);
extern int os_open_file(char *file, struct openflags flags, int mode); extern int os_open_file(char *file, struct openflags flags, int mode);
extern int os_read_file(int fd, void *buf, int len); extern int os_read_file(int fd, void *buf, int len);
extern int os_write_file(int fd, const void *buf, int count); extern int os_write_file(int fd, const void *buf, int count);
......
/* /*
* Copyright (C) 2002 Jeff Dike (jdike@karaya.com) * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL * Licensed under the GPL
*/ */
#ifndef __SKAS_H #ifndef __SKAS_H
#define __SKAS_H #define __SKAS_H
#include "mm_id.h"
#include "sysdep/ptrace.h" #include "sysdep/ptrace.h"
extern int userspace_pid[]; extern int userspace_pid[];
......
...@@ -97,12 +97,12 @@ struct syscall_args { ...@@ -97,12 +97,12 @@ struct syscall_args {
}; };
#define SYSCALL_ARGS(r) ((struct syscall_args) \ #define SYSCALL_ARGS(r) ((struct syscall_args) \
{ .args = { UPT_SYSCALL_ARG1(r), \ { .args = { UPT_SYSCALL_ARG1(r), \
UPT_SYSCALL_ARG2(r), \ UPT_SYSCALL_ARG2(r), \
UPT_SYSCALL_ARG3(r), \ UPT_SYSCALL_ARG3(r), \
UPT_SYSCALL_ARG4(r), \ UPT_SYSCALL_ARG4(r), \
UPT_SYSCALL_ARG5(r), \ UPT_SYSCALL_ARG5(r), \
UPT_SYSCALL_ARG6(r) } } ) UPT_SYSCALL_ARG6(r) } } )
#define UPT_REG(regs, reg) \ #define UPT_REG(regs, reg) \
({ unsigned long val; \ ({ unsigned long val; \
......
/* /*
* Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com) * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL * Licensed under the GPL
*/ */
#include "linux/slab.h" #include "linux/stddef.h"
#include "linux/fs.h"
#include "linux/smp_lock.h" #include "linux/smp_lock.h"
#include "linux/ptrace.h" #include "linux/ptrace.h"
#include "linux/fs.h" #include "linux/sched.h"
#include "asm/ptrace.h" #include "asm/current.h"
#include "asm/pgtable.h" #include "asm/processor.h"
#include "asm/tlbflush.h"
#include "asm/uaccess.h" #include "asm/uaccess.h"
#include "kern_util.h"
#include "as-layout.h"
#include "mem_user.h" #include "mem_user.h"
#include "kern.h" #include "skas.h"
#include "irq_user.h"
#include "tlb.h"
#include "os.h" #include "os.h"
#include "skas/skas.h"
void flush_thread(void) void flush_thread(void)
{ {
...@@ -29,8 +24,8 @@ void flush_thread(void) ...@@ -29,8 +24,8 @@ void flush_thread(void)
arch_flush_thread(&current->thread.arch); arch_flush_thread(&current->thread.arch);
ret = unmap(&current->mm->context.skas.id, 0, end, 1, &data); ret = unmap(&current->mm->context.skas.id, 0, end, 1, &data);
if(ret){ if (ret) {
printk("flush_thread - clearing address space failed, " printk(KERN_ERR "flush_thread - clearing address space failed, "
"err = %d\n", ret); "err = %d\n", ret);
force_sig(SIGKILL, current); force_sig(SIGKILL, current);
} }
...@@ -52,7 +47,7 @@ extern void log_exec(char **argv, void *tty); ...@@ -52,7 +47,7 @@ extern void log_exec(char **argv, void *tty);
static long execve1(char *file, char __user * __user *argv, static long execve1(char *file, char __user * __user *argv,
char __user *__user *env) char __user *__user *env)
{ {
long error; long error;
#ifdef CONFIG_TTY_LOG #ifdef CONFIG_TTY_LOG
struct tty_struct *tty; struct tty_struct *tty;
...@@ -62,16 +57,16 @@ static long execve1(char *file, char __user * __user *argv, ...@@ -62,16 +57,16 @@ static long execve1(char *file, char __user * __user *argv,
log_exec(argv, tty); log_exec(argv, tty);
mutex_unlock(&tty_mutex); mutex_unlock(&tty_mutex);
#endif #endif
error = do_execve(file, argv, env, &current->thread.regs); error = do_execve(file, argv, env, &current->thread.regs);
if (error == 0){ if (error == 0) {
task_lock(current); task_lock(current);
current->ptrace &= ~PT_DTRACE; current->ptrace &= ~PT_DTRACE;
#ifdef SUBARCH_EXECVE1 #ifdef SUBARCH_EXECVE1
SUBARCH_EXECVE1(&current->thread.regs.regs); SUBARCH_EXECVE1(&current->thread.regs.regs);
#endif #endif
task_unlock(current); task_unlock(current);
} }
return(error); return error;
} }
long um_execve(char *file, char __user *__user *argv, char __user *__user *env) long um_execve(char *file, char __user *__user *argv, char __user *__user *env)
...@@ -79,9 +74,9 @@ long um_execve(char *file, char __user *__user *argv, char __user *__user *env) ...@@ -79,9 +74,9 @@ long um_execve(char *file, char __user *__user *argv, char __user *__user *env)
long err; long err;
err = execve1(file, argv, env); err = execve1(file, argv, env);
if(!err) if (!err)
do_longjmp(current->thread.exec_buf, 1); do_longjmp(current->thread.exec_buf, 1);
return(err); return err;
} }
long sys_execve(char __user *file, char __user *__user *argv, long sys_execve(char __user *file, char __user *__user *argv,
...@@ -98,5 +93,5 @@ long sys_execve(char __user *file, char __user *__user *argv, ...@@ -98,5 +93,5 @@ long sys_execve(char __user *file, char __user *__user *argv,
putname(filename); putname(filename);
out: out:
unlock_kernel(); unlock_kernel();
return(error); return error;
} }
/* /*
* Copyright (C) 2000 Jeff Dike (jdike@karaya.com) * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL * Licensed under the GPL
* Derived (i.e. mostly copied) from arch/i386/kernel/irq.c: * Derived (i.e. mostly copied) from arch/i386/kernel/irq.c:
* Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar * Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar
*/ */
#include "linux/kernel.h" #include "linux/cpumask.h"
#include "linux/module.h" #include "linux/hardirq.h"
#include "linux/smp.h"
#include "linux/kernel_stat.h"
#include "linux/interrupt.h" #include "linux/interrupt.h"
#include "linux/random.h" #include "linux/kernel_stat.h"
#include "linux/slab.h" #include "linux/module.h"
#include "linux/file.h"
#include "linux/proc_fs.h"
#include "linux/init.h"
#include "linux/seq_file.h" #include "linux/seq_file.h"
#include "linux/profile.h" #include "as-layout.h"
#include "linux/hardirq.h"
#include "asm/irq.h"
#include "asm/hw_irq.h"
#include "asm/atomic.h"
#include "asm/signal.h"
#include "asm/system.h"
#include "asm/errno.h"
#include "asm/uaccess.h"
#include "kern_util.h" #include "kern_util.h"
#include "irq_user.h"
#include "irq_kern.h"
#include "os.h" #include "os.h"
#include "sigio.h"
#include "misc_constants.h"
#include "as-layout.h"
/* /*
* Generic, controller-independent functions: * Generic, controller-independent functions:
...@@ -71,9 +53,8 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -71,9 +53,8 @@ int show_interrupts(struct seq_file *p, void *v)
seq_putc(p, '\n'); seq_putc(p, '\n');
skip: skip:
spin_unlock_irqrestore(&irq_desc[i].lock, flags); spin_unlock_irqrestore(&irq_desc[i].lock, flags);
} else if (i == NR_IRQS) { } else if (i == NR_IRQS)
seq_putc(p, '\n'); seq_putc(p, '\n');
}
return 0; return 0;
} }
...@@ -102,11 +83,13 @@ void sigio_handler(int sig, struct uml_pt_regs *regs) ...@@ -102,11 +83,13 @@ void sigio_handler(int sig, struct uml_pt_regs *regs)
while (1) { while (1) {
n = os_waiting_for_events(active_fds); n = os_waiting_for_events(active_fds);
if (n <= 0) { if (n <= 0) {
if(n == -EINTR) continue; if (n == -EINTR)
continue;
else break; else break;
} }
for (irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next) { for (irq_fd = active_fds; irq_fd != NULL;
irq_fd = irq_fd->next) {
if (irq_fd->current_events != 0) { if (irq_fd->current_events != 0) {
irq_fd->current_events = 0; irq_fd->current_events = 0;
do_IRQ(irq_fd->irq, regs); do_IRQ(irq_fd->irq, regs);
...@@ -138,8 +121,7 @@ int activate_fd(int irq, int fd, int type, void *dev_id) ...@@ -138,8 +121,7 @@ int activate_fd(int irq, int fd, int type, void *dev_id)
if (type == IRQ_READ) if (type == IRQ_READ)
events = UM_POLLIN | UM_POLLPRI; events = UM_POLLIN | UM_POLLPRI;
else else events = UM_POLLOUT;
events = UM_POLLOUT;
*new_fd = ((struct irq_fd) { .next = NULL, *new_fd = ((struct irq_fd) { .next = NULL,
.id = dev_id, .id = dev_id,
.fd = fd, .fd = fd,
...@@ -153,9 +135,10 @@ int activate_fd(int irq, int fd, int type, void *dev_id) ...@@ -153,9 +135,10 @@ int activate_fd(int irq, int fd, int type, void *dev_id)
spin_lock_irqsave(&irq_lock, flags); spin_lock_irqsave(&irq_lock, flags);
for (irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next) { for (irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next) {
if ((irq_fd->fd == fd) && (irq_fd->type == type)) { if ((irq_fd->fd == fd) && (irq_fd->type == type)) {
printk("Registering fd %d twice\n", fd); printk(KERN_ERR "Registering fd %d twice\n", fd);
printk("Irqs : %d, %d\n", irq_fd->irq, irq); printk(KERN_ERR "Irqs : %d, %d\n", irq_fd->irq, irq);
printk("Ids : 0x%p, 0x%p\n", irq_fd->id, dev_id); printk(KERN_ERR "Ids : 0x%p, 0x%p\n", irq_fd->id,
dev_id);
goto out_unlock; goto out_unlock;
} }
} }
...@@ -171,7 +154,8 @@ int activate_fd(int irq, int fd, int type, void *dev_id) ...@@ -171,7 +154,8 @@ int activate_fd(int irq, int fd, int type, void *dev_id)
if (n == 0) if (n == 0)
break; break;
/* n > 0 /*
* n > 0
* It means we couldn't put new pollfd to current pollfds * It means we couldn't put new pollfd to current pollfds
* and tmp_fds is NULL or too small for new pollfds array. * and tmp_fds is NULL or too small for new pollfds array.
* Needed size is equal to n as minimum. * Needed size is equal to n as minimum.
...@@ -197,7 +181,8 @@ int activate_fd(int irq, int fd, int type, void *dev_id) ...@@ -197,7 +181,8 @@ int activate_fd(int irq, int fd, int type, void *dev_id)
spin_unlock_irqrestore(&irq_lock, flags); spin_unlock_irqrestore(&irq_lock, flags);
/* This calls activate_fd, so it has to be outside the critical /*
* This calls activate_fd, so it has to be outside the critical
* section. * section.
*/ */
maybe_sigio_broken(fd, (type == IRQ_READ)); maybe_sigio_broken(fd, (type == IRQ_READ));
...@@ -264,13 +249,14 @@ static struct irq_fd *find_irq_by_fd(int fd, int irqnum, int *index_out) ...@@ -264,13 +249,14 @@ static struct irq_fd *find_irq_by_fd(int fd, int irqnum, int *index_out)
i++; i++;
} }
if (irq == NULL) { if (irq == NULL) {
printk("find_irq_by_fd doesn't have descriptor %d\n", fd); printk(KERN_ERR "find_irq_by_fd doesn't have descriptor %d\n",
fd);
goto out; goto out;
} }
fdi = os_get_pollfd(i); fdi = os_get_pollfd(i);
if ((fdi != -1) && (fdi != fd)) { if ((fdi != -1) && (fdi != fd)) {
printk("find_irq_by_fd - mismatch between active_fds and " printk(KERN_ERR "find_irq_by_fd - mismatch between active_fds "
"pollfds, fd %d vs %d, need %d\n", irq->fd, "and pollfds, fd %d vs %d, need %d\n", irq->fd,
fdi, fd); fdi, fd);
irq = NULL; irq = NULL;
goto out; goto out;
...@@ -306,7 +292,7 @@ void deactivate_fd(int fd, int irqnum) ...@@ -306,7 +292,7 @@ void deactivate_fd(int fd, int irqnum)
spin_lock_irqsave(&irq_lock, flags); spin_lock_irqsave(&irq_lock, flags);
irq = find_irq_by_fd(fd, irqnum, &i); irq = find_irq_by_fd(fd, irqnum, &i);
if(irq == NULL){ if (irq == NULL) {
spin_unlock_irqrestore(&irq_lock, flags); spin_unlock_irqrestore(&irq_lock, flags);
return; return;
} }
...@@ -372,8 +358,10 @@ int um_request_irq(unsigned int irq, int fd, int type, ...@@ -372,8 +358,10 @@ int um_request_irq(unsigned int irq, int fd, int type,
EXPORT_SYMBOL(um_request_irq); EXPORT_SYMBOL(um_request_irq);
EXPORT_SYMBOL(reactivate_fd); EXPORT_SYMBOL(reactivate_fd);
/* hw_interrupt_type must define (startup || enable) && /*
* (shutdown || disable) && end */ * hw_interrupt_type must define (startup || enable) &&
* (shutdown || disable) && end
*/
static void dummy(unsigned int irq) static void dummy(unsigned int irq)
{ {
} }
...@@ -422,7 +410,8 @@ int init_aio_irq(int irq, char *name, irq_handler_t handler) ...@@ -422,7 +410,8 @@ int init_aio_irq(int irq, char *name, irq_handler_t handler)
err = os_pipe(fds, 1, 1); err = os_pipe(fds, 1, 1);
if (err) { if (err) {
printk("init_aio_irq - os_pipe failed, err = %d\n", -err); printk(KERN_ERR "init_aio_irq - os_pipe failed, err = %d\n",
-err);
goto out; goto out;
} }
...@@ -430,7 +419,8 @@ int init_aio_irq(int irq, char *name, irq_handler_t handler) ...@@ -430,7 +419,8 @@ int init_aio_irq(int irq, char *name, irq_handler_t handler)
IRQF_DISABLED | IRQF_SAMPLE_RANDOM, name, IRQF_DISABLED | IRQF_SAMPLE_RANDOM, name,
(void *) (long) fds[0]); (void *) (long) fds[0]);
if (err) { if (err) {
printk("init_aio_irq - : um_request_irq failed, err = %d\n", printk(KERN_ERR "init_aio_irq - : um_request_irq failed, "
"err = %d\n",
err); err);
goto out_close; goto out_close;
} }
...@@ -501,8 +491,9 @@ unsigned long to_irq_stack(unsigned long *mask_out) ...@@ -501,8 +491,9 @@ unsigned long to_irq_stack(unsigned long *mask_out)
int nested; int nested;
mask = xchg(&pending_mask, *mask_out); mask = xchg(&pending_mask, *mask_out);
if(mask != 0){ if (mask != 0) {
/* If any interrupts come in at this point, we want to /*
* If any interrupts come in at this point, we want to
* make sure that their bits aren't lost by our * make sure that their bits aren't lost by our
* putting our bit in. So, this loop accumulates bits * putting our bit in. So, this loop accumulates bits
* until xchg returns the same value that we put in. * until xchg returns the same value that we put in.
...@@ -514,13 +505,13 @@ unsigned long to_irq_stack(unsigned long *mask_out) ...@@ -514,13 +505,13 @@ unsigned long to_irq_stack(unsigned long *mask_out)
do { do {
old |= mask; old |= mask;
mask = xchg(&pending_mask, old); mask = xchg(&pending_mask, old);
} while(mask != old); } while (mask != old);
return 1; return 1;
} }
ti = current_thread_info(); ti = current_thread_info();
nested = (ti->real_thread != NULL); nested = (ti->real_thread != NULL);
if(!nested){ if (!nested) {
struct task_struct *task; struct task_struct *task;
struct thread_info *tti; struct thread_info *tti;
......
...@@ -75,7 +75,7 @@ void map_memory(unsigned long virt, unsigned long phys, unsigned long len, ...@@ -75,7 +75,7 @@ void map_memory(unsigned long virt, unsigned long phys, unsigned long len,
err = os_map_memory((void *) virt, fd, offset, len, r, w, x); err = os_map_memory((void *) virt, fd, offset, len, r, w, x);
if (err) { if (err) {
if (err == -ENOMEM) if (err == -ENOMEM)
printk("try increasing the host's " printk(KERN_ERR "try increasing the host's "
"/proc/sys/vm/max_map_count to <physical " "/proc/sys/vm/max_map_count to <physical "
"memory size>/4096\n"); "memory size>/4096\n");
panic("map_memory(0x%lx, %d, 0x%llx, %ld, %d, %d, %d) failed, " panic("map_memory(0x%lx, %d, 0x%llx, %ld, %d, %d, %d) failed, "
...@@ -103,7 +103,8 @@ void __init setup_physmem(unsigned long start, unsigned long reserve_end, ...@@ -103,7 +103,8 @@ void __init setup_physmem(unsigned long start, unsigned long reserve_end,
exit(1); exit(1);
} }
/* Special kludge - This page will be mapped in to userspace processes /*
* Special kludge - This page will be mapped in to userspace processes
* from physmem_fd, so it needs to be written out there. * from physmem_fd, so it needs to be written out there.
*/ */
os_seek_file(physmem_fd, __pa(&__syscall_stub_start)); os_seek_file(physmem_fd, __pa(&__syscall_stub_start));
...@@ -202,8 +203,8 @@ int setup_iomem(void) ...@@ -202,8 +203,8 @@ int setup_iomem(void)
err = os_map_memory((void *) iomem_start, region->fd, 0, err = os_map_memory((void *) iomem_start, region->fd, 0,
region->size, 1, 1, 0); region->size, 1, 1, 0);
if (err) if (err)
printk("Mapping iomem region for driver '%s' failed, " printk(KERN_ERR "Mapping iomem region for driver '%s' "
"errno = %d\n", region->driver, -err); "failed, errno = %d\n", region->driver, -err);
else { else {
region->virt = iomem_start; region->virt = iomem_start;
region->phys = __pa(region->virt); region->phys = __pa(region->virt);
......
/* /*
* Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Copyright 2003 PathScale, Inc. * Copyright 2003 PathScale, Inc.
* Licensed under the GPL * Licensed under the GPL
*/ */
#include "linux/kernel.h" #include "linux/stddef.h"
#include "linux/sched.h" #include "linux/err.h"
#include "linux/interrupt.h" #include "linux/hardirq.h"
#include "linux/string.h"
#include "linux/mm.h" #include "linux/mm.h"
#include "linux/slab.h" #include "linux/personality.h"
#include "linux/utsname.h"
#include "linux/fs.h"
#include "linux/utime.h"
#include "linux/smp_lock.h"
#include "linux/module.h"
#include "linux/init.h"
#include "linux/capability.h"
#include "linux/vmalloc.h"
#include "linux/spinlock.h"
#include "linux/proc_fs.h" #include "linux/proc_fs.h"
#include "linux/ptrace.h" #include "linux/ptrace.h"
#include "linux/random.h" #include "linux/random.h"
#include "linux/personality.h" #include "linux/sched.h"
#include "asm/unistd.h" #include "linux/threads.h"
#include "asm/mman.h"
#include "asm/segment.h"
#include "asm/stat.h"
#include "asm/pgtable.h" #include "asm/pgtable.h"
#include "asm/processor.h"
#include "asm/tlbflush.h"
#include "asm/uaccess.h" #include "asm/uaccess.h"
#include "asm/user.h"
#include "kern_util.h"
#include "as-layout.h" #include "as-layout.h"
#include "kern.h" #include "kern_util.h"
#include "signal_kern.h"
#include "init.h"
#include "irq_user.h"
#include "mem_user.h"
#include "tlb.h"
#include "frame_kern.h"
#include "sigcontext.h"
#include "os.h" #include "os.h"
#include "skas.h" #include "skas.h"
#include "tlb.h"
/* This is a per-cpu array. A processor only modifies its entry and it only /*
* This is a per-cpu array. A processor only modifies its entry and it only
* cares about its entry, so it's OK if another processor is modifying its * cares about its entry, so it's OK if another processor is modifying its
* entry. * entry.
*/ */
...@@ -54,15 +32,15 @@ struct cpu_task cpu_tasks[NR_CPUS] = { [0 ... NR_CPUS - 1] = { -1, NULL } }; ...@@ -54,15 +32,15 @@ struct cpu_task cpu_tasks[NR_CPUS] = { [0 ... NR_CPUS - 1] = { -1, NULL } };
static inline int external_pid(struct task_struct *task) static inline int external_pid(struct task_struct *task)
{ {
/* FIXME: Need to look up userspace_pid by cpu */ /* FIXME: Need to look up userspace_pid by cpu */
return(userspace_pid[0]); return userspace_pid[0];
} }
int pid_to_processor_id(int pid) int pid_to_processor_id(int pid)
{ {
int i; int i;
for(i = 0; i < ncpus; i++){ for(i = 0; i < ncpus; i++) {
if(cpu_tasks[i].pid == pid) if (cpu_tasks[i].pid == pid)
return i; return i;
} }
return -1; return -1;
...@@ -118,7 +96,7 @@ void *_switch_to(void *prev, void *next, void *last) ...@@ -118,7 +96,7 @@ void *_switch_to(void *prev, void *next, void *last)
current->thread.saved_task = NULL; current->thread.saved_task = NULL;
/* XXX need to check runqueues[cpu].idle */ /* XXX need to check runqueues[cpu].idle */
if(current->pid == 0) if (current->pid == 0)
switch_timers(0); switch_timers(0);
switch_threads(&from->thread.switch_buf, switch_threads(&from->thread.switch_buf,
...@@ -126,10 +104,10 @@ void *_switch_to(void *prev, void *next, void *last) ...@@ -126,10 +104,10 @@ void *_switch_to(void *prev, void *next, void *last)
arch_switch_to(current->thread.prev_sched, current); arch_switch_to(current->thread.prev_sched, current);
if(current->pid == 0) if (current->pid == 0)
switch_timers(1); switch_timers(1);
if(current->thread.saved_task) if (current->thread.saved_task)
show_regs(&(current->thread.regs)); show_regs(&(current->thread.regs));
next= current->thread.saved_task; next= current->thread.saved_task;
prev= current; prev= current;
...@@ -141,9 +119,9 @@ void *_switch_to(void *prev, void *next, void *last) ...@@ -141,9 +119,9 @@ void *_switch_to(void *prev, void *next, void *last)
void interrupt_end(void) void interrupt_end(void)
{ {
if(need_resched()) if (need_resched())
schedule(); schedule();
if(test_tsk_thread_flag(current, TIF_SIGPENDING)) if (test_tsk_thread_flag(current, TIF_SIGPENDING))
do_signal(); do_signal();
} }
...@@ -158,7 +136,8 @@ void *get_current(void) ...@@ -158,7 +136,8 @@ void *get_current(void)
extern void schedule_tail(struct task_struct *prev); extern void schedule_tail(struct task_struct *prev);
/* This is called magically, by its address being stuffed in a jmp_buf /*
* This is called magically, by its address being stuffed in a jmp_buf
* and being longjmp-d to. * and being longjmp-d to.
*/ */
void new_thread_handler(void) void new_thread_handler(void)
...@@ -166,18 +145,19 @@ void new_thread_handler(void) ...@@ -166,18 +145,19 @@ void new_thread_handler(void)
int (*fn)(void *), n; int (*fn)(void *), n;
void *arg; void *arg;
if(current->thread.prev_sched != NULL) if (current->thread.prev_sched != NULL)
schedule_tail(current->thread.prev_sched); schedule_tail(current->thread.prev_sched);
current->thread.prev_sched = NULL; current->thread.prev_sched = NULL;
fn = current->thread.request.u.thread.proc; fn = current->thread.request.u.thread.proc;
arg = current->thread.request.u.thread.arg; arg = current->thread.request.u.thread.arg;
/* The return value is 1 if the kernel thread execs a process, /*
* The return value is 1 if the kernel thread execs a process,
* 0 if it just exits * 0 if it just exits
*/ */
n = run_kernel_thread(fn, arg, &current->thread.exec_buf); n = run_kernel_thread(fn, arg, &current->thread.exec_buf);
if(n == 1){ if (n == 1) {
/* Handle any immediate reschedules or signals */ /* Handle any immediate reschedules or signals */
interrupt_end(); interrupt_end();
userspace(&current->thread.regs.regs); userspace(&current->thread.regs.regs);
...@@ -189,14 +169,16 @@ void new_thread_handler(void) ...@@ -189,14 +169,16 @@ void new_thread_handler(void)
void fork_handler(void) void fork_handler(void)
{ {
force_flush_all(); force_flush_all();
if(current->thread.prev_sched == NULL) if (current->thread.prev_sched == NULL)
panic("blech"); panic("blech");
schedule_tail(current->thread.prev_sched); schedule_tail(current->thread.prev_sched);
/* XXX: if interrupt_end() calls schedule, this call to /*
* XXX: if interrupt_end() calls schedule, this call to
* arch_switch_to isn't needed. We could want to apply this to * arch_switch_to isn't needed. We could want to apply this to
* improve performance. -bb */ * improve performance. -bb
*/
arch_switch_to(current->thread.prev_sched, current); arch_switch_to(current->thread.prev_sched, current);
current->thread.prev_sched = NULL; current->thread.prev_sched = NULL;
...@@ -216,11 +198,11 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, ...@@ -216,11 +198,11 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
p->thread = (struct thread_struct) INIT_THREAD; p->thread = (struct thread_struct) INIT_THREAD;
if(current->thread.forking){ if (current->thread.forking) {
memcpy(&p->thread.regs.regs, &regs->regs, memcpy(&p->thread.regs.regs, &regs->regs,
sizeof(p->thread.regs.regs)); sizeof(p->thread.regs.regs));
REGS_SET_SYSCALL_RETURN(p->thread.regs.regs.regs, 0); REGS_SET_SYSCALL_RETURN(p->thread.regs.regs.regs, 0);
if(sp != 0) if (sp != 0)
REGS_SP(p->thread.regs.regs.regs) = sp; REGS_SP(p->thread.regs.regs.regs) = sp;
handler = fork_handler; handler = fork_handler;
...@@ -259,14 +241,14 @@ void initial_thread_cb(void (*proc)(void *), void *arg) ...@@ -259,14 +241,14 @@ void initial_thread_cb(void (*proc)(void *), void *arg)
void default_idle(void) void default_idle(void)
{ {
while(1){ while(1) {
/* endless idle loop with no priority at all */ /* endless idle loop with no priority at all */
/* /*
* although we are an idle CPU, we do not want to * although we are an idle CPU, we do not want to
* get into the scheduler unnecessarily. * get into the scheduler unnecessarily.
*/ */
if(need_resched()) if (need_resched())
schedule(); schedule();
idle_sleep(10); idle_sleep(10);
...@@ -288,26 +270,26 @@ void *um_virt_to_phys(struct task_struct *task, unsigned long addr, ...@@ -288,26 +270,26 @@ void *um_virt_to_phys(struct task_struct *task, unsigned long addr,
pte_t *pte; pte_t *pte;
pte_t ptent; pte_t ptent;
if(task->mm == NULL) if (task->mm == NULL)
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
pgd = pgd_offset(task->mm, addr); pgd = pgd_offset(task->mm, addr);
if(!pgd_present(*pgd)) if (!pgd_present(*pgd))
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
pud = pud_offset(pgd, addr); pud = pud_offset(pgd, addr);
if(!pud_present(*pud)) if (!pud_present(*pud))
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
pmd = pmd_offset(pud, addr); pmd = pmd_offset(pud, addr);
if(!pmd_present(*pmd)) if (!pmd_present(*pmd))
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
pte = pte_offset_kernel(pmd, addr); pte = pte_offset_kernel(pmd, addr);
ptent = *pte; ptent = *pte;
if(!pte_present(ptent)) if (!pte_present(ptent))
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
if(pte_out != NULL) if (pte_out != NULL)
*pte_out = ptent; *pte_out = ptent;
return (void *) (pte_val(ptent) & PAGE_MASK) + (addr & ~PAGE_MASK); return (void *) (pte_val(ptent) & PAGE_MASK) + (addr & ~PAGE_MASK);
} }
...@@ -380,7 +362,7 @@ int smp_sigio_handler(void) ...@@ -380,7 +362,7 @@ int smp_sigio_handler(void)
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
int cpu = current_thread->cpu; int cpu = current_thread->cpu;
IPI_handler(cpu); IPI_handler(cpu);
if(cpu != 0) if (cpu != 0)
return 1; return 1;
#endif #endif
return 0; return 0;
...@@ -408,7 +390,8 @@ int get_using_sysemu(void) ...@@ -408,7 +390,8 @@ int get_using_sysemu(void)
static int proc_read_sysemu(char *buf, char **start, off_t offset, int size,int *eof, void *data) static int proc_read_sysemu(char *buf, char **start, off_t offset, int size,int *eof, void *data)
{ {
if (snprintf(buf, size, "%d\n", get_using_sysemu()) < size) /*No overflow*/ if (snprintf(buf, size, "%d\n", get_using_sysemu()) < size)
/* No overflow */
*eof = 1; *eof = 1;
return strlen(buf); return strlen(buf);
...@@ -423,7 +406,8 @@ static int proc_write_sysemu(struct file *file,const char __user *buf, unsigned ...@@ -423,7 +406,8 @@ static int proc_write_sysemu(struct file *file,const char __user *buf, unsigned
if (tmp[0] >= '0' && tmp[0] <= '2') if (tmp[0] >= '0' && tmp[0] <= '2')
set_using_sysemu(tmp[0] - '0'); set_using_sysemu(tmp[0] - '0');
return count; /*We use the first char, but pretend to write everything*/ /* We use the first char, but pretend to write everything */
return count;
} }
int __init make_proc_sysemu(void) int __init make_proc_sysemu(void)
...@@ -453,10 +437,10 @@ int singlestepping(void * t) ...@@ -453,10 +437,10 @@ int singlestepping(void * t)
struct task_struct *task = t ? t : current; struct task_struct *task = t ? t : current;
if ( ! (task->ptrace & PT_DTRACE) ) if ( ! (task->ptrace & PT_DTRACE) )
return(0); return 0;
if (task->thread.singlestep_syscall) if (task->thread.singlestep_syscall)
return(1); return 1;
return 2; return 2;
} }
......
/* /*
* Copyright (C) 2000 Jeff Dike (jdike@karaya.com) * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL * Licensed under the GPL
*/ */
#include "linux/sched.h"
#include "linux/mm.h"
#include "linux/errno.h"
#include "linux/smp_lock.h"
#include "linux/security.h"
#include "linux/ptrace.h"
#include "linux/audit.h" #include "linux/audit.h"
#include "linux/ptrace.h"
#include "linux/sched.h"
#include "asm/uaccess.h"
#ifdef CONFIG_PROC_MM #ifdef CONFIG_PROC_MM
#include "linux/proc_mm.h" #include "proc_mm.h"
#endif #endif
#include "asm/ptrace.h"
#include "asm/uaccess.h"
#include "kern_util.h"
#include "skas_ptrace.h" #include "skas_ptrace.h"
#include "sysdep/ptrace.h"
#include "os.h"
static inline void set_singlestepping(struct task_struct *child, int on) static inline void set_singlestepping(struct task_struct *child, int on)
{ {
if (on) if (on)
child->ptrace |= PT_DTRACE; child->ptrace |= PT_DTRACE;
else else
child->ptrace &= ~PT_DTRACE; child->ptrace &= ~PT_DTRACE;
child->thread.singlestep_syscall = 0; child->thread.singlestep_syscall = 0;
#ifdef SUBARCH_SET_SINGLESTEPPING #ifdef SUBARCH_SET_SINGLESTEPPING
SUBARCH_SET_SINGLESTEPPING(child, on); SUBARCH_SET_SINGLESTEPPING(child, on);
#endif #endif
} }
...@@ -37,8 +29,8 @@ static inline void set_singlestepping(struct task_struct *child, int on) ...@@ -37,8 +29,8 @@ static inline void set_singlestepping(struct task_struct *child, int on)
* Called by kernel/ptrace.c when detaching.. * Called by kernel/ptrace.c when detaching..
*/ */
void ptrace_disable(struct task_struct *child) void ptrace_disable(struct task_struct *child)
{ {
set_singlestepping(child,0); set_singlestepping(child,0);
} }
extern int peek_user(struct task_struct * child, long addr, long data); extern int peek_user(struct task_struct * child, long addr, long data);
...@@ -50,40 +42,40 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -50,40 +42,40 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
unsigned long __user *p = (void __user *)(unsigned long)data; unsigned long __user *p = (void __user *)(unsigned long)data;
switch (request) { switch (request) {
/* when I and D space are separate, these will need to be fixed. */ /* read word at location addr. */
case PTRACE_PEEKTEXT: /* read word at location addr. */ case PTRACE_PEEKTEXT:
case PTRACE_PEEKDATA: case PTRACE_PEEKDATA:
ret = generic_ptrace_peekdata(child, addr, data); ret = generic_ptrace_peekdata(child, addr, data);
break; break;
/* read the word at location addr in the USER area. */ /* read the word at location addr in the USER area. */
case PTRACE_PEEKUSR: case PTRACE_PEEKUSR:
ret = peek_user(child, addr, data); ret = peek_user(child, addr, data);
break; break;
/* when I and D space are separate, this will have to be fixed. */ /* write the word at location addr. */
case PTRACE_POKETEXT: /* write the word at location addr. */ case PTRACE_POKETEXT:
case PTRACE_POKEDATA: case PTRACE_POKEDATA:
ret = generic_ptrace_pokedata(child, addr, data); ret = generic_ptrace_pokedata(child, addr, data);
break; break;
case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ /* write the word at location addr in the USER area */
ret = poke_user(child, addr, data); case PTRACE_POKEUSR:
break; ret = poke_user(child, addr, data);
break;
case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ /* continue and stop at next (return from) syscall */
case PTRACE_CONT: { /* restart after signal. */ case PTRACE_SYSCALL:
/* restart after signal. */
case PTRACE_CONT: {
ret = -EIO; ret = -EIO;
if (!valid_signal(data)) if (!valid_signal(data))
break; break;
set_singlestepping(child, 0); set_singlestepping(child, 0);
if (request == PTRACE_SYSCALL) { if (request == PTRACE_SYSCALL)
set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
} else clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
else {
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
}
child->exit_code = data; child->exit_code = data;
wake_up_process(child); wake_up_process(child);
ret = 0; ret = 0;
...@@ -91,8 +83,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -91,8 +83,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
} }
/* /*
* make the child exit. Best I can do is send it a sigkill. * make the child exit. Best I can do is send it a sigkill.
* perhaps it should be put in the status that it wants to * perhaps it should be put in the status that it wants to
* exit. * exit.
*/ */
case PTRACE_KILL: { case PTRACE_KILL: {
...@@ -100,7 +92,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -100,7 +92,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
if (child->exit_state == EXIT_ZOMBIE) /* already dead */ if (child->exit_state == EXIT_ZOMBIE) /* already dead */
break; break;
set_singlestepping(child, 0); set_singlestepping(child, 0);
child->exit_code = SIGKILL; child->exit_code = SIGKILL;
wake_up_process(child); wake_up_process(child);
break; break;
...@@ -111,7 +103,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -111,7 +103,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
if (!valid_signal(data)) if (!valid_signal(data))
break; break;
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
set_singlestepping(child, 1); set_singlestepping(child, 1);
child->exit_code = data; child->exit_code = data;
/* give it a chance to run. */ /* give it a chance to run. */
wake_up_process(child); wake_up_process(child);
...@@ -180,13 +172,14 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -180,13 +172,14 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
break; break;
case PTRACE_FAULTINFO: { case PTRACE_FAULTINFO: {
/* Take the info from thread->arch->faultinfo, /*
* Take the info from thread->arch->faultinfo,
* but transfer max. sizeof(struct ptrace_faultinfo). * but transfer max. sizeof(struct ptrace_faultinfo).
* On i386, ptrace_faultinfo is smaller! * On i386, ptrace_faultinfo is smaller!
*/ */
ret = copy_to_user(p, &child->thread.arch.faultinfo, ret = copy_to_user(p, &child->thread.arch.faultinfo,
sizeof(struct ptrace_faultinfo)); sizeof(struct ptrace_faultinfo));
if(ret) if (ret)
break; break;
break; break;
} }
...@@ -195,12 +188,13 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -195,12 +188,13 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
case PTRACE_LDT: { case PTRACE_LDT: {
struct ptrace_ldt ldt; struct ptrace_ldt ldt;
if(copy_from_user(&ldt, p, sizeof(ldt))){ if (copy_from_user(&ldt, p, sizeof(ldt))) {
ret = -EIO; ret = -EIO;
break; break;
} }
/* This one is confusing, so just punt and return -EIO for /*
* This one is confusing, so just punt and return -EIO for
* now * now
*/ */
ret = -EIO; ret = -EIO;
...@@ -212,7 +206,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -212,7 +206,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
struct mm_struct *old = child->mm; struct mm_struct *old = child->mm;
struct mm_struct *new = proc_mm_get_mm(data); struct mm_struct *new = proc_mm_get_mm(data);
if(IS_ERR(new)){ if (IS_ERR(new)) {
ret = PTR_ERR(new); ret = PTR_ERR(new);
break; break;
} }
...@@ -226,10 +220,10 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -226,10 +220,10 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
} }
#endif #endif
#ifdef PTRACE_ARCH_PRCTL #ifdef PTRACE_ARCH_PRCTL
case PTRACE_ARCH_PRCTL: case PTRACE_ARCH_PRCTL:
/* XXX Calls ptrace on the host - needs some SMP thinking */ /* XXX Calls ptrace on the host - needs some SMP thinking */
ret = arch_prctl(child, data, (void *) addr); ret = arch_prctl(child, data, (void *) addr);
break; break;
#endif #endif
default: default:
ret = ptrace_request(child, request, addr, data); ret = ptrace_request(child, request, addr, data);
...@@ -255,7 +249,8 @@ void send_sigtrap(struct task_struct *tsk, struct uml_pt_regs *regs, ...@@ -255,7 +249,8 @@ void send_sigtrap(struct task_struct *tsk, struct uml_pt_regs *regs,
force_sig_info(SIGTRAP, &info, tsk); force_sig_info(SIGTRAP, &info, tsk);
} }
/* XXX Check PT_DTRACE vs TIF_SINGLESTEP for singlestepping check and /*
* XXX Check PT_DTRACE vs TIF_SINGLESTEP for singlestepping check and
* PT_PTRACED vs TIF_SYSCALL_TRACE for syscall tracing check * PT_PTRACED vs TIF_SYSCALL_TRACE for syscall tracing check
*/ */
void syscall_trace(struct uml_pt_regs *regs, int entryexit) void syscall_trace(struct uml_pt_regs *regs, int entryexit)
...@@ -272,7 +267,7 @@ void syscall_trace(struct uml_pt_regs *regs, int entryexit) ...@@ -272,7 +267,7 @@ void syscall_trace(struct uml_pt_regs *regs, int entryexit)
UPT_SYSCALL_ARG3(regs), UPT_SYSCALL_ARG3(regs),
UPT_SYSCALL_ARG4(regs)); UPT_SYSCALL_ARG4(regs));
else audit_syscall_exit(AUDITSC_RESULT(UPT_SYSCALL_RET(regs)), else audit_syscall_exit(AUDITSC_RESULT(UPT_SYSCALL_RET(regs)),
UPT_SYSCALL_RET(regs)); UPT_SYSCALL_RET(regs));
} }
/* Fake a debug trap */ /* Fake a debug trap */
...@@ -285,15 +280,18 @@ void syscall_trace(struct uml_pt_regs *regs, int entryexit) ...@@ -285,15 +280,18 @@ void syscall_trace(struct uml_pt_regs *regs, int entryexit)
if (!(current->ptrace & PT_PTRACED)) if (!(current->ptrace & PT_PTRACED))
return; return;
/* the 0x80 provides a way for the tracing parent to distinguish /*
between a syscall stop and SIGTRAP delivery */ * the 0x80 provides a way for the tracing parent to distinguish
* between a syscall stop and SIGTRAP delivery
*/
tracesysgood = (current->ptrace & PT_TRACESYSGOOD); tracesysgood = (current->ptrace & PT_TRACESYSGOOD);
ptrace_notify(SIGTRAP | (tracesysgood ? 0x80 : 0)); ptrace_notify(SIGTRAP | (tracesysgood ? 0x80 : 0));
if (entryexit) /* force do_signal() --> is_syscall() */ if (entryexit) /* force do_signal() --> is_syscall() */
set_thread_flag(TIF_SIGPENDING); set_thread_flag(TIF_SIGPENDING);
/* this isn't the same as continuing with a signal, but it will do /*
* this isn't the same as continuing with a signal, but it will do
* for normal use. strace only continues with a signal if the * for normal use. strace only continues with a signal if the
* stopping signal is not SIGTRAP. -brl * stopping signal is not SIGTRAP. -brl
*/ */
......
/* /*
* Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com) * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL * Licensed under the GPL
*/ */
#include "linux/module.h"
#include "linux/sched.h" #include "linux/sched.h"
#include "asm/smp.h"
#include "kern_util.h"
#include "kern.h"
#include "os.h" #include "os.h"
#include "skas.h" #include "skas.h"
...@@ -37,20 +33,20 @@ static void kill_off_processes(void) ...@@ -37,20 +33,20 @@ static void kill_off_processes(void)
void uml_cleanup(void) void uml_cleanup(void)
{ {
kmalloc_ok = 0; kmalloc_ok = 0;
do_uml_exitcalls(); do_uml_exitcalls();
kill_off_processes(); kill_off_processes();
} }
void machine_restart(char * __unused) void machine_restart(char * __unused)
{ {
uml_cleanup(); uml_cleanup();
reboot_skas(); reboot_skas();
} }
void machine_power_off(void) void machine_power_off(void)
{ {
uml_cleanup(); uml_cleanup();
halt_skas(); halt_skas();
} }
......
/* /*
* Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL * Licensed under the GPL
*/ */
#include "linux/stddef.h"
#include "linux/sys.h"
#include "linux/sched.h"
#include "linux/wait.h"
#include "linux/kernel.h"
#include "linux/smp_lock.h"
#include "linux/module.h" #include "linux/module.h"
#include "linux/slab.h"
#include "linux/tty.h"
#include "linux/binfmts.h"
#include "linux/ptrace.h" #include "linux/ptrace.h"
#include "linux/sched.h"
#include "asm/siginfo.h"
#include "asm/signal.h" #include "asm/signal.h"
#include "asm/uaccess.h"
#include "asm/unistd.h" #include "asm/unistd.h"
#include "asm/ucontext.h"
#include "kern_util.h"
#include "signal_kern.h"
#include "kern.h"
#include "frame_kern.h" #include "frame_kern.h"
#include "kern_util.h"
#include "sigcontext.h" #include "sigcontext.h"
EXPORT_SYMBOL(block_signals); EXPORT_SYMBOL(block_signals);
...@@ -45,9 +34,9 @@ static int handle_signal(struct pt_regs *regs, unsigned long signr, ...@@ -45,9 +34,9 @@ static int handle_signal(struct pt_regs *regs, unsigned long signr,
current_thread_info()->restart_block.fn = do_no_restart_syscall; current_thread_info()->restart_block.fn = do_no_restart_syscall;
/* Did we come from a system call? */ /* Did we come from a system call? */
if(PT_REGS_SYSCALL_NR(regs) >= 0){ if (PT_REGS_SYSCALL_NR(regs) >= 0) {
/* If so, check system call restarting.. */ /* If so, check system call restarting.. */
switch(PT_REGS_SYSCALL_RET(regs)){ switch(PT_REGS_SYSCALL_RET(regs)) {
case -ERESTART_RESTARTBLOCK: case -ERESTART_RESTARTBLOCK:
case -ERESTARTNOHAND: case -ERESTARTNOHAND:
PT_REGS_SYSCALL_RET(regs) = -EINTR; PT_REGS_SYSCALL_RET(regs) = -EINTR;
...@@ -67,17 +56,17 @@ static int handle_signal(struct pt_regs *regs, unsigned long signr, ...@@ -67,17 +56,17 @@ static int handle_signal(struct pt_regs *regs, unsigned long signr,
} }
sp = PT_REGS_SP(regs); sp = PT_REGS_SP(regs);
if((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags(sp) == 0)) if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags(sp) == 0))
sp = current->sas_ss_sp + current->sas_ss_size; sp = current->sas_ss_sp + current->sas_ss_size;
#ifdef CONFIG_ARCH_HAS_SC_SIGNALS #ifdef CONFIG_ARCH_HAS_SC_SIGNALS
if(!(ka->sa.sa_flags & SA_SIGINFO)) if (!(ka->sa.sa_flags & SA_SIGINFO))
err = setup_signal_stack_sc(sp, signr, ka, regs, oldset); err = setup_signal_stack_sc(sp, signr, ka, regs, oldset);
else else
#endif #endif
err = setup_signal_stack_si(sp, signr, ka, regs, info, oldset); err = setup_signal_stack_si(sp, signr, ka, regs, info, oldset);
if(err){ if (err) {
spin_lock_irq(&current->sighand->siglock); spin_lock_irq(&current->sighand->siglock);
current->blocked = *oldset; current->blocked = *oldset;
recalc_sigpending(); recalc_sigpending();
...@@ -87,7 +76,7 @@ static int handle_signal(struct pt_regs *regs, unsigned long signr, ...@@ -87,7 +76,7 @@ static int handle_signal(struct pt_regs *regs, unsigned long signr,
spin_lock_irq(&current->sighand->siglock); spin_lock_irq(&current->sighand->siglock);
sigorsets(&current->blocked, &current->blocked, sigorsets(&current->blocked, &current->blocked,
&ka->sa.sa_mask); &ka->sa.sa_mask);
if(!(ka->sa.sa_flags & SA_NODEFER)) if (!(ka->sa.sa_flags & SA_NODEFER))
sigaddset(&current->blocked, signr); sigaddset(&current->blocked, signr);
recalc_sigpending(); recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock); spin_unlock_irq(&current->sighand->siglock);
...@@ -108,14 +97,16 @@ static int kern_do_signal(struct pt_regs *regs) ...@@ -108,14 +97,16 @@ static int kern_do_signal(struct pt_regs *regs)
else else
oldset = &current->blocked; oldset = &current->blocked;
while((sig = get_signal_to_deliver(&info, &ka_copy, regs, NULL)) > 0){ while ((sig = get_signal_to_deliver(&info, &ka_copy, regs, NULL)) > 0) {
handled_sig = 1; handled_sig = 1;
/* Whee! Actually deliver the signal. */ /* Whee! Actually deliver the signal. */
if(!handle_signal(regs, sig, &ka_copy, &info, oldset)){ if (!handle_signal(regs, sig, &ka_copy, &info, oldset)) {
/* a signal was successfully delivered; the saved /*
* a signal was successfully delivered; the saved
* sigmask will have been stored in the signal frame, * sigmask will have been stored in the signal frame,
* and will be restored by sigreturn, so we can simply * and will be restored by sigreturn, so we can simply
* clear the TIF_RESTORE_SIGMASK flag */ * clear the TIF_RESTORE_SIGMASK flag
*/
if (test_thread_flag(TIF_RESTORE_SIGMASK)) if (test_thread_flag(TIF_RESTORE_SIGMASK))
clear_thread_flag(TIF_RESTORE_SIGMASK); clear_thread_flag(TIF_RESTORE_SIGMASK);
break; break;
...@@ -123,9 +114,9 @@ static int kern_do_signal(struct pt_regs *regs) ...@@ -123,9 +114,9 @@ static int kern_do_signal(struct pt_regs *regs)
} }
/* Did we come from a system call? */ /* Did we come from a system call? */
if(!handled_sig && (PT_REGS_SYSCALL_NR(regs) >= 0)){ if (!handled_sig && (PT_REGS_SYSCALL_NR(regs) >= 0)) {
/* Restart the system call - no handlers present */ /* Restart the system call - no handlers present */
switch(PT_REGS_SYSCALL_RET(regs)){ switch(PT_REGS_SYSCALL_RET(regs)) {
case -ERESTARTNOHAND: case -ERESTARTNOHAND:
case -ERESTARTSYS: case -ERESTARTSYS:
case -ERESTARTNOINTR: case -ERESTARTNOINTR:
...@@ -136,22 +127,25 @@ static int kern_do_signal(struct pt_regs *regs) ...@@ -136,22 +127,25 @@ static int kern_do_signal(struct pt_regs *regs)
PT_REGS_ORIG_SYSCALL(regs) = __NR_restart_syscall; PT_REGS_ORIG_SYSCALL(regs) = __NR_restart_syscall;
PT_REGS_RESTART_SYSCALL(regs); PT_REGS_RESTART_SYSCALL(regs);
break; break;
} }
} }
/* This closes a way to execute a system call on the host. If /*
* This closes a way to execute a system call on the host. If
* you set a breakpoint on a system call instruction and singlestep * you set a breakpoint on a system call instruction and singlestep
* from it, the tracing thread used to PTRACE_SINGLESTEP the process * from it, the tracing thread used to PTRACE_SINGLESTEP the process
* rather than PTRACE_SYSCALL it, allowing the system call to execute * rather than PTRACE_SYSCALL it, allowing the system call to execute
* on the host. The tracing thread will check this flag and * on the host. The tracing thread will check this flag and
* PTRACE_SYSCALL if necessary. * PTRACE_SYSCALL if necessary.
*/ */
if(current->ptrace & PT_DTRACE) if (current->ptrace & PT_DTRACE)
current->thread.singlestep_syscall = current->thread.singlestep_syscall =
is_syscall(PT_REGS_IP(&current->thread.regs)); is_syscall(PT_REGS_IP(&current->thread.regs));
/* if there's no signal to deliver, we just put the saved sigmask /*
* back */ * if there's no signal to deliver, we just put the saved sigmask
* back
*/
if (!handled_sig && test_thread_flag(TIF_RESTORE_SIGMASK)) { if (!handled_sig && test_thread_flag(TIF_RESTORE_SIGMASK)) {
clear_thread_flag(TIF_RESTORE_SIGMASK); clear_thread_flag(TIF_RESTORE_SIGMASK);
sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL); sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
......
# #
# Copyright (C) 2002 - 2004 Jeff Dike (jdike@addtoit.com) # Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
# Licensed under the GPL # Licensed under the GPL
# #
......
/* /*
* Copyright (C) 2002 Jeff Dike (jdike@karaya.com) * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL * Licensed under the GPL
*/ */
#include "linux/sched.h"
#include "linux/list.h"
#include "linux/spinlock.h"
#include "linux/slab.h"
#include "linux/errno.h"
#include "linux/mm.h" #include "linux/mm.h"
#include "asm/current.h" #include "linux/sched.h"
#include "asm/segment.h"
#include "asm/mmu.h"
#include "asm/pgalloc.h" #include "asm/pgalloc.h"
#include "asm/pgtable.h" #include "asm/pgtable.h"
#include "asm/ldt.h"
#include "os.h" #include "os.h"
#include "skas.h" #include "skas.h"
...@@ -41,10 +33,11 @@ static int init_stub_pte(struct mm_struct *mm, unsigned long proc, ...@@ -41,10 +33,11 @@ static int init_stub_pte(struct mm_struct *mm, unsigned long proc,
if (!pte) if (!pte)
goto out_pte; goto out_pte;
/* There's an interaction between the skas0 stub pages, stack /*
* There's an interaction between the skas0 stub pages, stack
* randomization, and the BUG at the end of exit_mmap. exit_mmap * randomization, and the BUG at the end of exit_mmap. exit_mmap
* checks that the number of page tables freed is the same as had * checks that the number of page tables freed is the same as had
* been allocated. If the stack is on the last page table page, * been allocated. If the stack is on the last page table page,
* then the stack pte page will be freed, and if not, it won't. To * then the stack pte page will be freed, and if not, it won't. To
* avoid having to know where the stack is, or if the process mapped * avoid having to know where the stack is, or if the process mapped
* something at the top of its address space for some other reason, * something at the top of its address space for some other reason,
...@@ -54,36 +47,37 @@ static int init_stub_pte(struct mm_struct *mm, unsigned long proc, ...@@ -54,36 +47,37 @@ static int init_stub_pte(struct mm_struct *mm, unsigned long proc,
* destroy_context_skas. * destroy_context_skas.
*/ */
mm->context.skas.last_page_table = pmd_page_vaddr(*pmd); mm->context.skas.last_page_table = pmd_page_vaddr(*pmd);
#ifdef CONFIG_3_LEVEL_PGTABLES #ifdef CONFIG_3_LEVEL_PGTABLES
mm->context.skas.last_pmd = (unsigned long) __va(pud_val(*pud)); mm->context.skas.last_pmd = (unsigned long) __va(pud_val(*pud));
#endif #endif
*pte = mk_pte(virt_to_page(kernel), __pgprot(_PAGE_PRESENT)); *pte = mk_pte(virt_to_page(kernel), __pgprot(_PAGE_PRESENT));
*pte = pte_mkread(*pte); *pte = pte_mkread(*pte);
return(0); return 0;
out_pmd: out_pmd:
pud_free(pud); pud_free(pud);
out_pte: out_pte:
pmd_free(pmd); pmd_free(pmd);
out: out:
return(-ENOMEM); return -ENOMEM;
} }
int init_new_context(struct task_struct *task, struct mm_struct *mm) int init_new_context(struct task_struct *task, struct mm_struct *mm)
{ {
struct mmu_context_skas *from_mm = NULL; struct mmu_context_skas *from_mm = NULL;
struct mmu_context_skas *to_mm = &mm->context.skas; struct mmu_context_skas *to_mm = &mm->context.skas;
unsigned long stack = 0; unsigned long stack = 0;
int ret = -ENOMEM; int ret = -ENOMEM;
if(skas_needs_stub){ if (skas_needs_stub) {
stack = get_zeroed_page(GFP_KERNEL); stack = get_zeroed_page(GFP_KERNEL);
if(stack == 0) if (stack == 0)
goto out; goto out;
/* This zeros the entry that pgd_alloc didn't, needed since /*
* This zeros the entry that pgd_alloc didn't, needed since
* we are about to reinitialize it, and want mm.nr_ptes to * we are about to reinitialize it, and want mm.nr_ptes to
* be accurate. * be accurate.
*/ */
...@@ -91,39 +85,39 @@ int init_new_context(struct task_struct *task, struct mm_struct *mm) ...@@ -91,39 +85,39 @@ int init_new_context(struct task_struct *task, struct mm_struct *mm)
ret = init_stub_pte(mm, CONFIG_STUB_CODE, ret = init_stub_pte(mm, CONFIG_STUB_CODE,
(unsigned long) &__syscall_stub_start); (unsigned long) &__syscall_stub_start);
if(ret) if (ret)
goto out_free; goto out_free;
ret = init_stub_pte(mm, CONFIG_STUB_DATA, stack); ret = init_stub_pte(mm, CONFIG_STUB_DATA, stack);
if(ret) if (ret)
goto out_free; goto out_free;
mm->nr_ptes--; mm->nr_ptes--;
} }
to_mm->id.stack = stack; to_mm->id.stack = stack;
if(current->mm != NULL && current->mm != &init_mm) if (current->mm != NULL && current->mm != &init_mm)
from_mm = &current->mm->context.skas; from_mm = &current->mm->context.skas;
if(proc_mm){ if (proc_mm) {
ret = new_mm(stack); ret = new_mm(stack);
if(ret < 0){ if (ret < 0) {
printk("init_new_context_skas - new_mm failed, " printk(KERN_ERR "init_new_context_skas - "
"errno = %d\n", ret); "new_mm failed, errno = %d\n", ret);
goto out_free; goto out_free;
} }
to_mm->id.u.mm_fd = ret; to_mm->id.u.mm_fd = ret;
} }
else { else {
if(from_mm) if (from_mm)
to_mm->id.u.pid = copy_context_skas0(stack, to_mm->id.u.pid = copy_context_skas0(stack,
from_mm->id.u.pid); from_mm->id.u.pid);
else to_mm->id.u.pid = start_userspace(stack); else to_mm->id.u.pid = start_userspace(stack);
} }
ret = init_new_ldt(to_mm, from_mm); ret = init_new_ldt(to_mm, from_mm);
if(ret < 0){ if (ret < 0) {
printk("init_new_context_skas - init_ldt" printk(KERN_ERR "init_new_context_skas - init_ldt"
" failed, errno = %d\n", ret); " failed, errno = %d\n", ret);
goto out_free; goto out_free;
} }
...@@ -131,7 +125,7 @@ int init_new_context(struct task_struct *task, struct mm_struct *mm) ...@@ -131,7 +125,7 @@ int init_new_context(struct task_struct *task, struct mm_struct *mm)
return 0; return 0;
out_free: out_free:
if(to_mm->id.stack != 0) if (to_mm->id.stack != 0)
free_page(to_mm->id.stack); free_page(to_mm->id.stack);
out: out:
return ret; return ret;
...@@ -141,12 +135,12 @@ void destroy_context(struct mm_struct *mm) ...@@ -141,12 +135,12 @@ void destroy_context(struct mm_struct *mm)
{ {
struct mmu_context_skas *mmu = &mm->context.skas; struct mmu_context_skas *mmu = &mm->context.skas;
if(proc_mm) if (proc_mm)
os_close_file(mmu->id.u.mm_fd); os_close_file(mmu->id.u.mm_fd);
else else
os_kill_ptraced_process(mmu->id.u.pid, 1); os_kill_ptraced_process(mmu->id.u.pid, 1);
if(!proc_mm || !ptrace_faultinfo){ if (!proc_mm || !ptrace_faultinfo) {
free_page(mmu->id.stack); free_page(mmu->id.stack);
pte_lock_deinit(virt_to_page(mmu->last_page_table)); pte_lock_deinit(virt_to_page(mmu->last_page_table));
pte_free_kernel((pte_t *) mmu->last_page_table); pte_free_kernel((pte_t *) mmu->last_page_table);
......
/* /*
* Copyright (C) 2002 Jeff Dike (jdike@karaya.com) * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL * Licensed under the GPL
*/ */
#include "linux/sched.h"
#include "linux/slab.h"
#include "linux/ptrace.h"
#include "linux/proc_fs.h"
#include "linux/file.h"
#include "linux/errno.h"
#include "linux/init.h" #include "linux/init.h"
#include "asm/uaccess.h" #include "linux/sched.h"
#include "asm/atomic.h"
#include "kern_util.h"
#include "as-layout.h" #include "as-layout.h"
#include "skas.h"
#include "os.h" #include "os.h"
#include "tlb.h" #include "skas.h"
#include "kern.h"
#include "registers.h"
extern void schedule_tail(struct task_struct *prev);
int new_mm(unsigned long stack) int new_mm(unsigned long stack)
{ {
int fd; int fd;
fd = os_open_file("/proc/mm", of_cloexec(of_write(OPENFLAGS())), 0); fd = os_open_file("/proc/mm", of_cloexec(of_write(OPENFLAGS())), 0);
if(fd < 0) if (fd < 0)
return fd; return fd;
if(skas_needs_stub) if (skas_needs_stub)
map_stub_pages(fd, CONFIG_STUB_CODE, CONFIG_STUB_DATA, stack); map_stub_pages(fd, CONFIG_STUB_CODE, CONFIG_STUB_DATA, stack);
return fd; return fd;
...@@ -62,7 +49,7 @@ int __init start_uml(void) ...@@ -62,7 +49,7 @@ int __init start_uml(void)
{ {
stack_protections((unsigned long) &cpu0_irqstack); stack_protections((unsigned long) &cpu0_irqstack);
set_sigstack(cpu0_irqstack, THREAD_SIZE); set_sigstack(cpu0_irqstack, THREAD_SIZE);
if(proc_mm) if (proc_mm)
userspace_pid[0] = start_userspace(0); userspace_pid[0] = start_userspace(0);
init_new_thread_signals(); init_new_thread_signals();
...@@ -75,7 +62,7 @@ int __init start_uml(void) ...@@ -75,7 +62,7 @@ int __init start_uml(void)
unsigned long current_stub_stack(void) unsigned long current_stub_stack(void)
{ {
if(current->mm == NULL) if (current->mm == NULL)
return 0; return 0;
return current->mm->context.skas.id.stack; return current->mm->context.skas.id.stack;
......
/* /*
* Copyright (C) 2002 Jeff Dike (jdike@karaya.com) * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL * Licensed under the GPL
*/ */
#include "linux/sys.h" #include "linux/kernel.h"
#include "linux/ptrace.h" #include "linux/ptrace.h"
#include "asm/errno.h"
#include "asm/unistd.h"
#include "asm/ptrace.h"
#include "asm/current.h"
#include "sysdep/syscalls.h"
#include "kern_util.h" #include "kern_util.h"
#include "syscall.h" #include "sysdep/ptrace.h"
#include "sysdep/syscalls.h"
void handle_syscall(struct uml_pt_regs *r) void handle_syscall(struct uml_pt_regs *r)
{ {
...@@ -24,7 +20,8 @@ void handle_syscall(struct uml_pt_regs *r) ...@@ -24,7 +20,8 @@ void handle_syscall(struct uml_pt_regs *r)
current->thread.nsyscalls++; current->thread.nsyscalls++;
nsyscalls++; nsyscalls++;
/* This should go in the declaration of syscall, but when I do that, /*
* This should go in the declaration of syscall, but when I do that,
* strace -f -c bash -c 'ls ; ls' breaks, sometimes not tracing * strace -f -c bash -c 'ls ; ls' breaks, sometimes not tracing
* children at all, sometimes hanging when bash doesn't see the first * children at all, sometimes hanging when bash doesn't see the first
* ls exit. * ls exit.
...@@ -33,7 +30,7 @@ void handle_syscall(struct uml_pt_regs *r) ...@@ -33,7 +30,7 @@ void handle_syscall(struct uml_pt_regs *r)
* in case it's a compiler bug. * in case it's a compiler bug.
*/ */
syscall = UPT_SYSCALL_NR(r); syscall = UPT_SYSCALL_NR(r);
if((syscall >= NR_syscalls) || (syscall < 0)) if ((syscall >= NR_syscalls) || (syscall < 0))
result = -ENOSYS; result = -ENOSYS;
else result = EXECUTE_SYSCALL(syscall, regs); else result = EXECUTE_SYSCALL(syscall, regs);
......
/* /*
* Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com) * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL * Licensed under the GPL
*/ */
#include "linux/sched.h"
#include "linux/file.h" #include "linux/file.h"
#include "linux/smp_lock.h"
#include "linux/mm.h"
#include "linux/fs.h" #include "linux/fs.h"
#include "linux/mm.h"
#include "linux/sched.h"
#include "linux/utsname.h" #include "linux/utsname.h"
#include "linux/msg.h" #include "asm/current.h"
#include "linux/shm.h"
#include "linux/sys.h"
#include "linux/syscalls.h"
#include "linux/unistd.h"
#include "linux/slab.h"
#include "linux/utime.h"
#include "asm/mman.h" #include "asm/mman.h"
#include "asm/uaccess.h" #include "asm/uaccess.h"
#include "kern_util.h" #include "asm/unistd.h"
#include "sysdep/syscalls.h"
/* Unlocked, I don't care if this is a bit off */ /* Unlocked, I don't care if this is a bit off */
int nsyscalls = 0; int nsyscalls = 0;
...@@ -32,7 +24,7 @@ long sys_fork(void) ...@@ -32,7 +24,7 @@ long sys_fork(void)
ret = do_fork(SIGCHLD, UPT_SP(&current->thread.regs.regs), ret = do_fork(SIGCHLD, UPT_SP(&current->thread.regs.regs),
&current->thread.regs, 0, NULL, NULL); &current->thread.regs, 0, NULL, NULL);
current->thread.forking = 0; current->thread.forking = 0;
return(ret); return ret;
} }
long sys_vfork(void) long sys_vfork(void)
...@@ -44,7 +36,7 @@ long sys_vfork(void) ...@@ -44,7 +36,7 @@ long sys_vfork(void)
UPT_SP(&current->thread.regs.regs), UPT_SP(&current->thread.regs.regs),
&current->thread.regs, 0, NULL, NULL); &current->thread.regs, 0, NULL, NULL);
current->thread.forking = 0; current->thread.forking = 0;
return(ret); return ret;
} }
/* common code for old and new mmaps */ /* common code for old and new mmaps */
...@@ -90,15 +82,15 @@ long old_mmap(unsigned long addr, unsigned long len, ...@@ -90,15 +82,15 @@ long old_mmap(unsigned long addr, unsigned long len,
*/ */
long sys_pipe(unsigned long __user * fildes) long sys_pipe(unsigned long __user * fildes)
{ {
int fd[2]; int fd[2];
long error; long error;
error = do_pipe(fd); error = do_pipe(fd);
if (!error) { if (!error) {
if (copy_to_user(fildes, fd, sizeof(fd))) if (copy_to_user(fildes, fd, sizeof(fd)))
error = -EFAULT; error = -EFAULT;
} }
return error; return error;
} }
...@@ -122,7 +114,7 @@ long sys_olduname(struct oldold_utsname __user * name) ...@@ -122,7 +114,7 @@ long sys_olduname(struct oldold_utsname __user * name)
if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname))) if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
return -EFAULT; return -EFAULT;
down_read(&uts_sem); down_read(&uts_sem);
error = __copy_to_user(&name->sysname, &utsname()->sysname, error = __copy_to_user(&name->sysname, &utsname()->sysname,
__OLD_UTS_LEN); __OLD_UTS_LEN);
......
/* /*
* Copyright (C) 2000 Jeff Dike (jdike@karaya.com) * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL * Licensed under the GPL
*/ */
#include "linux/kernel.h"
#include "linux/module.h"
#include "linux/unistd.h"
#include "linux/stddef.h"
#include "linux/spinlock.h"
#include "linux/time.h"
#include "linux/sched.h"
#include "linux/interrupt.h" #include "linux/interrupt.h"
#include "linux/init.h" #include "linux/jiffies.h"
#include "linux/delay.h" #include "linux/threads.h"
#include "linux/hrtimer.h"
#include "asm/irq.h" #include "asm/irq.h"
#include "asm/param.h" #include "asm/param.h"
#include "asm/current.h"
#include "kern_util.h" #include "kern_util.h"
#include "os.h" #include "os.h"
int hz(void) int hz(void)
{ {
return(HZ); return HZ;
} }
/* /*
...@@ -43,7 +34,7 @@ void timer_irq(struct uml_pt_regs *regs) ...@@ -43,7 +34,7 @@ void timer_irq(struct uml_pt_regs *regs)
unsigned long long ticks = 0; unsigned long long ticks = 0;
#ifdef CONFIG_UML_REAL_TIME_CLOCK #ifdef CONFIG_UML_REAL_TIME_CLOCK
int c = cpu(); int c = cpu();
if(prev_nsecs[c]){ if (prev_nsecs[c]) {
/* We've had 1 tick */ /* We've had 1 tick */
unsigned long long nsecs = os_nsecs(); unsigned long long nsecs = os_nsecs();
...@@ -51,7 +42,7 @@ void timer_irq(struct uml_pt_regs *regs) ...@@ -51,7 +42,7 @@ void timer_irq(struct uml_pt_regs *regs)
prev_nsecs[c] = nsecs; prev_nsecs[c] = nsecs;
/* Protect against the host clock being set backwards */ /* Protect against the host clock being set backwards */
if(delta[c] < 0) if (delta[c] < 0)
delta[c] = 0; delta[c] = 0;
ticks += (delta[c] * HZ) / BILLION; ticks += (delta[c] * HZ) / BILLION;
...@@ -61,7 +52,7 @@ void timer_irq(struct uml_pt_regs *regs) ...@@ -61,7 +52,7 @@ void timer_irq(struct uml_pt_regs *regs)
#else #else
ticks = 1; ticks = 1;
#endif #endif
while(ticks > 0){ while (ticks > 0) {
do_IRQ(TIMER_IRQ, regs); do_IRQ(TIMER_IRQ, regs);
ticks--; ticks--;
} }
...@@ -112,12 +103,12 @@ static void register_timer(void) ...@@ -112,12 +103,12 @@ static void register_timer(void)
int err; int err;
err = request_irq(TIMER_IRQ, um_timer, IRQF_DISABLED, "timer", NULL); err = request_irq(TIMER_IRQ, um_timer, IRQF_DISABLED, "timer", NULL);
if(err != 0) if (err != 0)
printk(KERN_ERR "register_timer : request_irq failed - " printk(KERN_ERR "register_timer : request_irq failed - "
"errno = %d\n", -err); "errno = %d\n", -err);
err = set_interval(1); err = set_interval(1);
if(err != 0) if (err != 0)
printk(KERN_ERR "register_timer : set_interval failed - " printk(KERN_ERR "register_timer : set_interval failed - "
"errno = %d\n", -err); "errno = %d\n", -err);
} }
...@@ -144,7 +135,8 @@ void do_gettimeofday(struct timeval *tv) ...@@ -144,7 +135,8 @@ void do_gettimeofday(struct timeval *tv)
xtime.tv_nsec; xtime.tv_nsec;
#endif #endif
tv->tv_sec = nsecs / NSEC_PER_SEC; tv->tv_sec = nsecs / NSEC_PER_SEC;
/* Careful about calculations here - this was originally done as /*
* Careful about calculations here - this was originally done as
* (nsecs - tv->tv_sec * NSEC_PER_SEC) / NSEC_PER_USEC * (nsecs - tv->tv_sec * NSEC_PER_SEC) / NSEC_PER_USEC
* which gave bogus (> 1000000) values. Dunno why, suspect gcc * which gave bogus (> 1000000) values. Dunno why, suspect gcc
* (4.0.0) miscompiled it, or there's a subtle 64/32-bit conversion * (4.0.0) miscompiled it, or there's a subtle 64/32-bit conversion
...@@ -176,7 +168,7 @@ int do_settimeofday(struct timespec *tv) ...@@ -176,7 +168,7 @@ int do_settimeofday(struct timespec *tv)
void timer_handler(int sig, struct uml_pt_regs *regs) void timer_handler(int sig, struct uml_pt_regs *regs)
{ {
if(current_thread->cpu == 0) if (current_thread->cpu == 0)
timer_irq(regs); timer_irq(regs);
local_irq_disable(); local_irq_disable();
irq_enter(); irq_enter();
......
This diff is collapsed.
/* /*
* Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com) * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL * Licensed under the GPL
*/ */
#include "linux/kernel.h"
#include "linux/sched.h"
#include "linux/notifier.h"
#include "linux/mm.h"
#include "linux/types.h"
#include "linux/tty.h"
#include "linux/init.h"
#include "linux/bootmem.h"
#include "linux/spinlock.h"
#include "linux/utsname.h"
#include "linux/sysrq.h"
#include "linux/seq_file.h"
#include "linux/delay.h" #include "linux/delay.h"
#include "linux/mm.h"
#include "linux/module.h" #include "linux/module.h"
#include "linux/seq_file.h"
#include "linux/string.h"
#include "linux/utsname.h" #include "linux/utsname.h"
#include "asm/page.h"
#include "asm/pgtable.h" #include "asm/pgtable.h"
#include "asm/ptrace.h" #include "asm/processor.h"
#include "asm/elf.h"
#include "asm/user.h"
#include "asm/setup.h" #include "asm/setup.h"
#include "ubd_user.h"
#include "asm/current.h"
#include "kern_util.h"
#include "as-layout.h"
#include "arch.h" #include "arch.h"
#include "as-layout.h"
#include "init.h"
#include "kern.h" #include "kern.h"
#include "mem_user.h" #include "mem_user.h"
#include "mem.h"
#include "initrd.h"
#include "init.h"
#include "os.h" #include "os.h"
#include "skas.h" #include "skas.h"
...@@ -48,7 +31,7 @@ static void __init add_arg(char *arg) ...@@ -48,7 +31,7 @@ static void __init add_arg(char *arg)
printf("add_arg: Too many command line arguments!\n"); printf("add_arg: Too many command line arguments!\n");
exit(1); exit(1);
} }
if(strlen(command_line) > 0) if (strlen(command_line) > 0)
strcat(command_line, " "); strcat(command_line, " ");
strcat(command_line, arg); strcat(command_line, arg);
} }
...@@ -133,7 +116,7 @@ static int have_root __initdata = 0; ...@@ -133,7 +116,7 @@ static int have_root __initdata = 0;
/* Set in uml_mem_setup and modified in linux_main */ /* Set in uml_mem_setup and modified in linux_main */
long long physmem_size = 32 * 1024 * 1024; long long physmem_size = 32 * 1024 * 1024;
static char *usage_string = static char *usage_string =
"User Mode Linux v%s\n" "User Mode Linux v%s\n"
" available at http://user-mode-linux.sourceforge.net/\n\n"; " available at http://user-mode-linux.sourceforge.net/\n\n";
...@@ -191,7 +174,7 @@ static int __init uml_ncpus_setup(char *line, int *add) ...@@ -191,7 +174,7 @@ static int __init uml_ncpus_setup(char *line, int *add)
__uml_setup("ncpus=", uml_ncpus_setup, __uml_setup("ncpus=", uml_ncpus_setup,
"ncpus=<# of desired CPUs>\n" "ncpus=<# of desired CPUs>\n"
" This tells an SMP kernel how many virtual processors to start.\n\n" " This tells an SMP kernel how many virtual processors to start.\n\n"
); );
#endif #endif
...@@ -223,9 +206,8 @@ static int __init uml_checksetup(char *line, int *add) ...@@ -223,9 +206,8 @@ static int __init uml_checksetup(char *line, int *add)
int n; int n;
n = strlen(p->str); n = strlen(p->str);
if(!strncmp(line, p->str, n)){ if (!strncmp(line, p->str, n) && p->setup_func(line + n, add))
if (p->setup_func(line + n, add)) return 1; return 1;
}
p++; p++;
} }
return 0; return 0;
...@@ -236,7 +218,7 @@ static void __init uml_postsetup(void) ...@@ -236,7 +218,7 @@ static void __init uml_postsetup(void)
initcall_t *p; initcall_t *p;
p = &__uml_postsetup_start; p = &__uml_postsetup_start;
while(p < &__uml_postsetup_end){ while(p < &__uml_postsetup_end) {
(*p)(); (*p)();
p++; p++;
} }
...@@ -272,16 +254,18 @@ int __init linux_main(int argc, char **argv) ...@@ -272,16 +254,18 @@ int __init linux_main(int argc, char **argv)
unsigned int i, add; unsigned int i, add;
char * mode; char * mode;
for (i = 1; i < argc; i++){ for (i = 1; i < argc; i++) {
if((i == 1) && (argv[i][0] == ' ')) continue; if ((i == 1) && (argv[i][0] == ' '))
continue;
add = 1; add = 1;
uml_checksetup(argv[i], &add); uml_checksetup(argv[i], &add);
if (add) if (add)
add_arg(argv[i]); add_arg(argv[i]);
} }
if(have_root == 0) if (have_root == 0)
add_arg(DEFAULT_COMMAND_LINE); add_arg(DEFAULT_COMMAND_LINE);
/* OS sanity checks that need to happen before the kernel runs */
os_early_checks(); os_early_checks();
can_do_skas(); can_do_skas();
...@@ -302,12 +286,14 @@ int __init linux_main(int argc, char **argv) ...@@ -302,12 +286,14 @@ int __init linux_main(int argc, char **argv)
brk_start = (unsigned long) sbrk(0); brk_start = (unsigned long) sbrk(0);
/* Increase physical memory size for exec-shield users /*
so they actually get what they asked for. This should * Increase physical memory size for exec-shield users
add zero for non-exec shield users */ * so they actually get what they asked for. This should
* add zero for non-exec shield users
*/
diff = UML_ROUND_UP(brk_start) - UML_ROUND_UP(&_end); diff = UML_ROUND_UP(brk_start) - UML_ROUND_UP(&_end);
if(diff > 1024 * 1024){ if (diff > 1024 * 1024) {
printf("Adding %ld bytes to physical memory to account for " printf("Adding %ld bytes to physical memory to account for "
"exec-shield gap\n", diff); "exec-shield gap\n", diff);
physmem_size += UML_ROUND_UP(brk_start) - UML_ROUND_UP(&_end); physmem_size += UML_ROUND_UP(brk_start) - UML_ROUND_UP(&_end);
...@@ -324,11 +310,12 @@ int __init linux_main(int argc, char **argv) ...@@ -324,11 +310,12 @@ int __init linux_main(int argc, char **argv)
iomem_size = (iomem_size + PAGE_SIZE - 1) & PAGE_MASK; iomem_size = (iomem_size + PAGE_SIZE - 1) & PAGE_MASK;
max_physmem = get_kmem_end() - uml_physmem - iomem_size - MIN_VMALLOC; max_physmem = get_kmem_end() - uml_physmem - iomem_size - MIN_VMALLOC;
/* Zones have to begin on a 1 << MAX_ORDER page boundary, /*
* Zones have to begin on a 1 << MAX_ORDER page boundary,
* so this makes sure that's true for highmem * so this makes sure that's true for highmem
*/ */
max_physmem &= ~((1 << (PAGE_SHIFT + MAX_ORDER)) - 1); max_physmem &= ~((1 << (PAGE_SHIFT + MAX_ORDER)) - 1);
if(physmem_size + iomem_size > max_physmem){ if (physmem_size + iomem_size > max_physmem) {
highmem = physmem_size + iomem_size - max_physmem; highmem = physmem_size + iomem_size - max_physmem;
physmem_size -= highmem; physmem_size -= highmem;
#ifndef CONFIG_HIGHMEM #ifndef CONFIG_HIGHMEM
...@@ -345,7 +332,7 @@ int __init linux_main(int argc, char **argv) ...@@ -345,7 +332,7 @@ int __init linux_main(int argc, char **argv)
start_vm = VMALLOC_START; start_vm = VMALLOC_START;
setup_physmem(uml_physmem, uml_reserved, physmem_size, highmem); setup_physmem(uml_physmem, uml_reserved, physmem_size, highmem);
if(init_maps(physmem_size, iomem_size, highmem)){ if (init_maps(physmem_size, iomem_size, highmem)) {
printf("Failed to allocate mem_map for %Lu bytes of physical " printf("Failed to allocate mem_map for %Lu bytes of physical "
"memory and %Lu bytes of highmem\n", physmem_size, "memory and %Lu bytes of highmem\n", physmem_size,
highmem); highmem);
...@@ -354,10 +341,11 @@ int __init linux_main(int argc, char **argv) ...@@ -354,10 +341,11 @@ int __init linux_main(int argc, char **argv)
virtmem_size = physmem_size; virtmem_size = physmem_size;
avail = get_kmem_end() - start_vm; avail = get_kmem_end() - start_vm;
if(physmem_size > avail) virtmem_size = avail; if (physmem_size > avail)
virtmem_size = avail;
end_vm = start_vm + virtmem_size; end_vm = start_vm + virtmem_size;
if(virtmem_size < physmem_size) if (virtmem_size < physmem_size)
printf("Kernel virtual memory size shrunk to %lu bytes\n", printf("Kernel virtual memory size shrunk to %lu bytes\n",
virtmem_size); virtmem_size);
......
/* /*
* Copyright (C) 2004 Jeff Dike (jdike@addtoit.com) * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL * Licensed under the GPL
*/ */
#include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <sched.h>
#include <signal.h> #include <signal.h>
#include <errno.h> #include <errno.h>
#include <sched.h> #include <sys/time.h>
#include <sys/syscall.h> #include <asm/unistd.h>
#include "os.h"
#include "aio.h" #include "aio.h"
#include "init.h" #include "init.h"
#include "user.h"
#include "kern_constants.h" #include "kern_constants.h"
#include "os.h"
#include "user.h"
struct aio_thread_req { struct aio_thread_req {
enum aio_type type; enum aio_type type;
...@@ -27,7 +27,8 @@ struct aio_thread_req { ...@@ -27,7 +27,8 @@ struct aio_thread_req {
#if defined(HAVE_AIO_ABI) #if defined(HAVE_AIO_ABI)
#include <linux/aio_abi.h> #include <linux/aio_abi.h>
/* If we have the headers, we are going to build with AIO enabled. /*
* If we have the headers, we are going to build with AIO enabled.
* If we don't have aio in libc, we define the necessary stubs here. * If we don't have aio in libc, we define the necessary stubs here.
*/ */
...@@ -51,7 +52,8 @@ static long io_getevents(aio_context_t ctx_id, long min_nr, long nr, ...@@ -51,7 +52,8 @@ static long io_getevents(aio_context_t ctx_id, long min_nr, long nr,
#endif #endif
/* The AIO_MMAP cases force the mmapped page into memory here /*
* The AIO_MMAP cases force the mmapped page into memory here
* rather than in whatever place first touches the data. I used * rather than in whatever place first touches the data. I used
* to do this by touching the page, but that's delicate because * to do this by touching the page, but that's delicate because
* gcc is prone to optimizing that away. So, what's done here * gcc is prone to optimizing that away. So, what's done here
...@@ -105,12 +107,12 @@ static int aio_thread(void *arg) ...@@ -105,12 +107,12 @@ static int aio_thread(void *arg)
signal(SIGWINCH, SIG_IGN); signal(SIGWINCH, SIG_IGN);
while(1){ while (1) {
n = io_getevents(ctx, 1, 1, &event, NULL); n = io_getevents(ctx, 1, 1, &event, NULL);
if(n < 0){ if (n < 0) {
if(errno == EINTR) if (errno == EINTR)
continue; continue;
printk("aio_thread - io_getevents failed, " printk(UM_KERN_ERR "aio_thread - io_getevents failed, "
"errno = %d\n", errno); "errno = %d\n", errno);
} }
else { else {
...@@ -119,9 +121,9 @@ static int aio_thread(void *arg) ...@@ -119,9 +121,9 @@ static int aio_thread(void *arg)
.err = event.res }); .err = event.res });
reply_fd = ((struct aio_context *) reply.data)->reply_fd; reply_fd = ((struct aio_context *) reply.data)->reply_fd;
err = write(reply_fd, &reply, sizeof(reply)); err = write(reply_fd, &reply, sizeof(reply));
if(err != sizeof(reply)) if (err != sizeof(reply))
printk("aio_thread - write failed, fd = %d, " printk(UM_KERN_ERR "aio_thread - write failed, "
"err = %d\n", reply_fd, errno); "fd = %d, err = %d\n", reply_fd, errno);
} }
} }
return 0; return 0;
...@@ -136,10 +138,10 @@ static int do_not_aio(struct aio_thread_req *req) ...@@ -136,10 +138,10 @@ static int do_not_aio(struct aio_thread_req *req)
int n; int n;
actual = lseek64(req->io_fd, req->offset, SEEK_SET); actual = lseek64(req->io_fd, req->offset, SEEK_SET);
if(actual != req->offset) if (actual != req->offset)
return -errno; return -errno;
switch(req->type){ switch(req->type) {
case AIO_READ: case AIO_READ:
n = read(req->io_fd, req->buf, req->len); n = read(req->io_fd, req->buf, req->len);
break; break;
...@@ -150,11 +152,12 @@ static int do_not_aio(struct aio_thread_req *req) ...@@ -150,11 +152,12 @@ static int do_not_aio(struct aio_thread_req *req)
n = read(req->io_fd, &c, sizeof(c)); n = read(req->io_fd, &c, sizeof(c));
break; break;
default: default:
printk("do_not_aio - bad request type : %d\n", req->type); printk(UM_KERN_ERR "do_not_aio - bad request type : %d\n",
req->type);
return -EINVAL; return -EINVAL;
} }
if(n < 0) if (n < 0)
return -errno; return -errno;
return 0; return 0;
} }
...@@ -172,16 +175,18 @@ static int not_aio_thread(void *arg) ...@@ -172,16 +175,18 @@ static int not_aio_thread(void *arg)
int err; int err;
signal(SIGWINCH, SIG_IGN); signal(SIGWINCH, SIG_IGN);
while(1){ while (1) {
err = read(aio_req_fd_r, &req, sizeof(req)); err = read(aio_req_fd_r, &req, sizeof(req));
if(err != sizeof(req)){ if (err != sizeof(req)) {
if(err < 0) if (err < 0)
printk("not_aio_thread - read failed, " printk(UM_KERN_ERR "not_aio_thread - "
"fd = %d, err = %d\n", aio_req_fd_r, "read failed, fd = %d, err = %d\n",
aio_req_fd_r,
errno); errno);
else { else {
printk("not_aio_thread - short read, fd = %d, " printk(UM_KERN_ERR "not_aio_thread - short "
"length = %d\n", aio_req_fd_r, err); "read, fd = %d, length = %d\n",
aio_req_fd_r, err);
} }
continue; continue;
} }
...@@ -189,9 +194,9 @@ static int not_aio_thread(void *arg) ...@@ -189,9 +194,9 @@ static int not_aio_thread(void *arg)
reply = ((struct aio_thread_reply) { .data = req.aio, reply = ((struct aio_thread_reply) { .data = req.aio,
.err = err }); .err = err });
err = write(req.aio->reply_fd, &reply, sizeof(reply)); err = write(req.aio->reply_fd, &reply, sizeof(reply));
if(err != sizeof(reply)) if (err != sizeof(reply))
printk("not_aio_thread - write failed, fd = %d, " printk(UM_KERN_ERR "not_aio_thread - write failed, "
"err = %d\n", req.aio->reply_fd, errno); "fd = %d, err = %d\n", req.aio->reply_fd, errno);
} }
return 0; return 0;
...@@ -202,19 +207,19 @@ static int init_aio_24(void) ...@@ -202,19 +207,19 @@ static int init_aio_24(void)
int fds[2], err; int fds[2], err;
err = os_pipe(fds, 1, 1); err = os_pipe(fds, 1, 1);
if(err) if (err)
goto out; goto out;
aio_req_fd_w = fds[0]; aio_req_fd_w = fds[0];
aio_req_fd_r = fds[1]; aio_req_fd_r = fds[1];
err = os_set_fd_block(aio_req_fd_w, 0); err = os_set_fd_block(aio_req_fd_w, 0);
if(err) if (err)
goto out_close_pipe; goto out_close_pipe;
err = run_helper_thread(not_aio_thread, NULL, err = run_helper_thread(not_aio_thread, NULL,
CLONE_FILES | CLONE_VM | SIGCHLD, &aio_stack); CLONE_FILES | CLONE_VM | SIGCHLD, &aio_stack);
if(err < 0) if (err < 0)
goto out_close_pipe; goto out_close_pipe;
aio_pid = err; aio_pid = err;
...@@ -227,10 +232,11 @@ static int init_aio_24(void) ...@@ -227,10 +232,11 @@ static int init_aio_24(void)
aio_req_fd_r = -1; aio_req_fd_r = -1;
out: out:
#ifndef HAVE_AIO_ABI #ifndef HAVE_AIO_ABI
printk("/usr/include/linux/aio_abi.h not present during build\n"); printk(UM_KERN_INFO "/usr/include/linux/aio_abi.h not present during "
"build\n");
#endif #endif
printk("2.6 host AIO support not used - falling back to I/O " printk(UM_KERN_INFO "2.6 host AIO support not used - falling back to "
"thread\n"); "I/O thread\n");
return 0; return 0;
} }
...@@ -240,21 +246,21 @@ static int init_aio_26(void) ...@@ -240,21 +246,21 @@ static int init_aio_26(void)
{ {
int err; int err;
if(io_setup(256, &ctx)){ if (io_setup(256, &ctx)) {
err = -errno; err = -errno;
printk("aio_thread failed to initialize context, err = %d\n", printk(UM_KERN_ERR "aio_thread failed to initialize context, "
errno); "err = %d\n", errno);
return err; return err;
} }
err = run_helper_thread(aio_thread, NULL, err = run_helper_thread(aio_thread, NULL,
CLONE_FILES | CLONE_VM | SIGCHLD, &aio_stack); CLONE_FILES | CLONE_VM | SIGCHLD, &aio_stack);
if(err < 0) if (err < 0)
return err; return err;
aio_pid = err; aio_pid = err;
printk("Using 2.6 host AIO\n"); printk(UM_KERN_INFO "Using 2.6 host AIO\n");
return 0; return 0;
} }
...@@ -265,13 +271,13 @@ static int submit_aio_26(enum aio_type type, int io_fd, char *buf, int len, ...@@ -265,13 +271,13 @@ static int submit_aio_26(enum aio_type type, int io_fd, char *buf, int len,
int err; int err;
err = do_aio(ctx, type, io_fd, buf, len, offset, aio); err = do_aio(ctx, type, io_fd, buf, len, offset, aio);
if(err){ if (err) {
reply = ((struct aio_thread_reply) { .data = aio, reply = ((struct aio_thread_reply) { .data = aio,
.err = err }); .err = err });
err = write(aio->reply_fd, &reply, sizeof(reply)); err = write(aio->reply_fd, &reply, sizeof(reply));
if(err != sizeof(reply)){ if (err != sizeof(reply)) {
err = -errno; err = -errno;
printk("submit_aio_26 - write failed, " printk(UM_KERN_ERR "submit_aio_26 - write failed, "
"fd = %d, err = %d\n", aio->reply_fd, -err); "fd = %d, err = %d\n", aio->reply_fd, -err);
} }
else err = 0; else err = 0;
...@@ -319,23 +325,24 @@ static int init_aio(void) ...@@ -319,23 +325,24 @@ static int init_aio(void)
{ {
int err; int err;
if(!aio_24){ if (!aio_24) {
err = init_aio_26(); err = init_aio_26();
if(err && (errno == ENOSYS)){ if (err && (errno == ENOSYS)) {
printk("2.6 AIO not supported on the host - " printk(UM_KERN_INFO "2.6 AIO not supported on the "
"reverting to 2.4 AIO\n"); "host - reverting to 2.4 AIO\n");
aio_24 = 1; aio_24 = 1;
} }
else return err; else return err;
} }
if(aio_24) if (aio_24)
return init_aio_24(); return init_aio_24();
return 0; return 0;
} }
/* The reason for the __initcall/__uml_exitcall asymmetry is that init_aio /*
* The reason for the __initcall/__uml_exitcall asymmetry is that init_aio
* needs to be called when the kernel is running because it calls run_helper, * needs to be called when the kernel is running because it calls run_helper,
* which needs get_free_page. exit_aio is a __uml_exitcall because the generic * which needs get_free_page. exit_aio is a __uml_exitcall because the generic
* kernel does not run __exitcalls on shutdown, and can't because many of them * kernel does not run __exitcalls on shutdown, and can't because many of them
...@@ -366,7 +373,7 @@ static int submit_aio_24(enum aio_type type, int io_fd, char *buf, int len, ...@@ -366,7 +373,7 @@ static int submit_aio_24(enum aio_type type, int io_fd, char *buf, int len,
int err; int err;
err = write(aio_req_fd_w, &req, sizeof(req)); err = write(aio_req_fd_w, &req, sizeof(req));
if(err == sizeof(req)) if (err == sizeof(req))
err = 0; err = 0;
else err = -errno; else err = -errno;
...@@ -378,9 +385,8 @@ int submit_aio(enum aio_type type, int io_fd, char *buf, int len, ...@@ -378,9 +385,8 @@ int submit_aio(enum aio_type type, int io_fd, char *buf, int len,
struct aio_context *aio) struct aio_context *aio)
{ {
aio->reply_fd = reply_fd; aio->reply_fd = reply_fd;
if(aio_24) if (aio_24)
return submit_aio_24(type, io_fd, buf, len, offset, aio); return submit_aio_24(type, io_fd, buf, len, offset, aio);
else { else
return submit_aio_26(type, io_fd, buf, len, offset, aio); return submit_aio_26(type, io_fd, buf, len, offset, aio);
}
} }
...@@ -267,9 +267,9 @@ void os_close_file(int fd) ...@@ -267,9 +267,9 @@ void os_close_file(int fd)
close(fd); close(fd);
} }
int os_seek_file(int fd, __u64 offset) int os_seek_file(int fd, unsigned long long offset)
{ {
__u64 actual; unsigned long long actual;
actual = lseek64(fd, offset, SEEK_SET); actual = lseek64(fd, offset, SEEK_SET);
if(actual != offset) if(actual != offset)
......
/* /*
* Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com) * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL * Licensed under the GPL
*/ */
#include <unistd.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <unistd.h>
#include <signal.h>
#include <errno.h> #include <errno.h>
#include <signal.h>
#include <string.h>
#include <sys/resource.h> #include <sys/resource.h>
#include <sys/mman.h>
#include <sys/user.h>
#include "kern_util.h"
#include "as-layout.h" #include "as-layout.h"
#include "mem_user.h"
#include "irq_user.h"
#include "user.h"
#include "init.h" #include "init.h"
#include "uml-config.h" #include "kern_constants.h"
#include "kern_util.h"
#include "os.h" #include "os.h"
#include "um_malloc.h" #include "um_malloc.h"
#include "kern_constants.h"
#define PGD_BOUND (4 * 1024 * 1024) #define PGD_BOUND (4 * 1024 * 1024)
#define STACKSIZE (8 * 1024 * 1024) #define STACKSIZE (8 * 1024 * 1024)
...@@ -31,13 +25,13 @@ static void set_stklim(void) ...@@ -31,13 +25,13 @@ static void set_stklim(void)
{ {
struct rlimit lim; struct rlimit lim;
if(getrlimit(RLIMIT_STACK, &lim) < 0){ if (getrlimit(RLIMIT_STACK, &lim) < 0) {
perror("getrlimit"); perror("getrlimit");
exit(1); exit(1);
} }
if((lim.rlim_cur == RLIM_INFINITY) || (lim.rlim_cur > STACKSIZE)){ if ((lim.rlim_cur == RLIM_INFINITY) || (lim.rlim_cur > STACKSIZE)) {
lim.rlim_cur = STACKSIZE; lim.rlim_cur = STACKSIZE;
if(setrlimit(RLIMIT_STACK, &lim) < 0){ if (setrlimit(RLIMIT_STACK, &lim) < 0) {
perror("setrlimit"); perror("setrlimit");
exit(1); exit(1);
} }
...@@ -49,7 +43,7 @@ static __init void do_uml_initcalls(void) ...@@ -49,7 +43,7 @@ static __init void do_uml_initcalls(void)
initcall_t *call; initcall_t *call;
call = &__uml_initcall_start; call = &__uml_initcall_start;
while (call < &__uml_initcall_end){ while (call < &__uml_initcall_end) {
(*call)(); (*call)();
call++; call++;
} }
...@@ -68,7 +62,8 @@ static void install_fatal_handler(int sig) ...@@ -68,7 +62,8 @@ static void install_fatal_handler(int sig)
/* All signals are enabled in this handler ... */ /* All signals are enabled in this handler ... */
sigemptyset(&action.sa_mask); sigemptyset(&action.sa_mask);
/* ... including the signal being handled, plus we want the /*
* ... including the signal being handled, plus we want the
* handler reset to the default behavior, so that if an exit * handler reset to the default behavior, so that if an exit
* handler is hanging for some reason, the UML will just die * handler is hanging for some reason, the UML will just die
* after this signal is sent a second time. * after this signal is sent a second time.
...@@ -76,7 +71,7 @@ static void install_fatal_handler(int sig) ...@@ -76,7 +71,7 @@ static void install_fatal_handler(int sig)
action.sa_flags = SA_RESETHAND | SA_NODEFER; action.sa_flags = SA_RESETHAND | SA_NODEFER;
action.sa_restorer = NULL; action.sa_restorer = NULL;
action.sa_handler = last_ditch_exit; action.sa_handler = last_ditch_exit;
if(sigaction(sig, &action, NULL) < 0){ if (sigaction(sig, &action, NULL) < 0) {
printf("failed to install handler for signal %d - errno = %d\n", printf("failed to install handler for signal %d - errno = %d\n",
errno); errno);
exit(1); exit(1);
...@@ -92,7 +87,8 @@ static void setup_env_path(void) ...@@ -92,7 +87,8 @@ static void setup_env_path(void)
int path_len = 0; int path_len = 0;
old_path = getenv("PATH"); old_path = getenv("PATH");
/* if no PATH variable is set or it has an empty value /*
* if no PATH variable is set or it has an empty value
* just use the default + /usr/lib/uml * just use the default + /usr/lib/uml
*/ */
if (!old_path || (path_len = strlen(old_path)) == 0) { if (!old_path || (path_len = strlen(old_path)) == 0) {
...@@ -125,38 +121,41 @@ int __init main(int argc, char **argv, char **envp) ...@@ -125,38 +121,41 @@ int __init main(int argc, char **argv, char **envp)
setup_env_path(); setup_env_path();
new_argv = malloc((argc + 1) * sizeof(char *)); new_argv = malloc((argc + 1) * sizeof(char *));
if(new_argv == NULL){ if (new_argv == NULL) {
perror("Mallocing argv"); perror("Mallocing argv");
exit(1); exit(1);
} }
for(i=0;i<argc;i++){ for (i = 0; i < argc; i++) {
new_argv[i] = strdup(argv[i]); new_argv[i] = strdup(argv[i]);
if(new_argv[i] == NULL){ if (new_argv[i] == NULL) {
perror("Mallocing an arg"); perror("Mallocing an arg");
exit(1); exit(1);
} }
} }
new_argv[argc] = NULL; new_argv[argc] = NULL;
/* Allow these signals to bring down a UML if all other /*
* Allow these signals to bring down a UML if all other
* methods of control fail. * methods of control fail.
*/ */
install_fatal_handler(SIGINT); install_fatal_handler(SIGINT);
install_fatal_handler(SIGTERM); install_fatal_handler(SIGTERM);
install_fatal_handler(SIGHUP); install_fatal_handler(SIGHUP);
scan_elf_aux( envp); scan_elf_aux(envp);
do_uml_initcalls(); do_uml_initcalls();
ret = linux_main(argc, argv); ret = linux_main(argc, argv);
/* Disable SIGPROF - I have no idea why libc doesn't do this or turn /*
* Disable SIGPROF - I have no idea why libc doesn't do this or turn
* off the profiling time, but UML dies with a SIGPROF just before * off the profiling time, but UML dies with a SIGPROF just before
* exiting when profiling is active. * exiting when profiling is active.
*/ */
change_sig(SIGPROF, 0); change_sig(SIGPROF, 0);
/* This signal stuff used to be in the reboot case. However, /*
* This signal stuff used to be in the reboot case. However,
* sometimes a SIGVTALRM can come in when we're halting (reproducably * sometimes a SIGVTALRM can come in when we're halting (reproducably
* when writing out gcov information, presumably because that takes * when writing out gcov information, presumably because that takes
* some time) and cause a segfault. * some time) and cause a segfault.
...@@ -167,17 +166,18 @@ int __init main(int argc, char **argv, char **envp) ...@@ -167,17 +166,18 @@ int __init main(int argc, char **argv, char **envp)
/* disable SIGIO for the fds and set SIGIO to be ignored */ /* disable SIGIO for the fds and set SIGIO to be ignored */
err = deactivate_all_fds(); err = deactivate_all_fds();
if(err) if (err)
printf("deactivate_all_fds failed, errno = %d\n", -err); printf("deactivate_all_fds failed, errno = %d\n", -err);
/* Let any pending signals fire now. This ensures /*
* Let any pending signals fire now. This ensures
* that they won't be delivered after the exec, when * that they won't be delivered after the exec, when
* they are definitely not expected. * they are definitely not expected.
*/ */
unblock_signals(); unblock_signals();
/* Reboot */ /* Reboot */
if(ret){ if (ret) {
printf("\n"); printf("\n");
execvp(new_argv[0], new_argv); execvp(new_argv[0], new_argv);
perror("Failed to exec kernel"); perror("Failed to exec kernel");
...@@ -193,17 +193,18 @@ void *__wrap_malloc(int size) ...@@ -193,17 +193,18 @@ void *__wrap_malloc(int size)
{ {
void *ret; void *ret;
if(!kmalloc_ok) if (!kmalloc_ok)
return __real_malloc(size); return __real_malloc(size);
else if(size <= UM_KERN_PAGE_SIZE) else if (size <= UM_KERN_PAGE_SIZE)
/* finding contiguous pages can be hard*/ /* finding contiguous pages can be hard*/
ret = kmalloc(size, UM_GFP_KERNEL); ret = kmalloc(size, UM_GFP_KERNEL);
else ret = vmalloc(size); else ret = vmalloc(size);
/* glibc people insist that if malloc fails, errno should be /*
* glibc people insist that if malloc fails, errno should be
* set by malloc as well. So we do. * set by malloc as well. So we do.
*/ */
if(ret == NULL) if (ret == NULL)
errno = ENOMEM; errno = ENOMEM;
return ret; return ret;
...@@ -213,7 +214,7 @@ void *__wrap_calloc(int n, int size) ...@@ -213,7 +214,7 @@ void *__wrap_calloc(int n, int size)
{ {
void *ptr = __wrap_malloc(n * size); void *ptr = __wrap_malloc(n * size);
if(ptr == NULL) if (ptr == NULL)
return NULL; return NULL;
memset(ptr, 0, n * size); memset(ptr, 0, n * size);
return ptr; return ptr;
...@@ -227,7 +228,8 @@ void __wrap_free(void *ptr) ...@@ -227,7 +228,8 @@ void __wrap_free(void *ptr)
{ {
unsigned long addr = (unsigned long) ptr; unsigned long addr = (unsigned long) ptr;
/* We need to know how the allocation happened, so it can be correctly /*
* We need to know how the allocation happened, so it can be correctly
* freed. This is done by seeing what region of memory the pointer is * freed. This is done by seeing what region of memory the pointer is
* in - * in -
* physical memory - kmalloc/kfree * physical memory - kmalloc/kfree
...@@ -245,12 +247,12 @@ void __wrap_free(void *ptr) ...@@ -245,12 +247,12 @@ void __wrap_free(void *ptr)
* there is a possibility for memory leaks. * there is a possibility for memory leaks.
*/ */
if((addr >= uml_physmem) && (addr < high_physmem)){ if ((addr >= uml_physmem) && (addr < high_physmem)) {
if(kmalloc_ok) if (kmalloc_ok)
kfree(ptr); kfree(ptr);
} }
else if((addr >= start_vm) && (addr < end_vm)){ else if ((addr >= start_vm) && (addr < end_vm)) {
if(kmalloc_ok) if (kmalloc_ok)
vfree(ptr); vfree(ptr);
} }
else __real_free(ptr); else __real_free(ptr);
......
/* /*
* Copyright (C) 2002 Jeff Dike (jdike@addtoit.com) * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL * Licensed under the GPL
*/ */
#include <unistd.h>
#include <stdio.h> #include <stdio.h>
#include <unistd.h>
#include <errno.h> #include <errno.h>
#include <signal.h> #include <signal.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/ptrace.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <sys/mman.h> #include <asm/unistd.h>
#include <sys/syscall.h> #include "init.h"
#include "ptrace_user.h" #include "kern_constants.h"
#include "longjmp.h"
#include "os.h" #include "os.h"
#include "user.h"
#include "process.h" #include "process.h"
#include "irq_user.h"
#include "kern_util.h"
#include "longjmp.h"
#include "skas_ptrace.h" #include "skas_ptrace.h"
#include "kern_constants.h" #include "user.h"
#include "uml-config.h"
#include "init.h"
#define ARBITRARY_ADDR -1 #define ARBITRARY_ADDR -1
#define FAILURE_PID -1 #define FAILURE_PID -1
...@@ -37,24 +33,25 @@ unsigned long os_process_pc(int pid) ...@@ -37,24 +33,25 @@ unsigned long os_process_pc(int pid)
sprintf(proc_stat, "/proc/%d/stat", pid); sprintf(proc_stat, "/proc/%d/stat", pid);
fd = os_open_file(proc_stat, of_read(OPENFLAGS()), 0); fd = os_open_file(proc_stat, of_read(OPENFLAGS()), 0);
if(fd < 0){ if (fd < 0) {
printk("os_process_pc - couldn't open '%s', err = %d\n", printk(UM_KERN_ERR "os_process_pc - couldn't open '%s', "
proc_stat, -fd); "err = %d\n", proc_stat, -fd);
return ARBITRARY_ADDR; return ARBITRARY_ADDR;
} }
CATCH_EINTR(err = read(fd, buf, sizeof(buf))); CATCH_EINTR(err = read(fd, buf, sizeof(buf)));
if(err < 0){ if (err < 0) {
printk("os_process_pc - couldn't read '%s', err = %d\n", printk(UM_KERN_ERR "os_process_pc - couldn't read '%s', "
proc_stat, errno); "err = %d\n", proc_stat, errno);
os_close_file(fd); os_close_file(fd);
return ARBITRARY_ADDR; return ARBITRARY_ADDR;
} }
os_close_file(fd); os_close_file(fd);
pc = ARBITRARY_ADDR; pc = ARBITRARY_ADDR;
if(sscanf(buf, "%*d " COMM_SCANF " %*c %*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 %*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); printk(UM_KERN_ERR "os_process_pc - couldn't find pc in '%s'\n",
buf);
} }
return pc; return pc;
} }
...@@ -65,28 +62,29 @@ int os_process_parent(int pid) ...@@ -65,28 +62,29 @@ int os_process_parent(int pid)
char data[256]; char data[256];
int parent, n, fd; int parent, n, fd;
if(pid == -1) if (pid == -1)
return -1; return -1;
snprintf(stat, sizeof(stat), "/proc/%d/stat", pid); snprintf(stat, sizeof(stat), "/proc/%d/stat", pid);
fd = os_open_file(stat, of_read(OPENFLAGS()), 0); fd = os_open_file(stat, of_read(OPENFLAGS()), 0);
if(fd < 0){ if (fd < 0) {
printk("Couldn't open '%s', err = %d\n", stat, -fd); printk(UM_KERN_ERR "Couldn't open '%s', err = %d\n", stat, -fd);
return FAILURE_PID; return FAILURE_PID;
} }
CATCH_EINTR(n = read(fd, data, sizeof(data))); CATCH_EINTR(n = read(fd, data, sizeof(data)));
os_close_file(fd); os_close_file(fd);
if(n < 0){ if (n < 0) {
printk("Couldn't read '%s', err = %d\n", stat, errno); printk(UM_KERN_ERR "Couldn't read '%s', err = %d\n", stat,
errno);
return FAILURE_PID; return FAILURE_PID;
} }
parent = FAILURE_PID; parent = FAILURE_PID;
n = sscanf(data, "%*d " COMM_SCANF " %*c %d", &parent); n = sscanf(data, "%*d " COMM_SCANF " %*c %d", &parent);
if(n != 1) if (n != 1)
printk("Failed to scan '%s'\n", data); printk(UM_KERN_ERR "Failed to scan '%s'\n", data);
return parent; return parent;
} }
...@@ -99,9 +97,8 @@ void os_stop_process(int pid) ...@@ -99,9 +97,8 @@ void os_stop_process(int pid)
void os_kill_process(int pid, int reap_child) void os_kill_process(int pid, int reap_child)
{ {
kill(pid, SIGKILL); kill(pid, SIGKILL);
if(reap_child) if (reap_child)
CATCH_EINTR(waitpid(pid, NULL, 0)); CATCH_EINTR(waitpid(pid, NULL, 0));
} }
/* This is here uniquely to have access to the userspace errno, i.e. the one /* This is here uniquely to have access to the userspace errno, i.e. the one
...@@ -129,7 +126,7 @@ void os_kill_ptraced_process(int pid, int reap_child) ...@@ -129,7 +126,7 @@ void os_kill_ptraced_process(int pid, int reap_child)
kill(pid, SIGKILL); kill(pid, SIGKILL);
ptrace(PTRACE_KILL, pid); ptrace(PTRACE_KILL, pid);
ptrace(PTRACE_CONT, pid); ptrace(PTRACE_CONT, pid);
if(reap_child) if (reap_child)
CATCH_EINTR(waitpid(pid, NULL, 0)); CATCH_EINTR(waitpid(pid, NULL, 0));
} }
...@@ -153,34 +150,35 @@ int os_map_memory(void *virt, int fd, unsigned long long off, unsigned long len, ...@@ -153,34 +150,35 @@ int os_map_memory(void *virt, int fd, unsigned long long off, unsigned long len,
void *loc; void *loc;
int prot; int prot;
prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
(x ? PROT_EXEC : 0); (x ? PROT_EXEC : 0);
loc = mmap64((void *) virt, len, prot, MAP_SHARED | MAP_FIXED, loc = mmap64((void *) virt, len, prot, MAP_SHARED | MAP_FIXED,
fd, off); fd, off);
if(loc == MAP_FAILED) if (loc == MAP_FAILED)
return -errno; return -errno;
return 0; return 0;
} }
int os_protect_memory(void *addr, unsigned long len, int r, int w, int x) int os_protect_memory(void *addr, unsigned long len, int r, int w, int x)
{ {
int prot = ((r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | int prot = ((r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
(x ? PROT_EXEC : 0)); (x ? PROT_EXEC : 0));
if(mprotect(addr, len, prot) < 0) if (mprotect(addr, len, prot) < 0)
return -errno; return -errno;
return 0;
return 0;
} }
int os_unmap_memory(void *addr, int len) int os_unmap_memory(void *addr, int len)
{ {
int err; int err;
err = munmap(addr, len); err = munmap(addr, len);
if(err < 0) if (err < 0)
return -errno; return -errno;
return 0; return 0;
} }
#ifndef MADV_REMOVE #ifndef MADV_REMOVE
...@@ -192,7 +190,7 @@ int os_drop_memory(void *addr, int length) ...@@ -192,7 +190,7 @@ int os_drop_memory(void *addr, int length)
int err; int err;
err = madvise(addr, length, MADV_REMOVE); err = madvise(addr, length, MADV_REMOVE);
if(err < 0) if (err < 0)
err = -errno; err = -errno;
return err; return err;
} }
...@@ -202,22 +200,24 @@ int __init can_drop_memory(void) ...@@ -202,22 +200,24 @@ int __init can_drop_memory(void)
void *addr; void *addr;
int fd, ok = 0; int fd, ok = 0;
printk("Checking host MADV_REMOVE support..."); printk(UM_KERN_INFO "Checking host MADV_REMOVE support...");
fd = create_mem_file(UM_KERN_PAGE_SIZE); fd = create_mem_file(UM_KERN_PAGE_SIZE);
if(fd < 0){ if (fd < 0) {
printk("Creating test memory file failed, err = %d\n", -fd); printk(UM_KERN_ERR "Creating test memory file failed, "
"err = %d\n", -fd);
goto out; goto out;
} }
addr = mmap64(NULL, UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE, addr = mmap64(NULL, UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, 0); MAP_SHARED, fd, 0);
if(addr == MAP_FAILED){ if (addr == MAP_FAILED) {
printk("Mapping test memory file failed, err = %d\n", -errno); printk(UM_KERN_ERR "Mapping test memory file failed, "
"err = %d\n", -errno);
goto out_close; goto out_close;
} }
if(madvise(addr, UM_KERN_PAGE_SIZE, MADV_REMOVE) != 0){ if (madvise(addr, UM_KERN_PAGE_SIZE, MADV_REMOVE) != 0) {
printk("MADV_REMOVE failed, err = %d\n", -errno); printk(UM_KERN_ERR "MADV_REMOVE failed, err = %d\n", -errno);
goto out_unmap; goto out_unmap;
} }
...@@ -256,7 +256,7 @@ int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr) ...@@ -256,7 +256,7 @@ int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr)
*jmp_ptr = &buf; *jmp_ptr = &buf;
n = UML_SETJMP(&buf); n = UML_SETJMP(&buf);
if(n != 0) if (n != 0)
return n; return n;
(*fn)(arg); (*fn)(arg);
return 0; return 0;
......
/* /*
* Copyright (C) 2004 PathScale, Inc * Copyright (C) 2004 PathScale, Inc
* Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL * Licensed under the GPL
*/ */
#include <errno.h> #include <errno.h>
#include <string.h> #include <string.h>
#include <sys/ptrace.h> #include <sys/ptrace.h>
#include "user.h"
#include "sysdep/ptrace.h" #include "sysdep/ptrace.h"
#include "user.h"
/* This is set once at boot time and not changed thereafter */ /* This is set once at boot time and not changed thereafter */
...@@ -23,7 +24,7 @@ void save_registers(int pid, struct uml_pt_regs *regs) ...@@ -23,7 +24,7 @@ void save_registers(int pid, struct uml_pt_regs *regs)
int err; int err;
err = ptrace(PTRACE_GETREGS, pid, 0, regs->regs); err = ptrace(PTRACE_GETREGS, pid, 0, regs->regs);
if(err < 0) if (err < 0)
panic("save_registers - saving registers failed, errno = %d\n", panic("save_registers - saving registers failed, errno = %d\n",
errno); errno);
} }
...@@ -33,7 +34,7 @@ void restore_registers(int pid, struct uml_pt_regs *regs) ...@@ -33,7 +34,7 @@ void restore_registers(int pid, struct uml_pt_regs *regs)
int err; int err;
err = ptrace(PTRACE_SETREGS, pid, 0, regs->regs); err = ptrace(PTRACE_SETREGS, pid, 0, regs->regs);
if(err < 0) if (err < 0)
panic("restore_registers - saving registers failed, " panic("restore_registers - saving registers failed, "
"errno = %d\n", errno); "errno = %d\n", errno);
} }
...@@ -43,7 +44,7 @@ void init_registers(int pid) ...@@ -43,7 +44,7 @@ void init_registers(int pid)
int err; int err;
err = ptrace(PTRACE_GETREGS, pid, 0, exec_regs); err = ptrace(PTRACE_GETREGS, pid, 0, exec_regs);
if(err) if (err)
panic("check_ptrace : PTRACE_GETREGS failed, errno = %d", panic("check_ptrace : PTRACE_GETREGS failed, errno = %d",
errno); errno);
} }
......
/* /*
* Copyright (C) 2004 PathScale, Inc * Copyright (C) 2004 PathScale, Inc
* Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL * Licensed under the GPL
*/ */
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h> #include <stdlib.h>
#include <errno.h>
#include <stdarg.h> #include <stdarg.h>
#include <string.h> #include <errno.h>
#include <sys/mman.h> #include <signal.h>
#include "user.h" #include <strings.h>
#include "signal_kern.h"
#include "sysdep/sigcontext.h"
#include "sysdep/barrier.h"
#include "sigcontext.h"
#include "os.h" #include "os.h"
#include "sysdep/barrier.h"
#include "sysdep/sigcontext.h"
#include "user.h"
/* These are the asynchronous signals. SIGVTALRM and SIGARLM are handled /*
* These are the asynchronous signals. SIGVTALRM and SIGARLM are handled
* together under SIGVTALRM_BIT. SIGPROF is excluded because we want to * together under SIGVTALRM_BIT. SIGPROF is excluded because we want to
* be able to profile all of UML, not just the non-critical sections. If * be able to profile all of UML, not just the non-critical sections. If
* profiling is not thread-safe, then that is not my problem. We can disable * profiling is not thread-safe, then that is not my problem. We can disable
...@@ -33,7 +30,8 @@ ...@@ -33,7 +30,8 @@
#define SIGALRM_BIT 2 #define SIGALRM_BIT 2
#define SIGALRM_MASK (1 << SIGALRM_BIT) #define SIGALRM_MASK (1 << SIGALRM_BIT)
/* These are used by both the signal handlers and /*
* These are used by both the signal handlers and
* block/unblock_signals. I don't want modifications cached in a * block/unblock_signals. I don't want modifications cached in a
* register - they must go straight to memory. * register - they must go straight to memory.
*/ */
...@@ -45,7 +43,7 @@ void sig_handler(int sig, struct sigcontext *sc) ...@@ -45,7 +43,7 @@ void sig_handler(int sig, struct sigcontext *sc)
int enabled; int enabled;
enabled = signals_enabled; enabled = signals_enabled;
if(!enabled && (sig == SIGIO)){ if (!enabled && (sig == SIGIO)) {
pending |= SIGIO_MASK; pending |= SIGIO_MASK;
return; return;
} }
...@@ -61,16 +59,16 @@ static void real_alarm_handler(int sig, struct sigcontext *sc) ...@@ -61,16 +59,16 @@ static void real_alarm_handler(int sig, struct sigcontext *sc)
{ {
struct uml_pt_regs regs; struct uml_pt_regs regs;
if(sig == SIGALRM) if (sig == SIGALRM)
switch_timers(0); switch_timers(0);
if(sc != NULL) if (sc != NULL)
copy_sc(&regs, sc); copy_sc(&regs, sc);
regs.is_user = 0; regs.is_user = 0;
unblock_signals(); unblock_signals();
timer_handler(sig, &regs); timer_handler(sig, &regs);
if(sig == SIGALRM) if (sig == SIGALRM)
switch_timers(1); switch_timers(1);
} }
...@@ -79,8 +77,8 @@ void alarm_handler(int sig, struct sigcontext *sc) ...@@ -79,8 +77,8 @@ void alarm_handler(int sig, struct sigcontext *sc)
int enabled; int enabled;
enabled = signals_enabled; enabled = signals_enabled;
if(!signals_enabled){ if (!signals_enabled) {
if(sig == SIGVTALRM) if (sig == SIGVTALRM)
pending |= SIGVTALRM_MASK; pending |= SIGVTALRM_MASK;
else pending |= SIGALRM_MASK; else pending |= SIGALRM_MASK;
...@@ -99,7 +97,7 @@ void set_sigstack(void *sig_stack, int size) ...@@ -99,7 +97,7 @@ void set_sigstack(void *sig_stack, int size)
.ss_sp = (__ptr_t) sig_stack, .ss_sp = (__ptr_t) sig_stack,
.ss_size = size - sizeof(void *) }); .ss_size = size - sizeof(void *) });
if(sigaltstack(&stack, NULL) != 0) if (sigaltstack(&stack, NULL) != 0)
panic("enabling signal stack failed, errno = %d\n", errno); panic("enabling signal stack failed, errno = %d\n", errno);
} }
...@@ -109,7 +107,7 @@ void remove_sigstack(void) ...@@ -109,7 +107,7 @@ void remove_sigstack(void)
.ss_sp = NULL, .ss_sp = NULL,
.ss_size = 0 }); .ss_size = 0 });
if(sigaltstack(&stack, NULL) != 0) if (sigaltstack(&stack, NULL) != 0)
panic("disabling signal stack failed, errno = %d\n", errno); panic("disabling signal stack failed, errno = %d\n", errno);
} }
...@@ -133,26 +131,27 @@ void handle_signal(int sig, struct sigcontext *sc) ...@@ -133,26 +131,27 @@ void handle_signal(int sig, struct sigcontext *sc)
* with this interrupt. * with this interrupt.
*/ */
bail = to_irq_stack(&pending); bail = to_irq_stack(&pending);
if(bail) if (bail)
return; return;
nested = pending & 1; nested = pending & 1;
pending &= ~1; pending &= ~1;
while((sig = ffs(pending)) != 0){ while ((sig = ffs(pending)) != 0){
sig--; sig--;
pending &= ~(1 << sig); pending &= ~(1 << sig);
(*handlers[sig])(sig, sc); (*handlers[sig])(sig, sc);
} }
/* Again, pending comes back with a mask of signals /*
* Again, pending comes back with a mask of signals
* that arrived while tearing down the stack. If this * that arrived while tearing down the stack. If this
* is non-zero, we just go back, set up the stack * is non-zero, we just go back, set up the stack
* again, and handle the new interrupts. * again, and handle the new interrupts.
*/ */
if(!nested) if (!nested)
pending = from_irq_stack(nested); pending = from_irq_stack(nested);
} while(pending); } while (pending);
} }
extern void hard_handler(int sig); extern void hard_handler(int sig);
...@@ -170,18 +169,18 @@ void set_handler(int sig, void (*handler)(int), int flags, ...) ...@@ -170,18 +169,18 @@ void set_handler(int sig, void (*handler)(int), int flags, ...)
sigemptyset(&action.sa_mask); sigemptyset(&action.sa_mask);
va_start(ap, flags); va_start(ap, flags);
while((mask = va_arg(ap, int)) != -1) while ((mask = va_arg(ap, int)) != -1)
sigaddset(&action.sa_mask, mask); sigaddset(&action.sa_mask, mask);
va_end(ap); va_end(ap);
action.sa_flags = flags; action.sa_flags = flags;
action.sa_restorer = NULL; action.sa_restorer = NULL;
if(sigaction(sig, &action, NULL) < 0) if (sigaction(sig, &action, NULL) < 0)
panic("sigaction failed - errno = %d\n", errno); panic("sigaction failed - errno = %d\n", errno);
sigemptyset(&sig_mask); sigemptyset(&sig_mask);
sigaddset(&sig_mask, sig); sigaddset(&sig_mask, sig);
if(sigprocmask(SIG_UNBLOCK, &sig_mask, NULL) < 0) if (sigprocmask(SIG_UNBLOCK, &sig_mask, NULL) < 0)
panic("sigprocmask failed - errno = %d\n", errno); panic("sigprocmask failed - errno = %d\n", errno);
} }
...@@ -192,13 +191,14 @@ int change_sig(int signal, int on) ...@@ -192,13 +191,14 @@ int change_sig(int signal, int on)
sigemptyset(&sigset); sigemptyset(&sigset);
sigaddset(&sigset, signal); sigaddset(&sigset, signal);
sigprocmask(on ? SIG_UNBLOCK : SIG_BLOCK, &sigset, &old); sigprocmask(on ? SIG_UNBLOCK : SIG_BLOCK, &sigset, &old);
return(!sigismember(&old, signal)); return !sigismember(&old, signal);
} }
void block_signals(void) void block_signals(void)
{ {
signals_enabled = 0; signals_enabled = 0;
/* This must return with signals disabled, so this barrier /*
* This must return with signals disabled, so this barrier
* ensures that writes are flushed out before the return. * ensures that writes are flushed out before the return.
* This might matter if gcc figures out how to inline this and * This might matter if gcc figures out how to inline this and
* decides to shuffle this code into the caller. * decides to shuffle this code into the caller.
...@@ -210,27 +210,31 @@ void unblock_signals(void) ...@@ -210,27 +210,31 @@ void unblock_signals(void)
{ {
int save_pending; int save_pending;
if(signals_enabled == 1) if (signals_enabled == 1)
return; return;
/* We loop because the IRQ handler returns with interrupts off. So, /*
* We loop because the IRQ handler returns with interrupts off. So,
* interrupts may have arrived and we need to re-enable them and * interrupts may have arrived and we need to re-enable them and
* recheck pending. * recheck pending.
*/ */
while(1){ while(1) {
/* Save and reset save_pending after enabling signals. This /*
* Save and reset save_pending after enabling signals. This
* way, pending won't be changed while we're reading it. * way, pending won't be changed while we're reading it.
*/ */
signals_enabled = 1; signals_enabled = 1;
/* Setting signals_enabled and reading pending must /*
* Setting signals_enabled and reading pending must
* happen in this order. * happen in this order.
*/ */
mb(); mb();
save_pending = pending; save_pending = pending;
if(save_pending == 0){ if (save_pending == 0) {
/* This must return with signals enabled, so /*
* This must return with signals enabled, so
* this barrier ensures that writes are * this barrier ensures that writes are
* flushed out before the return. This might * flushed out before the return. This might
* matter if gcc figures out how to inline * matter if gcc figures out how to inline
...@@ -243,24 +247,26 @@ void unblock_signals(void) ...@@ -243,24 +247,26 @@ void unblock_signals(void)
pending = 0; pending = 0;
/* We have pending interrupts, so disable signals, as the /*
* We have pending interrupts, so disable signals, as the
* handlers expect them off when they are called. They will * handlers expect them off when they are called. They will
* be enabled again above. * be enabled again above.
*/ */
signals_enabled = 0; signals_enabled = 0;
/* Deal with SIGIO first because the alarm handler might /*
* Deal with SIGIO first because the alarm handler might
* schedule, leaving the pending SIGIO stranded until we come * schedule, leaving the pending SIGIO stranded until we come
* back here. * back here.
*/ */
if(save_pending & SIGIO_MASK) if (save_pending & SIGIO_MASK)
sig_handler_common_skas(SIGIO, NULL); sig_handler_common_skas(SIGIO, NULL);
if(save_pending & SIGALRM_MASK) if (save_pending & SIGALRM_MASK)
real_alarm_handler(SIGALRM, NULL); real_alarm_handler(SIGALRM, NULL);
if(save_pending & SIGVTALRM_MASK) if (save_pending & SIGVTALRM_MASK)
real_alarm_handler(SIGVTALRM, NULL); real_alarm_handler(SIGVTALRM, NULL);
} }
} }
...@@ -273,11 +279,11 @@ int get_signals(void) ...@@ -273,11 +279,11 @@ int get_signals(void)
int set_signals(int enable) int set_signals(int enable)
{ {
int ret; int ret;
if(signals_enabled == enable) if (signals_enabled == enable)
return enable; return enable;
ret = signals_enabled; ret = signals_enabled;
if(enable) if (enable)
unblock_signals(); unblock_signals();
else block_signals(); else block_signals();
......
/* /*
* Copyright (C) 2002 Jeff Dike (jdike@karaya.com) * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL * Licensed under the GPL
*/ */
#include <signal.h> #include <stddef.h>
#include <unistd.h>
#include <errno.h> #include <errno.h>
#include <string.h> #include <string.h>
#include <unistd.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/wait.h> #include "init.h"
#include <asm/unistd.h> #include "kern_constants.h"
#include "mem_user.h" #include "mm_id.h"
#include "mem.h"
#include "skas.h"
#include "user.h"
#include "os.h" #include "os.h"
#include "proc_mm.h" #include "proc_mm.h"
#include "ptrace_user.h" #include "ptrace_user.h"
#include "kern_util.h"
#include "task.h"
#include "registers.h" #include "registers.h"
#include "uml-config.h" #include "skas.h"
#include "user.h"
#include "sysdep/ptrace.h" #include "sysdep/ptrace.h"
#include "sysdep/stub.h" #include "sysdep/stub.h"
#include "init.h" #include "uml-config.h"
#include "kern_constants.h"
extern unsigned long batch_syscall_stub, __syscall_stub_start; extern unsigned long batch_syscall_stub, __syscall_stub_start;
...@@ -33,7 +28,7 @@ extern void wait_stub_done(int pid); ...@@ -33,7 +28,7 @@ extern void wait_stub_done(int pid);
static inline unsigned long *check_init_stack(struct mm_id * mm_idp, static inline unsigned long *check_init_stack(struct mm_id * mm_idp,
unsigned long *stack) unsigned long *stack)
{ {
if(stack == NULL) { if (stack == NULL) {
stack = (unsigned long *) mm_idp->stack + 2; stack = (unsigned long *) mm_idp->stack + 2;
*stack = 0; *stack = 0;
} }
...@@ -67,29 +62,30 @@ static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr) ...@@ -67,29 +62,30 @@ static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr)
unsigned long * syscall; unsigned long * syscall;
int err, pid = mm_idp->u.pid; int err, pid = mm_idp->u.pid;
if(proc_mm) if (proc_mm)
/* FIXME: Need to look up userspace_pid by cpu */ /* FIXME: Need to look up userspace_pid by cpu */
pid = userspace_pid[0]; pid = userspace_pid[0];
multi_count++; multi_count++;
n = ptrace_setregs(pid, syscall_regs); n = ptrace_setregs(pid, syscall_regs);
if(n < 0){ if (n < 0) {
printk("Registers - \n"); printk(UM_KERN_ERR "Registers - \n");
for(i = 0; i < MAX_REG_NR; i++) for (i = 0; i < MAX_REG_NR; i++)
printk("\t%d\t0x%lx\n", i, syscall_regs[i]); printk(UM_KERN_ERR "\t%d\t0x%lx\n", i, syscall_regs[i]);
panic("do_syscall_stub : PTRACE_SETREGS failed, errno = %d\n", panic("do_syscall_stub : PTRACE_SETREGS failed, errno = %d\n",
-n); -n);
} }
err = ptrace(PTRACE_CONT, pid, 0, 0); err = ptrace(PTRACE_CONT, pid, 0, 0);
if(err) if (err)
panic("Failed to continue stub, pid = %d, errno = %d\n", pid, panic("Failed to continue stub, pid = %d, errno = %d\n", pid,
errno); errno);
wait_stub_done(pid); wait_stub_done(pid);
/* When the stub stops, we find the following values on the /*
* When the stub stops, we find the following values on the
* beginning of the stack: * beginning of the stack:
* (long )return_value * (long )return_value
* (long )offset to failed sycall-data (0, if no error) * (long )offset to failed sycall-data (0, if no error)
...@@ -99,24 +95,25 @@ static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr) ...@@ -99,24 +95,25 @@ static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr)
if (offset) { if (offset) {
data = (unsigned long *)(mm_idp->stack + data = (unsigned long *)(mm_idp->stack +
offset - UML_CONFIG_STUB_DATA); offset - UML_CONFIG_STUB_DATA);
printk("do_syscall_stub : ret = %ld, offset = %ld, " printk(UM_KERN_ERR "do_syscall_stub : ret = %ld, offset = %ld, "
"data = %p\n", ret, offset, data); "data = %p\n", ret, offset, data);
syscall = (unsigned long *)((unsigned long)data + data[0]); syscall = (unsigned long *)((unsigned long)data + data[0]);
printk("do_syscall_stub: syscall %ld failed, return value = " printk(UM_KERN_ERR "do_syscall_stub: syscall %ld failed, "
"0x%lx, expected return value = 0x%lx\n", "return value = 0x%lx, expected return value = 0x%lx\n",
syscall[0], ret, syscall[7]); syscall[0], ret, syscall[7]);
printk(" syscall parameters: " printk(UM_KERN_ERR " syscall parameters: "
"0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx\n", "0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx\n",
syscall[1], syscall[2], syscall[3], syscall[1], syscall[2], syscall[3],
syscall[4], syscall[5], syscall[6]); syscall[4], syscall[5], syscall[6]);
for(n = 1; n < data[0]/sizeof(long); n++) { for (n = 1; n < data[0]/sizeof(long); n++) {
if(n == 1) if (n == 1)
printk(" additional syscall data:"); printk(UM_KERN_ERR " additional syscall "
if(n % 4 == 1) "data:");
printk("\n "); if (n % 4 == 1)
printk("\n" UM_KERN_ERR " ");
printk(" 0x%lx", data[n]); printk(" 0x%lx", data[n]);
} }
if(n > 1) if (n > 1)
printk("\n"); printk("\n");
} }
else ret = 0; else ret = 0;
...@@ -132,7 +129,7 @@ long run_syscall_stub(struct mm_id * mm_idp, int syscall, ...@@ -132,7 +129,7 @@ long run_syscall_stub(struct mm_id * mm_idp, int syscall,
{ {
unsigned long *stack = check_init_stack(mm_idp, *addr); unsigned long *stack = check_init_stack(mm_idp, *addr);
if(done && *addr == NULL) if (done && *addr == NULL)
single_count++; single_count++;
*stack += sizeof(long); *stack += sizeof(long);
...@@ -149,8 +146,8 @@ long run_syscall_stub(struct mm_id * mm_idp, int syscall, ...@@ -149,8 +146,8 @@ long run_syscall_stub(struct mm_id * mm_idp, int syscall,
*stack = 0; *stack = 0;
multi_op_count++; multi_op_count++;
if(!done && ((((unsigned long) stack) & ~UM_KERN_PAGE_MASK) < if (!done && ((((unsigned long) stack) & ~UM_KERN_PAGE_MASK) <
UM_KERN_PAGE_SIZE - 10 * sizeof(long))){ UM_KERN_PAGE_SIZE - 10 * sizeof(long))) {
*addr = stack; *addr = stack;
return 0; return 0;
} }
...@@ -165,14 +162,15 @@ long syscall_stub_data(struct mm_id * mm_idp, ...@@ -165,14 +162,15 @@ long syscall_stub_data(struct mm_id * mm_idp,
unsigned long *stack; unsigned long *stack;
int ret = 0; int ret = 0;
/* If *addr still is uninitialized, it *must* contain NULL. /*
* If *addr still is uninitialized, it *must* contain NULL.
* Thus in this case do_syscall_stub correctly won't be called. * Thus in this case do_syscall_stub correctly won't be called.
*/ */
if((((unsigned long) *addr) & ~UM_KERN_PAGE_MASK) >= if ((((unsigned long) *addr) & ~UM_KERN_PAGE_MASK) >=
UM_KERN_PAGE_SIZE - (10 + data_count) * sizeof(long)) { UM_KERN_PAGE_SIZE - (10 + data_count) * sizeof(long)) {
ret = do_syscall_stub(mm_idp, addr); ret = do_syscall_stub(mm_idp, addr);
/* in case of error, don't overwrite data on stack */ /* in case of error, don't overwrite data on stack */
if(ret) if (ret)
return ret; return ret;
} }
...@@ -194,7 +192,7 @@ int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len, int prot, ...@@ -194,7 +192,7 @@ int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len, int prot,
{ {
int ret; int ret;
if(proc_mm){ if (proc_mm) {
struct proc_mm_op map; struct proc_mm_op map;
int fd = mm_idp->u.mm_fd; int fd = mm_idp->u.mm_fd;
...@@ -210,9 +208,10 @@ int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len, int prot, ...@@ -210,9 +208,10 @@ int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len, int prot,
.offset= offset .offset= offset
} } } ); } } } );
CATCH_EINTR(ret = write(fd, &map, sizeof(map))); CATCH_EINTR(ret = write(fd, &map, sizeof(map)));
if(ret != sizeof(map)){ if (ret != sizeof(map)) {
ret = -errno; ret = -errno;
printk("map : /proc/mm map failed, err = %d\n", -ret); printk(UM_KERN_ERR "map : /proc/mm map failed, "
"err = %d\n", -ret);
} }
else ret = 0; else ret = 0;
} }
...@@ -233,7 +232,7 @@ int unmap(struct mm_id * mm_idp, unsigned long addr, unsigned long len, ...@@ -233,7 +232,7 @@ int unmap(struct mm_id * mm_idp, unsigned long addr, unsigned long len,
{ {
int ret; int ret;
if(proc_mm){ if (proc_mm) {
struct proc_mm_op unmap; struct proc_mm_op unmap;
int fd = mm_idp->u.mm_fd; int fd = mm_idp->u.mm_fd;
...@@ -244,9 +243,10 @@ int unmap(struct mm_id * mm_idp, unsigned long addr, unsigned long len, ...@@ -244,9 +243,10 @@ int unmap(struct mm_id * mm_idp, unsigned long addr, unsigned long len,
(unsigned long) addr, (unsigned long) addr,
.len = len } } } ); .len = len } } } );
CATCH_EINTR(ret = write(fd, &unmap, sizeof(unmap))); CATCH_EINTR(ret = write(fd, &unmap, sizeof(unmap)));
if(ret != sizeof(unmap)){ if (ret != sizeof(unmap)) {
ret = -errno; ret = -errno;
printk("unmap - proc_mm write returned %d\n", ret); printk(UM_KERN_ERR "unmap - proc_mm write returned "
"%d\n", ret);
} }
else ret = 0; else ret = 0;
} }
...@@ -267,7 +267,7 @@ int protect(struct mm_id * mm_idp, unsigned long addr, unsigned long len, ...@@ -267,7 +267,7 @@ int protect(struct mm_id * mm_idp, unsigned long addr, unsigned long len,
struct proc_mm_op protect; struct proc_mm_op protect;
int ret; int ret;
if(proc_mm){ if (proc_mm) {
int fd = mm_idp->u.mm_fd; int fd = mm_idp->u.mm_fd;
protect = ((struct proc_mm_op) { .op = MM_MPROTECT, protect = ((struct proc_mm_op) { .op = MM_MPROTECT,
...@@ -279,9 +279,9 @@ int protect(struct mm_id * mm_idp, unsigned long addr, unsigned long len, ...@@ -279,9 +279,9 @@ int protect(struct mm_id * mm_idp, unsigned long addr, unsigned long len,
.prot = prot } } } ); .prot = prot } } } );
CATCH_EINTR(ret = write(fd, &protect, sizeof(protect))); CATCH_EINTR(ret = write(fd, &protect, sizeof(protect)));
if(ret != sizeof(protect)){ if (ret != sizeof(protect)) {
ret = -errno; ret = -errno;
printk("protect failed, err = %d", -ret); printk(UM_KERN_ERR "protect failed, err = %d", -ret);
} }
else ret = 0; else ret = 0;
} }
......
This diff is collapsed.
/* /*
* Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com) * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL * Licensed under the GPL
*/ */
#include <signal.h> #if 0
#include <errno.h>
#include "kern_util.h" #include "kern_util.h"
#include "as-layout.h"
#include "task.h"
#include "sigcontext.h"
#include "skas.h" #include "skas.h"
#include "ptrace_user.h" #include "ptrace_user.h"
#include "sysdep/ptrace.h"
#include "sysdep/ptrace_user.h" #include "sysdep/ptrace_user.h"
#endif
#include <errno.h>
#include <signal.h>
#include "sysdep/ptrace.h"
#include "kern_constants.h"
#include "as-layout.h"
#include "os.h" #include "os.h"
#include "sigcontext.h"
#include "task.h"
static struct uml_pt_regs ksig_regs[UM_NR_CPUS]; static struct uml_pt_regs ksig_regs[UM_NR_CPUS];
...@@ -24,14 +28,16 @@ void sig_handler_common_skas(int sig, void *sc_ptr) ...@@ -24,14 +28,16 @@ void sig_handler_common_skas(int sig, void *sc_ptr)
void (*handler)(int, struct uml_pt_regs *); void (*handler)(int, struct uml_pt_regs *);
int save_user, save_errno = errno; int save_user, save_errno = errno;
/* This is done because to allow SIGSEGV to be delivered inside a SEGV /*
* This is done because to allow SIGSEGV to be delivered inside a SEGV
* handler. This can happen in copy_user, and if SEGV is disabled, * handler. This can happen in copy_user, and if SEGV is disabled,
* the process will die. * the process will die.
* XXX Figure out why this is better than SA_NODEFER * XXX Figure out why this is better than SA_NODEFER
*/ */
if(sig == SIGSEGV) { if (sig == SIGSEGV) {
change_sig(SIGSEGV, 1); change_sig(SIGSEGV, 1);
/* For segfaults, we want the data from the /*
* For segfaults, we want the data from the
* sigcontext. In this case, we don't want to mangle * sigcontext. In this case, we don't want to mangle
* the process registers, so use a static set of * the process registers, so use a static set of
* registers. For other signals, the process * registers. For other signals, the process
...@@ -44,11 +50,9 @@ void sig_handler_common_skas(int sig, void *sc_ptr) ...@@ -44,11 +50,9 @@ void sig_handler_common_skas(int sig, void *sc_ptr)
save_user = r->is_user; save_user = r->is_user;
r->is_user = 0; r->is_user = 0;
if ( sig == SIGFPE || sig == SIGSEGV || if ((sig == SIGFPE) || (sig == SIGSEGV) || (sig == SIGBUS) ||
sig == SIGBUS || sig == SIGILL || (sig == SIGILL) || (sig == SIGTRAP))
sig == SIGTRAP ) {
GET_FAULTINFO_FROM_SC(r->faultinfo, sc); GET_FAULTINFO_FROM_SC(r->faultinfo, sc);
}
change_sig(SIGUSR1, 1); change_sig(SIGUSR1, 1);
......
This diff is collapsed.
/* /*
* Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL * Licensed under the GPL
*/ */
#include <stdlib.h>
#include <signal.h> #include <signal.h>
#include "kern_util.h"
#include "os.h" #include "os.h"
#include "longjmp.h" #include "sysdep/ptrace.h"
/* Initialized from linux_main() */ /* Initialized from linux_main() */
void (*sig_info[NSIG])(int, struct uml_pt_regs *); void (*sig_info[NSIG])(int, struct uml_pt_regs *);
......
/*
* Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
#include <stdio.h> #include <stdio.h>
#include <unistd.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <dirent.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h>
#include <signal.h> #include <signal.h>
#include <dirent.h> #include <string.h>
#include <sys/fcntl.h> #include <unistd.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/param.h>
#include "init.h" #include "init.h"
#include "kern_constants.h"
#include "os.h" #include "os.h"
#include "user.h" #include "user.h"
...@@ -27,13 +32,13 @@ static int __init make_uml_dir(void) ...@@ -27,13 +32,13 @@ static int __init make_uml_dir(void)
char dir[512] = { '\0' }; char dir[512] = { '\0' };
int len, err; int len, err;
if(*uml_dir == '~'){ if (*uml_dir == '~') {
char *home = getenv("HOME"); char *home = getenv("HOME");
err = -ENOENT; err = -ENOENT;
if(home == NULL){ if (home == NULL) {
printk("make_uml_dir : no value in environment for " printk(UM_KERN_ERR "make_uml_dir : no value in "
"$HOME\n"); "environment for $HOME\n");
goto err; goto err;
} }
strlcpy(dir, home, sizeof(dir)); strlcpy(dir, home, sizeof(dir));
...@@ -52,7 +57,7 @@ static int __init make_uml_dir(void) ...@@ -52,7 +57,7 @@ static int __init make_uml_dir(void)
} }
strcpy(uml_dir, dir); strcpy(uml_dir, dir);
if((mkdir(uml_dir, 0777) < 0) && (errno != EEXIST)){ if ((mkdir(uml_dir, 0777) < 0) && (errno != EEXIST)) {
printf("Failed to mkdir '%s': %s\n", uml_dir, strerror(errno)); printf("Failed to mkdir '%s': %s\n", uml_dir, strerror(errno));
err = -errno; err = -errno;
goto err_free; goto err_free;
...@@ -69,8 +74,8 @@ static int __init make_uml_dir(void) ...@@ -69,8 +74,8 @@ static int __init make_uml_dir(void)
/* /*
* Unlinks the files contained in @dir and then removes @dir. * Unlinks the files contained in @dir and then removes @dir.
* Doesn't handle directory trees, so it's not like rm -rf, but almost such. We * Doesn't handle directory trees, so it's not like rm -rf, but almost such. We
* ignore ENOENT errors for anything (they happen, strangely enough - possibly due * ignore ENOENT errors for anything (they happen, strangely enough - possibly
* to races between multiple dying UML threads). * due to races between multiple dying UML threads).
*/ */
static int remove_files_and_dir(char *dir) static int remove_files_and_dir(char *dir)
{ {
...@@ -115,7 +120,8 @@ static int remove_files_and_dir(char *dir) ...@@ -115,7 +120,8 @@ static int remove_files_and_dir(char *dir)
return ret; return ret;
} }
/* This says that there isn't already a user of the specified directory even if /*
* This says that there isn't already a user of the specified directory even if
* there are errors during the checking. This is because if these errors * there are errors during the checking. This is because if these errors
* happen, the directory is unusable by the pre-existing UML, so we might as * happen, the directory is unusable by the pre-existing UML, so we might as
* well take it over. This could happen either by * well take it over. This could happen either by
...@@ -133,44 +139,45 @@ static inline int is_umdir_used(char *dir) ...@@ -133,44 +139,45 @@ static inline int is_umdir_used(char *dir)
int dead, fd, p, n, err; int dead, fd, p, n, err;
n = snprintf(file, sizeof(file), "%s/pid", dir); n = snprintf(file, sizeof(file), "%s/pid", dir);
if(n >= sizeof(file)){ if (n >= sizeof(file)) {
printk("is_umdir_used - pid filename too long\n"); printk(UM_KERN_ERR "is_umdir_used - pid filename too long\n");
err = -E2BIG; err = -E2BIG;
goto out; goto out;
} }
dead = 0; dead = 0;
fd = open(file, O_RDONLY); fd = open(file, O_RDONLY);
if(fd < 0) { if (fd < 0) {
fd = -errno; fd = -errno;
if(fd != -ENOENT){ if (fd != -ENOENT) {
printk("is_umdir_used : couldn't open pid file '%s', " printk(UM_KERN_ERR "is_umdir_used : couldn't open pid "
"err = %d\n", file, -fd); "file '%s', err = %d\n", file, -fd);
} }
goto out; goto out;
} }
err = 0; err = 0;
n = read(fd, pid, sizeof(pid)); n = read(fd, pid, sizeof(pid));
if(n < 0){ if (n < 0) {
printk("is_umdir_used : couldn't read pid file '%s', " printk(UM_KERN_ERR "is_umdir_used : couldn't read pid file "
"err = %d\n", file, errno); "'%s', err = %d\n", file, errno);
goto out_close; goto out_close;
} else if(n == 0){ } else if (n == 0) {
printk("is_umdir_used : couldn't read pid file '%s', " printk(UM_KERN_ERR "is_umdir_used : couldn't read pid file "
"0-byte read\n", file); "'%s', 0-byte read\n", file);
goto out_close; goto out_close;
} }
p = strtoul(pid, &end, 0); p = strtoul(pid, &end, 0);
if(end == pid){ if (end == pid) {
printk("is_umdir_used : couldn't parse pid file '%s', " printk(UM_KERN_ERR "is_umdir_used : couldn't parse pid file "
"errno = %d\n", file, errno); "'%s', errno = %d\n", file, errno);
goto out_close; goto out_close;
} }
if((kill(p, 0) == 0) || (errno != ESRCH)){ if ((kill(p, 0) == 0) || (errno != ESRCH)) {
printk("umid \"%s\" is already in use by pid %d\n", umid, p); printk(UM_KERN_ERR "umid \"%s\" is already in use by pid %d\n",
umid, p);
return 1; return 1;
} }
...@@ -194,8 +201,8 @@ static int umdir_take_if_dead(char *dir) ...@@ -194,8 +201,8 @@ static int umdir_take_if_dead(char *dir)
ret = remove_files_and_dir(dir); ret = remove_files_and_dir(dir);
if (ret) { if (ret) {
printk("is_umdir_used - remove_files_and_dir failed with " printk(UM_KERN_ERR "is_umdir_used - remove_files_and_dir "
"err = %d\n", ret); "failed with err = %d\n", ret);
} }
return ret; return ret;
} }
...@@ -206,27 +213,28 @@ static void __init create_pid_file(void) ...@@ -206,27 +213,28 @@ static void __init create_pid_file(void)
char pid[sizeof("nnnnn\0")]; char pid[sizeof("nnnnn\0")];
int fd, n; int fd, n;
if(umid_file_name("pid", file, sizeof(file))) if (umid_file_name("pid", file, sizeof(file)))
return; return;
fd = open(file, O_RDWR | O_CREAT | O_EXCL, 0644); fd = open(file, O_RDWR | O_CREAT | O_EXCL, 0644);
if(fd < 0){ if (fd < 0) {
printk("Open of machine pid file \"%s\" failed: %s\n", printk(UM_KERN_ERR "Open of machine pid file \"%s\" failed: "
file, strerror(errno)); "%s\n", file, strerror(errno));
return; return;
} }
snprintf(pid, sizeof(pid), "%d\n", getpid()); snprintf(pid, sizeof(pid), "%d\n", getpid());
n = write(fd, pid, strlen(pid)); n = write(fd, pid, strlen(pid));
if(n != strlen(pid)) if (n != strlen(pid))
printk("Write of pid file failed - err = %d\n", errno); printk(UM_KERN_ERR "Write of pid file failed - err = %d\n",
errno);
close(fd); close(fd);
} }
int __init set_umid(char *name) int __init set_umid(char *name)
{ {
if(strlen(name) > UMID_LEN - 1) if (strlen(name) > UMID_LEN - 1)
return -E2BIG; return -E2BIG;
strlcpy(umid, name, sizeof(umid)); strlcpy(umid, name, sizeof(umid));
...@@ -242,18 +250,18 @@ int __init make_umid(void) ...@@ -242,18 +250,18 @@ int __init make_umid(void)
int fd, err; int fd, err;
char tmp[256]; char tmp[256];
if(umid_setup) if (umid_setup)
return 0; return 0;
make_uml_dir(); make_uml_dir();
if(*umid == '\0'){ if (*umid == '\0') {
strlcpy(tmp, uml_dir, sizeof(tmp)); strlcpy(tmp, uml_dir, sizeof(tmp));
strlcat(tmp, "XXXXXX", sizeof(tmp)); strlcat(tmp, "XXXXXX", sizeof(tmp));
fd = mkstemp(tmp); fd = mkstemp(tmp);
if(fd < 0){ if (fd < 0) {
printk("make_umid - mkstemp(%s) failed: %s\n", printk(UM_KERN_ERR "make_umid - mkstemp(%s) failed: "
tmp, strerror(errno)); "%s\n", tmp, strerror(errno));
err = -errno; err = -errno;
goto err; goto err;
} }
...@@ -262,11 +270,12 @@ int __init make_umid(void) ...@@ -262,11 +270,12 @@ int __init make_umid(void)
set_umid(&tmp[strlen(uml_dir)]); set_umid(&tmp[strlen(uml_dir)]);
/* There's a nice tiny little race between this unlink and /*
* There's a nice tiny little race between this unlink and
* the mkdir below. It'd be nice if there were a mkstemp * the mkdir below. It'd be nice if there were a mkstemp
* for directories. * for directories.
*/ */
if(unlink(tmp)){ if (unlink(tmp)) {
err = -errno; err = -errno;
goto err; goto err;
} }
...@@ -274,9 +283,9 @@ int __init make_umid(void) ...@@ -274,9 +283,9 @@ int __init make_umid(void)
snprintf(tmp, sizeof(tmp), "%s%s", uml_dir, umid); snprintf(tmp, sizeof(tmp), "%s%s", uml_dir, umid);
err = mkdir(tmp, 0777); err = mkdir(tmp, 0777);
if(err < 0){ if (err < 0) {
err = -errno; err = -errno;
if(err != -EEXIST) if (err != -EEXIST)
goto err; goto err;
if (umdir_take_if_dead(tmp) < 0) if (umdir_take_if_dead(tmp) < 0)
...@@ -284,9 +293,10 @@ int __init make_umid(void) ...@@ -284,9 +293,10 @@ int __init make_umid(void)
err = mkdir(tmp, 0777); err = mkdir(tmp, 0777);
} }
if(err){ if (err) {
err = -errno; err = -errno;
printk("Failed to create '%s' - err = %d\n", umid, -errno); printk(UM_KERN_ERR "Failed to create '%s' - err = %d\n", umid,
errno);
goto err; goto err;
} }
...@@ -301,14 +311,15 @@ int __init make_umid(void) ...@@ -301,14 +311,15 @@ int __init make_umid(void)
static int __init make_umid_init(void) static int __init make_umid_init(void)
{ {
if(!make_umid()) if (!make_umid())
return 0; return 0;
/* If initializing with the given umid failed, then try again with /*
* If initializing with the given umid failed, then try again with
* a random one. * a random one.
*/ */
printk("Failed to initialize umid \"%s\", trying with a random umid\n", printk(UM_KERN_ERR "Failed to initialize umid \"%s\", trying with a "
umid); "random umid\n", umid);
*umid = '\0'; *umid = '\0';
make_umid(); make_umid();
...@@ -322,12 +333,12 @@ int __init umid_file_name(char *name, char *buf, int len) ...@@ -322,12 +333,12 @@ int __init umid_file_name(char *name, char *buf, int len)
int n, err; int n, err;
err = make_umid(); err = make_umid();
if(err) if (err)
return err; return err;
n = snprintf(buf, len, "%s%s/%s", uml_dir, umid, name); n = snprintf(buf, len, "%s%s/%s", uml_dir, umid, name);
if(n >= len){ if (n >= len) {
printk("umid_file_name : buffer too short\n"); printk(UM_KERN_ERR "umid_file_name : buffer too short\n");
return -E2BIG; return -E2BIG;
} }
...@@ -341,21 +352,22 @@ char *get_umid(void) ...@@ -341,21 +352,22 @@ char *get_umid(void)
static int __init set_uml_dir(char *name, int *add) static int __init set_uml_dir(char *name, int *add)
{ {
if(*name == '\0'){ if (*name == '\0') {
printf("uml_dir can't be an empty string\n"); printf("uml_dir can't be an empty string\n");
return 0; return 0;
} }
if(name[strlen(name) - 1] == '/'){ if (name[strlen(name) - 1] == '/') {
uml_dir = name; uml_dir = name;
return 0; return 0;
} }
uml_dir = malloc(strlen(name) + 2); uml_dir = malloc(strlen(name) + 2);
if(uml_dir == NULL){ if (uml_dir == NULL) {
printf("Failed to malloc uml_dir - error = %d\n", errno); printf("Failed to malloc uml_dir - error = %d\n", errno);
/* Return 0 here because do_initcalls doesn't look at /*
* Return 0 here because do_initcalls doesn't look at
* the return value. * the return value.
*/ */
return 0; return 0;
...@@ -376,7 +388,7 @@ static void remove_umid_dir(void) ...@@ -376,7 +388,7 @@ static void remove_umid_dir(void)
sprintf(dir, "%s%s", uml_dir, umid); sprintf(dir, "%s%s", uml_dir, umid);
err = remove_files_and_dir(dir); err = remove_files_and_dir(dir);
if(err) if (err)
printf("remove_umid_dir - remove_files_and_dir failed with " printf("remove_umid_dir - remove_files_and_dir failed with "
"err = %d\n", err); "err = %d\n", err);
} }
......
/* /*
* Copyright (C) 2002 Jeff Dike (jdike@karaya.com) * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL * Licensed under the GPL
*/ */
#include <unistd.h>
#include <errno.h> #include <errno.h>
#include <signal.h>
#include <string.h> #include <string.h>
#include <sys/signal.h> #include "kern_constants.h"
#include <asm/ldt.h>
#include "kern_util.h"
#include "user.h"
#include "sysdep/ptrace.h"
#include "task.h"
#include "os.h" #include "os.h"
#include "task.h"
#include "user.h"
#define MAXTOKEN 64 #define MAXTOKEN 64
...@@ -30,18 +27,20 @@ static char token(int fd, char *buf, int len, char stop) ...@@ -30,18 +27,20 @@ static char token(int fd, char *buf, int len, char stop)
do { do {
n = os_read_file(fd, ptr, sizeof(*ptr)); n = os_read_file(fd, ptr, sizeof(*ptr));
c = *ptr++; c = *ptr++;
if(n != sizeof(*ptr)){ if (n != sizeof(*ptr)) {
if(n == 0) if (n == 0)
return 0; return 0;
printk("Reading /proc/cpuinfo failed, err = %d\n", -n); printk(UM_KERN_ERR "Reading /proc/cpuinfo failed, "
if(n < 0) "err = %d\n", -n);
if (n < 0)
return n; return n;
else return -EIO; else return -EIO;
} }
} while((c != '\n') && (c != stop) && (ptr < end)); } while ((c != '\n') && (c != stop) && (ptr < end));
if(ptr == end){ if (ptr == end) {
printk("Failed to find '%c' in /proc/cpuinfo\n", stop); printk(UM_KERN_ERR "Failed to find '%c' in /proc/cpuinfo\n",
stop);
return -1; return -1;
} }
*(ptr - 1) = '\0'; *(ptr - 1) = '\0';
...@@ -54,26 +53,27 @@ static int find_cpuinfo_line(int fd, char *key, char *scratch, int len) ...@@ -54,26 +53,27 @@ static int find_cpuinfo_line(int fd, char *key, char *scratch, int len)
char c; char c;
scratch[len - 1] = '\0'; scratch[len - 1] = '\0';
while(1){ while (1) {
c = token(fd, scratch, len - 1, ':'); c = token(fd, scratch, len - 1, ':');
if(c <= 0) if (c <= 0)
return 0; return 0;
else if(c != ':'){ else if (c != ':') {
printk("Failed to find ':' in /proc/cpuinfo\n"); printk(UM_KERN_ERR "Failed to find ':' in "
"/proc/cpuinfo\n");
return 0; return 0;
} }
if(!strncmp(scratch, key, strlen(key))) if (!strncmp(scratch, key, strlen(key)))
return 1; return 1;
do { do {
n = os_read_file(fd, &c, sizeof(c)); n = os_read_file(fd, &c, sizeof(c));
if(n != sizeof(c)){ if (n != sizeof(c)) {
printk("Failed to find newline in " printk(UM_KERN_ERR "Failed to find newline in "
"/proc/cpuinfo, err = %d\n", -n); "/proc/cpuinfo, err = %d\n", -n);
return 0; return 0;
} }
} while(c != '\n'); } while (c != '\n');
} }
return 0; return 0;
} }
...@@ -83,46 +83,50 @@ static int check_cpu_flag(char *feature, int *have_it) ...@@ -83,46 +83,50 @@ static int check_cpu_flag(char *feature, int *have_it)
char buf[MAXTOKEN], c; char buf[MAXTOKEN], c;
int fd, len = ARRAY_SIZE(buf); int fd, len = ARRAY_SIZE(buf);
printk("Checking for host processor %s support...", feature); printk(UM_KERN_INFO "Checking for host processor %s support...",
feature);
fd = os_open_file("/proc/cpuinfo", of_read(OPENFLAGS()), 0); fd = os_open_file("/proc/cpuinfo", of_read(OPENFLAGS()), 0);
if(fd < 0){ if (fd < 0) {
printk("Couldn't open /proc/cpuinfo, err = %d\n", -fd); printk(UM_KERN_ERR "Couldn't open /proc/cpuinfo, err = %d\n",
-fd);
return 0; return 0;
} }
*have_it = 0; *have_it = 0;
if(!find_cpuinfo_line(fd, "flags", buf, ARRAY_SIZE(buf))) if (!find_cpuinfo_line(fd, "flags", buf, ARRAY_SIZE(buf)))
goto out; goto out;
c = token(fd, buf, len - 1, ' '); c = token(fd, buf, len - 1, ' ');
if(c < 0) if (c < 0)
goto out; goto out;
else if(c != ' '){ else if (c != ' ') {
printk("Failed to find ' ' in /proc/cpuinfo\n"); printk(UM_KERN_ERR "Failed to find ' ' in /proc/cpuinfo\n");
goto out; goto out;
} }
while(1){ while (1) {
c = token(fd, buf, len - 1, ' '); c = token(fd, buf, len - 1, ' ');
if(c < 0) if (c < 0)
goto out; goto out;
else if(c == '\n') break; else if (c == '\n')
break;
if(!strcmp(buf, feature)){ if (!strcmp(buf, feature)) {
*have_it = 1; *have_it = 1;
goto out; goto out;
} }
} }
out: out:
if(*have_it == 0) if (*have_it == 0)
printk("No\n"); printk("No\n");
else if(*have_it == 1) else if (*have_it == 1)
printk("Yes\n"); printk("Yes\n");
os_close_file(fd); os_close_file(fd);
return 1; return 1;
} }
#if 0 /* This doesn't work in tt mode, plus it's causing compilation problems #if 0 /*
* This doesn't work in tt mode, plus it's causing compilation problems
* for some people. * for some people.
*/ */
static void disable_lcall(void) static void disable_lcall(void)
...@@ -135,8 +139,9 @@ static void disable_lcall(void) ...@@ -135,8 +139,9 @@ static void disable_lcall(void)
ldt.base_addr = 0; ldt.base_addr = 0;
ldt.limit = 0; ldt.limit = 0;
err = modify_ldt(1, &ldt, sizeof(ldt)); err = modify_ldt(1, &ldt, sizeof(ldt));
if(err) if (err)
printk("Failed to disable lcall7 - errno = %d\n", errno); printk(UM_KERN_ERR "Failed to disable lcall7 - errno = %d\n",
errno);
} }
#endif #endif
...@@ -151,14 +156,14 @@ void arch_check_bugs(void) ...@@ -151,14 +156,14 @@ void arch_check_bugs(void)
{ {
int have_it; int have_it;
if(os_access("/proc/cpuinfo", OS_ACC_R_OK) < 0){ if (os_access("/proc/cpuinfo", OS_ACC_R_OK) < 0) {
printk("/proc/cpuinfo not available - skipping CPU capability " printk(UM_KERN_ERR "/proc/cpuinfo not available - skipping CPU "
"checks\n"); "capability checks\n");
return; return;
} }
if(check_cpu_flag("cmov", &have_it)) if (check_cpu_flag("cmov", &have_it))
host_has_cmov = have_it; host_has_cmov = have_it;
if(check_cpu_flag("xmm", &have_it)) if (check_cpu_flag("xmm", &have_it))
host_has_xmm = have_it; host_has_xmm = have_it;
} }
...@@ -166,25 +171,26 @@ int arch_handle_signal(int sig, struct uml_pt_regs *regs) ...@@ -166,25 +171,26 @@ int arch_handle_signal(int sig, struct uml_pt_regs *regs)
{ {
unsigned char tmp[2]; unsigned char tmp[2];
/* This is testing for a cmov (0x0f 0x4x) instruction causing a /*
* This is testing for a cmov (0x0f 0x4x) instruction causing a
* SIGILL in init. * SIGILL in init.
*/ */
if((sig != SIGILL) || (TASK_PID(get_current()) != 1)) if ((sig != SIGILL) || (TASK_PID(get_current()) != 1))
return 0; return 0;
if (copy_from_user_proc(tmp, (void *) UPT_IP(regs), 2)) if (copy_from_user_proc(tmp, (void *) UPT_IP(regs), 2))
panic("SIGILL in init, could not read instructions!\n"); panic("SIGILL in init, could not read instructions!\n");
if((tmp[0] != 0x0f) || ((tmp[1] & 0xf0) != 0x40)) if ((tmp[0] != 0x0f) || ((tmp[1] & 0xf0) != 0x40))
return 0; return 0;
if(host_has_cmov == 0) if (host_has_cmov == 0)
panic("SIGILL caused by cmov, which this processor doesn't " panic("SIGILL caused by cmov, which this processor doesn't "
"implement, boot a filesystem compiled for older " "implement, boot a filesystem compiled for older "
"processors"); "processors");
else if(host_has_cmov == 1) else if (host_has_cmov == 1)
panic("SIGILL caused by cmov, which this processor claims to " panic("SIGILL caused by cmov, which this processor claims to "
"implement"); "implement");
else if(host_has_cmov == -1) else if (host_has_cmov == -1)
panic("SIGILL caused by cmov, couldn't tell if this processor " panic("SIGILL caused by cmov, couldn't tell if this processor "
"implements it, boot a filesystem compiled for older " "implements it, boot a filesystem compiled for older "
"processors"); "processors");
......
/* /*
* Copyright (C) 2002 - 2004 Jeff Dike (jdike@addtoit.com) * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL * Licensed under the GPL
*/ */
...@@ -20,9 +20,9 @@ int arch_fixup(unsigned long address, struct uml_pt_regs *regs) ...@@ -20,9 +20,9 @@ int arch_fixup(unsigned long address, struct uml_pt_regs *regs)
const struct exception_table_entry *fixup; const struct exception_table_entry *fixup;
fixup = search_exception_tables(address); fixup = search_exception_tables(address);
if(fixup != 0){ if (fixup != 0) {
UPT_IP(regs) = fixup->fixup; UPT_IP(regs) = fixup->fixup;
return(1); return 1;
} }
return(0); return 0;
} }
This diff is collapsed.
/* /*
* Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL * Licensed under the GPL
*/ */
#include <linux/compiler.h>
#include "linux/sched.h"
#include "linux/mm.h" #include "linux/mm.h"
#include "asm/elf.h" #include "linux/sched.h"
#include "asm/ptrace.h"
#include "asm/uaccess.h" #include "asm/uaccess.h"
#include "asm/unistd.h"
#include "sysdep/ptrace.h"
#include "sysdep/sigcontext.h"
#include "sysdep/sc.h"
extern int arch_switch_tls(struct task_struct *from, struct task_struct *to); extern int arch_switch_tls(struct task_struct *from, struct task_struct *to);
...@@ -23,7 +16,8 @@ void arch_switch_to(struct task_struct *from, struct task_struct *to) ...@@ -23,7 +16,8 @@ void arch_switch_to(struct task_struct *from, struct task_struct *to)
return; return;
if (err != -EINVAL) if (err != -EINVAL)
printk(KERN_WARNING "arch_switch_tls failed, errno %d, not EINVAL\n", -err); printk(KERN_WARNING "arch_switch_tls failed, errno %d, "
"not EINVAL\n", -err);
else else
printk(KERN_WARNING "arch_switch_tls failed, errno = EINVAL\n"); printk(KERN_WARNING "arch_switch_tls failed, errno = EINVAL\n");
} }
...@@ -34,21 +28,21 @@ int is_syscall(unsigned long addr) ...@@ -34,21 +28,21 @@ int is_syscall(unsigned long addr)
int n; int n;
n = copy_from_user(&instr, (void __user *) addr, sizeof(instr)); n = copy_from_user(&instr, (void __user *) addr, sizeof(instr));
if(n){ if (n) {
/* access_process_vm() grants access to vsyscall and stub, /* access_process_vm() grants access to vsyscall and stub,
* while copy_from_user doesn't. Maybe access_process_vm is * while copy_from_user doesn't. Maybe access_process_vm is
* slow, but that doesn't matter, since it will be called only * slow, but that doesn't matter, since it will be called only
* in case of singlestepping, if copy_from_user failed. * in case of singlestepping, if copy_from_user failed.
*/ */
n = access_process_vm(current, addr, &instr, sizeof(instr), 0); n = access_process_vm(current, addr, &instr, sizeof(instr), 0);
if(n != sizeof(instr)) { if (n != sizeof(instr)) {
printk("is_syscall : failed to read instruction from " printk(KERN_ERR "is_syscall : failed to read "
"0x%lx\n", addr); "instruction from 0x%lx\n", addr);
return(1); return 1;
} }
} }
/* int 0x80 or sysenter */ /* int 0x80 or sysenter */
return((instr == 0x80cd) || (instr == 0x340f)); return (instr == 0x80cd) || (instr == 0x340f);
} }
/* determines which flags the user has access to. */ /* determines which flags the user has access to. */
...@@ -92,21 +86,21 @@ int putreg(struct task_struct *child, int regno, unsigned long value) ...@@ -92,21 +86,21 @@ int putreg(struct task_struct *child, int regno, unsigned long value)
int poke_user(struct task_struct *child, long addr, long data) int poke_user(struct task_struct *child, long addr, long data)
{ {
if ((addr & 3) || addr < 0) if ((addr & 3) || addr < 0)
return -EIO; return -EIO;
if (addr < MAX_REG_OFFSET) if (addr < MAX_REG_OFFSET)
return putreg(child, addr, data); return putreg(child, addr, data);
else if ((addr >= offsetof(struct user, u_debugreg[0])) &&
else if((addr >= offsetof(struct user, u_debugreg[0])) && (addr <= offsetof(struct user, u_debugreg[7]))) {
(addr <= offsetof(struct user, u_debugreg[7]))){ addr -= offsetof(struct user, u_debugreg[0]);
addr -= offsetof(struct user, u_debugreg[0]); addr = addr >> 2;
addr = addr >> 2; if ((addr == 4) || (addr == 5))
if((addr == 4) || (addr == 5)) return -EIO; return -EIO;
child->thread.arch.debugregs[addr] = data; child->thread.arch.debugregs[addr] = data;
return 0; return 0;
} }
return -EIO; return -EIO;
} }
unsigned long getreg(struct task_struct *child, int regno) unsigned long getreg(struct task_struct *child, int regno)
...@@ -129,20 +123,20 @@ unsigned long getreg(struct task_struct *child, int regno) ...@@ -129,20 +123,20 @@ unsigned long getreg(struct task_struct *child, int regno)
return retval; return retval;
} }
/* read the word at location addr in the USER area. */
int peek_user(struct task_struct *child, long addr, long data) int peek_user(struct task_struct *child, long addr, long data)
{ {
/* read the word at location addr in the USER area. */
unsigned long tmp; unsigned long tmp;
if ((addr & 3) || addr < 0) if ((addr & 3) || addr < 0)
return -EIO; return -EIO;
tmp = 0; /* Default return condition */ tmp = 0; /* Default return condition */
if(addr < MAX_REG_OFFSET){ if (addr < MAX_REG_OFFSET) {
tmp = getreg(child, addr); tmp = getreg(child, addr);
} }
else if((addr >= offsetof(struct user, u_debugreg[0])) && else if ((addr >= offsetof(struct user, u_debugreg[0])) &&
(addr <= offsetof(struct user, u_debugreg[7]))){ (addr <= offsetof(struct user, u_debugreg[7]))) {
addr -= offsetof(struct user, u_debugreg[0]); addr -= offsetof(struct user, u_debugreg[0]);
addr = addr >> 2; addr = addr >> 2;
tmp = child->thread.arch.debugregs[addr]; tmp = child->thread.arch.debugregs[addr];
...@@ -173,15 +167,15 @@ struct i387_fxsave_struct { ...@@ -173,15 +167,15 @@ struct i387_fxsave_struct {
static inline unsigned short twd_i387_to_fxsr( unsigned short twd ) static inline unsigned short twd_i387_to_fxsr( unsigned short twd )
{ {
unsigned int tmp; /* to avoid 16 bit prefixes in the code */ unsigned int tmp; /* to avoid 16 bit prefixes in the code */
/* Transform each pair of bits into 01 (valid) or 00 (empty) */ /* Transform each pair of bits into 01 (valid) or 00 (empty) */
tmp = ~twd; tmp = ~twd;
tmp = (tmp | (tmp>>1)) & 0x5555; /* 0V0V0V0V0V0V0V0V */ tmp = (tmp | (tmp>>1)) & 0x5555; /* 0V0V0V0V0V0V0V0V */
/* and move the valid bits to the lower byte. */ /* and move the valid bits to the lower byte. */
tmp = (tmp | (tmp >> 1)) & 0x3333; /* 00VV00VV00VV00VV */ tmp = (tmp | (tmp >> 1)) & 0x3333; /* 00VV00VV00VV00VV */
tmp = (tmp | (tmp >> 2)) & 0x0f0f; /* 0000VVVV0000VVVV */ tmp = (tmp | (tmp >> 2)) & 0x0f0f; /* 0000VVVV0000VVVV */
tmp = (tmp | (tmp >> 4)) & 0x00ff; /* 00000000VVVVVVVV */ tmp = (tmp | (tmp >> 4)) & 0x00ff; /* 00000000VVVVVVVV */
return tmp; return tmp;
} }
static inline unsigned long twd_fxsr_to_i387( struct i387_fxsave_struct *fxsave ) static inline unsigned long twd_fxsr_to_i387( struct i387_fxsave_struct *fxsave )
...@@ -235,7 +229,7 @@ static inline int convert_fxsr_to_user(struct _fpstate __user *buf, ...@@ -235,7 +229,7 @@ static inline int convert_fxsr_to_user(struct _fpstate __user *buf,
return 0; return 0;
} }
static inline int convert_fxsr_from_user(struct pt_regs *regs, static inline int convert_fxsr_from_user(struct pt_regs *regs,
struct _fpstate __user *buf) struct _fpstate __user *buf)
{ {
return 0; return 0;
...@@ -247,18 +241,20 @@ int get_fpregs(unsigned long buf, struct task_struct *child) ...@@ -247,18 +241,20 @@ int get_fpregs(unsigned long buf, struct task_struct *child)
err = convert_fxsr_to_user((struct _fpstate __user *) buf, err = convert_fxsr_to_user((struct _fpstate __user *) buf,
&child->thread.regs); &child->thread.regs);
if(err) return(-EFAULT); if (err)
else return(0); return -EFAULT;
return 0;
} }
int set_fpregs(unsigned long buf, struct task_struct *child) int set_fpregs(unsigned long buf, struct task_struct *child)
{ {
int err; int err;
err = convert_fxsr_from_user(&child->thread.regs, err = convert_fxsr_from_user(&child->thread.regs,
(struct _fpstate __user *) buf); (struct _fpstate __user *) buf);
if(err) return(-EFAULT); if (err)
else return(0); return -EFAULT;
return 0;
} }
int get_fpxregs(unsigned long buf, struct task_struct *tsk) int get_fpxregs(unsigned long buf, struct task_struct *tsk)
...@@ -284,7 +280,7 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu) ...@@ -284,7 +280,7 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu)
fpu->fos = 0; fpu->fos = 0;
memcpy(fpu->st_space, (void *) SC_FP_ST(PT_REGS_SC(regs)), memcpy(fpu->st_space, (void *) SC_FP_ST(PT_REGS_SC(regs)),
sizeof(fpu->st_space)); sizeof(fpu->st_space));
return(1); return 1;
} }
#endif #endif
...@@ -292,14 +288,3 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu ) ...@@ -292,14 +288,3 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu )
{ {
return 1; return 1;
} }
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
* adjust the settings for this buffer only. This must remain at the end
* of the file.
* ---------------------------------------------------------------------------
* Local variables:
* c-file-style: "linux"
* End:
*/
This diff is collapsed.
This diff is collapsed.
...@@ -14,14 +14,15 @@ struct exception_table_entry ...@@ -14,14 +14,15 @@ struct exception_table_entry
}; };
const struct exception_table_entry *search_exception_tables(unsigned long add); const struct exception_table_entry *search_exception_tables(unsigned long add);
int arch_fixup(unsigned long address, struct uml_pt_regs *regs) int arch_fixup(unsigned long address, struct uml_pt_regs *regs)
{ {
const struct exception_table_entry *fixup; const struct exception_table_entry *fixup;
fixup = search_exception_tables(address); fixup = search_exception_tables(address);
if(fixup != 0){ if (fixup != 0) {
UPT_IP(regs) = fixup->fixup; UPT_IP(regs) = fixup->fixup;
return(1); return 1;
} }
return(0); return 0;
} }
This diff is collapsed.
This diff is collapsed.
...@@ -13,5 +13,5 @@ int arch_copy_tls(struct task_struct *t) ...@@ -13,5 +13,5 @@ int arch_copy_tls(struct task_struct *t)
*/ */
t->thread.arch.fs = t->thread.regs.regs.regs[R8 / sizeof(long)]; t->thread.arch.fs = t->thread.regs.regs.regs[R8 / sizeof(long)];
return 0; return 0;
} }
/* /*
* Copyright (C) 2002 Jeff Dike (jdike@karaya.com) * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL * Licensed under the GPL
*/ */
...@@ -55,14 +55,3 @@ extern int init_new_context(struct task_struct *task, struct mm_struct *mm); ...@@ -55,14 +55,3 @@ extern int init_new_context(struct task_struct *task, struct mm_struct *mm);
extern void destroy_context(struct mm_struct *mm); extern void destroy_context(struct mm_struct *mm);
#endif #endif
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
* adjust the settings for this buffer only. This must remain at the end
* of the file.
* ---------------------------------------------------------------------------
* Local variables:
* c-file-style: "linux"
* End:
*/
/* /*
* Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL * Licensed under the GPL
*/ */
...@@ -17,11 +17,14 @@ struct task_struct; ...@@ -17,11 +17,14 @@ struct task_struct;
struct mm_struct; struct mm_struct;
struct thread_struct { struct thread_struct {
/* This flag is set to 1 before calling do_fork (and analyzed in struct task_struct *saved_task;
/*
* This flag is set to 1 before calling do_fork (and analyzed in
* copy_thread) to mark that we are begin called from userspace (fork / * copy_thread) to mark that we are begin called from userspace (fork /
* vfork / clone), and reset to 0 after. It is left to 0 when called * vfork / clone), and reset to 0 after. It is left to 0 when called
* from kernelspace (i.e. kernel_thread() or fork_idle(), as of 2.6.11). */ * from kernelspace (i.e. kernel_thread() or fork_idle(),
struct task_struct *saved_task; * as of 2.6.11).
*/
int forking; int forking;
int nsyscalls; int nsyscalls;
struct pt_regs regs; struct pt_regs regs;
...@@ -56,7 +59,7 @@ struct thread_struct { ...@@ -56,7 +59,7 @@ struct thread_struct {
{ \ { \
.forking = 0, \ .forking = 0, \
.nsyscalls = 0, \ .nsyscalls = 0, \
.regs = EMPTY_REGS, \ .regs = EMPTY_REGS, \
.fault_addr = NULL, \ .fault_addr = NULL, \
.prev_sched = NULL, \ .prev_sched = NULL, \
.temp_stack = 0, \ .temp_stack = 0, \
......
/* /*
* Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL * Licensed under the GPL
*/ */
......
/* /*
* Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL * Licensed under the GPL
*/ */
...@@ -9,9 +9,8 @@ ...@@ -9,9 +9,8 @@
#define HOST_AUDIT_ARCH AUDIT_ARCH_I386 #define HOST_AUDIT_ARCH AUDIT_ARCH_I386
#include "linux/compiler.h" #include "linux/compiler.h"
#include "sysdep/ptrace.h"
#include "asm/ptrace-generic.h" #include "asm/ptrace-generic.h"
#include "asm/host_ldt.h" #include "sysdep/ptrace.h"
#define PT_REGS_EAX(r) UPT_EAX(&(r)->regs) #define PT_REGS_EAX(r) UPT_EAX(&(r)->regs)
#define PT_REGS_EBX(r) UPT_EBX(&(r)->regs) #define PT_REGS_EBX(r) UPT_EBX(&(r)->regs)
...@@ -40,6 +39,12 @@ ...@@ -40,6 +39,12 @@
#define user_mode(r) UPT_IS_USER(&(r)->regs) #define user_mode(r) UPT_IS_USER(&(r)->regs)
/*
* Forward declaration to avoid including sysdep/tls.h, which causes a
* circular include, and compilation failures.
*/
struct user_desc;
extern int ptrace_get_thread_area(struct task_struct *child, int idx, extern int ptrace_get_thread_area(struct task_struct *child, int idx,
struct user_desc __user *user_desc); struct user_desc __user *user_desc);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment