summaryrefslogtreecommitdiffstats
path: root/arch/um/kernel
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2006-10-01 17:55:53 +0100
committerDavid Woodhouse <dwmw2@infradead.org>2006-10-01 17:55:53 +0100
commit8a84fc15ae5cafcc366dd85cf8e1ab2040679abc (patch)
tree5d8dce194c9667fa92e9ec9f545cec867a9a1e0d /arch/um/kernel
parent28b79ff9661b22e4c41c0d00d4ab8503e810f13d (diff)
parent82965addad66fce61a92c5f03104ea90b0b87124 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Manually resolve conflict in include/mtd/Kbuild Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Diffstat (limited to 'arch/um/kernel')
-rw-r--r--arch/um/kernel/Makefile2
-rw-r--r--arch/um/kernel/exec.c4
-rw-r--r--arch/um/kernel/exitcode.c8
-rw-r--r--arch/um/kernel/gmon_syms.c13
-rw-r--r--arch/um/kernel/irq.c34
-rw-r--r--arch/um/kernel/ksyms.c3
-rw-r--r--arch/um/kernel/mem.c10
-rw-r--r--arch/um/kernel/process.c (renamed from arch/um/kernel/process_kern.c)36
-rw-r--r--arch/um/kernel/reboot.c13
-rw-r--r--arch/um/kernel/skas/Makefile3
-rw-r--r--arch/um/kernel/skas/exec.c30
-rw-r--r--arch/um/kernel/skas/exec_kern.c41
-rw-r--r--arch/um/kernel/skas/mmu.c8
-rw-r--r--arch/um/kernel/skas/process.c (renamed from arch/um/kernel/skas/process_kern.c)40
-rw-r--r--arch/um/kernel/time.c16
-rw-r--r--arch/um/kernel/tlb.c370
-rw-r--r--arch/um/kernel/trap.c30
-rw-r--r--arch/um/kernel/um_arch.c2
18 files changed, 313 insertions, 350 deletions
diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile
index a2d93065b2d..6fa63a2a89e 100644
--- a/arch/um/kernel/Makefile
+++ b/arch/um/kernel/Makefile
@@ -7,7 +7,7 @@ extra-y := vmlinux.lds
clean-files :=
obj-y = config.o exec.o exitcode.o init_task.o irq.o ksyms.o mem.o \
- physmem.o process_kern.o ptrace.o reboot.o resource.o sigio.o \
+ physmem.o process.o ptrace.o reboot.o resource.o sigio.o \
signal.o smp.o syscall.o sysrq.o time.o tlb.o trap.o uaccess.o \
um_arch.o umid.o
diff --git a/arch/um/kernel/exec.c b/arch/um/kernel/exec.c
index fc38a6d5906..0561c43b468 100644
--- a/arch/um/kernel/exec.c
+++ b/arch/um/kernel/exec.c
@@ -41,9 +41,11 @@ static long execve1(char *file, char __user * __user *argv,
long error;
#ifdef CONFIG_TTY_LOG
- task_lock(current);
+ mutex_lock(&tty_mutex);
+ task_lock(current); /* FIXME: is this needed ? */
log_exec(argv, current->signal->tty);
task_unlock(current);
+ mutex_unlock(&tty_mutex);
#endif
error = do_execve(file, argv, env, &current->thread.regs);
if (error == 0){
diff --git a/arch/um/kernel/exitcode.c b/arch/um/kernel/exitcode.c
index d21ebad666b..8b7f2cdedf9 100644
--- a/arch/um/kernel/exitcode.c
+++ b/arch/um/kernel/exitcode.c
@@ -16,9 +16,13 @@ int uml_exitcode = 0;
static int read_proc_exitcode(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
- int len;
+ int len, val;
- len = sprintf(page, "%d\n", uml_exitcode);
+ /* Save uml_exitcode in a local so that we don't need to guarantee
+ * that sprintf accesses it atomically.
+ */
+ val = uml_exitcode;
+ len = sprintf(page, "%d\n", val);
len -= off;
if(len <= off+count) *eof = 1;
*start = page + off;
diff --git a/arch/um/kernel/gmon_syms.c b/arch/um/kernel/gmon_syms.c
index 2c86e7fdb01..13aa115cd1b 100644
--- a/arch/um/kernel/gmon_syms.c
+++ b/arch/um/kernel/gmon_syms.c
@@ -5,7 +5,7 @@
#include "linux/module.h"
-extern void __bb_init_func(void *);
+extern void __bb_init_func(void *) __attribute__((weak));
EXPORT_SYMBOL(__bb_init_func);
/* This is defined (and referred to in profiling stub code) only by some GCC
@@ -21,14 +21,3 @@ EXPORT_SYMBOL(__gcov_init);
extern void __gcov_merge_add(void *) __attribute__((weak));
EXPORT_SYMBOL(__gcov_merge_add);
-
-/*
- * 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/irq.c b/arch/um/kernel/irq.c
index 589c69a7504..ce7f233fc49 100644
--- a/arch/um/kernel/irq.c
+++ b/arch/um/kernel/irq.c
@@ -142,19 +142,6 @@ int activate_fd(int irq, int fd, int type, void *dev_id)
.events = events,
.current_events = 0 } );
- /* Critical section - locked by a spinlock because this stuff can
- * be changed from interrupt handlers. The stuff above is done
- * outside the lock because it allocates memory.
- */
-
- /* Actually, it only looks like it can be called from interrupt
- * context. The culprit is reactivate_fd, which calls
- * maybe_sigio_broken, which calls write_sigio_workaround,
- * which calls activate_fd. However, write_sigio_workaround should
- * only be called once, at boot time. That would make it clear that
- * this is called only from process context, and can be locked with
- * a semaphore.
- */
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)) {
@@ -165,7 +152,6 @@ int activate_fd(int irq, int fd, int type, void *dev_id)
}
}
- /*-------------*/
if (type == IRQ_WRITE)
fd = -1;
@@ -198,7 +184,6 @@ int activate_fd(int irq, int fd, int type, void *dev_id)
spin_lock_irqsave(&irq_lock, flags);
}
- /*-------------*/
*last_irq_ptr = new_fd;
last_irq_ptr = &new_fd->next;
@@ -210,14 +195,14 @@ int activate_fd(int irq, int fd, int type, void *dev_id)
*/
maybe_sigio_broken(fd, (type == IRQ_READ));
- return(0);
+ return 0;
out_unlock:
spin_unlock_irqrestore(&irq_lock, flags);
out_kfree:
kfree(new_fd);
out:
- return(err);
+ return err;
}
static void free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg)
@@ -302,10 +287,7 @@ void reactivate_fd(int fd, int irqnum)
os_set_pollfd(i, irq->fd);
spin_unlock_irqrestore(&irq_lock, flags);
- /* This calls activate_fd, so it has to be outside the critical
- * section.
- */
- maybe_sigio_broken(fd, (irq->type == IRQ_READ));
+ add_sigio_fd(fd);
}
void deactivate_fd(int fd, int irqnum)
@@ -316,11 +298,15 @@ void deactivate_fd(int fd, int irqnum)
spin_lock_irqsave(&irq_lock, flags);
irq = find_irq_by_fd(fd, irqnum, &i);
- if (irq == NULL)
- goto out;
+ if(irq == NULL){
+ spin_unlock_irqrestore(&irq_lock, flags);
+ return;
+ }
+
os_set_pollfd(i, -1);
- out:
spin_unlock_irqrestore(&irq_lock, flags);
+
+ ignore_sigio_fd(fd);
}
int deactivate_all_fds(void)
diff --git a/arch/um/kernel/ksyms.c b/arch/um/kernel/ksyms.c
index c97045d6d89..f030e44262b 100644
--- a/arch/um/kernel/ksyms.c
+++ b/arch/um/kernel/ksyms.c
@@ -21,7 +21,6 @@
#include "mem_user.h"
#include "os.h"
-EXPORT_SYMBOL(stop);
EXPORT_SYMBOL(uml_physmem);
EXPORT_SYMBOL(set_signals);
EXPORT_SYMBOL(get_signals);
@@ -41,12 +40,14 @@ EXPORT_SYMBOL(handle_page_fault);
EXPORT_SYMBOL(find_iomem);
#ifdef CONFIG_MODE_TT
+EXPORT_SYMBOL(stop);
EXPORT_SYMBOL(strncpy_from_user_tt);
EXPORT_SYMBOL(copy_from_user_tt);
EXPORT_SYMBOL(copy_to_user_tt);
#endif
#ifdef CONFIG_MODE_SKAS
+EXPORT_SYMBOL(strnlen_user_skas);
EXPORT_SYMBOL(strncpy_from_user_skas);
EXPORT_SYMBOL(copy_to_user_skas);
EXPORT_SYMBOL(copy_from_user_skas);
diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c
index 61280167c56..c95855ba6ab 100644
--- a/arch/um/kernel/mem.c
+++ b/arch/um/kernel/mem.c
@@ -79,8 +79,10 @@ void mem_init(void)
/* this will put all low memory onto the freelists */
totalram_pages = free_all_bootmem();
+#ifdef CONFIG_HIGHMEM
totalhigh_pages = highmem >> PAGE_SHIFT;
totalram_pages += totalhigh_pages;
+#endif
num_physpages = totalram_pages;
max_pfn = totalram_pages;
printk(KERN_INFO "Memory: %luk available\n",
@@ -221,10 +223,14 @@ void paging_init(void)
empty_zero_page = (unsigned long *) alloc_bootmem_low_pages(PAGE_SIZE);
empty_bad_page = (unsigned long *) alloc_bootmem_low_pages(PAGE_SIZE);
- for(i=0;i<sizeof(zones_size)/sizeof(zones_size[0]);i++)
+ for(i = 0; i < ARRAY_SIZE(zones_size); i++)
zones_size[i] = 0;
- zones_size[ZONE_DMA] = (end_iomem >> PAGE_SHIFT) - (uml_physmem >> PAGE_SHIFT);
+
+ zones_size[ZONE_NORMAL] = (end_iomem >> PAGE_SHIFT) -
+ (uml_physmem >> PAGE_SHIFT);
+#ifdef CONFIG_HIGHMEM
zones_size[ZONE_HIGHMEM] = highmem >> PAGE_SHIFT;
+#endif
free_area_init(zones_size);
/*
diff --git a/arch/um/kernel/process_kern.c b/arch/um/kernel/process.c
index f6a5a502120..fe6c64abda5 100644
--- a/arch/um/kernel/process_kern.c
+++ b/arch/um/kernel/process.c
@@ -1,10 +1,9 @@
-/*
+/*
* Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
* Copyright 2003 PathScale, Inc.
* Licensed under the GPL
*/
-#include "linux/config.h"
#include "linux/kernel.h"
#include "linux/sched.h"
#include "linux/interrupt.h"
@@ -23,6 +22,7 @@
#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"
@@ -112,11 +112,11 @@ void set_current(void *t)
void *_switch_to(void *prev, void *next, void *last)
{
- struct task_struct *from = prev;
- struct task_struct *to= next;
+ struct task_struct *from = prev;
+ struct task_struct *to= next;
- to->thread.prev_sched = from;
- set_current(to);
+ to->thread.prev_sched = from;
+ set_current(to);
do {
current->thread.saved_task = NULL ;
@@ -127,7 +127,7 @@ void *_switch_to(void *prev, void *next, void *last)
prev= current;
} while(current->thread.saved_task);
- return(current->thread.prev_sched);
+ return(current->thread.prev_sched);
}
@@ -141,19 +141,19 @@ void release_thread(struct task_struct *task)
{
CHOOSE_MODE(release_thread_tt(task), release_thread_skas(task));
}
-
+
void exit_thread(void)
{
unprotect_stack((unsigned long) current_thread);
}
-
+
void *get_current(void)
{
return(current);
}
int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
- unsigned long stack_top, struct task_struct * p,
+ unsigned long stack_top, struct task_struct * p,
struct pt_regs *regs)
{
int ret;
@@ -182,11 +182,11 @@ void initial_thread_cb(void (*proc)(void *), void *arg)
int save_kmalloc_ok = kmalloc_ok;
kmalloc_ok = 0;
- CHOOSE_MODE_PROC(initial_thread_cb_tt, initial_thread_cb_skas, proc,
+ CHOOSE_MODE_PROC(initial_thread_cb_tt, initial_thread_cb_skas, proc,
arg);
kmalloc_ok = save_kmalloc_ok;
}
-
+
unsigned long stack_sp(unsigned long page)
{
return(page + PAGE_SIZE - sizeof(void *));
@@ -210,7 +210,7 @@ void default_idle(void)
*/
if(need_resched())
schedule();
-
+
idle_sleep(10);
}
}
@@ -225,7 +225,7 @@ int page_size(void)
return(PAGE_SIZE);
}
-void *um_virt_to_phys(struct task_struct *task, unsigned long addr,
+void *um_virt_to_phys(struct task_struct *task, unsigned long addr,
pte_t *pte_out)
{
pgd_t *pgd;
@@ -234,7 +234,7 @@ void *um_virt_to_phys(struct task_struct *task, unsigned long addr,
pte_t *pte;
pte_t ptent;
- if(task->mm == NULL)
+ if(task->mm == NULL)
return(ERR_PTR(-EINVAL));
pgd = pgd_offset(task->mm, addr);
if(!pgd_present(*pgd))
@@ -245,7 +245,7 @@ void *um_virt_to_phys(struct task_struct *task, unsigned long addr,
return(ERR_PTR(-EINVAL));
pmd = pmd_offset(pud, addr);
- if(!pmd_present(*pmd))
+ if(!pmd_present(*pmd))
return(ERR_PTR(-EINVAL));
pte = pte_offset_kernel(pmd, addr);
@@ -270,7 +270,7 @@ char *current_cmd(void)
void force_sigbus(void)
{
- printk(KERN_ERR "Killing pid %d because of a lack of memory\n",
+ printk(KERN_ERR "Killing pid %d because of a lack of memory\n",
current->pid);
lock_kernel();
sigaddset(&current->pending.signal, SIGBUS);
@@ -476,7 +476,7 @@ int singlestepping(void * t)
#ifndef arch_align_stack
unsigned long arch_align_stack(unsigned long sp)
{
- if (randomize_va_space)
+ if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
sp -= get_random_int() % 8192;
return sp & ~0xf;
}
diff --git a/arch/um/kernel/reboot.c b/arch/um/kernel/reboot.c
index 3ef73bf2e78..f602623644a 100644
--- a/arch/um/kernel/reboot.c
+++ b/arch/um/kernel/reboot.c
@@ -22,7 +22,7 @@ static void kill_idlers(int me)
struct task_struct *p;
int i;
- for(i = 0; i < sizeof(idle_threads)/sizeof(idle_threads[0]); i++){
+ for(i = 0; i < ARRAY_SIZE(idle_threads); i++){
p = idle_threads[i];
if((p != NULL) && (p->thread.mode.tt.extern_pid != me))
os_kill_process(p->thread.mode.tt.extern_pid, 0);
@@ -62,14 +62,3 @@ void machine_halt(void)
{
machine_power_off();
}
-
-/*
- * 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/Makefile b/arch/um/kernel/skas/Makefile
index ea3a8e409a6..3e3fa7e7e3c 100644
--- a/arch/um/kernel/skas/Makefile
+++ b/arch/um/kernel/skas/Makefile
@@ -3,8 +3,7 @@
# Licensed under the GPL
#
-obj-y := clone.o exec_kern.o mem.o mmu.o process_kern.o \
- syscall.o tlb.o uaccess.o
+obj-y := clone.o exec.o mem.o mmu.o process.o syscall.o tlb.o uaccess.o
# clone.o is in the stub, so it can't be built with profiling
# GCC hardened also auto-enables -fpic, but we need %ebx so it can't work ->
diff --git a/arch/um/kernel/skas/exec.c b/arch/um/kernel/skas/exec.c
new file mode 100644
index 00000000000..54b79595137
--- /dev/null
+++ b/arch/um/kernel/skas/exec.c
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#include "linux/kernel.h"
+#include "asm/current.h"
+#include "asm/page.h"
+#include "asm/signal.h"
+#include "asm/ptrace.h"
+#include "asm/uaccess.h"
+#include "asm/mmu_context.h"
+#include "tlb.h"
+#include "skas.h"
+#include "um_mmu.h"
+#include "os.h"
+
+void flush_thread_skas(void)
+{
+ force_flush_all();
+ switch_mm_skas(&current->mm->context.skas.id);
+}
+
+void start_thread_skas(struct pt_regs *regs, unsigned long eip,
+ unsigned long esp)
+{
+ set_fs(USER_DS);
+ PT_REGS_IP(regs) = eip;
+ PT_REGS_SP(regs) = esp;
+}
diff --git a/arch/um/kernel/skas/exec_kern.c b/arch/um/kernel/skas/exec_kern.c
deleted file mode 100644
index 77ed7bbab21..00000000000
--- a/arch/um/kernel/skas/exec_kern.c
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#include "linux/kernel.h"
-#include "asm/current.h"
-#include "asm/page.h"
-#include "asm/signal.h"
-#include "asm/ptrace.h"
-#include "asm/uaccess.h"
-#include "asm/mmu_context.h"
-#include "tlb.h"
-#include "skas.h"
-#include "um_mmu.h"
-#include "os.h"
-
-void flush_thread_skas(void)
-{
- force_flush_all();
- switch_mm_skas(&current->mm->context.skas.id);
-}
-
-void start_thread_skas(struct pt_regs *regs, unsigned long eip,
- unsigned long esp)
-{
- set_fs(USER_DS);
- PT_REGS_IP(regs) = eip;
- PT_REGS_SP(regs) = esp;
-}
-
-/*
- * 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/mmu.c b/arch/um/kernel/skas/mmu.c
index 624ca238d1f..4cd2ff546ef 100644
--- a/arch/um/kernel/skas/mmu.c
+++ b/arch/um/kernel/skas/mmu.c
@@ -55,14 +55,16 @@ static int init_stub_pte(struct mm_struct *mm, unsigned long proc,
* destroy_context_skas.
*/
- mm->context.skas.last_page_table = pmd_page_kernel(*pmd);
+ mm->context.skas.last_page_table = pmd_page_vaddr(*pmd);
#ifdef CONFIG_3_LEVEL_PGTABLES
mm->context.skas.last_pmd = (unsigned long) __va(pud_val(*pud));
#endif
*pte = mk_pte(virt_to_page(kernel), __pgprot(_PAGE_PRESENT));
- *pte = pte_mkexec(*pte);
- *pte = pte_wrprotect(*pte);
+ /* This is wrong for the code page, but it doesn't matter since the
+ * stub is mapped by hand with the correct permissions.
+ */
+ *pte = pte_mkwrite(*pte);
return(0);
out_pmd:
diff --git a/arch/um/kernel/skas/process_kern.c b/arch/um/kernel/skas/process.c
index 55caeec8b25..ae4fa71d3b8 100644
--- a/arch/um/kernel/skas/process_kern.c
+++ b/arch/um/kernel/skas/process.c
@@ -33,7 +33,7 @@ void switch_to_skas(void *prev, void *next)
switch_timers(0);
switch_threads(&from->thread.mode.skas.switch_buf,
- to->thread.mode.skas.switch_buf);
+ &to->thread.mode.skas.switch_buf);
arch_switch_to_skas(current->thread.prev_sched, current);
@@ -43,21 +43,21 @@ void switch_to_skas(void *prev, void *next)
extern void schedule_tail(struct task_struct *prev);
-void new_thread_handler(int sig)
+/* This is called magically, by its address being stuffed in a jmp_buf
+ * and being longjmp-d to.
+ */
+void new_thread_handler(void)
{
int (*fn)(void *), n;
void *arg;
- fn = current->thread.request.u.thread.proc;
- arg = current->thread.request.u.thread.arg;
- os_usr1_signal(1);
- thread_wait(&current->thread.mode.skas.switch_buf,
- current->thread.mode.skas.fork_buf);
-
if(current->thread.prev_sched != NULL)
schedule_tail(current->thread.prev_sched);
current->thread.prev_sched = NULL;
+ 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,
* 0 if it just exits
*/
@@ -70,22 +70,13 @@ void new_thread_handler(int sig)
else do_exit(0);
}
-void new_thread_proc(void *stack, void (*handler)(int sig))
-{
- init_new_thread_stack(stack, handler);
- os_usr1_process(os_getpid());
-}
-
void release_thread_skas(struct task_struct *task)
{
}
-void fork_handler(int sig)
+/* Called magically, see new_thread_handler above */
+void fork_handler(void)
{
- os_usr1_signal(1);
- thread_wait(&current->thread.mode.skas.switch_buf,
- current->thread.mode.skas.fork_buf);
-
force_flush_all();
if(current->thread.prev_sched == NULL)
panic("blech");
@@ -109,7 +100,7 @@ int copy_thread_skas(int nr, unsigned long clone_flags, unsigned long sp,
unsigned long stack_top, struct task_struct * p,
struct pt_regs *regs)
{
- void (*handler)(int);
+ void (*handler)(void);
if(current->thread.forking){
memcpy(&p->thread.regs.regs.skas, &regs->regs.skas,
@@ -123,12 +114,12 @@ int copy_thread_skas(int nr, unsigned long clone_flags, unsigned long sp,
}
else {
init_thread_registers(&p->thread.regs.regs);
- p->thread.request.u.thread = current->thread.request.u.thread;
+ p->thread.request.u.thread = current->thread.request.u.thread;
handler = new_thread_handler;
}
new_thread(task_stack_page(p), &p->thread.mode.skas.switch_buf,
- &p->thread.mode.skas.fork_buf, handler);
+ handler);
return(0);
}
@@ -164,7 +155,7 @@ static int start_kernel_proc(void *unused)
cpu_tasks[0].pid = pid;
cpu_tasks[0].task = current;
#ifdef CONFIG_SMP
- cpu_online_map = cpumask_of_cpu(0);
+ cpu_online_map = cpumask_of_cpu(0);
#endif
start_kernel();
return(0);
@@ -182,8 +173,7 @@ int start_uml_skas(void)
init_task.thread.request.u.thread.proc = start_kernel_proc;
init_task.thread.request.u.thread.arg = NULL;
return(start_idle_thread(task_stack_page(&init_task),
- &init_task.thread.mode.skas.switch_buf,
- &init_task.thread.mode.skas.fork_buf));
+ &init_task.thread.mode.skas.switch_buf));
}
int external_pid_skas(struct task_struct *task)
diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c
index 552ca1cb984..a92965f8f9c 100644
--- a/arch/um/kernel/time.c
+++ b/arch/um/kernel/time.c
@@ -35,9 +35,6 @@ unsigned long long sched_clock(void)
return (unsigned long long)jiffies_64 * (1000000000 / HZ);
}
-/* Changed at early boot */
-int timer_irq_inited = 0;
-
static unsigned long long prev_nsecs;
#ifdef CONFIG_UML_REAL_TIME_CLOCK
static long long delta; /* Deviation per interval */
@@ -96,9 +93,9 @@ irqreturn_t um_timer(int irq, void *dev, struct pt_regs *regs)
write_seqlock_irqsave(&xtime_lock, flags);
- do_timer(regs);
+ do_timer(1);
- nsecs = get_time() + local_offset;
+ nsecs = get_time();
xtime.tv_sec = nsecs / NSEC_PER_SEC;
xtime.tv_nsec = nsecs - xtime.tv_sec * NSEC_PER_SEC;
@@ -113,12 +110,13 @@ static void register_timer(void)
err = request_irq(TIMER_IRQ, um_timer, IRQF_DISABLED, "timer", NULL);
if(err != 0)
- printk(KERN_ERR "timer_init : request_irq failed - "
+ printk(KERN_ERR "register_timer : request_irq failed - "
"errno = %d\n", -err);
- timer_irq_inited = 1;
-
- user_time_init();
+ err = set_interval(1);
+ if(err != 0)
+ printk(KERN_ERR "register_timer : set_interval failed - "
+ "errno = %d\n", -err);
}
extern void (*late_time_init)(void);
diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c
index f5b0636f9ad..54a5ff25645 100644
--- a/arch/um/kernel/tlb.c
+++ b/arch/um/kernel/tlb.c
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
* Licensed under the GPL
*/
@@ -16,12 +16,12 @@
#include "os.h"
static int add_mmap(unsigned long virt, unsigned long phys, unsigned long len,
- int r, int w, int x, struct host_vm_op *ops, int *index,
+ int r, int w, int x, struct host_vm_op *ops, int *index,
int last_filled, union mm_context *mmu, void **flush,
int (*do_ops)(union mm_context *, struct host_vm_op *,
int, int, void **))
{
- __u64 offset;
+ __u64 offset;
struct host_vm_op *last;
int fd, ret = 0;
@@ -89,7 +89,7 @@ static int add_munmap(unsigned long addr, unsigned long len,
static int add_mprotect(unsigned long addr, unsigned long len, int r, int w,
int x, struct host_vm_op *ops, int *index,
int last_filled, union mm_context *mmu, void **flush,
- int (*do_ops)(union mm_context *, struct host_vm_op *,
+ int (*do_ops)(union mm_context *, struct host_vm_op *,
int, int, void **))
{
struct host_vm_op *last;
@@ -124,105 +124,105 @@ static int add_mprotect(unsigned long addr, unsigned long len, int r, int w,
#define ADD_ROUND(n, inc) (((n) + (inc)) & ~((inc) - 1))
void fix_range_common(struct mm_struct *mm, unsigned long start_addr,
- unsigned long end_addr, int force,
+ unsigned long end_addr, int force,
int (*do_ops)(union mm_context *, struct host_vm_op *,
int, int, void **))
{
- pgd_t *npgd;
- pud_t *npud;
- pmd_t *npmd;
- pte_t *npte;
- union mm_context *mmu = &mm->context;
- unsigned long addr, end;
- int r, w, x;
- struct host_vm_op ops[1];
- void *flush = NULL;
- int op_index = -1, last_op = sizeof(ops) / sizeof(ops[0]) - 1;
- int ret = 0;
-
- if(mm == NULL) return;
-
- ops[0].type = NONE;
- for(addr = start_addr; addr < end_addr && !ret;){
- npgd = pgd_offset(mm, addr);
- if(!pgd_present(*npgd)){
- end = ADD_ROUND(addr, PGDIR_SIZE);
- if(end > end_addr)
- end = end_addr;
- if(force || pgd_newpage(*npgd)){
- ret = add_munmap(addr, end - addr, ops,
- &op_index, last_op, mmu,
- &flush, do_ops);
- pgd_mkuptodate(*npgd);
- }
- addr = end;
- continue;
- }
-
- npud = pud_offset(npgd, addr);
- if(!pud_present(*npud)){
- end = ADD_ROUND(addr, PUD_SIZE);
- if(end > end_addr)
- end = end_addr;
- if(force || pud_newpage(*npud)){
- ret = add_munmap(addr, end - addr, ops,
- &op_index, last_op, mmu,
- &flush, do_ops);
- pud_mkuptodate(*npud);
- }
- addr = end;
- continue;
- }
-
- npmd = pmd_offset(npud, addr);
- if(!pmd_present(*npmd)){
- end = ADD_ROUND(addr, PMD_SIZE);
- if(end > end_addr)
- end = end_addr;
- if(force || pmd_newpage(*npmd)){
- ret = add_munmap(addr, end - addr, ops,
- &op_index, last_op, mmu,
- &flush, do_ops);
- pmd_mkuptodate(*npmd);
- }
- addr = end;
- continue;
- }
-
- npte = pte_offset_kernel(npmd, addr);
- r = pte_read(*npte);
- w = pte_write(*npte);
- x = pte_exec(*npte);
+ pgd_t *npgd;
+ pud_t *npud;
+ pmd_t *npmd;
+ pte_t *npte;
+ union mm_context *mmu = &mm->context;
+ unsigned long addr, end;
+ int r, w, x;
+ struct host_vm_op ops[1];
+ void *flush = NULL;
+ int op_index = -1, last_op = ARRAY_SIZE(ops) - 1;
+ int ret = 0;
+
+ if(mm == NULL)
+ return;
+
+ ops[0].type = NONE;
+ for(addr = start_addr; addr < end_addr && !ret;){
+ npgd = pgd_offset(mm, addr);
+ if(!pgd_present(*npgd)){
+ end = ADD_ROUND(addr, PGDIR_SIZE);
+ if(end > end_addr)
+ end = end_addr;
+ if(force || pgd_newpage(*npgd)){
+ ret = add_munmap(addr, end - addr, ops,
+ &op_index, last_op, mmu,
+ &flush, do_ops);
+ pgd_mkuptodate(*npgd);
+ }
+ addr = end;
+ continue;
+ }
+
+ npud = pud_offset(npgd, addr);
+ if(!pud_present(*npud)){
+ end = ADD_ROUND(addr, PUD_SIZE);
+ if(end > end_addr)
+ end = end_addr;
+ if(force || pud_newpage(*npud)){
+ ret = add_munmap(addr, end - addr, ops,
+ &op_index, last_op, mmu,
+ &flush, do_ops);
+ pud_mkuptodate(*npud);
+ }
+ addr = end;
+ continue;
+ }
+
+ npmd = pmd_offset(npud, addr);
+ if(!pmd_present(*npmd)){
+ end = ADD_ROUND(addr, PMD_SIZE);
+ if(end > end_addr)
+ end = end_addr;
+ if(force || pmd_newpage(*npmd)){
+ ret = add_munmap(addr, end - addr, ops,
+ &op_index, last_op, mmu,
+ &flush, do_ops);
+ pmd_mkuptodate(*npmd);
+ }
+ addr = end;
+ continue;
+ }
+
+ npte = pte_offset_kernel(npmd, addr);
+ r = pte_read(*npte);
+ w = pte_write(*npte);
+ x = pte_exec(*npte);
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,
- pte_val(*npte) & PAGE_MASK,
- PAGE_SIZE, r, w, x, ops,
- &op_index, last_op, mmu,
- &flush, do_ops);
+ if(force || pte_newpage(*npte)){
+ if(pte_present(*npte))
+ ret = add_mmap(addr,
+ pte_val(*npte) & PAGE_MASK,
+ PAGE_SIZE, r, w, x, ops,
+ &op_index, last_op, mmu,
+ &flush, do_ops);
else ret = add_munmap(addr, PAGE_SIZE, ops,
&op_index, last_op, mmu,
&flush, do_ops);
- }
- else if(pte_newprot(*npte))
+ }
+ else if(pte_newprot(*npte))
ret = add_mprotect(addr, PAGE_SIZE, r, w, x, ops,
&op_index, last_op, mmu,
&flush, do_ops);
- *npte = pte_mkuptodate(*npte);
- addr += PAGE_SIZE;
- }
-
+ *npte = pte_mkuptodate(*npte);
+ addr += PAGE_SIZE;
+ }
if(!ret)
ret = (*do_ops)(mmu, ops, op_index, 1, &flush);
- /* This is not an else because ret is modified above */
+/* This is not an else because ret is modified above */
if(ret) {
printk("fix_range_common: failed, killing current process\n");
force_sig(SIGKILL, current);
@@ -231,160 +231,160 @@ void fix_range_common(struct mm_struct *mm, unsigned long start_addr,
int flush_tlb_kernel_range_common(unsigned long start, unsigned long end)
{
- struct mm_struct *mm;
- pgd_t *pgd;
- pud_t *pud;
- pmd_t *pmd;
- pte_t *pte;
- unsigned long addr, last;
- int updated = 0, err;
-
- mm = &init_mm;
- for(addr = start; addr < end;){
- pgd = pgd_offset(mm, addr);
- if(!pgd_present(*pgd)){
- last = ADD_ROUND(addr, PGDIR_SIZE);
- if(last > end)
- last = end;
- if(pgd_newpage(*pgd)){
- updated = 1;
- err = os_unmap_memory((void *) addr,
- last - addr);
- if(err < 0)
- panic("munmap failed, errno = %d\n",
- -err);
- }
- addr = last;
- continue;
- }
-
- pud = pud_offset(pgd, addr);
- if(!pud_present(*pud)){
- last = ADD_ROUND(addr, PUD_SIZE);
- if(last > end)
- last = end;
- if(pud_newpage(*pud)){
- updated = 1;
- err = os_unmap_memory((void *) addr,
- last - addr);
- if(err < 0)
- panic("munmap failed, errno = %d\n",
- -err);
- }
- addr = last;
- continue;
- }
-
- pmd = pmd_offset(pud, addr);
- if(!pmd_present(*pmd)){
- last = ADD_ROUND(addr, PMD_SIZE);
- if(last > end)
- last = end;
- if(pmd_newpage(*pmd)){
- updated = 1;
- err = os_unmap_memory((void *) addr,
- last - addr);
- if(err < 0)
- panic("munmap failed, errno = %d\n",
- -err);
- }
- addr = last;
- continue;
- }
-
- pte = pte_offset_kernel(pmd, addr);
- if(!pte_present(*pte) || pte_newpage(*pte)){
- updated = 1;
- err = os_unmap_memory((void *) addr,
- PAGE_SIZE);
- if(err < 0)
- panic("munmap failed, errno = %d\n",
- -err);
- if(pte_present(*pte))
- map_memory(addr,
- pte_val(*pte) & PAGE_MASK,
- PAGE_SIZE, 1, 1, 1);
- }
- else if(pte_newprot(*pte)){
- updated = 1;
- os_protect_memory((void *) addr, PAGE_SIZE, 1, 1, 1);
- }
- addr += PAGE_SIZE;
- }
- return(updated);
+ struct mm_struct *mm;
+ pgd_t *pgd;
+ pud_t *pud;
+ pmd_t *pmd;
+ pte_t *pte;
+ unsigned long addr, last;
+ int updated = 0, err;
+
+ mm = &init_mm;
+ for(addr = start; addr < end;){
+ pgd = pgd_offset(mm, addr);
+ if(!pgd_present(*pgd)){
+ last = ADD_ROUND(addr, PGDIR_SIZE);
+ if(last > end)
+ last = end;
+ if(pgd_newpage(*pgd)){
+ updated = 1;
+ err = os_unmap_memory((void *) addr,
+ last - addr);
+ if(err < 0)
+ panic("munmap failed, errno = %d\n",
+ -err);
+ }
+ addr = last;
+ continue;
+ }
+
+ pud = pud_offset(pgd, addr);
+ if(!pud_present(*pud)){
+ last = ADD_ROUND(addr, PUD_SIZE);
+ if(last > end)
+ last = end;
+ if(pud_newpage(*pud)){
+ updated = 1;
+ err = os_unmap_memory((void *) addr,
+ last - addr);
+ if(err < 0)
+ panic("munmap failed, errno = %d\n",
+ -err);
+ }
+ addr = last;
+ continue;
+ }
+
+ pmd = pmd_offset(pud, addr);
+ if(!pmd_present(*pmd)){
+ last = ADD_ROUND(addr, PMD_SIZE);
+ if(last > end)
+ last = end;
+ if(pmd_newpage(*pmd)){
+ updated = 1;
+ err = os_unmap_memory((void *) addr,
+ last - addr);
+ if(err < 0)
+ panic("munmap failed, errno = %d\n",
+ -err);
+ }
+ addr = last;
+ continue;
+ }
+
+ pte = pte_offset_kernel(pmd, addr);
+ if(!pte_present(*pte) || pte_newpage(*pte)){
+ updated = 1;
+ err = os_unmap_memory((void *) addr,
+ PAGE_SIZE);
+ if(err < 0)
+ panic("munmap failed, errno = %d\n",
+ -err);
+ if(pte_present(*pte))
+ map_memory(addr,
+ pte_val(*pte) & PAGE_MASK,
+ PAGE_SIZE, 1, 1, 1);
+ }
+ else if(pte_newprot(*pte)){
+ updated = 1;
+ os_protect_memory((void *) addr, PAGE_SIZE, 1, 1, 1);
+ }
+ addr += PAGE_SIZE;
+ }
+ return(updated);
}
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)
{
- pgd_t *pgd = pgd_offset(task->mm, addr);
- pud_t *pud = pud_offset(pgd, addr);
- pmd_t *pmd = pmd_offset(pud, addr);
+ pgd_t *pgd = pgd_offset(task->mm, 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_page(struct vm_area_struct *vma, unsigned long address)
{
- address &= PAGE_MASK;
- flush_tlb_range(vma, address, address + PAGE_SIZE);
+ address &= PAGE_MASK;
+ flush_tlb_range(vma, address, address + PAGE_SIZE);
}
void flush_tlb_all(void)
{
- flush_tlb_mm(current->mm);
+ flush_tlb_mm(current->mm);
}
void flush_tlb_kernel_range(unsigned long start, unsigned long end)
{
- CHOOSE_MODE_PROC(flush_tlb_kernel_range_tt,
- flush_tlb_kernel_range_common, start, end);
+ CHOOSE_MODE_PROC(flush_tlb_kernel_range_tt,
+ flush_tlb_kernel_range_common, start, end);
}
void flush_tlb_kernel_vm(void)
{
- CHOOSE_MODE(flush_tlb_kernel_vm_tt(),
- flush_tlb_kernel_range_common(start_vm, end_vm));
+ CHOOSE_MODE(flush_tlb_kernel_vm_tt(),
+ flush_tlb_kernel_range_common(start_vm, end_vm));
}
void __flush_tlb_one(unsigned long addr)
{
- CHOOSE_MODE_PROC(__flush_tlb_one_tt, __flush_tlb_one_skas, addr);
+ CHOOSE_MODE_PROC(__flush_tlb_one_tt, __flush_tlb_one_skas, addr);
}
void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
unsigned long end)
{
- CHOOSE_MODE_PROC(flush_tlb_range_tt, flush_tlb_range_skas, vma, start,
- end);
+ CHOOSE_MODE_PROC(flush_tlb_range_tt, flush_tlb_range_skas, vma, start,
+ end);
}
void flush_tlb_mm(struct mm_struct *mm)
{
- CHOOSE_MODE_PROC(flush_tlb_mm_tt, flush_tlb_mm_skas, mm);
+ CHOOSE_MODE_PROC(flush_tlb_mm_tt, flush_tlb_mm_skas, mm);
}
void force_flush_all(void)
{
- CHOOSE_MODE(force_flush_all_tt(), force_flush_all_skas());
+ CHOOSE_MODE(force_flush_all_tt(), force_flush_all_skas());
}
diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c
index ac70fa5a2e2..c7b195c7e51 100644
--- a/arch/um/kernel/trap.c
+++ b/arch/um/kernel/trap.c
@@ -120,7 +120,7 @@ out_nosemaphore:
* us unable to handle the page fault gracefully.
*/
out_of_memory:
- if (current->pid == 1) {
+ if (is_init(current)) {
up_read(&mm->mmap_sem);
yield();
down_read(&mm->mmap_sem);
@@ -140,14 +140,6 @@ void segv_handler(int sig, union uml_pt_regs *regs)
segv(*fi, UPT_IP(regs), UPT_IS_USER(regs), regs);
}
-struct kern_handlers handlinfo_kern = {
- .relay_signal = relay_signal,
- .winch = winch,
- .bus_handler = relay_signal,
- .page_fault = segv_handler,
- .sigio_handler = sigio_handler,
- .timer_handler = timer_handler
-};
/*
* We give a *copy* of the faultinfo in the regs to segv.
* This must be done, since nesting SEGVs could overwrite
@@ -227,9 +219,16 @@ void bad_segv(struct faultinfo fi, unsigned long ip)
void relay_signal(int sig, union uml_pt_regs *regs)
{
- if(arch_handle_signal(sig, regs)) return;
- if(!UPT_IS_USER(regs))
+ if(arch_handle_signal(sig, regs))
+ return;
+
+ if(!UPT_IS_USER(regs)){
+ if(sig == SIGBUS)
+ printk("Bus error - the /dev/shm or /tmp mount likely "
+ "just ran out of space\n");
panic("Kernel mode signal %d", sig);
+ }
+
current->thread.arch.faultinfo = *UPT_FAULTINFO(regs);
force_sig(sig, current);
}
@@ -246,6 +245,15 @@ void winch(int sig, union uml_pt_regs *regs)
do_IRQ(WINCH_IRQ, regs);
}
+const struct kern_handlers handlinfo_kern = {
+ .relay_signal = relay_signal,
+ .winch = winch,
+ .bus_handler = bus_handler,
+ .page_fault = segv_handler,
+ .sigio_handler = sigio_handler,
+ .timer_handler = timer_handler
+};
+
void trap_init(void)
{
}
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
index 7896cf98232..55005710dcb 100644
--- a/arch/um/kernel/um_arch.c
+++ b/arch/um/kernel/um_arch.c
@@ -106,7 +106,7 @@ static void c_stop(struct seq_file *m, void *v)
{
}
-struct seq_operations cpuinfo_op = {
+const struct seq_operations cpuinfo_op = {
.start = c_start,
.next = c_next,
.stop = c_stop,