aboutsummaryrefslogtreecommitdiff
path: root/arch/um/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um/kernel')
-rw-r--r--arch/um/kernel/Makefile16
-rw-r--r--arch/um/kernel/helper.c12
-rw-r--r--arch/um/kernel/init_task.c5
-rw-r--r--arch/um/kernel/irq.c1
-rw-r--r--arch/um/kernel/mem.c16
-rw-r--r--arch/um/kernel/mem_user.c273
-rw-r--r--arch/um/kernel/process_kern.c22
-rw-r--r--arch/um/kernel/sigio_user.c2
-rw-r--r--arch/um/kernel/skas/Makefile2
-rw-r--r--arch/um/kernel/skas/include/mode_kern-skas.h2
-rw-r--r--arch/um/kernel/skas/include/uaccess-skas.h6
-rw-r--r--arch/um/kernel/skas/process_kern.c7
-rw-r--r--arch/um/kernel/skas/util/Makefile5
-rw-r--r--arch/um/kernel/skas/util/mk_ptregs-i386.c49
-rw-r--r--arch/um/kernel/skas/util/mk_ptregs-x86_64.c66
-rw-r--r--arch/um/kernel/sysrq.c8
-rw-r--r--arch/um/kernel/tempfile.c82
-rw-r--r--arch/um/kernel/tlb.c14
-rw-r--r--arch/um/kernel/trap_kern.c21
-rw-r--r--arch/um/kernel/tt/include/mode_kern-tt.h2
-rw-r--r--arch/um/kernel/tt/include/uaccess-tt.h6
-rw-r--r--arch/um/kernel/tt/mem_user.c1
-rw-r--r--arch/um/kernel/tt/process_kern.c8
-rw-r--r--arch/um/kernel/tt/uaccess_user.c11
-rw-r--r--arch/um/kernel/um_arch.c7
-rw-r--r--arch/um/kernel/umid.c41
-rw-r--r--arch/um/kernel/user_util.c18
27 files changed, 131 insertions, 572 deletions
diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile
index 614b8ebeb0e..1a0001b3850 100644
--- a/arch/um/kernel/Makefile
+++ b/arch/um/kernel/Makefile
@@ -1,4 +1,4 @@
-#
+#
# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
# Licensed under the GPL
#
@@ -7,11 +7,11 @@ extra-y := vmlinux.lds
clean-files :=
obj-y = config.o exec_kern.o exitcode.o \
- helper.o init_task.o irq.o irq_user.o ksyms.o main.o mem.o mem_user.o \
- physmem.o process_kern.o ptrace.o reboot.o resource.o sigio_user.o \
- sigio_kern.o signal_kern.o signal_user.o smp.o syscall_kern.o sysrq.o \
- tempfile.o time.o time_kern.o tlb.o trap_kern.o trap_user.o \
- uaccess_user.o um_arch.o umid.o user_util.o
+ helper.o init_task.o irq.o irq_user.o ksyms.o main.o mem.o physmem.o \
+ process_kern.o ptrace.o reboot.o resource.o sigio_user.o sigio_kern.o \
+ signal_kern.o signal_user.o smp.o syscall_kern.o sysrq.o time.o \
+ time_kern.o tlb.o trap_kern.o trap_user.o uaccess_user.o um_arch.o \
+ umid.o user_util.o
obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o
obj-$(CONFIG_GPROF) += gprof_syms.o
@@ -24,8 +24,8 @@ obj-$(CONFIG_MODE_SKAS) += skas/
user-objs-$(CONFIG_TTY_LOG) += tty_log.o
-USER_OBJS := $(user-objs-y) config.o helper.o main.o tempfile.o time.o \
- tty_log.o umid.o user_util.o
+USER_OBJS := $(user-objs-y) config.o helper.o main.o time.o tty_log.o umid.o \
+ user_util.o
include arch/um/scripts/Makefile.rules
diff --git a/arch/um/kernel/helper.c b/arch/um/kernel/helper.c
index f83e1e8e239..33fb0bd3b11 100644
--- a/arch/um/kernel/helper.c
+++ b/arch/um/kernel/helper.c
@@ -85,8 +85,8 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
data.fd = fds[1];
pid = clone(helper_child, (void *) sp, CLONE_VM | SIGCHLD, &data);
if(pid < 0){
- printk("run_helper : clone failed, errno = %d\n", errno);
ret = -errno;
+ printk("run_helper : clone failed, errno = %d\n", errno);
goto out_close;
}
@@ -122,7 +122,7 @@ int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags,
unsigned long *stack_out, int stack_order)
{
unsigned long stack, sp;
- int pid, status;
+ int pid, status, err;
stack = alloc_stack(stack_order, um_in_interrupt());
if(stack == 0) return(-ENOMEM);
@@ -130,16 +130,18 @@ int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags,
sp = stack + (page_size() << stack_order) - sizeof(void *);
pid = clone(proc, (void *) sp, flags | SIGCHLD, arg);
if(pid < 0){
+ err = -errno;
printk("run_helper_thread : clone failed, errno = %d\n",
errno);
- return(-errno);
+ return err;
}
if(stack_out == NULL){
CATCH_EINTR(pid = waitpid(pid, &status, 0));
if(pid < 0){
+ err = -errno;
printk("run_helper_thread - wait failed, errno = %d\n",
errno);
- pid = -errno;
+ pid = err;
}
if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0))
printk("run_helper_thread - thread returned status "
@@ -156,8 +158,8 @@ int helper_wait(int pid)
CATCH_EINTR(ret = waitpid(pid, NULL, WNOHANG));
if(ret < 0){
+ ret = -errno;
printk("helper_wait : waitpid failed, errno = %d\n", errno);
- return(-errno);
}
return(ret);
}
diff --git a/arch/um/kernel/init_task.c b/arch/um/kernel/init_task.c
index cd7c85be0a1..49ed5ddf070 100644
--- a/arch/um/kernel/init_task.c
+++ b/arch/um/kernel/init_task.c
@@ -13,6 +13,7 @@
#include "asm/pgtable.h"
#include "user_util.h"
#include "mem_user.h"
+#include "os.h"
static struct fs_struct init_fs = INIT_FS;
struct mm_struct init_mm = INIT_MM(init_mm);
@@ -45,8 +46,8 @@ __attribute__((__section__(".data.init_task"))) =
void unprotect_stack(unsigned long stack)
{
- protect_memory(stack, (1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE,
- 1, 1, 0, 1);
+ os_protect_memory((void *) stack, (1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE,
+ 1, 1, 0);
}
/*
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
index dcd81497199..bbf94bf2921 100644
--- a/arch/um/kernel/irq.c
+++ b/arch/um/kernel/irq.c
@@ -9,7 +9,6 @@
#include "linux/kernel.h"
#include "linux/module.h"
#include "linux/smp.h"
-#include "linux/irq.h"
#include "linux/kernel_stat.h"
#include "linux/interrupt.h"
#include "linux/random.h"
diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c
index 64fa062cc11..ea008b031a8 100644
--- a/arch/um/kernel/mem.c
+++ b/arch/um/kernel/mem.c
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
* Licensed under the GPL
*/
@@ -19,6 +19,10 @@
#include "mem_user.h"
#include "uml_uaccess.h"
#include "os.h"
+#include "linux/types.h"
+#include "linux/string.h"
+#include "init.h"
+#include "kern_constants.h"
extern char __binary_start;
@@ -368,6 +372,16 @@ struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
return pte;
}
+struct iomem_region *iomem_regions = NULL;
+int iomem_size = 0;
+
+extern int parse_iomem(char *str, int *add) __init;
+
+__uml_setup("iomem=", parse_iomem,
+"iomem=<name>,<file>\n"
+" Configure <file> as an IO memory region named <name>.\n\n"
+);
+
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
diff --git a/arch/um/kernel/mem_user.c b/arch/um/kernel/mem_user.c
deleted file mode 100644
index 4a663fd434b..00000000000
--- a/arch/um/kernel/mem_user.c
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * arch/um/kernel/mem_user.c
- *
- * BRIEF MODULE DESCRIPTION
- * user side memory routines for supporting IO memory inside user mode linux
- *
- * Copyright (C) 2001 RidgeRun, Inc.
- * Author: RidgeRun, Inc.
- * Greg Lonnon glonnon@ridgerun.com or info@ridgerun.com
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
- * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/mman.h>
-#include "kern_util.h"
-#include "user.h"
-#include "user_util.h"
-#include "mem_user.h"
-#include "init.h"
-#include "os.h"
-#include "tempfile.h"
-#include "kern_constants.h"
-
-#define TEMPNAME_TEMPLATE "vm_file-XXXXXX"
-
-static int create_tmp_file(unsigned long len)
-{
- int fd, err;
- char zero;
-
- fd = make_tempfile(TEMPNAME_TEMPLATE, NULL, 1);
- if(fd < 0) {
- os_print_error(fd, "make_tempfile");
- exit(1);
- }
-
- err = os_mode_fd(fd, 0777);
- if(err < 0){
- os_print_error(err, "os_mode_fd");
- exit(1);
- }
- err = os_seek_file(fd, len);
- if(err < 0){
- os_print_error(err, "os_seek_file");
- exit(1);
- }
- zero = 0;
- err = os_write_file(fd, &zero, 1);
- if(err != 1){
- os_print_error(err, "os_write_file");
- exit(1);
- }
-
- return(fd);
-}
-
-void check_tmpexec(void)
-{
- void *addr;
- int err, fd = create_tmp_file(UM_KERN_PAGE_SIZE);
-
- addr = mmap(NULL, UM_KERN_PAGE_SIZE,
- PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, fd, 0);
- printf("Checking PROT_EXEC mmap in /tmp...");
- fflush(stdout);
- if(addr == MAP_FAILED){
- err = errno;
- perror("failed");
- if(err == EPERM)
- printf("/tmp must be not mounted noexec\n");
- exit(1);
- }
- printf("OK\n");
- munmap(addr, UM_KERN_PAGE_SIZE);
-
- os_close_file(fd);
-}
-
-static int have_devanon = 0;
-
-void check_devanon(void)
-{
- int fd;
-
- printk("Checking for /dev/anon on the host...");
- fd = open("/dev/anon", O_RDWR);
- if(fd < 0){
- printk("Not available (open failed with errno %d)\n", errno);
- return;
- }
-
- printk("OK\n");
- have_devanon = 1;
-}
-
-static int create_anon_file(unsigned long len)
-{
- void *addr;
- int fd;
-
- fd = open("/dev/anon", O_RDWR);
- if(fd < 0) {
- os_print_error(fd, "opening /dev/anon");
- exit(1);
- }
-
- addr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
- if(addr == MAP_FAILED){
- perror("mapping physmem file");
- exit(1);
- }
- munmap(addr, len);
-
- return(fd);
-}
-
-int create_mem_file(unsigned long len)
-{
- int err, fd;
-
- if(have_devanon)
- fd = create_anon_file(len);
- else fd = create_tmp_file(len);
-
- err = os_set_exec_close(fd, 1);
- if(err < 0)
- os_print_error(err, "exec_close");
- return(fd);
-}
-
-struct iomem_region *iomem_regions = NULL;
-int iomem_size = 0;
-
-static int __init parse_iomem(char *str, int *add)
-{
- struct iomem_region *new;
- struct uml_stat buf;
- char *file, *driver;
- int fd, err, size;
-
- driver = str;
- file = strchr(str,',');
- if(file == NULL){
- printf("parse_iomem : failed to parse iomem\n");
- goto out;
- }
- *file = '\0';
- file++;
- fd = os_open_file(file, of_rdwr(OPENFLAGS()), 0);
- if(fd < 0){
- os_print_error(fd, "parse_iomem - Couldn't open io file");
- goto out;
- }
-
- err = os_stat_fd(fd, &buf);
- if(err < 0){
- os_print_error(err, "parse_iomem - cannot stat_fd file");
- goto out_close;
- }
-
- new = malloc(sizeof(*new));
- if(new == NULL){
- perror("Couldn't allocate iomem_region struct");
- goto out_close;
- }
-
- size = (buf.ust_size + UM_KERN_PAGE_SIZE) & ~(UM_KERN_PAGE_SIZE - 1);
-
- *new = ((struct iomem_region) { .next = iomem_regions,
- .driver = driver,
- .fd = fd,
- .size = size,
- .phys = 0,
- .virt = 0 });
- iomem_regions = new;
- iomem_size += new->size + UM_KERN_PAGE_SIZE;
-
- return(0);
- out_close:
- os_close_file(fd);
- out:
- return(1);
-}
-
-__uml_setup("iomem=", parse_iomem,
-"iomem=<name>,<file>\n"
-" Configure <file> as an IO memory region named <name>.\n\n"
-);
-
-int protect_memory(unsigned long addr, unsigned long len, int r, int w, int x,
- int must_succeed)
-{
- int err;
-
- err = os_protect_memory((void *) addr, len, r, w, x);
- if(err < 0){
- if(must_succeed)
- panic("protect failed, err = %d", -err);
- else return(err);
- }
- return(0);
-}
-
-#if 0
-/* Debugging facility for dumping stuff out to the host, avoiding the timing
- * problems that come with printf and breakpoints.
- * Enable in case of emergency.
- */
-
-int logging = 1;
-int logging_fd = -1;
-
-int logging_line = 0;
-char logging_buf[512];
-
-void log(char *fmt, ...)
-{
- va_list ap;
- struct timeval tv;
- struct openflags flags;
-
- if(logging == 0) return;
- if(logging_fd < 0){
- flags = of_create(of_trunc(of_rdwr(OPENFLAGS())));
- logging_fd = os_open_file("log", flags, 0644);
- }
- gettimeofday(&tv, NULL);
- sprintf(logging_buf, "%d\t %u.%u ", logging_line++, tv.tv_sec,
- tv.tv_usec);
- va_start(ap, fmt);
- vsprintf(&logging_buf[strlen(logging_buf)], fmt, ap);
- va_end(ap);
- write(logging_fd, logging_buf, strlen(logging_buf));
-}
-#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:
- */
diff --git a/arch/um/kernel/process_kern.c b/arch/um/kernel/process_kern.c
index c23d8a08d0f..ea65db679e9 100644
--- a/arch/um/kernel/process_kern.c
+++ b/arch/um/kernel/process_kern.c
@@ -82,7 +82,8 @@ unsigned long alloc_stack(int order, int atomic)
unsigned long page;
int flags = GFP_KERNEL;
- if(atomic) flags |= GFP_ATOMIC;
+ if (atomic)
+ flags = GFP_ATOMIC;
page = __get_free_pages(flags, order);
if(page == 0)
return(0);
@@ -113,8 +114,23 @@ void set_current(void *t)
void *_switch_to(void *prev, void *next, void *last)
{
- return(CHOOSE_MODE(switch_to_tt(prev, next),
- switch_to_skas(prev, next)));
+ struct task_struct *from = prev;
+ struct task_struct *to= next;
+
+ to->thread.prev_sched = from;
+ set_current(to);
+
+ do {
+ current->thread.saved_task = NULL ;
+ CHOOSE_MODE_PROC(switch_to_tt, switch_to_skas, prev, next);
+ if(current->thread.saved_task)
+ show_regs(&(current->thread.regs));
+ next= current->thread.saved_task;
+ prev= current;
+ } while(current->thread.saved_task);
+
+ return(current->thread.prev_sched);
+
}
void interrupt_end(void)
diff --git a/arch/um/kernel/sigio_user.c b/arch/um/kernel/sigio_user.c
index e89218958f3..a52751108aa 100644
--- a/arch/um/kernel/sigio_user.c
+++ b/arch/um/kernel/sigio_user.c
@@ -340,7 +340,7 @@ static int setup_initial_poll(int fd)
{
struct pollfd *p;
- p = um_kmalloc(sizeof(struct pollfd));
+ p = um_kmalloc_atomic(sizeof(struct pollfd));
if(p == NULL){
printk("setup_initial_poll : failed to allocate poll\n");
return(-1);
diff --git a/arch/um/kernel/skas/Makefile b/arch/um/kernel/skas/Makefile
index db36c7c9594..8de471b59c1 100644
--- a/arch/um/kernel/skas/Makefile
+++ b/arch/um/kernel/skas/Makefile
@@ -6,8 +6,6 @@
obj-y := clone.o exec_kern.o mem.o mem_user.o mmu.o process.o process_kern.o \
syscall.o tlb.o trap_user.o uaccess.o
-subdir- := util
-
USER_OBJS := process.o clone.o
include arch/um/scripts/Makefile.rules
diff --git a/arch/um/kernel/skas/include/mode_kern-skas.h b/arch/um/kernel/skas/include/mode_kern-skas.h
index e4849002811..c97a80dfe37 100644
--- a/arch/um/kernel/skas/include/mode_kern-skas.h
+++ b/arch/um/kernel/skas/include/mode_kern-skas.h
@@ -11,7 +11,7 @@
#include "asm/ptrace.h"
extern void flush_thread_skas(void);
-extern void *switch_to_skas(void *prev, void *next);
+extern void switch_to_skas(void *prev, void *next);
extern void start_thread_skas(struct pt_regs *regs, unsigned long eip,
unsigned long esp);
extern int copy_thread_skas(int nr, unsigned long clone_flags,
diff --git a/arch/um/kernel/skas/include/uaccess-skas.h b/arch/um/kernel/skas/include/uaccess-skas.h
index 6ee3f3902e6..7da0c2def0e 100644
--- a/arch/um/kernel/skas/include/uaccess-skas.h
+++ b/arch/um/kernel/skas/include/uaccess-skas.h
@@ -18,12 +18,6 @@
((unsigned long) (addr) + (size) <= FIXADDR_USER_END) && \
((unsigned long) (addr) + (size) >= (unsigned long)(addr))))
-static inline int verify_area_skas(int type, const void __user * addr,
- unsigned long size)
-{
- return(access_ok_skas(type, addr, size) ? 0 : -EFAULT);
-}
-
extern int copy_from_user_skas(void *to, const void __user *from, int n);
extern int copy_to_user_skas(void __user *to, const void *from, int n);
extern int strncpy_from_user_skas(char *dst, const char __user *src, int count);
diff --git a/arch/um/kernel/skas/process_kern.c b/arch/um/kernel/skas/process_kern.c
index 3d1b227226e..efe92e8aa2a 100644
--- a/arch/um/kernel/skas/process_kern.c
+++ b/arch/um/kernel/skas/process_kern.c
@@ -24,7 +24,7 @@
#include "proc_mm.h"
#include "registers.h"
-void *switch_to_skas(void *prev, void *next)
+void switch_to_skas(void *prev, void *next)
{
struct task_struct *from, *to;
@@ -35,16 +35,11 @@ void *switch_to_skas(void *prev, void *next)
if(current->pid == 0)
switch_timers(0);
- to->thread.prev_sched = from;
- set_current(to);
-
switch_threads(&from->thread.mode.skas.switch_buf,
to->thread.mode.skas.switch_buf);
if(current->pid == 0)
switch_timers(1);
-
- return(current->thread.prev_sched);
}
extern void schedule_tail(struct task_struct *prev);
diff --git a/arch/um/kernel/skas/util/Makefile b/arch/um/kernel/skas/util/Makefile
deleted file mode 100644
index f7b7eba8334..00000000000
--- a/arch/um/kernel/skas/util/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-hostprogs-y := mk_ptregs
-always := $(hostprogs-y)
-
-mk_ptregs-objs := mk_ptregs-$(SUBARCH).o
-HOSTCFLAGS_mk_ptregs-$(SUBARCH).o := -I$(objtree)/arch/um
diff --git a/arch/um/kernel/skas/util/mk_ptregs-i386.c b/arch/um/kernel/skas/util/mk_ptregs-i386.c
deleted file mode 100644
index 1f96e1eeb8a..00000000000
--- a/arch/um/kernel/skas/util/mk_ptregs-i386.c
+++ /dev/null
@@ -1,49 +0,0 @@
-#include <stdio.h>
-#include <user-offsets.h>
-
-#define SHOW(name) printf("#define %s %d\n", #name, name)
-
-int main(int argc, char **argv)
-{
- printf("/* Automatically generated by "
- "arch/um/kernel/skas/util/mk_ptregs */\n");
- printf("\n");
- printf("#ifndef __SKAS_PT_REGS_\n");
- printf("#define __SKAS_PT_REGS_\n");
- printf("\n");
- SHOW(HOST_FRAME_SIZE);
- SHOW(HOST_FP_SIZE);
- SHOW(HOST_XFP_SIZE);
-
- SHOW(HOST_IP);
- SHOW(HOST_SP);
- SHOW(HOST_EFLAGS);
- SHOW(HOST_EAX);
- SHOW(HOST_EBX);
- SHOW(HOST_ECX);
- SHOW(HOST_EDX);
- SHOW(HOST_ESI);
- SHOW(HOST_EDI);
- SHOW(HOST_EBP);
- SHOW(HOST_CS);
- SHOW(HOST_SS);
- SHOW(HOST_DS);
- SHOW(HOST_FS);
- SHOW(HOST_ES);
- SHOW(HOST_GS);
-
- printf("\n");
- printf("#endif\n");
- 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:
- */
diff --git a/arch/um/kernel/skas/util/mk_ptregs-x86_64.c b/arch/um/kernel/skas/util/mk_ptregs-x86_64.c
deleted file mode 100644
index 5fccbfe35f7..00000000000
--- a/arch/um/kernel/skas/util/mk_ptregs-x86_64.c
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright 2003 PathScale, Inc.
- *
- * Licensed under the GPL
- */
-
-#include <stdio.h>
-#include <user-offsets.h>
-
-#define SHOW(name) \
- printf("#define %s (%d / sizeof(unsigned long))\n", #name, name)
-
-int main(int argc, char **argv)
-{
- printf("/* Automatically generated by "
- "arch/um/kernel/skas/util/mk_ptregs */\n");
- printf("\n");
- printf("#ifndef __SKAS_PT_REGS_\n");
- printf("#define __SKAS_PT_REGS_\n");
- SHOW(HOST_FRAME_SIZE);
- SHOW(HOST_RBX);
- SHOW(HOST_RCX);
- SHOW(HOST_RDI);
- SHOW(HOST_RSI);
- SHOW(HOST_RDX);
- SHOW(HOST_RBP);
- SHOW(HOST_RAX);
- SHOW(HOST_R8);
- SHOW(HOST_R9);
- SHOW(HOST_R10);
- SHOW(HOST_R11);
- SHOW(HOST_R12);
- SHOW(HOST_R13);
- SHOW(HOST_R14);
- SHOW(HOST_R15);
- SHOW(HOST_ORIG_RAX);
- SHOW(HOST_CS);
- SHOW(HOST_SS);
- SHOW(HOST_EFLAGS);
-#if 0
- SHOW(HOST_FS);
- SHOW(HOST_GS);
- SHOW(HOST_DS);
- SHOW(HOST_ES);
-#endif
-
- SHOW(HOST_IP);
- SHOW(HOST_SP);
- printf("#define HOST_FP_SIZE 0\n");
- printf("#define HOST_XFP_SIZE 0\n");
- printf("\n");
- printf("\n");
- printf("#endif\n");
- 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:
- */
diff --git a/arch/um/kernel/sysrq.c b/arch/um/kernel/sysrq.c
index f80850091e7..b331e970002 100644
--- a/arch/um/kernel/sysrq.c
+++ b/arch/um/kernel/sysrq.c
@@ -62,13 +62,7 @@ void show_stack(struct task_struct *task, unsigned long *esp)
if (esp == NULL) {
if (task != current && task != NULL) {
- /* XXX: Isn't this bogus? I.e. isn't this the
- * *userspace* stack of this task? If not so, use this
- * even when task == current (as in i386).
- */
esp = (unsigned long *) KSTK_ESP(task);
- /* Which one? No actual difference - just coding style.*/
- //esp = (unsigned long *) PT_REGS_IP(&task->thread.regs);
} else {
esp = (unsigned long *) &esp;
}
@@ -84,5 +78,5 @@ void show_stack(struct task_struct *task, unsigned long *esp)
}
printk("Call Trace: \n");
- show_trace(current, esp);
+ show_trace(task, esp);
}
diff --git a/arch/um/kernel/tempfile.c b/arch/um/kernel/tempfile.c
deleted file mode 100644
index b1674bc1395..00000000000
--- a/arch/um/kernel/tempfile.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/param.h>
-#include "init.h"
-
-/* Modified from create_mem_file and start_debugger */
-static char *tempdir = NULL;
-
-static void __init find_tempdir(void)
-{
- char *dirs[] = { "TMP", "TEMP", "TMPDIR", NULL };
- int i;
- char *dir = NULL;
-
- if(tempdir != NULL) return; /* We've already been called */
- for(i = 0; dirs[i]; i++){
- dir = getenv(dirs[i]);
- if((dir != NULL) && (*dir != '\0'))
- break;
- }
- if((dir == NULL) || (*dir == '\0'))
- dir = "/tmp";
-
- tempdir = malloc(strlen(dir) + 2);
- if(tempdir == NULL){
- fprintf(stderr, "Failed to malloc tempdir, "
- "errno = %d\n", errno);
- return;
- }
- strcpy(tempdir, dir);
- strcat(tempdir, "/");
-}
-
-int make_tempfile(const char *template, char **out_tempname, int do_unlink)
-{
- char tempname[MAXPATHLEN];
- int fd;
-
- find_tempdir();
- if (*template != '/')
- strcpy(tempname, tempdir);
- else
- *tempname = 0;
- strcat(tempname, template);
- fd = mkstemp(tempname);
- if(fd < 0){
- fprintf(stderr, "open - cannot create %s: %s\n", tempname,
- strerror(errno));
- return -1;
- }
- if(do_unlink && (unlink(tempname) < 0)){
- perror("unlink");
- return -1;
- }
- if(out_tempname){
- *out_tempname = strdup(tempname);
- if(*out_tempname == NULL){
- perror("strdup");
- return -1;
- }
- }
- return(fd);
-}
-
-/*
- * 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:
- */
diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c
index 80ed6188e8a..f5b0636f9ad 100644
--- a/arch/um/kernel/tlb.c
+++ b/arch/um/kernel/tlb.c
@@ -193,12 +193,12 @@ void fix_range_common(struct mm_struct *mm, unsigned long start_addr,
r = pte_read(*npte);
w = pte_write(*npte);
x = pte_exec(*npte);
- if(!pte_dirty(*npte))
- w = 0;
- if(!pte_young(*npte)){
- r = 0;
- w = 0;
- }
+ if (!pte_young(*npte)) {
+ r = 0;
+ w = 0;
+ } else if (!pte_dirty(*npte)) {
+ w = 0;
+ }
if(force || pte_newpage(*npte)){
if(pte_present(*npte))
ret = add_mmap(addr,
@@ -307,7 +307,7 @@ int flush_tlb_kernel_range_common(unsigned long start, unsigned long end)
}
else if(pte_newprot(*pte)){
updated = 1;
- protect_memory(addr, PAGE_SIZE, 1, 1, 1, 1);
+ os_protect_memory((void *) addr, PAGE_SIZE, 1, 1, 1);
}
addr += PAGE_SIZE;
}
diff --git a/arch/um/kernel/trap_kern.c b/arch/um/kernel/trap_kern.c
index 87cc6fd76ce..95c8f8733ba 100644
--- a/arch/um/kernel/trap_kern.c
+++ b/arch/um/kernel/trap_kern.c
@@ -18,6 +18,7 @@
#include "asm/a.out.h"
#include "asm/current.h"
#include "asm/irq.h"
+#include "sysdep/sigcontext.h"
#include "user_util.h"
#include "kern_util.h"
#include "kern.h"
@@ -25,6 +26,9 @@
#include "mconsole_kern.h"
#include "mem.h"
#include "mem_kern.h"
+#ifdef CONFIG_MODE_SKAS
+#include "skas.h"
+#endif
/* Note this is constrained to return 0, -EFAULT, -EACCESS, -ENOMEM by segv(). */
int handle_page_fault(unsigned long address, unsigned long ip,
@@ -39,6 +43,12 @@ int handle_page_fault(unsigned long address, unsigned long ip,
int err = -EFAULT;
*code_out = SEGV_MAPERR;
+
+ /* If the fault was during atomic operation, don't take the fault, just
+ * fail. */
+ if (in_atomic())
+ goto out_nosemaphore;
+
down_read(&mm->mmap_sem);
vma = find_vma(mm, address);
if(!vma)
@@ -89,6 +99,7 @@ survive:
flush_tlb_page(vma, address);
out:
up_read(&mm->mmap_sem);
+out_nosemaphore:
return(err);
/*
@@ -125,7 +136,15 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, void *sc)
}
else if(current->mm == NULL)
panic("Segfault with no mm");
- err = handle_page_fault(address, ip, is_write, is_user, &si.si_code);
+
+ if (SEGV_IS_FIXABLE(&fi) || SEGV_MAYBE_FIXABLE(&fi))
+ err = handle_page_fault(address, ip, is_write, is_user, &si.si_code);
+ else {
+ err = -EFAULT;
+ /* A thread accessed NULL, we get a fault, but CR2 is invalid.
+ * This code is used in __do_copy_from_user() of TT mode. */
+ address = 0;
+ }
catcher = current->thread.fault_catcher;
if(!err)
diff --git a/arch/um/kernel/tt/include/mode_kern-tt.h b/arch/um/kernel/tt/include/mode_kern-tt.h
index e0ca0e0b251..2a35b15c5fe 100644
--- a/arch/um/kernel/tt/include/mode_kern-tt.h
+++ b/arch/um/kernel/tt/include/mode_kern-tt.h
@@ -11,7 +11,7 @@
#include "asm/ptrace.h"
#include "asm/uaccess.h"
-extern void *switch_to_tt(void *prev, void *next);
+extern void switch_to_tt(void *prev, void *next);
extern void flush_thread_tt(void);
extern void start_thread_tt(struct pt_regs *regs, unsigned long eip,
unsigned long esp);
diff --git a/arch/um/kernel/tt/include/uaccess-tt.h b/arch/um/kernel/tt/include/uaccess-tt.h
index aa6db384af8..dc2ebfa8c54 100644
--- a/arch/um/kernel/tt/include/uaccess-tt.h
+++ b/arch/um/kernel/tt/include/uaccess-tt.h
@@ -33,12 +33,6 @@ extern unsigned long uml_physmem;
(((unsigned long) (addr) <= ((unsigned long) (addr) + (size))) && \
(under_task_size(addr, size) || is_stack(addr, size))))
-static inline int verify_area_tt(int type, const void __user * addr,
- unsigned long size)
-{
- return(access_ok_tt(type, addr, size) ? 0 : -EFAULT);
-}
-
extern unsigned long get_fault_addr(void);
extern int __do_copy_from_user(void *to, const void *from, int n,
diff --git a/arch/um/kernel/tt/mem_user.c b/arch/um/kernel/tt/mem_user.c
index 3085267459b..03e58989538 100644
--- a/arch/um/kernel/tt/mem_user.c
+++ b/arch/um/kernel/tt/mem_user.c
@@ -12,6 +12,7 @@
#include "tt.h"
#include "mem_user.h"
#include "user_util.h"
+#include "os.h"
void remap_data(void *segment_start, void *segment_end, int w)
{
diff --git a/arch/um/kernel/tt/process_kern.c b/arch/um/kernel/tt/process_kern.c
index a189a2b9293..cfaa373a6e7 100644
--- a/arch/um/kernel/tt/process_kern.c
+++ b/arch/um/kernel/tt/process_kern.c
@@ -23,10 +23,11 @@
#include "mem_user.h"
#include "tlb.h"
#include "mode.h"
+#include "mode_kern.h"
#include "init.h"
#include "tt.h"
-void *switch_to_tt(void *prev, void *next, void *last)
+void switch_to_tt(void *prev, void *next)
{
struct task_struct *from, *to, *prev_sched;
unsigned long flags;
@@ -36,8 +37,6 @@ void *switch_to_tt(void *prev, void *next, void *last)
from = prev;
to = next;
- to->thread.prev_sched = from;
-
cpu = from->thread_info->cpu;
if(cpu == 0)
forward_interrupts(to->thread.mode.tt.extern_pid);
@@ -53,7 +52,6 @@ void *switch_to_tt(void *prev, void *next, void *last)
forward_pending_sigio(to->thread.mode.tt.extern_pid);
c = 0;
- set_current(to);
err = os_write_file(to->thread.mode.tt.switch_pipe[1], &c, sizeof(c));
if(err != sizeof(c))
@@ -85,8 +83,6 @@ void *switch_to_tt(void *prev, void *next, void *last)
flush_tlb_all();
local_irq_restore(flags);
-
- return(current->thread.prev_sched);
}
void release_thread_tt(struct task_struct *task)
diff --git a/arch/um/kernel/tt/uaccess_user.c b/arch/um/kernel/tt/uaccess_user.c
index f01475512ec..8c220f054b6 100644
--- a/arch/um/kernel/tt/uaccess_user.c
+++ b/arch/um/kernel/tt/uaccess_user.c
@@ -22,8 +22,15 @@ int __do_copy_from_user(void *to, const void *from, int n,
__do_copy, &faulted);
TASK_REGS(get_current())->tt = save;
- if(!faulted) return(0);
- else return(n - (fault - (unsigned long) from));
+ if(!faulted)
+ return 0;
+ else if (fault)
+ return n - (fault - (unsigned long) from);
+ else
+ /* In case of a general protection fault, we don't have the
+ * fault address, so NULL is used instead. Pretend we didn't
+ * copy anything. */
+ return n;
}
static void __do_strncpy(void *dst, const void *src, int count)
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
index 09f6f7ce469..93dc782dc1c 100644
--- a/arch/um/kernel/um_arch.c
+++ b/arch/um/kernel/um_arch.c
@@ -334,6 +334,8 @@ int linux_main(int argc, char **argv)
add_arg(DEFAULT_COMMAND_LINE);
os_early_checks();
+ if (force_tt)
+ clear_can_do_skas();
mode_tt = force_tt ? 1 : !can_do_skas();
#ifndef CONFIG_MODE_TT
if (mode_tt) {
@@ -361,11 +363,6 @@ int linux_main(int argc, char **argv)
uml_start = CHOOSE_MODE_PROC(set_task_sizes_tt, set_task_sizes_skas, 0,
&host_task_size, &task_size);
- /* Need to check this early because mmapping happens before the
- * kernel is running.
- */
- check_tmpexec();
-
brk_start = (unsigned long) sbrk(0);
CHOOSE_MODE_PROC(before_mem_tt, before_mem_skas, brk_start);
/* Increase physical memory size for exec-shield users
diff --git a/arch/um/kernel/umid.c b/arch/um/kernel/umid.c
index 186c2888501..0b21d59ba0c 100644
--- a/arch/um/kernel/umid.c
+++ b/arch/um/kernel/umid.c
@@ -31,6 +31,8 @@ static char *uml_dir = UML_DIR;
/* Changed by set_umid */
static int umid_is_random = 1;
static int umid_inited = 0;
+/* Have we created the files? Should we remove them? */
+static int umid_owned = 0;
static int make_umid(int (*printer)(const char *fmt, ...));
@@ -82,20 +84,21 @@ int __init umid_file_name(char *name, char *buf, int len)
extern int tracing_pid;
-static int __init create_pid_file(void)
+static void __init create_pid_file(void)
{
char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")];
char pid[sizeof("nnnnn\0")];
int fd, n;
- if(umid_file_name("pid", file, sizeof(file))) return 0;
+ if(umid_file_name("pid", file, sizeof(file)))
+ return;
fd = os_open_file(file, of_create(of_excl(of_rdwr(OPENFLAGS()))),
0644);
if(fd < 0){
printf("Open of machine pid file \"%s\" failed: %s\n",
file, strerror(-fd));
- return 0;
+ return;
}
sprintf(pid, "%d\n", os_getpid());
@@ -103,7 +106,6 @@ static int __init create_pid_file(void)
if(n != strlen(pid))
printf("Write of pid file failed - err = %d\n", -n);
os_close_file(fd);
- return 0;
}
static int actually_do_remove(char *dir)
@@ -147,7 +149,8 @@ static int actually_do_remove(char *dir)
void remove_umid_dir(void)
{
char dir[strlen(uml_dir) + UMID_LEN + 1];
- if(!umid_inited) return;
+ if (!umid_owned)
+ return;
sprintf(dir, "%s%s", uml_dir, umid);
actually_do_remove(dir);
@@ -155,11 +158,12 @@ void remove_umid_dir(void)
char *get_umid(int only_if_set)
{
- if(only_if_set && umid_is_random) return(NULL);
- return(umid);
+ if(only_if_set && umid_is_random)
+ return NULL;
+ return umid;
}
-int not_dead_yet(char *dir)
+static int not_dead_yet(char *dir)
{
char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")];
char pid[sizeof("nnnnn\0")], *end;
@@ -193,7 +197,8 @@ int not_dead_yet(char *dir)
(p == CHOOSE_MODE(tracing_pid, os_getpid())))
dead = 1;
}
- if(!dead) return(1);
+ if(!dead)
+ return(1);
return(actually_do_remove(dir));
}
@@ -232,16 +237,13 @@ static int __init make_uml_dir(void)
strlcpy(dir, home, sizeof(dir));
uml_dir++;
}
+ strlcat(dir, uml_dir, sizeof(dir));
len = strlen(dir);
- strncat(dir, uml_dir, sizeof(dir) - len);
- len = strlen(dir);
- if((len > 0) && (len < sizeof(dir) - 1) && (dir[len - 1] != '/')){
- dir[len] = '/';
- dir[len + 1] = '\0';
- }
+ if (len > 0 && dir[len - 1] != '/')
+ strlcat(dir, "/", sizeof(dir));
uml_dir = malloc(strlen(dir) + 1);
- if(uml_dir == NULL){
+ if (uml_dir == NULL) {
printf("make_uml_dir : malloc failed, errno = %d\n", errno);
exit(1);
}
@@ -286,6 +288,7 @@ static int __init make_umid(int (*printer)(const char *fmt, ...))
if(errno == EEXIST){
if(not_dead_yet(tmp)){
(*printer)("umid '%s' is in use\n", umid);
+ umid_owned = 0;
return(-1);
}
err = mkdir(tmp, 0777);
@@ -296,7 +299,8 @@ static int __init make_umid(int (*printer)(const char *fmt, ...))
return(-1);
}
- return(0);
+ umid_owned = 1;
+ return 0;
}
__uml_setup("uml_dir=", set_uml_dir,
@@ -309,7 +313,8 @@ static int __init make_umid_setup(void)
/* one function with the ordering we need ... */
make_uml_dir();
make_umid(printf);
- return create_pid_file();
+ create_pid_file();
+ return 0;
}
__uml_postsetup(make_umid_setup);
diff --git a/arch/um/kernel/user_util.c b/arch/um/kernel/user_util.c
index 954ff67cc8b..41d17c71511 100644
--- a/arch/um/kernel/user_util.c
+++ b/arch/um/kernel/user_util.c
@@ -109,18 +109,14 @@ int raw(int fd)
int err;
CATCH_EINTR(err = tcgetattr(fd, &tt));
- if (err < 0) {
- printk("tcgetattr failed, errno = %d\n", errno);
- return(-errno);
- }
+ if(err < 0)
+ return -errno;
cfmakeraw(&tt);
CATCH_EINTR(err = tcsetattr(fd, TCSADRAIN, &tt));
- if (err < 0) {
- printk("tcsetattr failed, errno = %d\n", errno);
- return(-errno);
- }
+ if(err < 0)
+ return -errno;
/* XXX tcsetattr could have applied only some changes
* (and cfmakeraw() is a set of changes) */
@@ -132,6 +128,12 @@ void setup_machinename(char *machine_out)
struct utsname host;
uname(&host);
+#if defined(UML_CONFIG_UML_X86) && !defined(UML_CONFIG_64BIT)
+ if (!strcmp(host.machine, "x86_64")) {
+ strcpy(machine_out, "i686");
+ return;
+ }
+#endif
strcpy(machine_out, host.machine);
}