diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2017-02-16 15:03:28 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2017-02-16 15:03:28 +0000 |
commit | 7a37b59f1d28e4b4c0f99f49aa305a59986f6643 (patch) | |
tree | 42139414172f50fcc579ed4d0ca8c114979530a1 | |
parent | ca5266de6cde132b647b44a108f6c0c009785fdd (diff) | |
parent | 21992cb6794a5f8edb0cee01bdfe0b03d0438dac (diff) |
Merge remote-tracking branch 'remotes/vivier2/tags/linux-user-for-upstream-pull-request' into staging
# gpg: Signature made Thu 16 Feb 2017 14:35:46 GMT
# gpg: using RSA key 0xF30C38BD3F2FBE3C
# gpg: Good signature from "Laurent Vivier <lvivier@redhat.com>"
# gpg: aka "Laurent Vivier <laurent@vivier.eu>"
# gpg: aka "Laurent Vivier (Red Hat) <lvivier@redhat.com>"
# Primary key fingerprint: CD2F 75DD C8E3 A4DC 2E4F 5173 F30C 38BD 3F2F BE3C
* remotes/vivier2/tags/linux-user-for-upstream-pull-request:
linux-user: Add FICLONE and FICLONERANGE ioctls
linux-user: Use correct types in load_symbols()
linux-user: fill target sigcontext struct accordingly
linux-user: fix tcg/mmap test
linux-user: fix settime old value location
linux-user: Update m68k syscall definitions to match Linux 4.6
linux-user: Update sh4 syscall definitions to match Linux 4.8
linux-user: manage two new IFLA host message types
linux-user: Fix mq_open
linux-user: Fix readahead
linux-user: Fix inotify_init1 support
linux-user: Fix s390x safe-syscall for z900
linux-user: drop __cygwin__ ifdef
linux-user: remove ifdef __USER_MISC
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r-- | linux-user/elfload.c | 22 | ||||
-rw-r--r-- | linux-user/host/s390x/safe-syscall.inc.S | 2 | ||||
-rw-r--r-- | linux-user/ioctls.h | 5 | ||||
-rw-r--r-- | linux-user/m68k/syscall_nr.h | 3 | ||||
-rw-r--r-- | linux-user/mmap.c | 9 | ||||
-rw-r--r-- | linux-user/sh4/syscall_nr.h | 14 | ||||
-rw-r--r-- | linux-user/signal.c | 5 | ||||
-rw-r--r-- | linux-user/strace.c | 2 | ||||
-rw-r--r-- | linux-user/syscall.c | 26 | ||||
-rw-r--r-- | linux-user/syscall_defs.h | 4 | ||||
-rw-r--r-- | linux-user/syscall_types.h | 6 |
11 files changed, 75 insertions, 23 deletions
diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 8271227339..f520d7723c 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -2262,6 +2262,7 @@ static int symcmp(const void *s0, const void *s1) static void load_symbols(struct elfhdr *hdr, int fd, abi_ulong load_bias) { int i, shnum, nsyms, sym_idx = 0, str_idx = 0; + uint64_t segsz; struct elf_shdr *shdr; char *strings = NULL; struct syminfo *s = NULL; @@ -2293,19 +2294,26 @@ static void load_symbols(struct elfhdr *hdr, int fd, abi_ulong load_bias) goto give_up; } - i = shdr[str_idx].sh_size; - s->disas_strtab = strings = g_try_malloc(i); - if (!strings || pread(fd, strings, i, shdr[str_idx].sh_offset) != i) { + segsz = shdr[str_idx].sh_size; + s->disas_strtab = strings = g_try_malloc(segsz); + if (!strings || + pread(fd, strings, segsz, shdr[str_idx].sh_offset) != segsz) { goto give_up; } - i = shdr[sym_idx].sh_size; - syms = g_try_malloc(i); - if (!syms || pread(fd, syms, i, shdr[sym_idx].sh_offset) != i) { + segsz = shdr[sym_idx].sh_size; + syms = g_try_malloc(segsz); + if (!syms || pread(fd, syms, segsz, shdr[sym_idx].sh_offset) != segsz) { goto give_up; } - nsyms = i / sizeof(struct elf_sym); + if (segsz / sizeof(struct elf_sym) > INT_MAX) { + /* Implausibly large symbol table: give up rather than ploughing + * on with the number of symbols calculation overflowing + */ + goto give_up; + } + nsyms = segsz / sizeof(struct elf_sym); for (i = 0; i < nsyms; ) { bswap_sym(syms + i); /* Throw away entries which we do not need. */ diff --git a/linux-user/host/s390x/safe-syscall.inc.S b/linux-user/host/s390x/safe-syscall.inc.S index f1b446abf6..414b44ad38 100644 --- a/linux-user/host/s390x/safe-syscall.inc.S +++ b/linux-user/host/s390x/safe-syscall.inc.S @@ -72,7 +72,7 @@ safe_syscall_base: */ safe_syscall_start: /* if signal_pending is non-zero, don't do the call */ - lt %r0,0(%r8) + icm %r0,15,0(%r8) jne 2f svc 0 safe_syscall_end: diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h index 2f6e85bd78..e6997ff230 100644 --- a/linux-user/ioctls.h +++ b/linux-user/ioctls.h @@ -112,6 +112,11 @@ #ifdef FIBMAP IOCTL(FIBMAP, IOC_W | IOC_R, MK_PTR(TYPE_LONG)) #endif +#ifdef FICLONE + IOCTL(FICLONE, IOC_W, TYPE_INT) + IOCTL(FICLONERANGE, IOC_W, MK_PTR(MK_STRUCT(STRUCT_file_clone_range))) +#endif + #ifdef FIGETBSZ IOCTL(FIGETBSZ, IOC_R, MK_PTR(TYPE_LONG)) #endif diff --git a/linux-user/m68k/syscall_nr.h b/linux-user/m68k/syscall_nr.h index 4b50fb29b6..d239551b34 100644 --- a/linux-user/m68k/syscall_nr.h +++ b/linux-user/m68k/syscall_nr.h @@ -376,3 +376,6 @@ #define TARGET_NR_userfaultfd 373 #define TARGET_NR_membarrier 374 #define TARGET_NR_mlock2 375 +#define TARGET_NR_copy_file_range 376 +#define TARGET_NR_preadv2 377 +#define TARGET_NR_pwritev2 378 diff --git a/linux-user/mmap.c b/linux-user/mmap.c index 61685bf79e..4888f53139 100644 --- a/linux-user/mmap.c +++ b/linux-user/mmap.c @@ -193,9 +193,6 @@ static int mmap_frag(abi_ulong real_start, #if HOST_LONG_BITS == 64 && TARGET_ABI_BITS == 64 # define TASK_UNMAPPED_BASE (1ul << 38) -#elif defined(__CYGWIN__) -/* Cygwin doesn't have a whole lot of address space. */ -# define TASK_UNMAPPED_BASE 0x18000000 #else # define TASK_UNMAPPED_BASE 0x40000000 #endif @@ -429,9 +426,9 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, may need to truncate file maps at EOF and add extra anonymous pages up to the targets page boundary. */ - if ((qemu_real_host_page_size < TARGET_PAGE_SIZE) - && !(flags & MAP_ANONYMOUS)) { - struct stat sb; + if ((qemu_real_host_page_size < qemu_host_page_size) && + !(flags & MAP_ANONYMOUS)) { + struct stat sb; if (fstat (fd, &sb) == -1) goto fail; diff --git a/linux-user/sh4/syscall_nr.h b/linux-user/sh4/syscall_nr.h index e99f73589d..d6c1e059f6 100644 --- a/linux-user/sh4/syscall_nr.h +++ b/linux-user/sh4/syscall_nr.h @@ -372,3 +372,17 @@ #define TARGET_NR_process_vm_writev 366 #define TARGET_NR_kcmp 367 #define TARGET_NR_finit_module 368 +#define TARGET_NR_sched_getattr 369 +#define TARGET_NR_sched_setattr 370 +#define TARGET_NR_renameat2 371 +#define TARGET_NR_seccomp 372 +#define TARGET_NR_getrandom 373 +#define TARGET_NR_memfd_create 374 +#define TARGET_NR_bpf 375 +#define TARGET_NR_execveat 376 +#define TARGET_NR_userfaultfd 377 +#define TARGET_NR_membarrier 378 +#define TARGET_NR_mlock2 379 +#define TARGET_NR_copy_file_range 380 +#define TARGET_NR_preadv2 381 +#define TARGET_NR_pwritev2 382 diff --git a/linux-user/signal.c b/linux-user/signal.c index 5064de0c08..8209539555 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -5155,6 +5155,7 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka, target_ulong rt_sf_addr, newsp = 0; int i, err = 0; #if defined(TARGET_PPC64) + struct target_sigcontext *sc = 0; struct image_info *image = ((TaskState *)thread_cpu->opaque)->info; #endif @@ -5183,6 +5184,10 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka, #if defined(TARGET_PPC64) mctx = &rt_sf->uc.tuc_sigcontext.mcontext; trampptr = &rt_sf->trampoline[0]; + + sc = &rt_sf->uc.tuc_sigcontext; + __put_user(h2g(mctx), &sc->regs); + __put_user(sig, &sc->signal); #else mctx = &rt_sf->uc.tuc_mcontext; trampptr = (uint32_t *)&rt_sf->uc.tuc_mcontext.tramp; diff --git a/linux-user/strace.c b/linux-user/strace.c index 489dbc9583..8fb1b6e252 100644 --- a/linux-user/strace.c +++ b/linux-user/strace.c @@ -90,10 +90,8 @@ if( cmd == val ) { \ output_cmd( IPC_STAT ); output_cmd( IPC_INFO ); /* msgctl() commands */ - #ifdef __USER_MISC output_cmd( MSG_STAT ); output_cmd( MSG_INFO ); - #endif /* shmctl() commands */ output_cmd( SHM_LOCK ); output_cmd( SHM_UNLOCK ); diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 9be8e9530e..f569f827fc 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -2326,6 +2326,8 @@ static abi_long host_to_target_data_link_rtattr(struct rtattr *rtattr) case QEMU_IFLA_GROUP: case QEMU_IFLA_MASTER: case QEMU_IFLA_NUM_VF: + case QEMU_IFLA_GSO_MAX_SEGS: + case QEMU_IFLA_GSO_MAX_SIZE: u32 = RTA_DATA(rtattr); *u32 = tswap32(*u32); break; @@ -11228,7 +11230,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, arg3 = arg4; arg4 = arg5; } - ret = get_errno(readahead(arg1, ((off64_t)arg3 << 32) | arg2, arg4)); + ret = get_errno(readahead(arg1, target_offset64(arg2, arg3) , arg4)); #else ret = get_errno(readahead(arg1, arg2, arg3)); #endif @@ -11561,7 +11563,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #ifdef CONFIG_INOTIFY1 #if defined(TARGET_NR_inotify_init1) && defined(__NR_inotify_init1) case TARGET_NR_inotify_init1: - ret = get_errno(sys_inotify_init1(arg1)); + ret = get_errno(sys_inotify_init1(target_to_host_bitmask(arg1, + fcntl_flags_tbl))); break; #endif #endif @@ -11582,17 +11585,22 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, case TARGET_NR_mq_open: { struct mq_attr posix_mq_attr; + struct mq_attr *pposix_mq_attr; int host_flags; host_flags = target_to_host_bitmask(arg2, fcntl_flags_tbl); - if (copy_from_user_mq_attr(&posix_mq_attr, arg4) != 0) { - goto efault; + pposix_mq_attr = NULL; + if (arg4) { + if (copy_from_user_mq_attr(&posix_mq_attr, arg4) != 0) { + goto efault; + } + pposix_mq_attr = &posix_mq_attr; } p = lock_user_string(arg1 - 1); if (!p) { goto efault; } - ret = get_errno(mq_open(p, host_flags, arg3, &posix_mq_attr)); + ret = get_errno(mq_open(p, host_flags, arg3, pposix_mq_attr)); unlock_user (p, arg1, 0); } break; @@ -12035,10 +12043,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, timer_t htimer = g_posix_timers[timerid]; struct itimerspec hspec_new = {{0},}, hspec_old = {{0},}; - target_to_host_itimerspec(&hspec_new, arg3); + if (target_to_host_itimerspec(&hspec_new, arg3)) { + goto efault; + } ret = get_errno( timer_settime(htimer, arg2, &hspec_new, &hspec_old)); - host_to_target_itimerspec(arg2, &hspec_old); + if (arg4 && host_to_target_itimerspec(arg4, &hspec_old)) { + goto efault; + } } break; } diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index 4442c22bc3..72ca5b11d6 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -1086,6 +1086,10 @@ struct target_pollfd { #define TARGET_FIBMAP TARGET_IO(0x00,1) /* bmap access */ #define TARGET_FIGETBSZ TARGET_IO(0x00,2) /* get the block size used for bmap */ + +#define TARGET_FICLONE TARGET_IOW(0x94, 9, int) +#define TARGET_FICLONERANGE TARGET_IOW(0x94, 13, struct file_clone_range) + /* Note that the ioctl numbers claim type "long" but the actual type * used by the kernel is "int". */ diff --git a/linux-user/syscall_types.h b/linux-user/syscall_types.h index 2b8c0c6df6..24631b09be 100644 --- a/linux-user/syscall_types.h +++ b/linux-user/syscall_types.h @@ -232,6 +232,12 @@ STRUCT(dm_target_versions, STRUCT(dm_target_msg, TYPE_ULONGLONG) /* sector */ +STRUCT(file_clone_range, + TYPE_LONGLONG, /* src_fd */ + TYPE_ULONGLONG, /* src_offset */ + TYPE_ULONGLONG, /* src_length */ + TYPE_ULONGLONG) /* dest_offset */ + STRUCT(fiemap_extent, TYPE_ULONGLONG, /* fe_logical */ TYPE_ULONGLONG, /* fe_physical */ |