aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2017-02-16 15:03:28 +0000
committerPeter Maydell <peter.maydell@linaro.org>2017-02-16 15:03:28 +0000
commit7a37b59f1d28e4b4c0f99f49aa305a59986f6643 (patch)
tree42139414172f50fcc579ed4d0ca8c114979530a1
parentca5266de6cde132b647b44a108f6c0c009785fdd (diff)
parent21992cb6794a5f8edb0cee01bdfe0b03d0438dac (diff)
downloadqemu-arm-7a37b59f1d28e4b4c0f99f49aa305a59986f6643.tar.gz
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.c22
-rw-r--r--linux-user/host/s390x/safe-syscall.inc.S2
-rw-r--r--linux-user/ioctls.h5
-rw-r--r--linux-user/m68k/syscall_nr.h3
-rw-r--r--linux-user/mmap.c9
-rw-r--r--linux-user/sh4/syscall_nr.h14
-rw-r--r--linux-user/signal.c5
-rw-r--r--linux-user/strace.c2
-rw-r--r--linux-user/syscall.c26
-rw-r--r--linux-user/syscall_defs.h4
-rw-r--r--linux-user/syscall_types.h6
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 */