diff options
Diffstat (limited to 'arch/um/kernel')
-rw-r--r-- | arch/um/kernel/irq.c | 8 | ||||
-rw-r--r-- | arch/um/kernel/physmem.c | 2 | ||||
-rw-r--r-- | arch/um/kernel/sigio_kern.c | 2 | ||||
-rw-r--r-- | arch/um/kernel/skas/mmu.c | 2 | ||||
-rw-r--r-- | arch/um/kernel/skas/uaccess.c | 15 | ||||
-rw-r--r-- | arch/um/kernel/time.c | 172 | ||||
-rw-r--r-- | arch/um/kernel/time_kern.c | 36 | ||||
-rw-r--r-- | arch/um/kernel/vmlinux.lds.S | 3 |
8 files changed, 28 insertions, 212 deletions
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c index 2ffda012385..bfd0bdc8cd4 100644 --- a/arch/um/kernel/irq.c +++ b/arch/um/kernel/irq.c @@ -63,7 +63,7 @@ int show_interrupts(struct seq_file *p, void *v) for_each_online_cpu(j) seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); #endif - seq_printf(p, " %14s", irq_desc[i].handler->typename); + seq_printf(p, " %14s", irq_desc[i].chip->typename); seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) @@ -451,13 +451,13 @@ void __init init_IRQ(void) irq_desc[TIMER_IRQ].status = IRQ_DISABLED; irq_desc[TIMER_IRQ].action = NULL; irq_desc[TIMER_IRQ].depth = 1; - irq_desc[TIMER_IRQ].handler = &SIGVTALRM_irq_type; + irq_desc[TIMER_IRQ].chip = &SIGVTALRM_irq_type; enable_irq(TIMER_IRQ); for (i = 1; i < NR_IRQS; i++) { irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = NULL; irq_desc[i].depth = 1; - irq_desc[i].handler = &normal_irq_type; + irq_desc[i].chip = &normal_irq_type; enable_irq(i); } } @@ -474,7 +474,7 @@ int init_aio_irq(int irq, char *name, irqreturn_t (*handler)(int, void *, } err = um_request_irq(irq, fds[0], IRQ_READ, handler, - SA_INTERRUPT | SA_SAMPLE_RANDOM, name, + IRQF_DISABLED | IRQF_SAMPLE_RANDOM, name, (void *) (long) fds[0]); if (err) { printk("init_aio_irq - : um_request_irq failed, err = %d\n", diff --git a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c index fc0f0b085ca..166cb09cae4 100644 --- a/arch/um/kernel/physmem.c +++ b/arch/um/kernel/physmem.c @@ -69,7 +69,7 @@ static void insert_phys_mapping(struct phys_desc *desc) panic("Physical remapping for %p already present", desc->virt); - rb_link_node(&desc->rb, (*n)->rb_parent, n); + rb_link_node(&desc->rb, rb_parent(*n), n); rb_insert_color(&desc->rb, &phys_mappings); } diff --git a/arch/um/kernel/sigio_kern.c b/arch/um/kernel/sigio_kern.c index 1c1300fb1e9..51b67708394 100644 --- a/arch/um/kernel/sigio_kern.c +++ b/arch/um/kernel/sigio_kern.c @@ -31,7 +31,7 @@ int write_sigio_irq(int fd) int err; err = um_request_irq(SIGIO_WRITE_IRQ, fd, IRQ_READ, sigio_interrupt, - SA_INTERRUPT | SA_SAMPLE_RANDOM, "write sigio", + IRQF_DISABLED | IRQF_SAMPLE_RANDOM, "write sigio", NULL); if(err){ printk("write_sigio_irq : um_request_irq failed, err = %d\n", diff --git a/arch/um/kernel/skas/mmu.c b/arch/um/kernel/skas/mmu.c index c5c9885a829..624ca238d1f 100644 --- a/arch/um/kernel/skas/mmu.c +++ b/arch/um/kernel/skas/mmu.c @@ -152,7 +152,7 @@ void destroy_context_skas(struct mm_struct *mm) free_page(mmu->id.stack); pte_lock_deinit(virt_to_page(mmu->last_page_table)); pte_free_kernel((pte_t *) mmu->last_page_table); - dec_page_state(nr_page_table_pages); + dec_zone_page_state(virt_to_page(mmu->last_page_table), NR_PAGETABLE); #ifdef CONFIG_3_LEVEL_PGTABLES pmd_free((pmd_t *) mmu->last_pmd); #endif diff --git a/arch/um/kernel/skas/uaccess.c b/arch/um/kernel/skas/uaccess.c index 5992c325716..8912cec0fe4 100644 --- a/arch/um/kernel/skas/uaccess.c +++ b/arch/um/kernel/skas/uaccess.c @@ -8,6 +8,7 @@ #include "linux/kernel.h" #include "linux/string.h" #include "linux/fs.h" +#include "linux/hardirq.h" #include "linux/highmem.h" #include "asm/page.h" #include "asm/pgtable.h" @@ -38,7 +39,7 @@ static unsigned long maybe_map(unsigned long virt, int is_write) return((unsigned long) phys); } -static int do_op(unsigned long addr, int len, int is_write, +static int do_op_one_page(unsigned long addr, int len, int is_write, int (*op)(unsigned long addr, int len, void *arg), void *arg) { struct page *page; @@ -49,9 +50,11 @@ static int do_op(unsigned long addr, int len, int is_write, return(-1); page = phys_to_page(addr); - addr = (unsigned long) kmap(page) + (addr & ~PAGE_MASK); + addr = (unsigned long) kmap_atomic(page, KM_UML_USERCOPY) + (addr & ~PAGE_MASK); + n = (*op)(addr, len, arg); - kunmap(page); + + kunmap_atomic(page, KM_UML_USERCOPY); return(n); } @@ -77,7 +80,7 @@ static void do_buffer_op(void *jmpbuf, void *arg_ptr) remain = len; current->thread.fault_catcher = jmpbuf; - n = do_op(addr, size, is_write, op, arg); + n = do_op_one_page(addr, size, is_write, op, arg); if(n != 0){ *res = (n < 0 ? remain : 0); goto out; @@ -91,7 +94,7 @@ static void do_buffer_op(void *jmpbuf, void *arg_ptr) } while(addr < ((addr + remain) & PAGE_MASK)){ - n = do_op(addr, PAGE_SIZE, is_write, op, arg); + n = do_op_one_page(addr, PAGE_SIZE, is_write, op, arg); if(n != 0){ *res = (n < 0 ? remain : 0); goto out; @@ -105,7 +108,7 @@ static void do_buffer_op(void *jmpbuf, void *arg_ptr) goto out; } - n = do_op(addr, remain, is_write, op, arg); + n = do_op_one_page(addr, remain, is_write, op, arg); if(n != 0) *res = (n < 0 ? remain : 0); else *res = 0; diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c deleted file mode 100644 index 8fa2ae7f302..00000000000 --- a/arch/um/kernel/time.c +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <time.h> -#include <sys/time.h> -#include <signal.h> -#include <errno.h> -#include "user_util.h" -#include "kern_util.h" -#include "user.h" -#include "process.h" -#include "time_user.h" -#include "kern_constants.h" -#include "os.h" - -/* XXX This really needs to be declared and initialized in a kernel file since - * it's in <linux/time.h> - */ -extern struct timespec wall_to_monotonic; - -extern struct timeval xtime; - -struct timeval local_offset = { 0, 0 }; - -void timer(void) -{ - gettimeofday(&xtime, NULL); - timeradd(&xtime, &local_offset, &xtime); -} - -static void set_interval(int timer_type) -{ - int usec = 1000000/hz(); - struct itimerval interval = ((struct itimerval) { { 0, usec }, - { 0, usec } }); - - if(setitimer(timer_type, &interval, NULL) == -1) - panic("setitimer failed - errno = %d\n", errno); -} - -void enable_timer(void) -{ - set_interval(ITIMER_VIRTUAL); -} - -void prepare_timer(void * ptr) -{ - int usec = 1000000/hz(); - *(struct itimerval *)ptr = ((struct itimerval) { { 0, usec }, - { 0, usec }}); -} - -void disable_timer(void) -{ - struct itimerval disable = ((struct itimerval) { { 0, 0 }, { 0, 0 }}); - if((setitimer(ITIMER_VIRTUAL, &disable, NULL) < 0) || - (setitimer(ITIMER_REAL, &disable, NULL) < 0)) - printk("disnable_timer - setitimer failed, errno = %d\n", - errno); - /* If there are signals already queued, after unblocking ignore them */ - set_handler(SIGALRM, SIG_IGN, 0, -1); - set_handler(SIGVTALRM, SIG_IGN, 0, -1); -} - -void switch_timers(int to_real) -{ - struct itimerval disable = ((struct itimerval) { { 0, 0 }, { 0, 0 }}); - struct itimerval enable = ((struct itimerval) { { 0, 1000000/hz() }, - { 0, 1000000/hz() }}); - int old, new; - - if(to_real){ - old = ITIMER_VIRTUAL; - new = ITIMER_REAL; - } - else { - old = ITIMER_REAL; - new = ITIMER_VIRTUAL; - } - - if((setitimer(old, &disable, NULL) < 0) || - (setitimer(new, &enable, NULL))) - printk("switch_timers - setitimer failed, errno = %d\n", - errno); -} - -void uml_idle_timer(void) -{ - if(signal(SIGVTALRM, SIG_IGN) == SIG_ERR) - panic("Couldn't unset SIGVTALRM handler"); - - set_handler(SIGALRM, (__sighandler_t) alarm_handler, - SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1); - set_interval(ITIMER_REAL); -} - -extern void ktime_get_ts(struct timespec *ts); -#define do_posix_clock_monotonic_gettime(ts) ktime_get_ts(ts) - -void time_init(void) -{ - struct timespec now; - - if(signal(SIGVTALRM, boot_timer_handler) == SIG_ERR) - panic("Couldn't set SIGVTALRM handler"); - set_interval(ITIMER_VIRTUAL); - - do_posix_clock_monotonic_gettime(&now); - wall_to_monotonic.tv_sec = -now.tv_sec; - wall_to_monotonic.tv_nsec = -now.tv_nsec; -} - -/* Defined in linux/ktimer.h, which can't be included here */ -#define clock_was_set() do { } while (0) - -void do_gettimeofday(struct timeval *tv) -{ - unsigned long flags; - - flags = time_lock(); - gettimeofday(tv, NULL); - timeradd(tv, &local_offset, tv); - time_unlock(flags); - clock_was_set(); -} - -int do_settimeofday(struct timespec *tv) -{ - struct timeval now; - unsigned long flags; - struct timeval tv_in; - - if ((unsigned long) tv->tv_nsec >= UM_NSEC_PER_SEC) - return -EINVAL; - - tv_in.tv_sec = tv->tv_sec; - tv_in.tv_usec = tv->tv_nsec / 1000; - - flags = time_lock(); - gettimeofday(&now, NULL); - timersub(&tv_in, &now, &local_offset); - time_unlock(flags); - - return(0); -} - -void idle_sleep(int secs) -{ - struct timespec ts; - - ts.tv_sec = secs; - ts.tv_nsec = 0; - nanosleep(&ts, NULL); -} - -/* XXX This partly duplicates init_irq_signals */ - -void user_time_init(void) -{ - set_handler(SIGVTALRM, (__sighandler_t) alarm_handler, - SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, - SIGALRM, SIGUSR2, -1); - set_handler(SIGALRM, (__sighandler_t) alarm_handler, - SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, - SIGVTALRM, SIGUSR2, -1); - set_interval(ITIMER_VIRTUAL); -} diff --git a/arch/um/kernel/time_kern.c b/arch/um/kernel/time_kern.c index 86f51d04c98..d7e044b5e5e 100644 --- a/arch/um/kernel/time_kern.c +++ b/arch/um/kernel/time_kern.c @@ -87,7 +87,7 @@ void timer_irq(union uml_pt_regs *regs) void time_init_kern(void) { - unsigned long long nsecs; + long long nsecs; nsecs = os_nsecs(); set_normalized_timespec(&wall_to_monotonic, -nsecs / BILLION, @@ -96,11 +96,15 @@ void time_init_kern(void) void do_boot_timer_handler(struct sigcontext * sc) { + unsigned long flags; struct pt_regs regs; CHOOSE_MODE((void) (UPT_SC(®s.regs) = sc), (void) (regs.regs.skas.is_user = 0)); + + write_seqlock_irqsave(&xtime_lock, flags); do_timer(®s); + write_sequnlock_irqrestore(&xtime_lock, flags); } static DEFINE_SPINLOCK(timer_spinlock); @@ -125,25 +129,17 @@ irqreturn_t um_timer(int irq, void *dev, struct pt_regs *regs) unsigned long long nsecs; unsigned long flags; + write_seqlock_irqsave(&xtime_lock, flags); + do_timer(regs); - write_seqlock_irqsave(&xtime_lock, flags); nsecs = get_time() + local_offset; xtime.tv_sec = nsecs / NSEC_PER_SEC; xtime.tv_nsec = nsecs - xtime.tv_sec * NSEC_PER_SEC; - write_sequnlock_irqrestore(&xtime_lock, flags); - - return(IRQ_HANDLED); -} -long um_time(int __user *tloc) -{ - long ret = get_time() / NSEC_PER_SEC; - - if((tloc != NULL) && put_user(ret, tloc)) - return -EFAULT; + write_sequnlock_irqrestore(&xtime_lock, flags); - return ret; + return IRQ_HANDLED; } void do_gettimeofday(struct timeval *tv) @@ -174,18 +170,6 @@ static inline void set_time(unsigned long long nsecs) clock_was_set(); } -long um_stime(int __user *tptr) -{ - int value; - - if (get_user(value, tptr)) - return -EFAULT; - - set_time((unsigned long long) value * NSEC_PER_SEC); - - return 0; -} - int do_settimeofday(struct timespec *tv) { set_time((unsigned long long) tv->tv_sec * NSEC_PER_SEC + tv->tv_nsec); @@ -211,7 +195,7 @@ int __init timer_init(void) int err; user_time_init(); - err = request_irq(TIMER_IRQ, um_timer, SA_INTERRUPT, "timer", NULL); + err = request_irq(TIMER_IRQ, um_timer, IRQF_DISABLED, "timer", NULL); if(err != 0) printk(KERN_ERR "timer_init : request_irq failed - " "errno = %d\n", -err); diff --git a/arch/um/kernel/vmlinux.lds.S b/arch/um/kernel/vmlinux.lds.S index 1660a769674..72acdce205e 100644 --- a/arch/um/kernel/vmlinux.lds.S +++ b/arch/um/kernel/vmlinux.lds.S @@ -1,4 +1,5 @@ -#include <linux/config.h> +/* in case the preprocessor is a 32bit one */ +#undef i386 #ifdef CONFIG_LD_SCRIPT_STATIC #include "uml.lds.S" #else |