Commit b6011bd8 authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/riku/tags/pull-linux-user-20141006-2' into staging



linux-user pull for 2.2

Clearest linux-user patches sent to the list since august,
Apart from Mikhails patch, the rest are quite trivial.

v2: check for CONFIG_TIMERFD only after it has been defined

# gpg: Signature made Mon 06 Oct 2014 20:08:10 BST using RSA key ID DE3C9BC0
# gpg: Good signature from "Riku Voipio <riku.voipio@iki.fi>"
# gpg:                 aka "Riku Voipio <riku.voipio@linaro.org>"

* remotes/riku/tags/pull-linux-user-20141006-2:
  translate-all.c: memory walker initial address miscalculation
  linux-user: don't include timerfd if not needed
  linux-user: Simplify timerid checks on g_posix_timers range
  linux-user: Convert blkpg to use a special subop handler
  linux-user: Enable epoll_pwait syscall for ARM

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 2472b6c0 1a1c4db9
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -232,8 +232,8 @@ extern uintptr_t qemu_host_page_mask;
#if defined(CONFIG_USER_ONLY)
void page_dump(FILE *f);

typedef int (*walk_memory_regions_fn)(void *, abi_ulong,
                                      abi_ulong, unsigned long);
typedef int (*walk_memory_regions_fn)(void *, target_ulong,
                                      target_ulong, unsigned long);
int walk_memory_regions(void *, walk_memory_regions_fn);

int page_get_flags(target_ulong address);
+1 −1
Original line number Diff line number Diff line
@@ -350,7 +350,7 @@
#define TARGET_NR_vmsplice			(343)
#define TARGET_NR_move_pages			(344)
#define TARGET_NR_getcpu			(345)
					/* 346 for epoll_pwait */
#define TARGET_NR_epoll_pwait                   (346)
#define TARGET_NR_kexec_load			(347)
#define TARGET_NR_utimensat			(348)
#define TARGET_NR_signalfd			(349)
+9 −9
Original line number Diff line number Diff line
@@ -2355,8 +2355,8 @@ struct elf_note_info {
};

struct vm_area_struct {
    abi_ulong   vma_start;  /* start vaddr of memory region */
    abi_ulong   vma_end;    /* end vaddr of memory region */
    target_ulong   vma_start;  /* start vaddr of memory region */
    target_ulong   vma_end;    /* end vaddr of memory region */
    abi_ulong      vma_flags;  /* protection etc. flags for the region */
    QTAILQ_ENTRY(vm_area_struct) vma_link;
};
@@ -2368,13 +2368,13 @@ struct mm_struct {

static struct mm_struct *vma_init(void);
static void vma_delete(struct mm_struct *);
static int vma_add_mapping(struct mm_struct *, abi_ulong,
                           abi_ulong, abi_ulong);
static int vma_add_mapping(struct mm_struct *, target_ulong,
                           target_ulong, abi_ulong);
static int vma_get_mapping_count(const struct mm_struct *);
static struct vm_area_struct *vma_first(const struct mm_struct *);
static struct vm_area_struct *vma_next(struct vm_area_struct *);
static abi_ulong vma_dump_size(const struct vm_area_struct *);
static int vma_walker(void *priv, abi_ulong start, abi_ulong end,
static int vma_walker(void *priv, target_ulong start, target_ulong end,
                      unsigned long flags);

static void fill_elf_header(struct elfhdr *, int, uint16_t, uint32_t);
@@ -2466,8 +2466,8 @@ static void vma_delete(struct mm_struct *mm)
    g_free(mm);
}

static int vma_add_mapping(struct mm_struct *mm, abi_ulong start,
                           abi_ulong end, abi_ulong flags)
static int vma_add_mapping(struct mm_struct *mm, target_ulong start,
                           target_ulong end, abi_ulong flags)
{
    struct vm_area_struct *vma;

@@ -2535,7 +2535,7 @@ static abi_ulong vma_dump_size(const struct vm_area_struct *vma)
    return (vma->vma_end - vma->vma_start);
}

static int vma_walker(void *priv, abi_ulong start, abi_ulong end,
static int vma_walker(void *priv, target_ulong start, target_ulong end,
                      unsigned long flags)
{
    struct mm_struct *mm = (struct mm_struct *)priv;
+2 −1
Original line number Diff line number Diff line
@@ -78,7 +78,8 @@
     IOCTL(BLKRAGET, IOC_R, MK_PTR(TYPE_LONG))
     IOCTL(BLKSSZGET, IOC_R, MK_PTR(TYPE_LONG))
     IOCTL(BLKBSZGET, IOC_R, MK_PTR(TYPE_INT))
     IOCTL(BLKPG, IOC_W, MK_PTR(MK_STRUCT(STRUCT_blkpg_ioctl_arg)))
     IOCTL_SPECIAL(BLKPG, IOC_W, do_ioctl_blkpg,
                   MK_PTR(MK_STRUCT(STRUCT_blkpg_ioctl_arg)))
#ifdef FIBMAP
     IOCTL(FIBMAP, IOC_W | IOC_R, MK_PTR(TYPE_LONG))
#endif
+73 −14
Original line number Diff line number Diff line
@@ -58,7 +58,6 @@ int __clone2(int (*fn)(void *), void *child_stack_base,
#include <sys/shm.h>
#include <sys/sem.h>
#include <sys/statfs.h>
#include <sys/timerfd.h>
#include <utime.h>
#include <sys/sysinfo.h>
//#include <sys/user.h>
@@ -67,6 +66,9 @@ int __clone2(int (*fn)(void *), void *child_stack_base,
#include <linux/wireless.h>
#include <linux/icmp.h>
#include "qemu-common.h"
#ifdef CONFIG_TIMERFD
#include <sys/timerfd.h>
#endif
#ifdef TARGET_GPROF
#include <sys/gmon.h>
#endif
@@ -3696,6 +3698,59 @@ out:
    return ret;
}

static abi_long do_ioctl_blkpg(const IOCTLEntry *ie, uint8_t *buf_temp, int fd,
                               abi_long cmd, abi_long arg)
{
    void *argptr;
    int target_size;
    const argtype *arg_type = ie->arg_type;
    const argtype part_arg_type[] = { MK_STRUCT(STRUCT_blkpg_partition) };
    abi_long ret;

    struct blkpg_ioctl_arg *host_blkpg = (void*)buf_temp;
    struct blkpg_partition host_part;

    /* Read and convert blkpg */
    arg_type++;
    target_size = thunk_type_size(arg_type, 0);
    argptr = lock_user(VERIFY_READ, arg, target_size, 1);
    if (!argptr) {
        ret = -TARGET_EFAULT;
        goto out;
    }
    thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
    unlock_user(argptr, arg, 0);

    switch (host_blkpg->op) {
    case BLKPG_ADD_PARTITION:
    case BLKPG_DEL_PARTITION:
        /* payload is struct blkpg_partition */
        break;
    default:
        /* Unknown opcode */
        ret = -TARGET_EINVAL;
        goto out;
    }

    /* Read and convert blkpg->data */
    arg = (abi_long)(uintptr_t)host_blkpg->data;
    target_size = thunk_type_size(part_arg_type, 0);
    argptr = lock_user(VERIFY_READ, arg, target_size, 1);
    if (!argptr) {
        ret = -TARGET_EFAULT;
        goto out;
    }
    thunk_convert(&host_part, argptr, part_arg_type, THUNK_HOST);
    unlock_user(argptr, arg, 0);

    /* Swizzle the data pointer to our local copy and call! */
    host_blkpg->data = &host_part;
    ret = get_errno(ioctl(fd, ie->host_cmd, host_blkpg));

out:
    return ret;
}

static abi_long do_ioctl_rt(const IOCTLEntry *ie, uint8_t *buf_temp,
                                int fd, abi_long cmd, abi_long arg)
{
@@ -9562,11 +9617,12 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
    {
        /* args: timer_t timerid, int flags, const struct itimerspec *new_value,
         * struct itimerspec * old_value */
        arg1 &= 0xffff;
        if (arg3 == 0 || arg1 < 0 || arg1 >= ARRAY_SIZE(g_posix_timers)) {
        target_ulong timerid = arg1;

        if (arg3 == 0 || timerid >= ARRAY_SIZE(g_posix_timers)) {
            ret = -TARGET_EINVAL;
        } else {
            timer_t htimer = g_posix_timers[arg1];
            timer_t htimer = g_posix_timers[timerid];
            struct itimerspec hspec_new = {{0},}, hspec_old = {{0},};

            target_to_host_itimerspec(&hspec_new, arg3);
@@ -9582,13 +9638,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
    case TARGET_NR_timer_gettime:
    {
        /* args: timer_t timerid, struct itimerspec *curr_value */
        arg1 &= 0xffff;
        target_ulong timerid = arg1;

        if (!arg2) {
            return -TARGET_EFAULT;
        } else if (arg1 < 0 || arg1 >= ARRAY_SIZE(g_posix_timers)) {
        } else if (timerid >= ARRAY_SIZE(g_posix_timers)) {
            ret = -TARGET_EINVAL;
        } else {
            timer_t htimer = g_posix_timers[arg1];
            timer_t htimer = g_posix_timers[timerid];
            struct itimerspec hspec;
            ret = get_errno(timer_gettime(htimer, &hspec));

@@ -9604,11 +9661,12 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
    case TARGET_NR_timer_getoverrun:
    {
        /* args: timer_t timerid */
        arg1 &= 0xffff;
        if (arg1 < 0 || arg1 >= ARRAY_SIZE(g_posix_timers)) {
        target_ulong timerid = arg1;

        if (timerid >= ARRAY_SIZE(g_posix_timers)) {
            ret = -TARGET_EINVAL;
        } else {
            timer_t htimer = g_posix_timers[arg1];
            timer_t htimer = g_posix_timers[timerid];
            ret = get_errno(timer_getoverrun(htimer));
        }
        break;
@@ -9619,13 +9677,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
    case TARGET_NR_timer_delete:
    {
        /* args: timer_t timerid */
        arg1 &= 0xffff;
        if (arg1 < 0 || arg1 >= ARRAY_SIZE(g_posix_timers)) {
        target_ulong timerid = arg1;

        if (timerid >= ARRAY_SIZE(g_posix_timers)) {
            ret = -TARGET_EINVAL;
        } else {
            timer_t htimer = g_posix_timers[arg1];
            timer_t htimer = g_posix_timers[timerid];
            ret = get_errno(timer_delete(htimer));
            g_posix_timers[arg1] = 0;
            g_posix_timers[timerid] = 0;
        }
        break;
    }
Loading