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: Jeff Dike <jdike@linux.intel.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
77bf440031
commit
ba180fd437
|
@ -1,12 +1,12 @@
|
|||
/*
|
||||
* Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
|
||||
* Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||
* Licensed under the GPL
|
||||
*/
|
||||
|
||||
#ifndef __IRQ_USER_H__
|
||||
#define __IRQ_USER_H__
|
||||
|
||||
#include "uml-config.h"
|
||||
#include "sysdep/ptrace.h"
|
||||
|
||||
struct irq_fd {
|
||||
struct irq_fd *next;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
|
@ -8,7 +8,6 @@
|
|||
|
||||
#include "sysdep/ptrace.h"
|
||||
#include "sysdep/faultinfo.h"
|
||||
#include "uml-config.h"
|
||||
|
||||
typedef void (*kern_hndl)(int, struct uml_pt_regs *);
|
||||
|
||||
|
|
|
@ -1,20 +1,18 @@
|
|||
/*
|
||||
* Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
|
||||
* Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||
* Licensed under the GPL
|
||||
*/
|
||||
|
||||
#ifndef __OS_H__
|
||||
#define __OS_H__
|
||||
|
||||
#include "uml-config.h"
|
||||
#include "asm/types.h"
|
||||
#include "../os/include/file.h"
|
||||
#include "sysdep/ptrace.h"
|
||||
#include "kern_util.h"
|
||||
#include "skas/mm_id.h"
|
||||
#include <stdarg.h>
|
||||
#include "irq_user.h"
|
||||
#include "kern_util.h"
|
||||
#include "longjmp.h"
|
||||
#include "mm_id.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))
|
||||
|
||||
|
@ -140,7 +138,7 @@ extern int os_set_slip(int fd);
|
|||
extern int os_set_owner(int fd, int pid);
|
||||
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_read_file(int fd, void *buf, int len);
|
||||
extern int os_write_file(int fd, const void *buf, int count);
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
/*
|
||||
* Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
|
||||
* Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||
* Licensed under the GPL
|
||||
*/
|
||||
|
||||
#ifndef __SKAS_H
|
||||
#define __SKAS_H
|
||||
|
||||
#include "mm_id.h"
|
||||
#include "sysdep/ptrace.h"
|
||||
|
||||
extern int userspace_pid[];
|
||||
|
|
|
@ -1,24 +1,19 @@
|
|||
/*
|
||||
* Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
|
||||
* Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||
* Licensed under the GPL
|
||||
*/
|
||||
|
||||
#include "linux/slab.h"
|
||||
#include "linux/stddef.h"
|
||||
#include "linux/fs.h"
|
||||
#include "linux/smp_lock.h"
|
||||
#include "linux/ptrace.h"
|
||||
#include "linux/fs.h"
|
||||
#include "asm/ptrace.h"
|
||||
#include "asm/pgtable.h"
|
||||
#include "asm/tlbflush.h"
|
||||
#include "linux/sched.h"
|
||||
#include "asm/current.h"
|
||||
#include "asm/processor.h"
|
||||
#include "asm/uaccess.h"
|
||||
#include "kern_util.h"
|
||||
#include "as-layout.h"
|
||||
#include "mem_user.h"
|
||||
#include "kern.h"
|
||||
#include "irq_user.h"
|
||||
#include "tlb.h"
|
||||
#include "skas.h"
|
||||
#include "os.h"
|
||||
#include "skas/skas.h"
|
||||
|
||||
void flush_thread(void)
|
||||
{
|
||||
|
@ -30,7 +25,7 @@ void flush_thread(void)
|
|||
|
||||
ret = unmap(¤t->mm->context.skas.id, 0, end, 1, &data);
|
||||
if (ret) {
|
||||
printk("flush_thread - clearing address space failed, "
|
||||
printk(KERN_ERR "flush_thread - clearing address space failed, "
|
||||
"err = %d\n", ret);
|
||||
force_sig(SIGKILL, current);
|
||||
}
|
||||
|
@ -71,7 +66,7 @@ static long execve1(char *file, char __user * __user *argv,
|
|||
#endif
|
||||
task_unlock(current);
|
||||
}
|
||||
return(error);
|
||||
return error;
|
||||
}
|
||||
|
||||
long um_execve(char *file, char __user *__user *argv, char __user *__user *env)
|
||||
|
@ -81,7 +76,7 @@ long um_execve(char *file, char __user *__user *argv, char __user *__user *env)
|
|||
err = execve1(file, argv, env);
|
||||
if (!err)
|
||||
do_longjmp(current->thread.exec_buf, 1);
|
||||
return(err);
|
||||
return err;
|
||||
}
|
||||
|
||||
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);
|
||||
out:
|
||||
unlock_kernel();
|
||||
return(error);
|
||||
return error;
|
||||
}
|
||||
|
|
|
@ -1,37 +1,19 @@
|
|||
/*
|
||||
* Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
|
||||
* Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||
* Licensed under the GPL
|
||||
* Derived (i.e. mostly copied) from arch/i386/kernel/irq.c:
|
||||
* Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar
|
||||
*/
|
||||
|
||||
#include "linux/kernel.h"
|
||||
#include "linux/module.h"
|
||||
#include "linux/smp.h"
|
||||
#include "linux/kernel_stat.h"
|
||||
#include "linux/interrupt.h"
|
||||
#include "linux/random.h"
|
||||
#include "linux/slab.h"
|
||||
#include "linux/file.h"
|
||||
#include "linux/proc_fs.h"
|
||||
#include "linux/init.h"
|
||||
#include "linux/seq_file.h"
|
||||
#include "linux/profile.h"
|
||||
#include "linux/cpumask.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 "irq_user.h"
|
||||
#include "irq_kern.h"
|
||||
#include "os.h"
|
||||
#include "sigio.h"
|
||||
#include "misc_constants.h"
|
||||
#include "linux/interrupt.h"
|
||||
#include "linux/kernel_stat.h"
|
||||
#include "linux/module.h"
|
||||
#include "linux/seq_file.h"
|
||||
#include "as-layout.h"
|
||||
#include "kern_util.h"
|
||||
#include "os.h"
|
||||
|
||||
/*
|
||||
* Generic, controller-independent functions:
|
||||
|
@ -71,9 +53,8 @@ int show_interrupts(struct seq_file *p, void *v)
|
|||
seq_putc(p, '\n');
|
||||
skip:
|
||||
spin_unlock_irqrestore(&irq_desc[i].lock, flags);
|
||||
} else if (i == NR_IRQS) {
|
||||
} else if (i == NR_IRQS)
|
||||
seq_putc(p, '\n');
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -102,11 +83,13 @@ void sigio_handler(int sig, struct uml_pt_regs *regs)
|
|||
while (1) {
|
||||
n = os_waiting_for_events(active_fds);
|
||||
if (n <= 0) {
|
||||
if(n == -EINTR) continue;
|
||||
if (n == -EINTR)
|
||||
continue;
|
||||
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) {
|
||||
irq_fd->current_events = 0;
|
||||
do_IRQ(irq_fd->irq, regs);
|
||||
|
@ -138,8 +121,7 @@ int activate_fd(int irq, int fd, int type, void *dev_id)
|
|||
|
||||
if (type == IRQ_READ)
|
||||
events = UM_POLLIN | UM_POLLPRI;
|
||||
else
|
||||
events = UM_POLLOUT;
|
||||
else events = UM_POLLOUT;
|
||||
*new_fd = ((struct irq_fd) { .next = NULL,
|
||||
.id = dev_id,
|
||||
.fd = fd,
|
||||
|
@ -153,9 +135,10 @@ int activate_fd(int irq, int fd, int type, void *dev_id)
|
|||
spin_lock_irqsave(&irq_lock, flags);
|
||||
for (irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next) {
|
||||
if ((irq_fd->fd == fd) && (irq_fd->type == type)) {
|
||||
printk("Registering fd %d twice\n", fd);
|
||||
printk("Irqs : %d, %d\n", irq_fd->irq, irq);
|
||||
printk("Ids : 0x%p, 0x%p\n", irq_fd->id, dev_id);
|
||||
printk(KERN_ERR "Registering fd %d twice\n", fd);
|
||||
printk(KERN_ERR "Irqs : %d, %d\n", irq_fd->irq, irq);
|
||||
printk(KERN_ERR "Ids : 0x%p, 0x%p\n", irq_fd->id,
|
||||
dev_id);
|
||||
goto out_unlock;
|
||||
}
|
||||
}
|
||||
|
@ -171,7 +154,8 @@ int activate_fd(int irq, int fd, int type, void *dev_id)
|
|||
if (n == 0)
|
||||
break;
|
||||
|
||||
/* n > 0
|
||||
/*
|
||||
* n > 0
|
||||
* It means we couldn't put new pollfd to current pollfds
|
||||
* and tmp_fds is NULL or too small for new pollfds array.
|
||||
* Needed size is equal to n as minimum.
|
||||
|
@ -197,7 +181,8 @@ int activate_fd(int irq, int fd, int type, void *dev_id)
|
|||
|
||||
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.
|
||||
*/
|
||||
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)
|
|||
i++;
|
||||
}
|
||||
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;
|
||||
}
|
||||
fdi = os_get_pollfd(i);
|
||||
if ((fdi != -1) && (fdi != fd)) {
|
||||
printk("find_irq_by_fd - mismatch between active_fds and "
|
||||
"pollfds, fd %d vs %d, need %d\n", irq->fd,
|
||||
printk(KERN_ERR "find_irq_by_fd - mismatch between active_fds "
|
||||
"and pollfds, fd %d vs %d, need %d\n", irq->fd,
|
||||
fdi, fd);
|
||||
irq = NULL;
|
||||
goto out;
|
||||
|
@ -372,8 +358,10 @@ int um_request_irq(unsigned int irq, int fd, int type,
|
|||
EXPORT_SYMBOL(um_request_irq);
|
||||
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)
|
||||
{
|
||||
}
|
||||
|
@ -422,7 +410,8 @@ int init_aio_irq(int irq, char *name, irq_handler_t handler)
|
|||
|
||||
err = os_pipe(fds, 1, 1);
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -430,7 +419,8 @@ int init_aio_irq(int irq, char *name, irq_handler_t handler)
|
|||
IRQF_DISABLED | IRQF_SAMPLE_RANDOM, name,
|
||||
(void *) (long) fds[0]);
|
||||
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);
|
||||
goto out_close;
|
||||
}
|
||||
|
@ -502,7 +492,8 @@ unsigned long to_irq_stack(unsigned long *mask_out)
|
|||
|
||||
mask = xchg(&pending_mask, *mask_out);
|
||||
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
|
||||
* putting our bit in. So, this loop accumulates bits
|
||||
* until xchg returns the same value that we put in.
|
||||
|
|
|
@ -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);
|
||||
if (err) {
|
||||
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 "
|
||||
"memory size>/4096\n");
|
||||
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,
|
|||
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.
|
||||
*/
|
||||
os_seek_file(physmem_fd, __pa(&__syscall_stub_start));
|
||||
|
@ -202,8 +203,8 @@ int setup_iomem(void)
|
|||
err = os_map_memory((void *) iomem_start, region->fd, 0,
|
||||
region->size, 1, 1, 0);
|
||||
if (err)
|
||||
printk("Mapping iomem region for driver '%s' failed, "
|
||||
"errno = %d\n", region->driver, -err);
|
||||
printk(KERN_ERR "Mapping iomem region for driver '%s' "
|
||||
"failed, errno = %d\n", region->driver, -err);
|
||||
else {
|
||||
region->virt = iomem_start;
|
||||
region->phys = __pa(region->virt);
|
||||
|
|
|
@ -1,51 +1,29 @@
|
|||
/*
|
||||
* 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.
|
||||
* Licensed under the GPL
|
||||
*/
|
||||
|
||||
#include "linux/kernel.h"
|
||||
#include "linux/sched.h"
|
||||
#include "linux/interrupt.h"
|
||||
#include "linux/string.h"
|
||||
#include "linux/stddef.h"
|
||||
#include "linux/err.h"
|
||||
#include "linux/hardirq.h"
|
||||
#include "linux/mm.h"
|
||||
#include "linux/slab.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/personality.h"
|
||||
#include "linux/proc_fs.h"
|
||||
#include "linux/ptrace.h"
|
||||
#include "linux/random.h"
|
||||
#include "linux/personality.h"
|
||||
#include "asm/unistd.h"
|
||||
#include "asm/mman.h"
|
||||
#include "asm/segment.h"
|
||||
#include "asm/stat.h"
|
||||
#include "linux/sched.h"
|
||||
#include "linux/threads.h"
|
||||
#include "asm/pgtable.h"
|
||||
#include "asm/processor.h"
|
||||
#include "asm/tlbflush.h"
|
||||
#include "asm/uaccess.h"
|
||||
#include "asm/user.h"
|
||||
#include "kern_util.h"
|
||||
#include "as-layout.h"
|
||||
#include "kern.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 "kern_util.h"
|
||||
#include "os.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
|
||||
* entry.
|
||||
*/
|
||||
|
@ -54,7 +32,7 @@ struct cpu_task cpu_tasks[NR_CPUS] = { [0 ... NR_CPUS - 1] = { -1, NULL } };
|
|||
static inline int external_pid(struct task_struct *task)
|
||||
{
|
||||
/* FIXME: Need to look up userspace_pid by cpu */
|
||||
return(userspace_pid[0]);
|
||||
return userspace_pid[0];
|
||||
}
|
||||
|
||||
int pid_to_processor_id(int pid)
|
||||
|
@ -158,7 +136,8 @@ void *get_current(void)
|
|||
|
||||
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.
|
||||
*/
|
||||
void new_thread_handler(void)
|
||||
|
@ -173,7 +152,8 @@ void new_thread_handler(void)
|
|||
fn = current->thread.request.u.thread.proc;
|
||||
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
|
||||
*/
|
||||
n = run_kernel_thread(fn, arg, ¤t->thread.exec_buf);
|
||||
|
@ -194,9 +174,11 @@ void fork_handler(void)
|
|||
|
||||
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
|
||||
* improve performance. -bb */
|
||||
* improve performance. -bb
|
||||
*/
|
||||
arch_switch_to(current->thread.prev_sched, current);
|
||||
|
||||
current->thread.prev_sched = NULL;
|
||||
|
@ -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)
|
||||
{
|
||||
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;
|
||||
|
||||
return strlen(buf);
|
||||
|
@ -423,7 +406,8 @@ static int proc_write_sysemu(struct file *file,const char __user *buf, unsigned
|
|||
|
||||
if (tmp[0] >= '0' && tmp[0] <= '2')
|
||||
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)
|
||||
|
@ -453,10 +437,10 @@ int singlestepping(void * t)
|
|||
struct task_struct *task = t ? t : current;
|
||||
|
||||
if ( ! (task->ptrace & PT_DTRACE) )
|
||||
return(0);
|
||||
return 0;
|
||||
|
||||
if (task->thread.singlestep_syscall)
|
||||
return(1);
|
||||
return 1;
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
|
|
@ -1,24 +1,16 @@
|
|||
/*
|
||||
* Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
|
||||
* Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||
* 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"
|
||||
#ifdef CONFIG_PROC_MM
|
||||
#include "linux/proc_mm.h"
|
||||
#endif
|
||||
#include "asm/ptrace.h"
|
||||
#include "linux/ptrace.h"
|
||||
#include "linux/sched.h"
|
||||
#include "asm/uaccess.h"
|
||||
#include "kern_util.h"
|
||||
#ifdef CONFIG_PROC_MM
|
||||
#include "proc_mm.h"
|
||||
#endif
|
||||
#include "skas_ptrace.h"
|
||||
#include "sysdep/ptrace.h"
|
||||
#include "os.h"
|
||||
|
||||
static inline void set_singlestepping(struct task_struct *child, int on)
|
||||
{
|
||||
|
@ -50,8 +42,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
|
|||
unsigned long __user *p = (void __user *)(unsigned long)data;
|
||||
|
||||
switch (request) {
|
||||
/* when I and D space are separate, these will need to be fixed. */
|
||||
case PTRACE_PEEKTEXT: /* read word at location addr. */
|
||||
/* read word at location addr. */
|
||||
case PTRACE_PEEKTEXT:
|
||||
case PTRACE_PEEKDATA:
|
||||
ret = generic_ptrace_peekdata(child, addr, data);
|
||||
break;
|
||||
|
@ -61,29 +53,29 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
|
|||
ret = peek_user(child, addr, data);
|
||||
break;
|
||||
|
||||
/* when I and D space are separate, this will have to be fixed. */
|
||||
case PTRACE_POKETEXT: /* write the word at location addr. */
|
||||
/* write the word at location addr. */
|
||||
case PTRACE_POKETEXT:
|
||||
case PTRACE_POKEDATA:
|
||||
ret = generic_ptrace_pokedata(child, addr, data);
|
||||
break;
|
||||
|
||||
case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
|
||||
/* write the word at location addr in the USER area */
|
||||
case PTRACE_POKEUSR:
|
||||
ret = poke_user(child, addr, data);
|
||||
break;
|
||||
|
||||
case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
|
||||
case PTRACE_CONT: { /* restart after signal. */
|
||||
/* continue and stop at next (return from) syscall */
|
||||
case PTRACE_SYSCALL:
|
||||
/* restart after signal. */
|
||||
case PTRACE_CONT: {
|
||||
ret = -EIO;
|
||||
if (!valid_signal(data))
|
||||
break;
|
||||
|
||||
set_singlestepping(child, 0);
|
||||
if (request == PTRACE_SYSCALL) {
|
||||
if (request == PTRACE_SYSCALL)
|
||||
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;
|
||||
wake_up_process(child);
|
||||
ret = 0;
|
||||
|
@ -180,7 +172,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
|
|||
break;
|
||||
|
||||
case PTRACE_FAULTINFO: {
|
||||
/* Take the info from thread->arch->faultinfo,
|
||||
/*
|
||||
* Take the info from thread->arch->faultinfo,
|
||||
* but transfer max. sizeof(struct ptrace_faultinfo).
|
||||
* On i386, ptrace_faultinfo is smaller!
|
||||
*/
|
||||
|
@ -200,7 +193,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
|
|||
break;
|
||||
}
|
||||
|
||||
/* This one is confusing, so just punt and return -EIO for
|
||||
/*
|
||||
* This one is confusing, so just punt and return -EIO for
|
||||
* now
|
||||
*/
|
||||
ret = -EIO;
|
||||
|
@ -255,7 +249,8 @@ void send_sigtrap(struct task_struct *tsk, struct uml_pt_regs *regs,
|
|||
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
|
||||
*/
|
||||
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))
|
||||
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);
|
||||
ptrace_notify(SIGTRAP | (tracesysgood ? 0x80 : 0));
|
||||
|
||||
if (entryexit) /* force do_signal() --> is_syscall() */
|
||||
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
|
||||
* stopping signal is not SIGTRAP. -brl
|
||||
*/
|
||||
|
|
|
@ -1,13 +1,9 @@
|
|||
/*
|
||||
* Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
|
||||
* Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||
* Licensed under the GPL
|
||||
*/
|
||||
|
||||
#include "linux/module.h"
|
||||
#include "linux/sched.h"
|
||||
#include "asm/smp.h"
|
||||
#include "kern_util.h"
|
||||
#include "kern.h"
|
||||
#include "os.h"
|
||||
#include "skas.h"
|
||||
|
||||
|
|
|
@ -1,27 +1,16 @@
|
|||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#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/slab.h"
|
||||
#include "linux/tty.h"
|
||||
#include "linux/binfmts.h"
|
||||
#include "linux/ptrace.h"
|
||||
#include "linux/sched.h"
|
||||
#include "asm/siginfo.h"
|
||||
#include "asm/signal.h"
|
||||
#include "asm/uaccess.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 "kern_util.h"
|
||||
#include "sigcontext.h"
|
||||
|
||||
EXPORT_SYMBOL(block_signals);
|
||||
|
@ -112,10 +101,12 @@ static int kern_do_signal(struct pt_regs *regs)
|
|||
handled_sig = 1;
|
||||
/* Whee! Actually deliver the signal. */
|
||||
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,
|
||||
* 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))
|
||||
clear_thread_flag(TIF_RESTORE_SIGMASK);
|
||||
break;
|
||||
|
@ -139,7 +130,8 @@ static int kern_do_signal(struct pt_regs *regs)
|
|||
}
|
||||
}
|
||||
|
||||
/* 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
|
||||
* from it, the tracing thread used to PTRACE_SINGLESTEP the process
|
||||
* rather than PTRACE_SYSCALL it, allowing the system call to execute
|
||||
|
@ -150,8 +142,10 @@ static int kern_do_signal(struct pt_regs *regs)
|
|||
current->thread.singlestep_syscall =
|
||||
is_syscall(PT_REGS_IP(¤t->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)) {
|
||||
clear_thread_flag(TIF_RESTORE_SIGMASK);
|
||||
sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (C) 2002 - 2004 Jeff Dike (jdike@addtoit.com)
|
||||
# Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||
# Licensed under the GPL
|
||||
#
|
||||
|
||||
|
|
|
@ -1,20 +1,12 @@
|
|||
/*
|
||||
* Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
|
||||
* Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||
* 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 "asm/current.h"
|
||||
#include "asm/segment.h"
|
||||
#include "asm/mmu.h"
|
||||
#include "linux/sched.h"
|
||||
#include "asm/pgalloc.h"
|
||||
#include "asm/pgtable.h"
|
||||
#include "asm/ldt.h"
|
||||
#include "os.h"
|
||||
#include "skas.h"
|
||||
|
||||
|
@ -41,7 +33,8 @@ static int init_stub_pte(struct mm_struct *mm, unsigned long proc,
|
|||
if (!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
|
||||
* 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,
|
||||
|
@ -61,14 +54,14 @@ static int init_stub_pte(struct mm_struct *mm, unsigned long proc,
|
|||
|
||||
*pte = mk_pte(virt_to_page(kernel), __pgprot(_PAGE_PRESENT));
|
||||
*pte = pte_mkread(*pte);
|
||||
return(0);
|
||||
return 0;
|
||||
|
||||
out_pmd:
|
||||
pud_free(pud);
|
||||
out_pte:
|
||||
pmd_free(pmd);
|
||||
out:
|
||||
return(-ENOMEM);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
int init_new_context(struct task_struct *task, struct mm_struct *mm)
|
||||
|
@ -83,7 +76,8 @@ int init_new_context(struct task_struct *task, struct mm_struct *mm)
|
|||
if (stack == 0)
|
||||
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
|
||||
* be accurate.
|
||||
*/
|
||||
|
@ -108,8 +102,8 @@ int init_new_context(struct task_struct *task, struct mm_struct *mm)
|
|||
if (proc_mm) {
|
||||
ret = new_mm(stack);
|
||||
if (ret < 0) {
|
||||
printk("init_new_context_skas - new_mm failed, "
|
||||
"errno = %d\n", ret);
|
||||
printk(KERN_ERR "init_new_context_skas - "
|
||||
"new_mm failed, errno = %d\n", ret);
|
||||
goto out_free;
|
||||
}
|
||||
to_mm->id.u.mm_fd = ret;
|
||||
|
@ -123,7 +117,7 @@ int init_new_context(struct task_struct *task, struct mm_struct *mm)
|
|||
|
||||
ret = init_new_ldt(to_mm, from_mm);
|
||||
if (ret < 0) {
|
||||
printk("init_new_context_skas - init_ldt"
|
||||
printk(KERN_ERR "init_new_context_skas - init_ldt"
|
||||
" failed, errno = %d\n", ret);
|
||||
goto out_free;
|
||||
}
|
||||
|
|
|
@ -1,26 +1,13 @@
|
|||
/*
|
||||
* Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
|
||||
* Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||
* 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 "asm/uaccess.h"
|
||||
#include "asm/atomic.h"
|
||||
#include "kern_util.h"
|
||||
#include "linux/sched.h"
|
||||
#include "as-layout.h"
|
||||
#include "skas.h"
|
||||
#include "os.h"
|
||||
#include "tlb.h"
|
||||
#include "kern.h"
|
||||
#include "registers.h"
|
||||
|
||||
extern void schedule_tail(struct task_struct *prev);
|
||||
#include "skas.h"
|
||||
|
||||
int new_mm(unsigned long stack)
|
||||
{
|
||||
|
|
|
@ -1,17 +1,13 @@
|
|||
/*
|
||||
* Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
|
||||
* Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||
* Licensed under the GPL
|
||||
*/
|
||||
|
||||
#include "linux/sys.h"
|
||||
#include "linux/kernel.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 "syscall.h"
|
||||
#include "sysdep/ptrace.h"
|
||||
#include "sysdep/syscalls.h"
|
||||
|
||||
void handle_syscall(struct uml_pt_regs *r)
|
||||
{
|
||||
|
@ -24,7 +20,8 @@ void handle_syscall(struct uml_pt_regs *r)
|
|||
current->thread.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
|
||||
* children at all, sometimes hanging when bash doesn't see the first
|
||||
* ls exit.
|
||||
|
|
|
@ -1,25 +1,17 @@
|
|||
/*
|
||||
* Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
|
||||
* Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||
* Licensed under the GPL
|
||||
*/
|
||||
|
||||
#include "linux/sched.h"
|
||||
#include "linux/file.h"
|
||||
#include "linux/smp_lock.h"
|
||||
#include "linux/mm.h"
|
||||
#include "linux/fs.h"
|
||||
#include "linux/mm.h"
|
||||
#include "linux/sched.h"
|
||||
#include "linux/utsname.h"
|
||||
#include "linux/msg.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/current.h"
|
||||
#include "asm/mman.h"
|
||||
#include "asm/uaccess.h"
|
||||
#include "kern_util.h"
|
||||
#include "sysdep/syscalls.h"
|
||||
#include "asm/unistd.h"
|
||||
|
||||
/* Unlocked, I don't care if this is a bit off */
|
||||
int nsyscalls = 0;
|
||||
|
@ -32,7 +24,7 @@ long sys_fork(void)
|
|||
ret = do_fork(SIGCHLD, UPT_SP(¤t->thread.regs.regs),
|
||||
¤t->thread.regs, 0, NULL, NULL);
|
||||
current->thread.forking = 0;
|
||||
return(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
long sys_vfork(void)
|
||||
|
@ -44,7 +36,7 @@ long sys_vfork(void)
|
|||
UPT_SP(¤t->thread.regs.regs),
|
||||
¤t->thread.regs, 0, NULL, NULL);
|
||||
current->thread.forking = 0;
|
||||
return(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* common code for old and new mmaps */
|
||||
|
|
|
@ -1,28 +1,19 @@
|
|||
/*
|
||||
* Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
|
||||
* Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||
* 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/init.h"
|
||||
#include "linux/delay.h"
|
||||
#include "linux/hrtimer.h"
|
||||
#include "linux/jiffies.h"
|
||||
#include "linux/threads.h"
|
||||
#include "asm/irq.h"
|
||||
#include "asm/param.h"
|
||||
#include "asm/current.h"
|
||||
#include "kern_util.h"
|
||||
#include "os.h"
|
||||
|
||||
int hz(void)
|
||||
{
|
||||
return(HZ);
|
||||
return HZ;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -144,7 +135,8 @@ void do_gettimeofday(struct timeval *tv)
|
|||
xtime.tv_nsec;
|
||||
#endif
|
||||
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
|
||||
* which gave bogus (> 1000000) values. Dunno why, suspect gcc
|
||||
* (4.0.0) miscompiled it, or there's a subtle 64/32-bit conversion
|
||||
|
|
|
@ -1,19 +1,16 @@
|
|||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include "linux/mm.h"
|
||||
#include "asm/page.h"
|
||||
#include "asm/pgalloc.h"
|
||||
#include "asm/pgtable.h"
|
||||
#include "asm/tlbflush.h"
|
||||
#include "as-layout.h"
|
||||
#include "tlb.h"
|
||||
#include "mem.h"
|
||||
#include "mem_user.h"
|
||||
#include "os.h"
|
||||
#include "skas.h"
|
||||
#include "tlb.h"
|
||||
|
||||
static int add_mmap(unsigned long virt, unsigned long phys, unsigned long len,
|
||||
unsigned int prot, struct host_vm_op *ops, int *index,
|
||||
|
@ -251,7 +248,8 @@ void fix_range_common(struct mm_struct *mm, unsigned long start_addr,
|
|||
|
||||
/* This is not an else because ret is modified above */
|
||||
if (ret) {
|
||||
printk("fix_range_common: failed, killing current process\n");
|
||||
printk(KERN_ERR "fix_range_common: failed, killing current "
|
||||
"process\n");
|
||||
force_sig(SIGKILL, current);
|
||||
}
|
||||
}
|
||||
|
@ -338,7 +336,7 @@ int flush_tlb_kernel_range_common(unsigned long start, unsigned long end)
|
|||
}
|
||||
addr += PAGE_SIZE;
|
||||
}
|
||||
return(updated);
|
||||
return updated;
|
||||
}
|
||||
|
||||
void flush_tlb_page(struct vm_area_struct *vma, unsigned long address)
|
||||
|
@ -402,28 +400,28 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long address)
|
|||
return;
|
||||
|
||||
kill:
|
||||
printk("Failed to flush page for address 0x%lx\n", address);
|
||||
printk(KERN_ERR "Failed to flush page for address 0x%lx\n", address);
|
||||
force_sig(SIGKILL, current);
|
||||
}
|
||||
|
||||
pgd_t *pgd_offset_proc(struct mm_struct *mm, unsigned long address)
|
||||
{
|
||||
return(pgd_offset(mm, address));
|
||||
return pgd_offset(mm, address);
|
||||
}
|
||||
|
||||
pud_t *pud_offset_proc(pgd_t *pgd, unsigned long address)
|
||||
{
|
||||
return(pud_offset(pgd, address));
|
||||
return pud_offset(pgd, address);
|
||||
}
|
||||
|
||||
pmd_t *pmd_offset_proc(pud_t *pud, unsigned long address)
|
||||
{
|
||||
return(pmd_offset(pud, address));
|
||||
return pmd_offset(pud, address);
|
||||
}
|
||||
|
||||
pte_t *pte_offset_proc(pmd_t *pmd, unsigned long address)
|
||||
{
|
||||
return(pte_offset_kernel(pmd, address));
|
||||
return pte_offset_kernel(pmd, address);
|
||||
}
|
||||
|
||||
pte_t *addr_pte(struct task_struct *task, unsigned long addr)
|
||||
|
@ -432,7 +430,7 @@ pte_t *addr_pte(struct task_struct *task, unsigned long addr)
|
|||
pud_t *pud = pud_offset(pgd, addr);
|
||||
pmd_t *pmd = pmd_offset(pud, addr);
|
||||
|
||||
return(pte_offset_map(pmd, addr));
|
||||
return pte_offset_map(pmd, addr);
|
||||
}
|
||||
|
||||
void flush_tlb_all(void)
|
||||
|
@ -480,7 +478,8 @@ static int do_ops(union mm_context *mmu, struct host_vm_op *ops, int last,
|
|||
finished, flush);
|
||||
break;
|
||||
default:
|
||||
printk("Unknown op type %d in do_ops\n", op->type);
|
||||
printk(KERN_ERR "Unknown op type %d in do_ops\n",
|
||||
op->type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -509,7 +508,8 @@ void flush_tlb_mm(struct mm_struct *mm)
|
|||
{
|
||||
unsigned long end;
|
||||
|
||||
/* Don't bother flushing if this address space is about to be
|
||||
/*
|
||||
* Don't bother flushing if this address space is about to be
|
||||
* destroyed.
|
||||
*/
|
||||
if (atomic_read(&mm->mm_users) == 0)
|
||||
|
|
|
@ -1,39 +1,22 @@
|
|||
/*
|
||||
* Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
|
||||
* Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||
* 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/mm.h"
|
||||
#include "linux/module.h"
|
||||
#include "linux/seq_file.h"
|
||||
#include "linux/string.h"
|
||||
#include "linux/utsname.h"
|
||||
#include "asm/page.h"
|
||||
#include "asm/pgtable.h"
|
||||
#include "asm/ptrace.h"
|
||||
#include "asm/elf.h"
|
||||
#include "asm/user.h"
|
||||
#include "asm/processor.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 "as-layout.h"
|
||||
#include "init.h"
|
||||
#include "kern.h"
|
||||
#include "mem_user.h"
|
||||
#include "mem.h"
|
||||
#include "initrd.h"
|
||||
#include "init.h"
|
||||
#include "os.h"
|
||||
#include "skas.h"
|
||||
|
||||
|
@ -223,9 +206,8 @@ static int __init uml_checksetup(char *line, int *add)
|
|||
int n;
|
||||
|
||||
n = strlen(p->str);
|
||||
if(!strncmp(line, p->str, n)){
|
||||
if (p->setup_func(line + n, add)) return 1;
|
||||
}
|
||||
if (!strncmp(line, p->str, n) && p->setup_func(line + n, add))
|
||||
return 1;
|
||||
p++;
|
||||
}
|
||||
return 0;
|
||||
|
@ -273,7 +255,8 @@ int __init linux_main(int argc, char **argv)
|
|||
char * mode;
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
if((i == 1) && (argv[i][0] == ' ')) continue;
|
||||
if ((i == 1) && (argv[i][0] == ' '))
|
||||
continue;
|
||||
add = 1;
|
||||
uml_checksetup(argv[i], &add);
|
||||
if (add)
|
||||
|
@ -282,6 +265,7 @@ int __init linux_main(int argc, char **argv)
|
|||
if (have_root == 0)
|
||||
add_arg(DEFAULT_COMMAND_LINE);
|
||||
|
||||
/* OS sanity checks that need to happen before the kernel runs */
|
||||
os_early_checks();
|
||||
|
||||
can_do_skas();
|
||||
|
@ -302,9 +286,11 @@ int __init linux_main(int argc, char **argv)
|
|||
|
||||
brk_start = (unsigned long) sbrk(0);
|
||||
|
||||
/* Increase physical memory size for exec-shield users
|
||||
so they actually get what they asked for. This should
|
||||
add zero for non-exec shield users */
|
||||
/*
|
||||
* Increase physical memory size for 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);
|
||||
if (diff > 1024 * 1024) {
|
||||
|
@ -324,7 +310,8 @@ int __init linux_main(int argc, char **argv)
|
|||
iomem_size = (iomem_size + PAGE_SIZE - 1) & PAGE_MASK;
|
||||
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
|
||||
*/
|
||||
max_physmem &= ~((1 << (PAGE_SHIFT + MAX_ORDER)) - 1);
|
||||
|
@ -354,7 +341,8 @@ int __init linux_main(int argc, char **argv)
|
|||
|
||||
virtmem_size = physmem_size;
|
||||
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;
|
||||
|
||||
if (virtmem_size < physmem_size)
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
/*
|
||||
* Copyright (C) 2004 Jeff Dike (jdike@addtoit.com)
|
||||
* Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||
* Licensed under the GPL
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sched.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <sched.h>
|
||||
#include <sys/syscall.h>
|
||||
#include "os.h"
|
||||
#include <sys/time.h>
|
||||
#include <asm/unistd.h>
|
||||
#include "aio.h"
|
||||
#include "init.h"
|
||||
#include "user.h"
|
||||
#include "kern_constants.h"
|
||||
#include "os.h"
|
||||
#include "user.h"
|
||||
|
||||
struct aio_thread_req {
|
||||
enum aio_type type;
|
||||
|
@ -27,7 +27,8 @@ struct aio_thread_req {
|
|||
#if defined(HAVE_AIO_ABI)
|
||||
#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.
|
||||
*/
|
||||
|
||||
|
@ -51,7 +52,8 @@ static long io_getevents(aio_context_t ctx_id, long min_nr, long nr,
|
|||
|
||||
#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
|
||||
* to do this by touching the page, but that's delicate because
|
||||
* gcc is prone to optimizing that away. So, what's done here
|
||||
|
@ -110,7 +112,7 @@ static int aio_thread(void *arg)
|
|||
if (n < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
printk("aio_thread - io_getevents failed, "
|
||||
printk(UM_KERN_ERR "aio_thread - io_getevents failed, "
|
||||
"errno = %d\n", errno);
|
||||
}
|
||||
else {
|
||||
|
@ -120,8 +122,8 @@ static int aio_thread(void *arg)
|
|||
reply_fd = ((struct aio_context *) reply.data)->reply_fd;
|
||||
err = write(reply_fd, &reply, sizeof(reply));
|
||||
if (err != sizeof(reply))
|
||||
printk("aio_thread - write failed, fd = %d, "
|
||||
"err = %d\n", reply_fd, errno);
|
||||
printk(UM_KERN_ERR "aio_thread - write failed, "
|
||||
"fd = %d, err = %d\n", reply_fd, errno);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
@ -150,7 +152,8 @@ static int do_not_aio(struct aio_thread_req *req)
|
|||
n = read(req->io_fd, &c, sizeof(c));
|
||||
break;
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -176,12 +179,14 @@ static int not_aio_thread(void *arg)
|
|||
err = read(aio_req_fd_r, &req, sizeof(req));
|
||||
if (err != sizeof(req)) {
|
||||
if (err < 0)
|
||||
printk("not_aio_thread - read failed, "
|
||||
"fd = %d, err = %d\n", aio_req_fd_r,
|
||||
printk(UM_KERN_ERR "not_aio_thread - "
|
||||
"read failed, fd = %d, err = %d\n",
|
||||
aio_req_fd_r,
|
||||
errno);
|
||||
else {
|
||||
printk("not_aio_thread - short read, fd = %d, "
|
||||
"length = %d\n", aio_req_fd_r, err);
|
||||
printk(UM_KERN_ERR "not_aio_thread - short "
|
||||
"read, fd = %d, length = %d\n",
|
||||
aio_req_fd_r, err);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
@ -190,8 +195,8 @@ static int not_aio_thread(void *arg)
|
|||
.err = err });
|
||||
err = write(req.aio->reply_fd, &reply, sizeof(reply));
|
||||
if (err != sizeof(reply))
|
||||
printk("not_aio_thread - write failed, fd = %d, "
|
||||
"err = %d\n", req.aio->reply_fd, errno);
|
||||
printk(UM_KERN_ERR "not_aio_thread - write failed, "
|
||||
"fd = %d, err = %d\n", req.aio->reply_fd, errno);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -227,10 +232,11 @@ out_close_pipe:
|
|||
aio_req_fd_r = -1;
|
||||
out:
|
||||
#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
|
||||
printk("2.6 host AIO support not used - falling back to I/O "
|
||||
"thread\n");
|
||||
printk(UM_KERN_INFO "2.6 host AIO support not used - falling back to "
|
||||
"I/O thread\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -242,8 +248,8 @@ static int init_aio_26(void)
|
|||
|
||||
if (io_setup(256, &ctx)) {
|
||||
err = -errno;
|
||||
printk("aio_thread failed to initialize context, err = %d\n",
|
||||
errno);
|
||||
printk(UM_KERN_ERR "aio_thread failed to initialize context, "
|
||||
"err = %d\n", errno);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -254,7 +260,7 @@ static int init_aio_26(void)
|
|||
|
||||
aio_pid = err;
|
||||
|
||||
printk("Using 2.6 host AIO\n");
|
||||
printk(UM_KERN_INFO "Using 2.6 host AIO\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -271,7 +277,7 @@ static int submit_aio_26(enum aio_type type, int io_fd, char *buf, int len,
|
|||
err = write(aio->reply_fd, &reply, sizeof(reply));
|
||||
if (err != sizeof(reply)) {
|
||||
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);
|
||||
}
|
||||
else err = 0;
|
||||
|
@ -322,8 +328,8 @@ static int init_aio(void)
|
|||
if (!aio_24) {
|
||||
err = init_aio_26();
|
||||
if (err && (errno == ENOSYS)) {
|
||||
printk("2.6 AIO not supported on the host - "
|
||||
"reverting to 2.4 AIO\n");
|
||||
printk(UM_KERN_INFO "2.6 AIO not supported on the "
|
||||
"host - reverting to 2.4 AIO\n");
|
||||
aio_24 = 1;
|
||||
}
|
||||
else return err;
|
||||
|
@ -335,7 +341,8 @@ static int init_aio(void)
|
|||
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,
|
||||
* 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
|
||||
|
@ -380,7 +387,6 @@ int submit_aio(enum aio_type type, int io_fd, char *buf, int len,
|
|||
aio->reply_fd = reply_fd;
|
||||
if (aio_24)
|
||||
return submit_aio_24(type, io_fd, buf, len, offset, aio);
|
||||
else {
|
||||
else
|
||||
return submit_aio_26(type, io_fd, buf, len, offset, aio);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -267,9 +267,9 @@ void os_close_file(int 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);
|
||||
if(actual != offset)
|
||||
|
|
|
@ -1,27 +1,21 @@
|
|||
/*
|
||||
* Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
|
||||
* Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||
* Licensed under the GPL
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/user.h>
|
||||
#include "kern_util.h"
|
||||
#include "as-layout.h"
|
||||
#include "mem_user.h"
|
||||
#include "irq_user.h"
|
||||
#include "user.h"
|
||||
#include "init.h"
|
||||
#include "uml-config.h"
|
||||
#include "kern_constants.h"
|
||||
#include "kern_util.h"
|
||||
#include "os.h"
|
||||
#include "um_malloc.h"
|
||||
#include "kern_constants.h"
|
||||
|
||||
#define PGD_BOUND (4 * 1024 * 1024)
|
||||
#define STACKSIZE (8 * 1024 * 1024)
|
||||
|
@ -68,7 +62,8 @@ static void install_fatal_handler(int sig)
|
|||
/* All signals are enabled in this handler ... */
|
||||
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 is hanging for some reason, the UML will just die
|
||||
* after this signal is sent a second time.
|
||||
|
@ -92,7 +87,8 @@ static void setup_env_path(void)
|
|||
int path_len = 0;
|
||||
|
||||
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
|
||||
*/
|
||||
if (!old_path || (path_len = strlen(old_path)) == 0) {
|
||||
|
@ -138,7 +134,8 @@ int __init main(int argc, char **argv, char **envp)
|
|||
}
|
||||
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.
|
||||
*/
|
||||
install_fatal_handler(SIGINT);
|
||||
|
@ -150,13 +147,15 @@ int __init main(int argc, char **argv, char **envp)
|
|||
do_uml_initcalls();
|
||||
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
|
||||
* exiting when profiling is active.
|
||||
*/
|
||||
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
|
||||
* when writing out gcov information, presumably because that takes
|
||||
* some time) and cause a segfault.
|
||||
|
@ -170,7 +169,8 @@ int __init main(int argc, char **argv, char **envp)
|
|||
if (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
|
||||
* they are definitely not expected.
|
||||
*/
|
||||
|
@ -200,7 +200,8 @@ void *__wrap_malloc(int size)
|
|||
ret = kmalloc(size, UM_GFP_KERNEL);
|
||||
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.
|
||||
*/
|
||||
if (ret == NULL)
|
||||
|
@ -227,7 +228,8 @@ void __wrap_free(void *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
|
||||
* in -
|
||||
* physical memory - kmalloc/kfree
|
||||
|
|
|
@ -1,27 +1,23 @@
|
|||
/*
|
||||
* Copyright (C) 2002 Jeff Dike (jdike@addtoit.com)
|
||||
* Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||
* Licensed under the GPL
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/ptrace.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/syscall.h>
|
||||
#include "ptrace_user.h"
|
||||
#include "os.h"
|
||||
#include "user.h"
|
||||
#include "process.h"
|
||||
#include "irq_user.h"
|
||||
#include "kern_util.h"
|
||||
#include "longjmp.h"
|
||||
#include "skas_ptrace.h"
|
||||
#include "kern_constants.h"
|
||||
#include "uml-config.h"
|
||||
#include <asm/unistd.h>
|
||||
#include "init.h"
|
||||
#include "kern_constants.h"
|
||||
#include "longjmp.h"
|
||||
#include "os.h"
|
||||
#include "process.h"
|
||||
#include "skas_ptrace.h"
|
||||
#include "user.h"
|
||||
|
||||
#define ARBITRARY_ADDR -1
|
||||
#define FAILURE_PID -1
|
||||
|
@ -38,14 +34,14 @@ unsigned long os_process_pc(int pid)
|
|||
sprintf(proc_stat, "/proc/%d/stat", pid);
|
||||
fd = os_open_file(proc_stat, of_read(OPENFLAGS()), 0);
|
||||
if (fd < 0) {
|
||||
printk("os_process_pc - couldn't open '%s', err = %d\n",
|
||||
proc_stat, -fd);
|
||||
printk(UM_KERN_ERR "os_process_pc - couldn't open '%s', "
|
||||
"err = %d\n", proc_stat, -fd);
|
||||
return ARBITRARY_ADDR;
|
||||
}
|
||||
CATCH_EINTR(err = read(fd, buf, sizeof(buf)));
|
||||
if (err < 0) {
|
||||
printk("os_process_pc - couldn't read '%s', err = %d\n",
|
||||
proc_stat, errno);
|
||||
printk(UM_KERN_ERR "os_process_pc - couldn't read '%s', "
|
||||
"err = %d\n", proc_stat, errno);
|
||||
os_close_file(fd);
|
||||
return ARBITRARY_ADDR;
|
||||
}
|
||||
|
@ -54,7 +50,8 @@ unsigned long os_process_pc(int pid)
|
|||
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 %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;
|
||||
}
|
||||
|
@ -71,7 +68,7 @@ int os_process_parent(int pid)
|
|||
snprintf(stat, sizeof(stat), "/proc/%d/stat", pid);
|
||||
fd = os_open_file(stat, of_read(OPENFLAGS()), 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;
|
||||
}
|
||||
|
||||
|
@ -79,14 +76,15 @@ int os_process_parent(int pid)
|
|||
os_close_file(fd);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
parent = FAILURE_PID;
|
||||
n = sscanf(data, "%*d " COMM_SCANF " %*c %d", &parent);
|
||||
if (n != 1)
|
||||
printk("Failed to scan '%s'\n", data);
|
||||
printk(UM_KERN_ERR "Failed to scan '%s'\n", data);
|
||||
|
||||
return parent;
|
||||
}
|
||||
|
@ -101,7 +99,6 @@ void os_kill_process(int pid, int reap_child)
|
|||
kill(pid, SIGKILL);
|
||||
if (reap_child)
|
||||
CATCH_EINTR(waitpid(pid, NULL, 0));
|
||||
|
||||
}
|
||||
|
||||
/* This is here uniquely to have access to the userspace errno, i.e. the one
|
||||
|
@ -170,6 +167,7 @@ int os_protect_memory(void *addr, unsigned long len, int r, int w, int x)
|
|||
|
||||
if (mprotect(addr, len, prot) < 0)
|
||||
return -errno;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -202,22 +200,24 @@ int __init can_drop_memory(void)
|
|||
void *addr;
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
addr = mmap64(NULL, UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED, fd, 0);
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
/*
|
||||
* Copyright (C) 2004 PathScale, Inc
|
||||
* Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||
* Licensed under the GPL
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <sys/ptrace.h>
|
||||
#include "user.h"
|
||||
#include "sysdep/ptrace.h"
|
||||
#include "user.h"
|
||||
|
||||
/* This is set once at boot time and not changed thereafter */
|
||||
|
||||
|
|
|
@ -1,24 +1,21 @@
|
|||
/*
|
||||
* Copyright (C) 2004 PathScale, Inc
|
||||
* Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||
* Licensed under the GPL
|
||||
*/
|
||||
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <sys/mman.h>
|
||||
#include "user.h"
|
||||
#include "signal_kern.h"
|
||||
#include "sysdep/sigcontext.h"
|
||||
#include "sysdep/barrier.h"
|
||||
#include "sigcontext.h"
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <strings.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
|
||||
* 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
|
||||
|
@ -33,7 +30,8 @@
|
|||
#define SIGALRM_BIT 2
|
||||
#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
|
||||
* register - they must go straight to memory.
|
||||
*/
|
||||
|
@ -145,7 +143,8 @@ void handle_signal(int sig, struct sigcontext *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
|
||||
* is non-zero, we just go back, set up the stack
|
||||
* again, and handle the new interrupts.
|
||||
|
@ -192,13 +191,14 @@ int change_sig(int signal, int on)
|
|||
sigemptyset(&sigset);
|
||||
sigaddset(&sigset, signal);
|
||||
sigprocmask(on ? SIG_UNBLOCK : SIG_BLOCK, &sigset, &old);
|
||||
return(!sigismember(&old, signal));
|
||||
return !sigismember(&old, signal);
|
||||
}
|
||||
|
||||
void block_signals(void)
|
||||
{
|
||||
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.
|
||||
* This might matter if gcc figures out how to inline this and
|
||||
* decides to shuffle this code into the caller.
|
||||
|
@ -213,24 +213,28 @@ void unblock_signals(void)
|
|||
if (signals_enabled == 1)
|
||||
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
|
||||
* recheck pending.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
signals_enabled = 1;
|
||||
|
||||
/* Setting signals_enabled and reading pending must
|
||||
/*
|
||||
* Setting signals_enabled and reading pending must
|
||||
* happen in this order.
|
||||
*/
|
||||
mb();
|
||||
|
||||
save_pending = pending;
|
||||
if (save_pending == 0) {
|
||||
/* This must return with signals enabled, so
|
||||
/*
|
||||
* This must return with signals enabled, so
|
||||
* this barrier ensures that writes are
|
||||
* flushed out before the return. This might
|
||||
* matter if gcc figures out how to inline
|
||||
|
@ -243,14 +247,16 @@ void unblock_signals(void)
|
|||
|
||||
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
|
||||
* be enabled again above.
|
||||
*/
|
||||
|
||||
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
|
||||
* back here.
|
||||
*/
|
||||
|
|
|
@ -1,30 +1,25 @@
|
|||
/*
|
||||
* Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
|
||||
* Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||
* Licensed under the GPL
|
||||
*/
|
||||
|
||||
#include <signal.h>
|
||||
#include <stddef.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/wait.h>
|
||||
#include <asm/unistd.h>
|
||||
#include "mem_user.h"
|
||||
#include "mem.h"
|
||||
#include "skas.h"
|
||||
#include "user.h"
|
||||
#include "init.h"
|
||||
#include "kern_constants.h"
|
||||
#include "mm_id.h"
|
||||
#include "os.h"
|
||||
#include "proc_mm.h"
|
||||
#include "ptrace_user.h"
|
||||
#include "kern_util.h"
|
||||
#include "task.h"
|
||||
#include "registers.h"
|
||||
#include "uml-config.h"
|
||||
#include "skas.h"
|
||||
#include "user.h"
|
||||
#include "sysdep/ptrace.h"
|
||||
#include "sysdep/stub.h"
|
||||
#include "init.h"
|
||||
#include "kern_constants.h"
|
||||
#include "uml-config.h"
|
||||
|
||||
extern unsigned long batch_syscall_stub, __syscall_stub_start;
|
||||
|
||||
|
@ -75,9 +70,9 @@ static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr)
|
|||
|
||||
n = ptrace_setregs(pid, syscall_regs);
|
||||
if (n < 0) {
|
||||
printk("Registers - \n");
|
||||
printk(UM_KERN_ERR "Registers - \n");
|
||||
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",
|
||||
-n);
|
||||
}
|
||||
|
@ -89,7 +84,8 @@ static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr)
|
|||
|
||||
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:
|
||||
* (long )return_value
|
||||
* (long )offset to failed sycall-data (0, if no error)
|
||||
|
@ -99,21 +95,22 @@ static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr)
|
|||
if (offset) {
|
||||
data = (unsigned long *)(mm_idp->stack +
|
||||
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);
|
||||
syscall = (unsigned long *)((unsigned long)data + data[0]);
|
||||
printk("do_syscall_stub: syscall %ld failed, return value = "
|
||||
"0x%lx, expected return value = 0x%lx\n",
|
||||
printk(UM_KERN_ERR "do_syscall_stub: syscall %ld failed, "
|
||||
"return value = 0x%lx, expected return value = 0x%lx\n",
|
||||
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",
|
||||
syscall[1], syscall[2], syscall[3],
|
||||
syscall[4], syscall[5], syscall[6]);
|
||||
for (n = 1; n < data[0]/sizeof(long); n++) {
|
||||
if (n == 1)
|
||||
printk(" additional syscall data:");
|
||||
printk(UM_KERN_ERR " additional syscall "
|
||||
"data:");
|
||||
if (n % 4 == 1)
|
||||
printk("\n ");
|
||||
printk("\n" UM_KERN_ERR " ");
|
||||
printk(" 0x%lx", data[n]);
|
||||
}
|
||||
if (n > 1)
|
||||
|
@ -165,7 +162,8 @@ long syscall_stub_data(struct mm_id * mm_idp,
|
|||
unsigned long *stack;
|
||||
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.
|
||||
*/
|
||||
if ((((unsigned long) *addr) & ~UM_KERN_PAGE_MASK) >=
|
||||
|
@ -212,7 +210,8 @@ int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len, int prot,
|
|||
CATCH_EINTR(ret = write(fd, &map, sizeof(map)));
|
||||
if (ret != sizeof(map)) {
|
||||
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;
|
||||
}
|
||||
|
@ -246,7 +245,8 @@ int unmap(struct mm_id * mm_idp, unsigned long addr, unsigned long len,
|
|||
CATCH_EINTR(ret = write(fd, &unmap, sizeof(unmap)));
|
||||
if (ret != sizeof(unmap)) {
|
||||
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;
|
||||
}
|
||||
|
@ -281,7 +281,7 @@ int protect(struct mm_id * mm_idp, unsigned long addr, unsigned long len,
|
|||
CATCH_EINTR(ret = write(fd, &protect, sizeof(protect)));
|
||||
if (ret != sizeof(protect)) {
|
||||
ret = -errno;
|
||||
printk("protect failed, err = %d", -ret);
|
||||
printk(UM_KERN_ERR "protect failed, err = %d", -ret);
|
||||
}
|
||||
else ret = 0;
|
||||
}
|
||||
|
|
|
@ -1,48 +1,38 @@
|
|||
/*
|
||||
* Copyright (C) 2002- 2004 Jeff Dike (jdike@addtoit.com)
|
||||
* Copyright (C) 2002- 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||
* Licensed under the GPL
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <sched.h>
|
||||
#include "ptrace_user.h"
|
||||
#include <sys/wait.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/user.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <asm/types.h>
|
||||
#include "user.h"
|
||||
#include "sysdep/ptrace.h"
|
||||
#include "kern_util.h"
|
||||
#include "skas.h"
|
||||
#include "stub-data.h"
|
||||
#include "mm_id.h"
|
||||
#include "sysdep/sigcontext.h"
|
||||
#include "sysdep/stub.h"
|
||||
#include "os.h"
|
||||
#include "proc_mm.h"
|
||||
#include "skas_ptrace.h"
|
||||
#include "chan_user.h"
|
||||
#include "registers.h"
|
||||
#include "mem.h"
|
||||
#include "uml-config.h"
|
||||
#include "process.h"
|
||||
#include "longjmp.h"
|
||||
#include "kern_constants.h"
|
||||
#include <sys/ptrace.h>
|
||||
#include <sys/wait.h>
|
||||
#include <asm/unistd.h>
|
||||
#include "as-layout.h"
|
||||
#include "chan_user.h"
|
||||
#include "kern_constants.h"
|
||||
#include "mem.h"
|
||||
#include "os.h"
|
||||
#include "process.h"
|
||||
#include "proc_mm.h"
|
||||
#include "ptrace_user.h"
|
||||
#include "registers.h"
|
||||
#include "skas.h"
|
||||
#include "skas_ptrace.h"
|
||||
#include "user.h"
|
||||
#include "sysdep/stub.h"
|
||||
|
||||
int is_skas_winch(int pid, int fd, void *data)
|
||||
{
|
||||
if (pid != os_getpgrp())
|
||||
return(0);
|
||||
return 0;
|
||||
|
||||
register_winch_irq(-1, fd, -1, data, 0);
|
||||
return(1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ptrace_dump_regs(int pid)
|
||||
|
@ -52,11 +42,10 @@ static int ptrace_dump_regs(int pid)
|
|||
|
||||
if (ptrace(PTRACE_GETREGS, pid, 0, regs) < 0)
|
||||
return -errno;
|
||||
else {
|
||||
printk("Stub registers -\n");
|
||||
|
||||
printk(UM_KERN_ERR "Stub registers -\n");
|
||||
for (i = 0; i < ARRAY_SIZE(regs); i++)
|
||||
printk("\t%d - %lx\n", i, regs[i]);
|
||||
}
|
||||
printk(UM_KERN_ERR "\t%d - %lx\n", i, regs[i]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -94,7 +83,8 @@ void wait_stub_done(int pid)
|
|||
bad_wait:
|
||||
err = ptrace_dump_regs(pid);
|
||||
if (err)
|
||||
printk("Failed to get registers from stub, errno = %d\n", -err);
|
||||
printk(UM_KERN_ERR "Failed to get registers from stub, "
|
||||
"errno = %d\n", -err);
|
||||
panic("wait_stub_done : failed to wait for SIGUSR1/SIGTRAP, pid = %d, "
|
||||
"n = %d, errno = %d, status = 0x%x\n", pid, n, errno, status);
|
||||
}
|
||||
|
@ -124,7 +114,8 @@ void get_skas_faultinfo(int pid, struct faultinfo * fi)
|
|||
pid, errno);
|
||||
wait_stub_done(pid);
|
||||
|
||||
/* faultinfo is prepared by the stub-segv-handler at start of
|
||||
/*
|
||||
* faultinfo is prepared by the stub-segv-handler at start of
|
||||
* the stub stack page. We just have to copy it.
|
||||
*/
|
||||
memcpy(fi, (void *)current_stub_stack(), sizeof(*fi));
|
||||
|
@ -137,8 +128,12 @@ static void handle_segv(int pid, struct uml_pt_regs * regs)
|
|||
segv(regs->faultinfo, 0, 1, NULL);
|
||||
}
|
||||
|
||||
/*To use the same value of using_sysemu as the caller, ask it that value (in local_using_sysemu)*/
|
||||
static void handle_trap(int pid, struct uml_pt_regs *regs, int local_using_sysemu)
|
||||
/*
|
||||
* To use the same value of using_sysemu as the caller, ask it that value
|
||||
* (in local_using_sysemu
|
||||
*/
|
||||
static void handle_trap(int pid, struct uml_pt_regs *regs,
|
||||
int local_using_sysemu)
|
||||
{
|
||||
int err, status;
|
||||
|
||||
|
@ -150,21 +145,21 @@ static void handle_trap(int pid, struct uml_pt_regs *regs, int local_using_sysem
|
|||
err = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_NR_OFFSET,
|
||||
__NR_getpid);
|
||||
if (err < 0)
|
||||
panic("handle_trap - nullifying syscall failed errno = %d\n",
|
||||
errno);
|
||||
panic("handle_trap - nullifying syscall failed, "
|
||||
"errno = %d\n", errno);
|
||||
|
||||
err = ptrace(PTRACE_SYSCALL, pid, 0, 0);
|
||||
if (err < 0)
|
||||
panic("handle_trap - continuing to end of syscall failed, "
|
||||
"errno = %d\n", errno);
|
||||
panic("handle_trap - continuing to end of syscall "
|
||||
"failed, errno = %d\n", errno);
|
||||
|
||||
CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED));
|
||||
if ((err < 0) || !WIFSTOPPED(status) ||
|
||||
(WSTOPSIG(status) != SIGTRAP + 0x80)) {
|
||||
err = ptrace_dump_regs(pid);
|
||||
if (err)
|
||||
printk("Failed to get registers from process, "
|
||||
"errno = %d\n", -err);
|
||||
printk(UM_KERN_ERR "Failed to get registers "
|
||||
"from process, errno = %d\n", -err);
|
||||
panic("handle_trap - failed to wait at end of syscall, "
|
||||
"errno = %d, status = %d\n", errno, status);
|
||||
}
|
||||
|
@ -189,17 +184,18 @@ static int userspace_tramp(void *stack)
|
|||
err);
|
||||
|
||||
if (!proc_mm) {
|
||||
/* This has a pte, but it can't be mapped in with the usual
|
||||
/*
|
||||
* This has a pte, but it can't be mapped in with the usual
|
||||
* tlb_flush mechanism because this is part of that mechanism
|
||||
*/
|
||||
int fd;
|
||||
__u64 offset;
|
||||
unsigned long long offset;
|
||||
fd = phys_mapping(to_phys(&__syscall_stub_start), &offset);
|
||||
addr = mmap64((void *) UML_CONFIG_STUB_CODE, UM_KERN_PAGE_SIZE,
|
||||
PROT_EXEC, MAP_FIXED | MAP_PRIVATE, fd, offset);
|
||||
if (addr == MAP_FAILED) {
|
||||
printk("mapping mmap stub failed, errno = %d\n",
|
||||
errno);
|
||||
printk(UM_KERN_ERR "mapping mmap stub failed, "
|
||||
"errno = %d\n", errno);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
@ -209,8 +205,8 @@ static int userspace_tramp(void *stack)
|
|||
UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE,
|
||||
MAP_FIXED | MAP_SHARED, fd, offset);
|
||||
if (addr == MAP_FAILED) {
|
||||
printk("mapping segfault stack failed, "
|
||||
"errno = %d\n", errno);
|
||||
printk(UM_KERN_ERR "mapping segfault stack "
|
||||
"failed, errno = %d\n", errno);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
@ -238,7 +234,7 @@ static int userspace_tramp(void *stack)
|
|||
}
|
||||
|
||||
os_stop_process(os_getpid());
|
||||
return(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Each element set once, and only accessed by a single processor anyway */
|
||||
|
@ -260,7 +256,9 @@ int start_userspace(unsigned long stub_stack)
|
|||
sp = (unsigned long) stack + UM_KERN_PAGE_SIZE - sizeof(void *);
|
||||
|
||||
flags = CLONE_FILES | SIGCHLD;
|
||||
if(proc_mm) flags |= CLONE_VM;
|
||||
if (proc_mm)
|
||||
flags |= CLONE_VM;
|
||||
|
||||
pid = clone(userspace_tramp, (void *) sp, flags, (void *) stub_stack);
|
||||
if (pid < 0)
|
||||
panic("start_userspace : clone failed, errno = %d", errno);
|
||||
|
@ -276,14 +274,15 @@ int start_userspace(unsigned long stub_stack)
|
|||
panic("start_userspace : expected SIGSTOP, got status = %d",
|
||||
status);
|
||||
|
||||
if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL, (void *)PTRACE_O_TRACESYSGOOD) < 0)
|
||||
panic("start_userspace : PTRACE_OLDSETOPTIONS failed, errno=%d\n",
|
||||
errno);
|
||||
if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL,
|
||||
(void *) PTRACE_O_TRACESYSGOOD) < 0)
|
||||
panic("start_userspace : PTRACE_OLDSETOPTIONS failed, "
|
||||
"errno = %d\n", errno);
|
||||
|
||||
if (munmap(stack, UM_KERN_PAGE_SIZE) < 0)
|
||||
panic("start_userspace : munmap failed, errno = %d\n", errno);
|
||||
|
||||
return(pid);
|
||||
return pid;
|
||||
}
|
||||
|
||||
void userspace(struct uml_pt_regs *regs)
|
||||
|
@ -320,8 +319,10 @@ void userspace(struct uml_pt_regs *regs)
|
|||
int sig = WSTOPSIG(status);
|
||||
switch(sig) {
|
||||
case SIGSEGV:
|
||||
if(PTRACE_FULL_FAULTINFO || !ptrace_faultinfo){
|
||||
get_skas_faultinfo(pid, ®s->faultinfo);
|
||||
if (PTRACE_FULL_FAULTINFO ||
|
||||
!ptrace_faultinfo) {
|
||||
get_skas_faultinfo(pid,
|
||||
®s->faultinfo);
|
||||
(*sig_info[SIGSEGV])(SIGSEGV, regs);
|
||||
}
|
||||
else handle_segv(pid, regs);
|
||||
|
@ -343,8 +344,8 @@ void userspace(struct uml_pt_regs *regs)
|
|||
unblock_signals();
|
||||
break;
|
||||
default:
|
||||
printk("userspace - child stopped with signal "
|
||||
"%d\n", sig);
|
||||
printk(UM_KERN_ERR "userspace - child stopped "
|
||||
"with signal %d\n", sig);
|
||||
}
|
||||
pid = userspace_pid[0];
|
||||
interrupt_end();
|
||||
|
@ -384,7 +385,8 @@ int copy_context_skas0(unsigned long new_stack, int pid)
|
|||
__u64 new_offset;
|
||||
int new_fd = phys_mapping(to_phys((void *)new_stack), &new_offset);
|
||||
|
||||
/* prepare offset and fd of child's stack as argument for parent's
|
||||
/*
|
||||
* prepare offset and fd of child's stack as argument for parent's
|
||||
* and child's mmap2 calls
|
||||
*/
|
||||
*data = ((struct stub_data) { .offset = MMAP_OFFSET(new_offset),
|
||||
|
@ -400,7 +402,8 @@ int copy_context_skas0(unsigned long new_stack, int pid)
|
|||
/* set a well known return code for detection of child write failure */
|
||||
child_data->err = 12345678;
|
||||
|
||||
/* Wait, until parent has finished its work: read child's pid from
|
||||
/*
|
||||
* Wait, until parent has finished its work: read child's pid from
|
||||
* parent's stack, and check, if bad result.
|
||||
*/
|
||||
err = ptrace(PTRACE_CONT, pid, 0, 0);
|
||||
|
@ -414,7 +417,8 @@ int copy_context_skas0(unsigned long new_stack, int pid)
|
|||
panic("copy_context_skas0 - stub-parent reports error %d\n",
|
||||
-pid);
|
||||
|
||||
/* Wait, until child has finished too: read child's result from
|
||||
/*
|
||||
* Wait, until child has finished too: read child's result from
|
||||
* child's stack and check it.
|
||||
*/
|
||||
wait_stub_done(pid);
|
||||
|
@ -457,8 +461,9 @@ void map_stub_pages(int fd, unsigned long code,
|
|||
CATCH_EINTR(n = write(fd, &mmop, sizeof(mmop)));
|
||||
if (n != sizeof(mmop)) {
|
||||
n = errno;
|
||||
printk("mmap args - addr = 0x%lx, fd = %d, offset = %llx\n",
|
||||
code, code_fd, (unsigned long long) code_offset);
|
||||
printk(UM_KERN_ERR "mmap args - addr = 0x%lx, fd = %d, "
|
||||
"offset = %llx\n", code, code_fd,
|
||||
(unsigned long long) code_offset);
|
||||
panic("map_stub_pages : /proc/mm map for code failed, "
|
||||
"err = %d\n", n);
|
||||
}
|
||||
|
@ -538,10 +543,10 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf)
|
|||
break;
|
||||
case INIT_JMP_HALT:
|
||||
kmalloc_ok = 0;
|
||||
return(0);
|
||||
return 0;
|
||||
case INIT_JMP_REBOOT:
|
||||
kmalloc_ok = 0;
|
||||
return(1);
|
||||
return 1;
|
||||
default:
|
||||
panic("Bad sigsetjmp return in start_idle_thread - %d\n", n);
|
||||
}
|
||||
|
|
|
@ -1,19 +1,23 @@
|
|||
/*
|
||||
* Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
|
||||
* Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||
* Licensed under the GPL
|
||||
*/
|
||||
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#if 0
|
||||
#include "kern_util.h"
|
||||
#include "as-layout.h"
|
||||
#include "task.h"
|
||||
#include "sigcontext.h"
|
||||
#include "skas.h"
|
||||
#include "ptrace_user.h"
|
||||
#include "sysdep/ptrace.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 "sigcontext.h"
|
||||
#include "task.h"
|
||||
|
||||
static struct uml_pt_regs ksig_regs[UM_NR_CPUS];
|
||||
|
||||
|
@ -24,14 +28,16 @@ void sig_handler_common_skas(int sig, void *sc_ptr)
|
|||
void (*handler)(int, struct uml_pt_regs *);
|
||||
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,
|
||||
* the process will die.
|
||||
* XXX Figure out why this is better than SA_NODEFER
|
||||
*/
|
||||
if (sig == SIGSEGV) {
|
||||
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
|
||||
* the process registers, so use a static set of
|
||||
* registers. For other signals, the process
|
||||
|
@ -44,11 +50,9 @@ void sig_handler_common_skas(int sig, void *sc_ptr)
|
|||
|
||||
save_user = r->is_user;
|
||||
r->is_user = 0;
|
||||
if ( sig == SIGFPE || sig == SIGSEGV ||
|
||||
sig == SIGBUS || sig == SIGILL ||
|
||||
sig == SIGTRAP ) {
|
||||
if ((sig == SIGFPE) || (sig == SIGSEGV) || (sig == SIGBUS) ||
|
||||
(sig == SIGILL) || (sig == SIGTRAP))
|
||||
GET_FAULTINFO_FROM_SC(r->faultinfo, sc);
|
||||
}
|
||||
|
||||
change_sig(SIGUSR1, 1);
|
||||
|
||||
|
|
|
@ -1,41 +1,29 @@
|
|||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include <pty.h>
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <sched.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/wait.h>
|
||||
#include <fcntl.h>
|
||||
#include <sched.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/ptrace.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include <asm/unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include "kern_util.h"
|
||||
#include "user.h"
|
||||
#include "signal_kern.h"
|
||||
#include "sysdep/ptrace.h"
|
||||
#include "sysdep/sigcontext.h"
|
||||
#include "irq_user.h"
|
||||
#include "ptrace_user.h"
|
||||
#include "mem_user.h"
|
||||
#include "init.h"
|
||||
#include "os.h"
|
||||
#include "uml-config.h"
|
||||
#include "tempfile.h"
|
||||
#include "kern_constants.h"
|
||||
#include "skas.h"
|
||||
#include "skas_ptrace.h"
|
||||
#include "os.h"
|
||||
#include "mem_user.h"
|
||||
#include "ptrace_user.h"
|
||||
#include "registers.h"
|
||||
#include "skas_ptrace.h"
|
||||
|
||||
static int ptrace_child(void *arg)
|
||||
{
|
||||
|
@ -50,20 +38,27 @@ static int ptrace_child(void *arg)
|
|||
}
|
||||
kill(pid, SIGSTOP);
|
||||
|
||||
/*This syscall will be intercepted by the parent. Don't call more than
|
||||
* once, please.*/
|
||||
/*
|
||||
* This syscall will be intercepted by the parent. Don't call more than
|
||||
* once, please.
|
||||
*/
|
||||
sc_result = os_getpid();
|
||||
|
||||
if (sc_result == pid)
|
||||
ret = 1; /*Nothing modified by the parent, we are running
|
||||
normally.*/
|
||||
/* Nothing modified by the parent, we are running normally. */
|
||||
ret = 1;
|
||||
else if (sc_result == ppid)
|
||||
ret = 0; /*Expected in check_ptrace and check_sysemu when they
|
||||
succeed in modifying the stack frame*/
|
||||
/*
|
||||
* Expected in check_ptrace and check_sysemu when they succeed
|
||||
* in modifying the stack frame
|
||||
*/
|
||||
ret = 0;
|
||||
else
|
||||
ret = 2; /*Serious trouble! This could be caused by a bug in
|
||||
host 2.6 SKAS3/2.6 patch before release -V6, together
|
||||
with a bug in the UML code itself.*/
|
||||
/* Serious trouble! This could be caused by a bug in host 2.6
|
||||
* SKAS3/2.6 patch before release -V6, together with a bug in
|
||||
* the UML code itself.
|
||||
*/
|
||||
ret = 2;
|
||||
_exit(ret);
|
||||
}
|
||||
|
||||
|
@ -106,10 +101,12 @@ static int start_ptraced_child(void **stack_out)
|
|||
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||
if (stack == MAP_FAILED)
|
||||
fatal_perror("check_ptrace : mmap failed");
|
||||
|
||||
sp = (unsigned long) stack + UM_KERN_PAGE_SIZE - sizeof(void *);
|
||||
pid = clone(ptrace_child, (void *) sp, SIGCHLD, NULL);
|
||||
if (pid < 0)
|
||||
fatal_perror("start_ptraced_child : clone failed");
|
||||
|
||||
CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
|
||||
if (n < 0)
|
||||
fatal_perror("check_ptrace : clone failed");
|
||||
|
@ -256,7 +253,8 @@ static void __init check_sysemu(void)
|
|||
if (n < 0)
|
||||
fatal_perror("check_ptrace : wait failed");
|
||||
|
||||
if(WIFSTOPPED(status) && (WSTOPSIG(status) == (SIGTRAP|0x80))){
|
||||
if (WIFSTOPPED(status) &&
|
||||
(WSTOPSIG(status) == (SIGTRAP|0x80))) {
|
||||
if (!count)
|
||||
fatal("check_ptrace : SYSEMU_SINGLESTEP "
|
||||
"doesn't singlestep");
|
||||
|
@ -477,12 +475,9 @@ static inline void check_skas3_proc_mm(void)
|
|||
proc_mm = 0;
|
||||
perror("not found");
|
||||
}
|
||||
else {
|
||||
if (!proc_mm)
|
||||
else if (!proc_mm)
|
||||
non_fatal("found but disabled on command line\n");
|
||||
else
|
||||
non_fatal("found\n");
|
||||
}
|
||||
else non_fatal("found\n");
|
||||
}
|
||||
|
||||
int can_do_skas(void)
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include "kern_util.h"
|
||||
#include "os.h"
|
||||
#include "longjmp.h"
|
||||
#include "sysdep/ptrace.h"
|
||||
|
||||
/* Initialized from linux_main() */
|
||||
void (*sig_info[NSIG])(int, struct uml_pt_regs *);
|
||||
|
|
|
@ -1,14 +1,19 @@
|
|||
/*
|
||||
* Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||
* Licensed under the GPL
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/param.h>
|
||||
#include "init.h"
|
||||
#include "kern_constants.h"
|
||||
#include "os.h"
|
||||
#include "user.h"
|
||||
|
||||
|
@ -32,8 +37,8 @@ static int __init make_uml_dir(void)
|
|||
|
||||
err = -ENOENT;
|
||||
if (home == NULL) {
|
||||
printk("make_uml_dir : no value in environment for "
|
||||
"$HOME\n");
|
||||
printk(UM_KERN_ERR "make_uml_dir : no value in "
|
||||
"environment for $HOME\n");
|
||||
goto err;
|
||||
}
|
||||
strlcpy(dir, home, sizeof(dir));
|
||||
|
@ -69,8 +74,8 @@ err:
|
|||
/*
|
||||
* 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
|
||||
* ignore ENOENT errors for anything (they happen, strangely enough - possibly due
|
||||
* to races between multiple dying UML threads).
|
||||
* ignore ENOENT errors for anything (they happen, strangely enough - possibly
|
||||
* due to races between multiple dying UML threads).
|
||||
*/
|
||||
static int remove_files_and_dir(char *dir)
|
||||
{
|
||||
|
@ -115,7 +120,8 @@ out:
|
|||
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
|
||||
* happen, the directory is unusable by the pre-existing UML, so we might as
|
||||
* well take it over. This could happen either by
|
||||
|
@ -134,7 +140,7 @@ static inline int is_umdir_used(char *dir)
|
|||
|
||||
n = snprintf(file, sizeof(file), "%s/pid", dir);
|
||||
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;
|
||||
goto out;
|
||||
}
|
||||
|
@ -144,8 +150,8 @@ static inline int is_umdir_used(char *dir)
|
|||
if (fd < 0) {
|
||||
fd = -errno;
|
||||
if (fd != -ENOENT) {
|
||||
printk("is_umdir_used : couldn't open pid file '%s', "
|
||||
"err = %d\n", file, -fd);
|
||||
printk(UM_KERN_ERR "is_umdir_used : couldn't open pid "
|
||||
"file '%s', err = %d\n", file, -fd);
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
|
@ -153,24 +159,25 @@ static inline int is_umdir_used(char *dir)
|
|||
err = 0;
|
||||
n = read(fd, pid, sizeof(pid));
|
||||
if (n < 0) {
|
||||
printk("is_umdir_used : couldn't read pid file '%s', "
|
||||
"err = %d\n", file, errno);
|
||||
printk(UM_KERN_ERR "is_umdir_used : couldn't read pid file "
|
||||
"'%s', err = %d\n", file, errno);
|
||||
goto out_close;
|
||||
} else if (n == 0) {
|
||||
printk("is_umdir_used : couldn't read pid file '%s', "
|
||||
"0-byte read\n", file);
|
||||
printk(UM_KERN_ERR "is_umdir_used : couldn't read pid file "
|
||||
"'%s', 0-byte read\n", file);
|
||||
goto out_close;
|
||||
}
|
||||
|
||||
p = strtoul(pid, &end, 0);
|
||||
if (end == pid) {
|
||||
printk("is_umdir_used : couldn't parse pid file '%s', "
|
||||
"errno = %d\n", file, errno);
|
||||
printk(UM_KERN_ERR "is_umdir_used : couldn't parse pid file "
|
||||
"'%s', errno = %d\n", file, errno);
|
||||
goto out_close;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -194,8 +201,8 @@ static int umdir_take_if_dead(char *dir)
|
|||
|
||||
ret = remove_files_and_dir(dir);
|
||||
if (ret) {
|
||||
printk("is_umdir_used - remove_files_and_dir failed with "
|
||||
"err = %d\n", ret);
|
||||
printk(UM_KERN_ERR "is_umdir_used - remove_files_and_dir "
|
||||
"failed with err = %d\n", ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -211,15 +218,16 @@ static void __init create_pid_file(void)
|
|||
|
||||
fd = open(file, O_RDWR | O_CREAT | O_EXCL, 0644);
|
||||
if (fd < 0) {
|
||||
printk("Open of machine pid file \"%s\" failed: %s\n",
|
||||
file, strerror(errno));
|
||||
printk(UM_KERN_ERR "Open of machine pid file \"%s\" failed: "
|
||||
"%s\n", file, strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
snprintf(pid, sizeof(pid), "%d\n", getpid());
|
||||
n = write(fd, pid, 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);
|
||||
}
|
||||
|
@ -252,8 +260,8 @@ int __init make_umid(void)
|
|||
strlcat(tmp, "XXXXXX", sizeof(tmp));
|
||||
fd = mkstemp(tmp);
|
||||
if (fd < 0) {
|
||||
printk("make_umid - mkstemp(%s) failed: %s\n",
|
||||
tmp, strerror(errno));
|
||||
printk(UM_KERN_ERR "make_umid - mkstemp(%s) failed: "
|
||||
"%s\n", tmp, strerror(errno));
|
||||
err = -errno;
|
||||
goto err;
|
||||
}
|
||||
|
@ -262,7 +270,8 @@ int __init make_umid(void)
|
|||
|
||||
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
|
||||
* for directories.
|
||||
*/
|
||||
|
@ -286,7 +295,8 @@ int __init make_umid(void)
|
|||
}
|
||||
if (err) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -304,11 +314,12 @@ static int __init make_umid_init(void)
|
|||
if (!make_umid())
|
||||
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.
|
||||
*/
|
||||
printk("Failed to initialize umid \"%s\", trying with a random umid\n",
|
||||
umid);
|
||||
printk(UM_KERN_ERR "Failed to initialize umid \"%s\", trying with a "
|
||||
"random umid\n", umid);
|
||||
*umid = '\0';
|
||||
make_umid();
|
||||
|
||||
|
@ -327,7 +338,7 @@ int __init umid_file_name(char *name, char *buf, int len)
|
|||
|
||||
n = snprintf(buf, len, "%s%s/%s", uml_dir, umid, name);
|
||||
if (n >= len) {
|
||||
printk("umid_file_name : buffer too short\n");
|
||||
printk(UM_KERN_ERR "umid_file_name : buffer too short\n");
|
||||
return -E2BIG;
|
||||
}
|
||||
|
||||
|
@ -355,7 +366,8 @@ static int __init set_uml_dir(char *name, int *add)
|
|||
if (uml_dir == NULL) {
|
||||
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.
|
||||
*/
|
||||
return 0;
|
||||
|
|
|
@ -1,18 +1,15 @@
|
|||
/*
|
||||
* Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
|
||||
* Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||
* Licensed under the GPL
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <sys/signal.h>
|
||||
#include <asm/ldt.h>
|
||||
#include "kern_util.h"
|
||||
#include "user.h"
|
||||
#include "sysdep/ptrace.h"
|
||||
#include "task.h"
|
||||
#include "kern_constants.h"
|
||||
#include "os.h"
|
||||
#include "task.h"
|
||||
#include "user.h"
|
||||
|
||||
#define MAXTOKEN 64
|
||||
|
||||
|
@ -33,7 +30,8 @@ static char token(int fd, char *buf, int len, char stop)
|
|||
if (n != sizeof(*ptr)) {
|
||||
if (n == 0)
|
||||
return 0;
|
||||
printk("Reading /proc/cpuinfo failed, err = %d\n", -n);
|
||||
printk(UM_KERN_ERR "Reading /proc/cpuinfo failed, "
|
||||
"err = %d\n", -n);
|
||||
if (n < 0)
|
||||
return n;
|
||||
else return -EIO;
|
||||
|
@ -41,7 +39,8 @@ static char token(int fd, char *buf, int len, char stop)
|
|||
} while ((c != '\n') && (c != stop) && (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;
|
||||
}
|
||||
*(ptr - 1) = '\0';
|
||||
|
@ -59,7 +58,8 @@ static int find_cpuinfo_line(int fd, char *key, char *scratch, int len)
|
|||
if (c <= 0)
|
||||
return 0;
|
||||
else if (c != ':') {
|
||||
printk("Failed to find ':' in /proc/cpuinfo\n");
|
||||
printk(UM_KERN_ERR "Failed to find ':' in "
|
||||
"/proc/cpuinfo\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -69,7 +69,7 @@ static int find_cpuinfo_line(int fd, char *key, char *scratch, int len)
|
|||
do {
|
||||
n = os_read_file(fd, &c, 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);
|
||||
return 0;
|
||||
}
|
||||
|
@ -83,10 +83,12 @@ static int check_cpu_flag(char *feature, int *have_it)
|
|||
char buf[MAXTOKEN], c;
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -98,7 +100,7 @@ static int check_cpu_flag(char *feature, int *have_it)
|
|||
if (c < 0)
|
||||
goto out;
|
||||
else if (c != ' ') {
|
||||
printk("Failed to find ' ' in /proc/cpuinfo\n");
|
||||
printk(UM_KERN_ERR "Failed to find ' ' in /proc/cpuinfo\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -106,7 +108,8 @@ static int check_cpu_flag(char *feature, int *have_it)
|
|||
c = token(fd, buf, len - 1, ' ');
|
||||
if (c < 0)
|
||||
goto out;
|
||||
else if(c == '\n') break;
|
||||
else if (c == '\n')
|
||||
break;
|
||||
|
||||
if (!strcmp(buf, feature)) {
|
||||
*have_it = 1;
|
||||
|
@ -122,7 +125,8 @@ static int check_cpu_flag(char *feature, int *have_it)
|
|||
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.
|
||||
*/
|
||||
static void disable_lcall(void)
|
||||
|
@ -136,7 +140,8 @@ static void disable_lcall(void)
|
|||
ldt.limit = 0;
|
||||
err = modify_ldt(1, &ldt, sizeof(ldt));
|
||||
if (err)
|
||||
printk("Failed to disable lcall7 - errno = %d\n", errno);
|
||||
printk(UM_KERN_ERR "Failed to disable lcall7 - errno = %d\n",
|
||||
errno);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -152,8 +157,8 @@ void arch_check_bugs(void)
|
|||
int have_it;
|
||||
|
||||
if (os_access("/proc/cpuinfo", OS_ACC_R_OK) < 0) {
|
||||
printk("/proc/cpuinfo not available - skipping CPU capability "
|
||||
"checks\n");
|
||||
printk(UM_KERN_ERR "/proc/cpuinfo not available - skipping CPU "
|
||||
"capability checks\n");
|
||||
return;
|
||||
}
|
||||
if (check_cpu_flag("cmov", &have_it))
|
||||
|
@ -166,7 +171,8 @@ int arch_handle_signal(int sig, struct uml_pt_regs *regs)
|
|||
{
|
||||
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.
|
||||
*/
|
||||
if ((sig != SIGILL) || (TASK_PID(get_current()) != 1))
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2002 - 2004 Jeff Dike (jdike@addtoit.com)
|
||||
* Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||
* Licensed under the GPL
|
||||
*/
|
||||
|
||||
|
@ -22,7 +22,7 @@ int arch_fixup(unsigned long address, struct uml_pt_regs *regs)
|
|||
fixup = search_exception_tables(address);
|
||||
if (fixup != 0) {
|
||||
UPT_IP(regs) = fixup->fixup;
|
||||
return(1);
|
||||
return 1;
|
||||
}
|
||||
return(0);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,26 +1,17 @@
|
|||
/*
|
||||
* Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
|
||||
* Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||
* Licensed under the GPL
|
||||
*/
|
||||
|
||||
#include "linux/sched.h"
|
||||
#include "linux/slab.h"
|
||||
#include "linux/types.h"
|
||||
#include "linux/errno.h"
|
||||
#include "linux/spinlock.h"
|
||||
#include "asm/uaccess.h"
|
||||
#include "asm/smp.h"
|
||||
#include "asm/ldt.h"
|
||||
#include "linux/mm.h"
|
||||
#include "asm/unistd.h"
|
||||
#include "kern.h"
|
||||
#include "os.h"
|
||||
|
||||
extern int modify_ldt(int func, void *ptr, unsigned long bytecount);
|
||||
|
||||
#include "proc_mm.h"
|
||||
#include "skas.h"
|
||||
#include "skas_ptrace.h"
|
||||
#include "asm/mmu_context.h"
|
||||
#include "proc_mm.h"
|
||||
#include "sysdep/tls.h"
|
||||
|
||||
extern int modify_ldt(int func, void *ptr, unsigned long bytecount);
|
||||
|
||||
long write_ldt_entry(struct mm_id * mm_idp, int func, struct user_desc * desc,
|
||||
void **addr, int done)
|
||||
|
@ -28,7 +19,8 @@ long write_ldt_entry(struct mm_id * mm_idp, int func, struct user_desc * desc,
|
|||
long res;
|
||||
|
||||
if (proc_mm) {
|
||||
/* This is a special handling for the case, that the mm to
|
||||
/*
|
||||
* This is a special handling for the case, that the mm to
|
||||
* modify isn't current->active_mm.
|
||||
* If this is called directly by modify_ldt,
|
||||
* (current->active_mm->context.skas.u == mm_idp)
|
||||
|
@ -82,7 +74,8 @@ long write_ldt_entry(struct mm_id * mm_idp, int func, struct user_desc * desc,
|
|||
}
|
||||
|
||||
if (proc_mm) {
|
||||
/* This is the second part of special handling, that makes
|
||||
/*
|
||||
* This is the second part of special handling, that makes
|
||||
* PTRACE_LDT possible to implement.
|
||||
*/
|
||||
if (current->active_mm && current->active_mm != &init_mm &&
|
||||
|
@ -105,7 +98,8 @@ static long read_ldt_from_host(void __user * ptr, unsigned long bytecount)
|
|||
if (ptrace_ldt.ptr == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
/* This is called from sys_modify_ldt only, so userspace_pid gives
|
||||
/*
|
||||
* This is called from sys_modify_ldt only, so userspace_pid gives
|
||||
* us the right number
|
||||
*/
|
||||
|
||||
|
@ -149,9 +143,8 @@ static int read_ldt(void __user * ptr, unsigned long bytecount)
|
|||
bytecount = LDT_ENTRY_SIZE*LDT_ENTRIES;
|
||||
err = bytecount;
|
||||
|
||||
if(ptrace_ldt){
|
||||
if (ptrace_ldt)
|
||||
return read_ldt_from_host(ptr, bytecount);
|
||||
}
|
||||
|
||||
down(&ldt->semaphore);
|
||||
if (ldt->entry_count <= LDT_DIRECT_ENTRIES) {
|
||||
|
@ -197,7 +190,8 @@ static int read_default_ldt(void __user * ptr, unsigned long bytecount)
|
|||
bytecount = 5*LDT_ENTRY_SIZE;
|
||||
|
||||
err = bytecount;
|
||||
/* UML doesn't support lcall7 and lcall27.
|
||||
/*
|
||||
* UML doesn't support lcall7 and lcall27.
|
||||
* So, we don't really have a default ldt, but emulate
|
||||
* an empty ldt of common host default ldt size.
|
||||
*/
|
||||
|
@ -340,19 +334,20 @@ static void ldt_get_host_info(void)
|
|||
|
||||
spin_unlock(&host_ldt_lock);
|
||||
|
||||
for(i = LDT_PAGES_MAX-1, order=0; i; i>>=1, order++);
|
||||
for (i = LDT_PAGES_MAX-1, order=0; i; i>>=1, order++)
|
||||
;
|
||||
|
||||
ldt = (struct ldt_entry *)
|
||||
__get_free_pages(GFP_KERNEL|__GFP_ZERO, order);
|
||||
if (ldt == NULL) {
|
||||
printk("ldt_get_host_info: couldn't allocate buffer for host "
|
||||
"ldt\n");
|
||||
printk(KERN_ERR "ldt_get_host_info: couldn't allocate buffer "
|
||||
"for host ldt\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ret = modify_ldt(0, ldt, (1<<order)*PAGE_SIZE);
|
||||
if (ret < 0) {
|
||||
printk("ldt_get_host_info: couldn't read host ldt\n");
|
||||
printk(KERN_ERR "ldt_get_host_info: couldn't read host ldt\n");
|
||||
goto out_free;
|
||||
}
|
||||
if (ret == 0) {
|
||||
|
@ -372,18 +367,17 @@ static void ldt_get_host_info(void)
|
|||
size = (size + 1) * sizeof(dummy_list[0]);
|
||||
tmp = kmalloc(size, GFP_KERNEL);
|
||||
if (tmp == NULL) {
|
||||
printk("ldt_get_host_info: couldn't allocate host ldt "
|
||||
"list\n");
|
||||
printk(KERN_ERR "ldt_get_host_info: couldn't allocate "
|
||||
"host ldt list\n");
|
||||
goto out_free;
|
||||
}
|
||||
host_ldt_entries = tmp;
|
||||
}
|
||||
|
||||
for (i=0, k=0; i<ret/LDT_ENTRY_SIZE; i++) {
|
||||
if(ldt[i].a != 0 || ldt[i].b != 0) {
|
||||
if (ldt[i].a != 0 || ldt[i].b != 0)
|
||||
host_ldt_entries[k++] = i;
|
||||
}
|
||||
}
|
||||
host_ldt_entries[k] = -1;
|
||||
|
||||
out_free:
|
||||
|
@ -417,8 +411,7 @@ long init_new_ldt(struct mmu_context_skas * new_mm,
|
|||
* To remove these gates, we simply write an empty
|
||||
* entry as number 0 to the host.
|
||||
*/
|
||||
err = write_ldt_entry(&new_mm->id, 1, &desc,
|
||||
&addr, 1);
|
||||
err = write_ldt_entry(&new_mm->id, 1, &desc, &addr, 1);
|
||||
}
|
||||
else{
|
||||
/*
|
||||
|
@ -441,7 +434,8 @@ long init_new_ldt(struct mmu_context_skas * new_mm,
|
|||
}
|
||||
|
||||
if (proc_mm) {
|
||||
/* We have a valid from_mm, so we now have to copy the LDT of
|
||||
/*
|
||||
* We have a valid from_mm, so we now have to copy the LDT of
|
||||
* from_mm to new_mm, because using proc_mm an new mm with
|
||||
* an empty/default LDT was created in new_mm()
|
||||
*/
|
||||
|
@ -451,21 +445,21 @@ long init_new_ldt(struct mmu_context_skas * new_mm,
|
|||
from_mm->id.u.mm_fd } } );
|
||||
i = os_write_file(new_mm->id.u.mm_fd, ©, sizeof(copy));
|
||||
if (i != sizeof(copy))
|
||||
printk("new_mm : /proc/mm copy_segments failed, "
|
||||
"err = %d\n", -i);
|
||||
printk(KERN_ERR "new_mm : /proc/mm copy_segments "
|
||||
"failed, err = %d\n", -i);
|
||||
}
|
||||
|
||||
if (!ptrace_ldt) {
|
||||
/* Our local LDT is used to supply the data for
|
||||
/*
|
||||
* Our local LDT is used to supply the data for
|
||||
* modify_ldt(READLDT), if PTRACE_LDT isn't available,
|
||||
* i.e., we have to use the stub for modify_ldt, which
|
||||
* can't handle the big read buffer of up to 64kB.
|
||||
*/
|
||||
down(&from_mm->ldt.semaphore);
|
||||
if(from_mm->ldt.entry_count <= LDT_DIRECT_ENTRIES){
|
||||
if (from_mm->ldt.entry_count <= LDT_DIRECT_ENTRIES)
|
||||
memcpy(new_mm->ldt.u.entries, from_mm->ldt.u.entries,
|
||||
sizeof(new_mm->ldt.u.entries));
|
||||
}
|
||||
else {
|
||||
i = from_mm->ldt.entry_count / LDT_ENTRIES_PER_PAGE;
|
||||
while (i-->0) {
|
||||
|
@ -495,10 +489,9 @@ void free_ldt(struct mmu_context_skas * mm)
|
|||
|
||||
if (!ptrace_ldt && mm->ldt.entry_count > LDT_DIRECT_ENTRIES) {
|
||||
i = mm->ldt.entry_count / LDT_ENTRIES_PER_PAGE;
|
||||
while(i-- > 0){
|
||||
while (i-- > 0)
|
||||
free_page((long) mm->ldt.u.pages[i]);
|
||||
}
|
||||
}
|
||||
mm->ldt.entry_count = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,18 +1,11 @@
|
|||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include <linux/compiler.h>
|
||||
#include "linux/sched.h"
|
||||
#include "linux/mm.h"
|
||||
#include "asm/elf.h"
|
||||
#include "asm/ptrace.h"
|
||||
#include "linux/sched.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);
|
||||
|
||||
|
@ -23,7 +16,8 @@ void arch_switch_to(struct task_struct *from, struct task_struct *to)
|
|||
return;
|
||||
|
||||
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
|
||||
printk(KERN_WARNING "arch_switch_tls failed, errno = EINVAL\n");
|
||||
}
|
||||
|
@ -42,13 +36,13 @@ int is_syscall(unsigned long addr)
|
|||
*/
|
||||
n = access_process_vm(current, addr, &instr, sizeof(instr), 0);
|
||||
if (n != sizeof(instr)) {
|
||||
printk("is_syscall : failed to read instruction from "
|
||||
"0x%lx\n", addr);
|
||||
return(1);
|
||||
printk(KERN_ERR "is_syscall : failed to read "
|
||||
"instruction from 0x%lx\n", addr);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
/* int 0x80 or sysenter */
|
||||
return((instr == 0x80cd) || (instr == 0x340f));
|
||||
return (instr == 0x80cd) || (instr == 0x340f);
|
||||
}
|
||||
|
||||
/* determines which flags the user has access to. */
|
||||
|
@ -97,12 +91,12 @@ int poke_user(struct task_struct *child, long addr, long data)
|
|||
|
||||
if (addr < MAX_REG_OFFSET)
|
||||
return putreg(child, addr, data);
|
||||
|
||||
else if ((addr >= offsetof(struct user, u_debugreg[0])) &&
|
||||
(addr <= offsetof(struct user, u_debugreg[7]))) {
|
||||
addr -= offsetof(struct user, u_debugreg[0]);
|
||||
addr = addr >> 2;
|
||||
if((addr == 4) || (addr == 5)) return -EIO;
|
||||
if ((addr == 4) || (addr == 5))
|
||||
return -EIO;
|
||||
child->thread.arch.debugregs[addr] = data;
|
||||
return 0;
|
||||
}
|
||||
|
@ -129,9 +123,9 @@ unsigned long getreg(struct task_struct *child, int regno)
|
|||
return retval;
|
||||
}
|
||||
|
||||
/* read the word at location addr in the USER area. */
|
||||
int peek_user(struct task_struct *child, long addr, long data)
|
||||
{
|
||||
/* read the word at location addr in the USER area. */
|
||||
unsigned long tmp;
|
||||
|
||||
if ((addr & 3) || addr < 0)
|
||||
|
@ -247,8 +241,9 @@ int get_fpregs(unsigned long buf, struct task_struct *child)
|
|||
|
||||
err = convert_fxsr_to_user((struct _fpstate __user *) buf,
|
||||
&child->thread.regs);
|
||||
if(err) return(-EFAULT);
|
||||
else return(0);
|
||||
if (err)
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int set_fpregs(unsigned long buf, struct task_struct *child)
|
||||
|
@ -257,8 +252,9 @@ int set_fpregs(unsigned long buf, struct task_struct *child)
|
|||
|
||||
err = convert_fxsr_from_user(&child->thread.regs,
|
||||
(struct _fpstate __user *) buf);
|
||||
if(err) return(-EFAULT);
|
||||
else return(0);
|
||||
if (err)
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
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)
|
|||
fpu->fos = 0;
|
||||
memcpy(fpu->st_space, (void *) SC_FP_ST(PT_REGS_SC(regs)),
|
||||
sizeof(fpu->st_space));
|
||||
return(1);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -292,14 +288,3 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu )
|
|||
{
|
||||
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:
|
||||
*/
|
||||
|
|
|
@ -1,17 +1,13 @@
|
|||
/*
|
||||
* Copyright (C) 2004 Jeff Dike (jdike@addtoit.com)
|
||||
* Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||
* Licensed under the GPL
|
||||
*/
|
||||
|
||||
#include "linux/signal.h"
|
||||
#include "linux/ptrace.h"
|
||||
#include "asm/current.h"
|
||||
#include "asm/ucontext.h"
|
||||
#include "asm/uaccess.h"
|
||||
#include "asm/unistd.h"
|
||||
#include "asm/uaccess.h"
|
||||
#include "asm/ucontext.h"
|
||||
#include "frame_kern.h"
|
||||
#include "sigcontext.h"
|
||||
#include "registers.h"
|
||||
#include "skas.h"
|
||||
|
||||
void copy_sc(struct uml_pt_regs *regs, void *from)
|
||||
|
@ -52,8 +48,8 @@ static int copy_sc_from_user(struct pt_regs *regs,
|
|||
|
||||
err = restore_fp_registers(userspace_pid[0], fpregs);
|
||||
if (err < 0) {
|
||||
printk("copy_sc_from_user_skas - PTRACE_SETFPREGS failed, "
|
||||
"errno = %d\n", -err);
|
||||
printk(KERN_ERR "copy_sc_from_user_skas - PTRACE_SETFPREGS "
|
||||
"failed, errno = %d\n", -err);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -92,8 +88,8 @@ static int copy_sc_to_user(struct sigcontext __user *to,
|
|||
|
||||
err = save_fp_registers(userspace_pid[0], fpregs);
|
||||
if (err < 0) {
|
||||
printk("copy_sc_to_user_skas - PTRACE_GETFPREGS failed, "
|
||||
"errno = %d\n", err);
|
||||
printk(KERN_ERR "copy_sc_to_user_skas - PTRACE_GETFPREGS "
|
||||
"failed, errno = %d\n", err);
|
||||
return 1;
|
||||
}
|
||||
to_fp = (to_fp ? to_fp : (struct _fpstate __user *) (to + 1));
|
||||
|
@ -106,8 +102,9 @@ static int copy_sc_to_user(struct sigcontext __user *to,
|
|||
copy_to_user(to_fp, fpregs, sizeof(fpregs));
|
||||
}
|
||||
|
||||
static int copy_ucontext_to_user(struct ucontext __user *uc, struct _fpstate __user *fp,
|
||||
sigset_t *set, unsigned long sp)
|
||||
static int copy_ucontext_to_user(struct ucontext __user *uc,
|
||||
struct _fpstate __user *fp, sigset_t *set,
|
||||
unsigned long sp)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
|
@ -300,7 +297,8 @@ long sys_sigreturn(struct pt_regs regs)
|
|||
long sys_rt_sigreturn(struct pt_regs regs)
|
||||
{
|
||||
unsigned long sp = PT_REGS_SP(¤t->thread.regs);
|
||||
struct rt_sigframe __user *frame = (struct rt_sigframe __user *) (sp - 4);
|
||||
struct rt_sigframe __user *frame =
|
||||
(struct rt_sigframe __user *) (sp - 4);
|
||||
sigset_t set;
|
||||
struct ucontext __user *uc = &frame->uc;
|
||||
int sig_size = _NSIG_WORDS * sizeof(unsigned long);
|
||||
|
|
|
@ -3,19 +3,12 @@
|
|||
* Licensed under the GPL
|
||||
*/
|
||||
|
||||
#include "linux/kernel.h"
|
||||
#include "linux/percpu.h"
|
||||
#include "linux/sched.h"
|
||||
#include "linux/slab.h"
|
||||
#include "linux/types.h"
|
||||
#include "asm/uaccess.h"
|
||||
#include "asm/ptrace.h"
|
||||
#include "asm/segment.h"
|
||||
#include "asm/smp.h"
|
||||
#include "asm/desc.h"
|
||||
#include "kern.h"
|
||||
#include "kern_util.h"
|
||||
#include "os.h"
|
||||
#include "skas.h"
|
||||
#include "sysdep/tls.h"
|
||||
|
||||
/*
|
||||
* If needed we can detect when it's uninitialized.
|
||||
|
@ -74,7 +67,8 @@ static inline void clear_user_desc(struct user_desc* info)
|
|||
/* Postcondition: LDT_empty(info) returns true. */
|
||||
memset(info, 0, sizeof(*info));
|
||||
|
||||
/* Check the LDT_empty or the i386 sys_get_thread_area code - we obtain
|
||||
/*
|
||||
* Check the LDT_empty or the i386 sys_get_thread_area code - we obtain
|
||||
* indeed an empty user_desc.
|
||||
*/
|
||||
info->read_exec_only = 1;
|
||||
|
@ -89,10 +83,13 @@ static int load_TLS(int flags, struct task_struct *to)
|
|||
int idx;
|
||||
|
||||
for (idx = GDT_ENTRY_TLS_MIN; idx < GDT_ENTRY_TLS_MAX; idx++) {
|
||||
struct uml_tls_struct* curr = &to->thread.arch.tls_array[idx - GDT_ENTRY_TLS_MIN];
|
||||
struct uml_tls_struct* curr =
|
||||
&to->thread.arch.tls_array[idx - GDT_ENTRY_TLS_MIN];
|
||||
|
||||
/* Actually, now if it wasn't flushed it gets cleared and
|
||||
* flushed to the host, which will clear it.*/
|
||||
/*
|
||||
* Actually, now if it wasn't flushed it gets cleared and
|
||||
* flushed to the host, which will clear it.
|
||||
*/
|
||||
if (!curr->present) {
|
||||
if (!curr->flushed) {
|
||||
clear_user_desc(&curr->tls);
|
||||
|
@ -116,7 +113,8 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* Verify if we need to do a flush for the new process, i.e. if there are any
|
||||
/*
|
||||
* Verify if we need to do a flush for the new process, i.e. if there are any
|
||||
* present desc's, only if they haven't been flushed.
|
||||
*/
|
||||
static inline int needs_TLS_update(struct task_struct *task)
|
||||
|
@ -125,10 +123,13 @@ static inline int needs_TLS_update(struct task_struct *task)
|
|||
int ret = 0;
|
||||
|
||||
for (i = GDT_ENTRY_TLS_MIN; i < GDT_ENTRY_TLS_MAX; i++) {
|
||||
struct uml_tls_struct* curr = &task->thread.arch.tls_array[i - GDT_ENTRY_TLS_MIN];
|
||||
struct uml_tls_struct* curr =
|
||||
&task->thread.arch.tls_array[i - GDT_ENTRY_TLS_MIN];
|
||||
|
||||
/* Can't test curr->present, we may need to clear a descriptor
|
||||
* which had a value. */
|
||||
/*
|
||||
* Can't test curr->present, we may need to clear a descriptor
|
||||
* which had a value.
|
||||
*/
|
||||
if (curr->flushed)
|
||||
continue;
|
||||
ret = 1;
|
||||
|
@ -137,7 +138,8 @@ static inline int needs_TLS_update(struct task_struct *task)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* On a newly forked process, the TLS descriptors haven't yet been flushed. So
|
||||
/*
|
||||
* On a newly forked process, the TLS descriptors haven't yet been flushed. So
|
||||
* we mark them as such and the first switch_to will do the job.
|
||||
*/
|
||||
void clear_flushed_tls(struct task_struct *task)
|
||||
|
@ -145,10 +147,13 @@ void clear_flushed_tls(struct task_struct *task)
|
|||
int i;
|
||||
|
||||
for (i = GDT_ENTRY_TLS_MIN; i < GDT_ENTRY_TLS_MAX; i++) {
|
||||
struct uml_tls_struct* curr = &task->thread.arch.tls_array[i - GDT_ENTRY_TLS_MIN];
|
||||
struct uml_tls_struct* curr =
|
||||
&task->thread.arch.tls_array[i - GDT_ENTRY_TLS_MIN];
|
||||
|
||||
/* Still correct to do this, if it wasn't present on the host it
|
||||
* will remain as flushed as it was. */
|
||||
/*
|
||||
* Still correct to do this, if it wasn't present on the host it
|
||||
* will remain as flushed as it was.
|
||||
*/
|
||||
if (!curr->present)
|
||||
continue;
|
||||
|
||||
|
@ -156,23 +161,27 @@ void clear_flushed_tls(struct task_struct *task)
|
|||
}
|
||||
}
|
||||
|
||||
/* In SKAS0 mode, currently, multiple guest threads sharing the same ->mm have a
|
||||
/*
|
||||
* In SKAS0 mode, currently, multiple guest threads sharing the same ->mm have a
|
||||
* common host process. So this is needed in SKAS0 too.
|
||||
*
|
||||
* However, if each thread had a different host process (and this was discussed
|
||||
* for SMP support) this won't be needed.
|
||||
*
|
||||
* And this will not need be used when (and if) we'll add support to the host
|
||||
* SKAS patch. */
|
||||
* SKAS patch.
|
||||
*/
|
||||
|
||||
int arch_switch_tls(struct task_struct *from, struct task_struct *to)
|
||||
{
|
||||
if (!host_supports_tls)
|
||||
return 0;
|
||||
|
||||
/* We have no need whatsoever to switch TLS for kernel threads; beyond
|
||||
/*
|
||||
* We have no need whatsoever to switch TLS for kernel threads; beyond
|
||||
* that, that would also result in us calling os_set_thread_area with
|
||||
* userspace_pid[cpu] == 0, which gives an error. */
|
||||
* userspace_pid[cpu] == 0, which gives an error.
|
||||
*/
|
||||
if (likely(to->mm))
|
||||
return load_TLS(O_FORCE, to);
|
||||
|
||||
|
@ -232,17 +241,20 @@ static int get_tls_entry(struct task_struct* task, struct user_desc *info, int i
|
|||
*info = t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].tls;
|
||||
|
||||
out:
|
||||
/* Temporary debugging check, to make sure that things have been
|
||||
/*
|
||||
* Temporary debugging check, to make sure that things have been
|
||||
* flushed. This could be triggered if load_TLS() failed.
|
||||
*/
|
||||
if (unlikely(task == current && !t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].flushed)) {
|
||||
if (unlikely(task == current &&
|
||||
!t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].flushed)) {
|
||||
printk(KERN_ERR "get_tls_entry: task with pid %d got here "
|
||||
"without flushed TLS.", current->pid);
|
||||
}
|
||||
|
||||
return 0;
|
||||
clear:
|
||||
/* When the TLS entry has not been set, the values read to user in the
|
||||
/*
|
||||
* When the TLS entry has not been set, the values read to user in the
|
||||
* tls_array are 0 (because it's cleared at boot, see
|
||||
* arch/i386/kernel/head.S:cpu_gdt_table). Emulate that.
|
||||
*/
|
||||
|
@ -344,8 +356,10 @@ out:
|
|||
}
|
||||
|
||||
|
||||
/* XXX: This part is probably common to i386 and x86-64. Don't create a common
|
||||
* file for now, do that when implementing x86-64 support.*/
|
||||
/*
|
||||
* XXX: This part is probably common to i386 and x86-64. Don't create a common
|
||||
* file for now, do that when implementing x86-64 support.
|
||||
*/
|
||||
static int __init __setup_host_supports_tls(void)
|
||||
{
|
||||
check_host_supports_tls(&host_supports_tls, &host_gdt_entry_tls_min);
|
||||
|
|
|
@ -14,6 +14,7 @@ struct exception_table_entry
|
|||
};
|
||||
|
||||
const struct exception_table_entry *search_exception_tables(unsigned long add);
|
||||
|
||||
int arch_fixup(unsigned long address, struct uml_pt_regs *regs)
|
||||
{
|
||||
const struct exception_table_entry *fixup;
|
||||
|
@ -21,7 +22,7 @@ int arch_fixup(unsigned long address, struct uml_pt_regs *regs)
|
|||
fixup = search_exception_tables(address);
|
||||
if (fixup != 0) {
|
||||
UPT_IP(regs) = fixup->fixup;
|
||||
return(1);
|
||||
return 1;
|
||||
}
|
||||
return(0);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -3,16 +3,11 @@
|
|||
* Licensed under the GPL
|
||||
*/
|
||||
|
||||
#include "linux/stddef.h"
|
||||
#include "linux/errno.h"
|
||||
#include "linux/personality.h"
|
||||
#include "linux/ptrace.h"
|
||||
#include "asm/current.h"
|
||||
#include "asm/unistd.h"
|
||||
#include "asm/uaccess.h"
|
||||
#include "asm/sigcontext.h"
|
||||
#include "asm/ptrace.h"
|
||||
#include "asm/arch/ucontext.h"
|
||||
#include "sysdep/ptrace.h"
|
||||
#include "asm/ucontext.h"
|
||||
#include "frame_kern.h"
|
||||
#include "skas.h"
|
||||
|
||||
|
@ -262,13 +257,3 @@ long sys_rt_sigreturn(struct pt_regs *regs)
|
|||
force_sig(SIGSEGV, current);
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* 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:
|
||||
*/
|
||||
|
|
|
@ -1,30 +1,28 @@
|
|||
/*
|
||||
* Copyright (C) 2003 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||
* Copyright 2003 PathScale, Inc.
|
||||
*
|
||||
* Licensed under the GPL
|
||||
*/
|
||||
|
||||
#include "linux/linkage.h"
|
||||
#include "linux/slab.h"
|
||||
#include "linux/shm.h"
|
||||
#include "linux/utsname.h"
|
||||
#include "linux/personality.h"
|
||||
#include "asm/uaccess.h"
|
||||
#define __FRAME_OFFSETS
|
||||
#include "asm/ptrace.h"
|
||||
#include "asm/unistd.h"
|
||||
#include "linux/utsname.h"
|
||||
#include "asm/prctl.h" /* XXX This should get the constants from libc */
|
||||
#include "kern.h"
|
||||
#include "asm/uaccess.h"
|
||||
#include "os.h"
|
||||
|
||||
asmlinkage long sys_uname64(struct new_utsname __user * name)
|
||||
{
|
||||
int err;
|
||||
|
||||
down_read(&uts_sem);
|
||||
err = copy_to_user(name, utsname(), sizeof (*name));
|
||||
up_read(&uts_sem);
|
||||
|
||||
if (personality(current->personality) == PER_LINUX32)
|
||||
err |= copy_to_user(&name->machine, "i686", 5);
|
||||
|
||||
return err ? -EFAULT : 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
|
||||
* Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||
* Licensed under the GPL
|
||||
*/
|
||||
|
||||
|
@ -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);
|
||||
|
||||
#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:
|
||||
*/
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
|
@ -17,11 +17,14 @@ struct task_struct;
|
|||
struct mm_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 /
|
||||
* 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). */
|
||||
struct task_struct *saved_task;
|
||||
* from kernelspace (i.e. kernel_thread() or fork_idle(),
|
||||
* as of 2.6.11).
|
||||
*/
|
||||
int forking;
|
||||
int nsyscalls;
|
||||
struct pt_regs regs;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
|
@ -9,9 +9,8 @@
|
|||
#define HOST_AUDIT_ARCH AUDIT_ARCH_I386
|
||||
|
||||
#include "linux/compiler.h"
|
||||
#include "sysdep/ptrace.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_EBX(r) UPT_EBX(&(r)->regs)
|
||||
|
@ -40,6 +39,12 @@
|
|||
|
||||
#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,
|
||||
struct user_desc __user *user_desc);
|
||||
|
||||
|
|
Loading…
Reference in a new issue