diff options
Diffstat (limited to 'arch/um')
-rw-r--r-- | arch/um/drivers/ubd_kern.c | 1 | ||||
-rw-r--r-- | arch/um/include/os.h | 2 | ||||
-rw-r--r-- | arch/um/kernel/um_arch.c | 2 | ||||
-rw-r--r-- | arch/um/os-Linux/helper.c | 1 | ||||
-rw-r--r-- | arch/um/os-Linux/skas/process.c | 2 | ||||
-rw-r--r-- | arch/um/os-Linux/sys-i386/task_size.c | 31 | ||||
-rw-r--r-- | arch/um/os-Linux/sys-x86_64/task_size.c | 2 | ||||
-rw-r--r-- | arch/um/os-Linux/time.c | 7 | ||||
-rw-r--r-- | arch/um/sys-x86_64/ksyms.c | 4 |
9 files changed, 39 insertions, 13 deletions
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 44ad1607be2..b58fb8941d8 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -49,7 +49,6 @@ #include "irq_user.h" #include "irq_kern.h" #include "ubd_user.h" -#include "kern_util.h" #include "os.h" #include "mem.h" #include "mem_kern.h" diff --git a/arch/um/include/os.h b/arch/um/include/os.h index e2716ac8889..db5be46e3e1 100644 --- a/arch/um/include/os.h +++ b/arch/um/include/os.h @@ -299,6 +299,6 @@ extern int os_arch_prctl(int pid, int code, unsigned long *addr); extern int get_pty(void); /* sys-$ARCH/task_size.c */ -extern unsigned long os_get_task_size(void); +extern unsigned long os_get_top_address(void); #endif diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index 9db85b2ce69..8d84250324b 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c @@ -274,7 +274,7 @@ int __init linux_main(int argc, char **argv) if (have_root == 0) add_arg(DEFAULT_COMMAND_LINE); - host_task_size = os_get_task_size(); + host_task_size = os_get_top_address(); /* * TASK_SIZE needs to be PGDIR_SIZE aligned or else exit_mmap craps * out diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c index 74ca7aabf4e..30860b89ec5 100644 --- a/arch/um/os-Linux/helper.c +++ b/arch/um/os-Linux/helper.c @@ -7,6 +7,7 @@ #include <unistd.h> #include <errno.h> #include <sched.h> +#include <linux/limits.h> #include <sys/socket.h> #include <sys/wait.h> #include "kern_constants.h" diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index 6be028ca181..172ad8f72e1 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c @@ -55,7 +55,7 @@ static int ptrace_dump_regs(int pid) * Signals that are OK to receive in the stub - we'll just continue it. * SIGWINCH will happen when UML is inside a detached screen. */ -#define STUB_SIG_MASK (1 << SIGVTALRM) +#define STUB_SIG_MASK ((1 << SIGVTALRM) | (1 << SIGWINCH)) /* Signals that the stub will finish with - anything else is an error */ #define STUB_DONE_MASK (1 << SIGTRAP) diff --git a/arch/um/os-Linux/sys-i386/task_size.c b/arch/um/os-Linux/sys-i386/task_size.c index ccb49b0aff5..be04c1e183b 100644 --- a/arch/um/os-Linux/sys-i386/task_size.c +++ b/arch/um/os-Linux/sys-i386/task_size.c @@ -63,7 +63,7 @@ static int page_ok(unsigned long page) return ok; } -unsigned long os_get_task_size(void) +unsigned long os_get_top_address(void) { struct sigaction sa, old; unsigned long bottom = 0; @@ -76,9 +76,9 @@ unsigned long os_get_task_size(void) * hosts, but shouldn't hurt otherwise. */ unsigned long top = 0xffffd000 >> UM_KERN_PAGE_SHIFT; - unsigned long test; + unsigned long test, original; - printf("Locating the top of the address space ... "); + printf("Locating the bottom of the address space ... "); fflush(stdout); /* @@ -89,16 +89,31 @@ unsigned long os_get_task_size(void) sigemptyset(&sa.sa_mask); sa.sa_flags = SA_NODEFER; if (sigaction(SIGSEGV, &sa, &old)) { - perror("os_get_task_size"); + perror("os_get_top_address"); exit(1); } - if (!page_ok(bottom)) { - fprintf(stderr, "Address 0x%x no good?\n", - bottom << UM_KERN_PAGE_SHIFT); + /* Manually scan the address space, bottom-up, until we find + * the first valid page (or run out of them). + */ + for (bottom = 0; bottom < top; bottom++) { + if (page_ok(bottom)) + break; + } + + /* If we've got this far, we ran out of pages. */ + if (bottom == top) { + fprintf(stderr, "Unable to determine bottom of address " + "space.\n"); exit(1); } + printf("0x%x\n", bottom << UM_KERN_PAGE_SHIFT); + printf("Locating the top of the address space ... "); + fflush(stdout); + + original = bottom; + /* This could happen with a 4G/4G split */ if (page_ok(top)) goto out; @@ -114,7 +129,7 @@ unsigned long os_get_task_size(void) out: /* Restore the old SIGSEGV handling */ if (sigaction(SIGSEGV, &old, NULL)) { - perror("os_get_task_size"); + perror("os_get_top_address"); exit(1); } top <<= UM_KERN_PAGE_SHIFT; diff --git a/arch/um/os-Linux/sys-x86_64/task_size.c b/arch/um/os-Linux/sys-x86_64/task_size.c index fad6f57f8ee..26a0dd1f349 100644 --- a/arch/um/os-Linux/sys-x86_64/task_size.c +++ b/arch/um/os-Linux/sys-x86_64/task_size.c @@ -1,4 +1,4 @@ -unsigned long os_get_task_size(unsigned long shift) +unsigned long os_get_top_address(unsigned long shift) { /* The old value of CONFIG_TOP_ADDR */ return 0x7fc0000000; diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c index bee98f466d6..dec5678fc17 100644 --- a/arch/um/os-Linux/time.c +++ b/arch/um/os-Linux/time.c @@ -106,6 +106,10 @@ static void deliver_alarm(void) unsigned long long this_tick = os_nsecs(); int one_tick = UM_NSEC_PER_SEC / UM_HZ; + /* Protection against the host's time going backwards */ + if ((last_tick != 0) && (this_tick < last_tick)) + this_tick = last_tick; + if (last_tick == 0) last_tick = this_tick - one_tick; @@ -148,6 +152,9 @@ static int after_sleep_interval(struct timespec *ts) start_usecs = usec; start_usecs -= skew / UM_NSEC_PER_USEC; + if (start_usecs < 0) + start_usecs = 0; + tv = ((struct timeval) { .tv_sec = start_usecs / UM_USEC_PER_SEC, .tv_usec = start_usecs % UM_USEC_PER_SEC }); interval = ((struct itimerval) { { 0, usec }, tv }); diff --git a/arch/um/sys-x86_64/ksyms.c b/arch/um/sys-x86_64/ksyms.c index 6604673a849..1db2fce0094 100644 --- a/arch/um/sys-x86_64/ksyms.c +++ b/arch/um/sys-x86_64/ksyms.c @@ -3,5 +3,9 @@ #include <asm/checksum.h> /*XXX: we need them because they would be exported by x86_64 */ +#if (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) || __GNUC__ > 4 +EXPORT_SYMBOL(memcpy); +#else EXPORT_SYMBOL(__memcpy); +#endif EXPORT_SYMBOL(csum_partial); |