diff options
Diffstat (limited to 'arch/um')
31 files changed, 147 insertions, 312 deletions
diff --git a/arch/um/Kconfig.debug b/arch/um/Kconfig.debug index 5681a8bd370..bab51d61917 100644 --- a/arch/um/Kconfig.debug +++ b/arch/um/Kconfig.debug @@ -49,7 +49,6 @@ config GCOV config SYSCALL_DEBUG bool "Enable system call debugging" - default N depends on DEBUG_INFO help This adds some system debugging to UML, including keeping a ring buffer diff --git a/arch/um/Makefile-x86_64 b/arch/um/Makefile-x86_64 index dfd88b652fb..dffd1184c95 100644 --- a/arch/um/Makefile-x86_64 +++ b/arch/um/Makefile-x86_64 @@ -6,9 +6,11 @@ START := 0x60000000 #We #undef __x86_64__ for kernelspace, not for userspace where #it's needed for headers to work! -CFLAGS += -U__$(SUBARCH)__ -fno-builtin -USER_CFLAGS += -fno-builtin +CFLAGS += -U__$(SUBARCH)__ -fno-builtin -m64 +USER_CFLAGS += -fno-builtin -m64 CHECKFLAGS += -m64 +AFLAGS += -m64 +LDFLAGS += -m elf_x86_64 ELF_ARCH := i386:x86-64 ELF_FORMAT := elf64-x86-64 @@ -16,3 +18,4 @@ ELF_FORMAT := elf64-x86-64 # Not on all 64-bit distros /lib is a symlink to /lib64. PLD is an example. LINK-$(CONFIG_LD_SCRIPT_DYN) += -Wl,-rpath,/lib64 +LINK-y += -m64 diff --git a/arch/um/drivers/harddog_kern.c b/arch/um/drivers/harddog_kern.c index d18a974735e..64ff22aa077 100644 --- a/arch/um/drivers/harddog_kern.c +++ b/arch/um/drivers/harddog_kern.c @@ -35,7 +35,6 @@ */ #include <linux/module.h> -#include <linux/config.h> #include <linux/types.h> #include <linux/kernel.h> #include <linux/fs.h> diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index 6c2d4ccaf20..ebebaabb78a 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c @@ -8,7 +8,6 @@ #include "linux/list.h" #include "linux/kd.h" #include "linux/interrupt.h" -#include "linux/devfs_fs_kernel.h" #include "asm/uaccess.h" #include "chan_kern.h" #include "irq_user.h" @@ -374,7 +373,7 @@ static irqreturn_t line_write_interrupt(int irq, void *data, int err; /* Interrupts are enabled here because we registered the interrupt with - * SA_INTERRUPT (see line_setup_irq).*/ + * IRQF_DISABLED (see line_setup_irq).*/ spin_lock_irq(&line->lock); err = flush_buffer(line); @@ -407,7 +406,7 @@ static irqreturn_t line_write_interrupt(int irq, void *data, int line_setup_irq(int fd, int input, int output, struct line *line, void *data) { struct line_driver *driver = line->driver; - int err = 0, flags = SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM; + int err = 0, flags = IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM; if (input) err = um_request_irq(driver->read_irq, fd, IRQ_READ, @@ -655,7 +654,6 @@ struct tty_driver *line_register_devfs(struct lines *set, driver->driver_name = line_driver->name; driver->name = line_driver->device_name; - driver->devfs_name = line_driver->devfs_name; driver->major = line_driver->major; driver->minor_start = line_driver->minor_start; driver->type = line_driver->type; @@ -769,7 +767,7 @@ void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty) spin_unlock(&winch_handler_lock); if(um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt, - SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, + IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM, "winch", winch) < 0) printk("register_winch_irq - failed to register IRQ\n"); } diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c index 6d7173fc55a..b414522f768 100644 --- a/arch/um/drivers/mconsole_kern.c +++ b/arch/um/drivers/mconsole_kern.c @@ -300,8 +300,6 @@ void mconsole_reboot(struct mc_request *req) machine_restart(NULL); } -extern void ctrl_alt_del(void); - void mconsole_cad(struct mc_request *req) { mconsole_reply(req, "", 0, 0); @@ -779,7 +777,7 @@ static int mconsole_init(void) register_reboot_notifier(&reboot_notifier); err = um_request_irq(MCONSOLE_IRQ, sock, IRQ_READ, mconsole_interrupt, - SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, + IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM, "mconsole", (void *)sock); if (err){ printk("Failed to get IRQ for management console\n"); diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c index 8c7279bb353..501f95675d8 100644 --- a/arch/um/drivers/net_kern.c +++ b/arch/um/drivers/net_kern.c @@ -128,7 +128,7 @@ static int uml_net_open(struct net_device *dev) } err = um_request_irq(dev->irq, lp->fd, IRQ_READ, uml_net_interrupt, - SA_INTERRUPT | SA_SHIRQ, dev->name, dev); + IRQF_DISABLED | IRQF_SHARED, dev->name, dev); if(err != 0){ printk(KERN_ERR "uml_net_open: failed to get irq(%d)\n", err); err = -ENETUNREACH; diff --git a/arch/um/drivers/port_kern.c b/arch/um/drivers/port_kern.c index 189839e4f1d..73755f37a8a 100644 --- a/arch/um/drivers/port_kern.c +++ b/arch/um/drivers/port_kern.c @@ -105,7 +105,7 @@ static int port_accept(struct port_list *port) .port = port }); if(um_request_irq(TELNETD_IRQ, socket[0], IRQ_READ, pipe_interrupt, - SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, + IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM, "telnetd", conn)){ printk(KERN_ERR "port_accept : failed to get IRQ for " "telnetd\n"); @@ -186,7 +186,7 @@ void *port_data(int port_num) goto out_free; } if(um_request_irq(ACCEPT_IRQ, fd, IRQ_READ, port_interrupt, - SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, "port", + IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM, "port", port)){ printk(KERN_ERR "Failed to get IRQ for port %d\n", port_num); goto out_close; diff --git a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c index a4d6415bc8c..6dafd6fbfda 100644 --- a/arch/um/drivers/ssl.c +++ b/arch/um/drivers/ssl.c @@ -54,7 +54,6 @@ static int ssl_remove(int n); static struct line_driver driver = { .name = "UML serial line", .device_name = "ttyS", - .devfs_name = "tts/", .major = TTY_MAJOR, .minor_start = 64, .type = TTY_DRIVER_TYPE_SERIAL, diff --git a/arch/um/drivers/stderr_console.c b/arch/um/drivers/stderr_console.c index 429ae8e6c7e..6d2cf32a9e8 100644 --- a/arch/um/drivers/stderr_console.c +++ b/arch/um/drivers/stderr_console.c @@ -8,10 +8,7 @@ /* * Don't register by default -- as this registeres very early in the - * boot process it becomes the default console. And as this isn't a - * real tty driver init isn't able to open /dev/console then. - * - * In most cases this isn't what you want ... + * boot process it becomes the default console. */ static int use_stderr_console = 0; @@ -43,3 +40,20 @@ static int stderr_setup(char *str) return 1; } __setup("stderr=", stderr_setup); + +/* The previous behavior of not unregistering led to /dev/console being + * impossible to open. My FC5 filesystem started having init die, and the + * system panicing because of this. Unregistering causes the real + * console to become the default console, and /dev/console can then be + * opened. Making this an initcall makes this happen late enough that + * there is no added value in dumping everything to stderr, and the + * normal console is good enough to show you all available output. + */ +static int __init unregister_stderr(void) +{ + unregister_console(&stderr_console); + + return 0; +} + +__initcall(unregister_stderr); diff --git a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c index 61db8b2fc83..856f568c268 100644 --- a/arch/um/drivers/stdio_console.c +++ b/arch/um/drivers/stdio_console.c @@ -60,7 +60,6 @@ static int con_remove(int n); static struct line_driver driver = { .name = "UML console", .device_name = "tty", - .devfs_name = "vc/", .major = TTY_MAJOR, .minor_start = 0, .type = TTY_DRIVER_TYPE_CONSOLE, diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 0897852b09a..602d7286b9e 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -25,7 +25,6 @@ #include "linux/blkdev.h" #include "linux/hdreg.h" #include "linux/init.h" -#include "linux/devfs_fs_kernel.h" #include "linux/cdrom.h" #include "linux/proc_fs.h" #include "linux/ctype.h" @@ -628,7 +627,6 @@ static int ubd_new_disk(int major, u64 size, int unit, { struct gendisk *disk; - char from[sizeof("ubd/nnnnn\0")], to[sizeof("discnnnnn/disc\0")]; int err; disk = alloc_disk(1 << UBD_SHIFT); @@ -639,20 +637,10 @@ static int ubd_new_disk(int major, u64 size, int unit, disk->first_minor = unit << UBD_SHIFT; disk->fops = &ubd_blops; set_capacity(disk, size / 512); - if(major == MAJOR_NR){ + if(major == MAJOR_NR) sprintf(disk->disk_name, "ubd%c", 'a' + unit); - sprintf(disk->devfs_name, "ubd/disc%d", unit); - sprintf(from, "ubd/%d", unit); - sprintf(to, "disc%d/disc", unit); - err = devfs_mk_symlink(from, to); - if(err) - printk("ubd_new_disk failed to make link from %s to " - "%s, error = %d\n", from, to, err); - } - else { + else sprintf(disk->disk_name, "ubd_fake%d", unit); - sprintf(disk->devfs_name, "ubd_fake/disc%d", unit); - } /* sysfs register (not for ide fake devices) */ if (major == MAJOR_NR) { @@ -841,7 +829,6 @@ int ubd_init(void) { int i; - devfs_mk_dir("ubd"); if (register_blkdev(MAJOR_NR, "ubd")) return -1; @@ -855,7 +842,6 @@ int ubd_init(void) char name[sizeof("ubd_nnn\0")]; snprintf(name, sizeof(name), "ubd_%d", fake_major); - devfs_mk_dir(name); if (register_blkdev(fake_major, "ubd")) return -1; } @@ -888,7 +874,7 @@ int ubd_driver_init(void){ return(0); } err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr, - SA_INTERRUPT, "ubd", ubd_dev); + IRQF_DISABLED, "ubd", ubd_dev); if(err != 0) printk(KERN_ERR "um_request_irq failed - errno = %d\n", -err); return 0; @@ -1222,7 +1208,7 @@ int open_ubd_file(char *file, struct openflags *openflags, int shared, } } - /* Succesful return case! */ + /* Successful return case! */ if(backing_file_out == NULL) return(fd); diff --git a/arch/um/drivers/xterm_kern.c b/arch/um/drivers/xterm_kern.c index d269a80f4b0..6036ec85895 100644 --- a/arch/um/drivers/xterm_kern.c +++ b/arch/um/drivers/xterm_kern.c @@ -54,7 +54,7 @@ int xterm_fd(int socket, int *pid_out) init_completion(&data->ready); err = um_request_irq(XTERM_IRQ, socket, IRQ_READ, xterm_interrupt, - SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, + IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM, "xterm", data); if (err){ printk(KERN_ERR "xterm_fd : failed to get IRQ for xterm, " diff --git a/arch/um/include/line.h b/arch/um/include/line.h index 6ac0f8252e2..27bf2f6fbc0 100644 --- a/arch/um/include/line.h +++ b/arch/um/include/line.h @@ -17,7 +17,6 @@ struct line_driver { char *name; char *device_name; - char *devfs_name; short major; short minor_start; short type; diff --git a/arch/um/include/sysdep-x86_64/kernel-offsets.h b/arch/um/include/sysdep-x86_64/kernel-offsets.h index 939cc475757..91d129fb393 100644 --- a/arch/um/include/sysdep-x86_64/kernel-offsets.h +++ b/arch/um/include/sysdep-x86_64/kernel-offsets.h @@ -1,4 +1,3 @@ -#include <linux/config.h> #include <linux/stddef.h> #include <linux/sched.h> #include <linux/time.h> diff --git a/arch/um/include/sysdep-x86_64/syscalls.h b/arch/um/include/sysdep-x86_64/syscalls.h index e06f83e80f4..5e86aa047b2 100644 --- a/arch/um/include/sysdep-x86_64/syscalls.h +++ b/arch/um/include/sysdep-x86_64/syscalls.h @@ -12,8 +12,6 @@ typedef long syscall_handler_t(void); -extern syscall_handler_t *ia32_sys_call_table[]; - extern syscall_handler_t *sys_call_table[]; #define EXECUTE_SYSCALL(syscall, regs) \ 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 diff --git a/arch/um/os-Linux/mem.c b/arch/um/os-Linux/mem.c index c6432e72924..560c8063c77 100644 --- a/arch/um/os-Linux/mem.c +++ b/arch/um/os-Linux/mem.c @@ -55,7 +55,7 @@ static void __init find_tempdir(void) */ static int next(int fd, char *buf, int size, char c) { - int n; + int n, len; char *ptr; while((ptr = strchr(buf, c)) == NULL){ @@ -69,7 +69,17 @@ static int next(int fd, char *buf, int size, char c) } ptr++; - memmove(buf, ptr, strlen(ptr) + 1); + len = strlen(ptr); + memmove(buf, ptr, len + 1); + + /* Refill the buffer so that if there's a partial string that we care + * about, it will be completed, and we can recognize it. + */ + n = read(fd, &buf[len], size - len - 1); + if(n < 0) + return -errno; + + buf[len + n] = '\0'; return 1; } @@ -200,8 +210,11 @@ int create_tmp_file(unsigned long long len) exit(1); } - if (lseek64(fd, len, SEEK_SET) < 0) { - perror("os_seek_file"); + /* Seek to len - 1 because writing a character there will + * increase the file size by one byte, to the desired length. + */ + if (lseek64(fd, len - 1, SEEK_SET) < 0) { + perror("os_seek_file"); exit(1); } diff --git a/arch/um/os-Linux/umid.c b/arch/um/os-Linux/umid.c index 362db059fe3..48092b95c8a 100644 --- a/arch/um/os-Linux/umid.c +++ b/arch/um/os-Linux/umid.c @@ -67,32 +67,53 @@ err: return err; } -static int actually_do_remove(char *dir) +/* + * Unlinks the files contained in @dir and then removes @dir. + * Doesn't handle directory trees, so it's not like rm -rf, but almost such. We + * 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) { DIR *directory; struct dirent *ent; int len; char file[256]; + int ret; directory = opendir(dir); - if(directory == NULL) - return -errno; + if (directory == NULL) { + if (errno != ENOENT) + return -errno; + else + return 0; + } - while((ent = readdir(directory)) != NULL){ - if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) + while ((ent = readdir(directory)) != NULL) { + if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) continue; len = strlen(dir) + sizeof("/") + strlen(ent->d_name) + 1; - if(len > sizeof(file)) - return -E2BIG; + if (len > sizeof(file)) { + ret = -E2BIG; + goto out; + } sprintf(file, "%s/%s", dir, ent->d_name); - if(unlink(file) < 0) - return -errno; + if (unlink(file) < 0 && errno != ENOENT) { + ret = -errno; + goto out; + } } - if(rmdir(dir) < 0) - return -errno; - return 0; + if (rmdir(dir) < 0 && errno != ENOENT) { + ret = -errno; + goto out; + } + + ret = 0; +out: + closedir(directory); + return ret; } /* This says that there isn't already a user of the specified directory even if @@ -103,9 +124,10 @@ static int actually_do_remove(char *dir) * something other than UML sticking stuff in the directory * this boot racing with a shutdown of the other UML * In any of these cases, the directory isn't useful for anything else. + * + * Boolean return: 1 if in use, 0 otherwise. */ - -static int not_dead_yet(char *dir) +static inline int is_umdir_used(char *dir) { char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")]; char pid[sizeof("nnnnn\0")], *end; @@ -113,7 +135,7 @@ static int not_dead_yet(char *dir) n = snprintf(file, sizeof(file), "%s/pid", dir); if(n >= sizeof(file)){ - printk("not_dead_yet - pid filename too long\n"); + printk("is_umdir_used - pid filename too long\n"); err = -E2BIG; goto out; } @@ -123,7 +145,7 @@ static int not_dead_yet(char *dir) if(fd < 0) { fd = -errno; if(fd != -ENOENT){ - printk("not_dead_yet : couldn't open pid file '%s', " + printk("is_umdir_used : couldn't open pid file '%s', " "err = %d\n", file, -fd); } goto out; @@ -132,18 +154,18 @@ static int not_dead_yet(char *dir) err = 0; n = read(fd, pid, sizeof(pid)); if(n < 0){ - printk("not_dead_yet : couldn't read pid file '%s', " + printk("is_umdir_used : couldn't read pid file '%s', " "err = %d\n", file, errno); goto out_close; } else if(n == 0){ - printk("not_dead_yet : couldn't read pid file '%s', " + printk("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("not_dead_yet : couldn't parse pid file '%s', " + printk("is_umdir_used : couldn't parse pid file '%s', " "errno = %d\n", file, errno); goto out_close; } @@ -153,19 +175,32 @@ static int not_dead_yet(char *dir) return 1; } - err = actually_do_remove(dir); - if(err) - printk("not_dead_yet - actually_do_remove failed with " - "err = %d\n", err); - - return err; - out_close: close(fd); out: return 0; } +/* + * Try to remove the directory @dir unless it's in use. + * Precondition: @dir exists. + * Returns 0 for success, < 0 for failure in removal or if the directory is in + * use. + */ +static int umdir_take_if_dead(char *dir) +{ + int ret; + if (is_umdir_used(dir)) + return -EEXIST; + + ret = remove_files_and_dir(dir); + if (ret) { + printk("is_umdir_used - remove_files_and_dir failed with " + "err = %d\n", ret); + } + return ret; +} + static void __init create_pid_file(void) { char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")]; @@ -244,11 +279,7 @@ int __init make_umid(void) if(err != -EEXIST) goto err; - /* 1 -> this umid is already in use - * < 0 -> we couldn't remove the umid directory - * In either case, we can't use this umid, so return -EEXIST. - */ - if(not_dead_yet(tmp) != 0) + if (umdir_take_if_dead(tmp) < 0) goto err; err = mkdir(tmp, 0777); @@ -344,9 +375,9 @@ static void remove_umid_dir(void) char dir[strlen(uml_dir) + UMID_LEN + 1], err; sprintf(dir, "%s%s", uml_dir, umid); - err = actually_do_remove(dir); + err = remove_files_and_dir(dir); if(err) - printf("remove_umid_dir - actually_do_remove failed with " + printf("remove_umid_dir - remove_files_and_dir failed with " "err = %d\n", err); } diff --git a/arch/um/scripts/Makefile.rules b/arch/um/scripts/Makefile.rules index 1347dc6d521..813077fb1e5 100644 --- a/arch/um/scripts/Makefile.rules +++ b/arch/um/scripts/Makefile.rules @@ -8,7 +8,7 @@ USER_OBJS += $(filter %_user.o,$(obj-y) $(obj-m) $(USER_SINGLE_OBJS)) USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file)) $(USER_OBJS:.o=.%): \ - c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) $(CFLAGS_$(*F).o) + c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) $(CFLAGS_$(basetarget).o) $(USER_OBJS) : CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ \ -Dunix -D__unix__ -D__$(SUBARCH)__ @@ -17,7 +17,7 @@ $(USER_OBJS) : CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ \ UNPROFILE_OBJS := $(foreach file,$(UNPROFILE_OBJS),$(obj)/$(file)) $(UNPROFILE_OBJS:.o=.%): \ - c_flags = -Wp,-MD,$(depfile) $(call unprofile,$(USER_CFLAGS)) $(CFLAGS_$(*F).o) + c_flags = -Wp,-MD,$(depfile) $(call unprofile,$(USER_CFLAGS)) $(CFLAGS_$(basetarget).o) $(UNPROFILE_OBJS) : CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ \ -Dunix -D__unix__ -D__$(SUBARCH)__ diff --git a/arch/um/sys-i386/checksum.S b/arch/um/sys-i386/checksum.S index d98b2fff3d0..62c7e564f22 100644 --- a/arch/um/sys-i386/checksum.S +++ b/arch/um/sys-i386/checksum.S @@ -25,7 +25,6 @@ * 2 of the License, or (at your option) any later version. */ -#include <linux/config.h> #include <asm/errno.h> /* diff --git a/arch/um/sys-i386/ptrace.c b/arch/um/sys-i386/ptrace.c index 6028bc7cc01..28bf0115032 100644 --- a/arch/um/sys-i386/ptrace.c +++ b/arch/um/sys-i386/ptrace.c @@ -3,7 +3,6 @@ * Licensed under the GPL */ -#include <linux/config.h> #include <linux/compiler.h> #include "linux/sched.h" #include "linux/mm.h" diff --git a/arch/um/sys-i386/sys_call_table.S b/arch/um/sys-i386/sys_call_table.S index 1ff61474b25..2497554b7b9 100644 --- a/arch/um/sys-i386/sys_call_table.S +++ b/arch/um/sys-i386/sys_call_table.S @@ -7,8 +7,6 @@ #define sys_vm86old sys_ni_syscall #define sys_vm86 sys_ni_syscall -#define sys_stime um_stime -#define sys_time um_time #define old_mmap old_mmap_i386 #include "../../i386/kernel/syscall_table.S" diff --git a/arch/um/sys-ppc/misc.S b/arch/um/sys-ppc/misc.S index 11b7bd768cf..1364b7da578 100644 --- a/arch/um/sys-ppc/misc.S +++ b/arch/um/sys-ppc/misc.S @@ -15,7 +15,6 @@ * */ -#include <linux/config.h> #include <asm/processor.h> #include "ppc_asm.h" @@ -23,14 +22,10 @@ #define CACHE_LINE_SIZE 16 #define LG_CACHE_LINE_SIZE 4 #define MAX_COPY_PREFETCH 1 -#elif !defined(CONFIG_PPC64BRIDGE) +#else #define CACHE_LINE_SIZE 32 #define LG_CACHE_LINE_SIZE 5 #define MAX_COPY_PREFETCH 4 -#else -#define CACHE_LINE_SIZE 128 -#define LG_CACHE_LINE_SIZE 7 -#define MAX_COPY_PREFETCH 1 #endif /* CONFIG_4xx || CONFIG_8xx */ .text diff --git a/arch/um/sys-x86_64/syscall_table.c b/arch/um/sys-x86_64/syscall_table.c index 34b2e842864..9e9ad72c2ba 100644 --- a/arch/um/sys-x86_64/syscall_table.c +++ b/arch/um/sys-x86_64/syscall_table.c @@ -4,7 +4,6 @@ #include <linux/linkage.h> #include <linux/sys.h> #include <linux/cache.h> -#include <linux/config.h> #define __NO_STUBS @@ -20,12 +19,6 @@ /*#define sys_set_thread_area sys_ni_syscall #define sys_get_thread_area sys_ni_syscall*/ -/* For __NR_time. The x86-64 name hopefully will change from sys_time64 to - * sys_time (since the current situation is bogus). I've sent a patch to cleanup - * this. Remove below the obsoleted line. */ -#define sys_time64 um_time -#define sys_time um_time - /* On UML we call it this way ("old" means it's not mmap2) */ #define sys_mmap old_mmap /* On x86-64 sys_uname is actually sys_newuname plus a compatibility trick. |