diff options
Diffstat (limited to 'arch/um')
-rw-r--r-- | arch/um/Makefile-x86_64 | 7 | ||||
-rw-r--r-- | arch/um/drivers/stderr_console.c | 22 | ||||
-rw-r--r-- | arch/um/kernel/skas/mmu.c | 2 | ||||
-rw-r--r-- | arch/um/kernel/time.c | 172 | ||||
-rw-r--r-- | arch/um/kernel/time_kern.c | 32 | ||||
-rw-r--r-- | arch/um/kernel/vmlinux.lds.S | 2 | ||||
-rw-r--r-- | arch/um/os-Linux/mem.c | 21 | ||||
-rw-r--r-- | arch/um/sys-i386/sys_call_table.S | 2 | ||||
-rw-r--r-- | arch/um/sys-x86_64/syscall_table.c | 6 |
9 files changed, 51 insertions, 215 deletions
diff --git a/arch/um/Makefile-x86_64 b/arch/um/Makefile-x86_64 index dfd88b652fbe..dffd1184c956 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/stderr_console.c b/arch/um/drivers/stderr_console.c index 429ae8e6c7e5..6d2cf32a9e8f 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/kernel/skas/mmu.c b/arch/um/kernel/skas/mmu.c index c5c9885a8297..624ca238d1fd 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/time.c b/arch/um/kernel/time.c deleted file mode 100644 index 8fa2ae7f3026..000000000000 --- 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 87cdbc560d36..820fa3615a3f 100644 --- a/arch/um/kernel/time_kern.c +++ b/arch/um/kernel/time_kern.c @@ -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); diff --git a/arch/um/kernel/vmlinux.lds.S b/arch/um/kernel/vmlinux.lds.S index f8aeb448aab6..72acdce205e0 100644 --- a/arch/um/kernel/vmlinux.lds.S +++ b/arch/um/kernel/vmlinux.lds.S @@ -1,3 +1,5 @@ +/* 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 c6432e729241..560c8063c77c 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/sys-i386/sys_call_table.S b/arch/um/sys-i386/sys_call_table.S index 1ff61474b25c..2497554b7b95 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-x86_64/syscall_table.c b/arch/um/sys-x86_64/syscall_table.c index 67ba024581e9..9e9ad72c2ba4 100644 --- a/arch/um/sys-x86_64/syscall_table.c +++ b/arch/um/sys-x86_64/syscall_table.c @@ -19,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. |