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

Merge remote-tracking branch 'remotes/vivier2/tags/linux-user-for-5.0-pull-request' into staging



Fix mmap guest space and brk
Add FS/FD/RTC/KCOV ioctls

# gpg: Signature made Thu 23 Jan 2020 08:21:41 GMT
# gpg:                using RSA key CD2F75DDC8E3A4DC2E4F5173F30C38BD3F2FBE3C
# gpg:                issuer "laurent@vivier.eu"
# gpg: Good signature from "Laurent Vivier <lvivier@redhat.com>" [full]
# gpg:                 aka "Laurent Vivier <laurent@vivier.eu>" [full]
# gpg:                 aka "Laurent Vivier (Red Hat) <lvivier@redhat.com>" [full]
# Primary key fingerprint: CD2F 75DD C8E3 A4DC 2E4F  5173 F30C 38BD 3F2F BE3C

* remotes/vivier2/tags/linux-user-for-5.0-pull-request:
  linux-user: Add support for read/clear RTC voltage low detector using ioctls
  linux-user: Add support for getting/setting RTC PLL correction using ioctls
  linux-user: Add support for getting/setting RTC wakeup alarm using ioctls
  linux-user: Add support for getting/setting RTC periodic interrupt and epoch using ioctls
  linux-user: Add support for getting/setting RTC time and alarm using ioctls
  linux-user: Add support for enabling/disabling RTC features using ioctls
  linux-user: Add support for TYPE_LONG and TYPE_ULONG in do_ioctl()
  linux-user: Add support for KCOV_INIT_TRACE ioctl
  linux-user: Add support for KCOV_<ENABLE|DISABLE> ioctls
  configure: Detect kcov support and introduce CONFIG_KCOV
  linux-user: Add support for FDFMT<BEG|TRK|END> ioctls
  linux-user: Add support for FD<SETEMSGTRESH|SETMAXERRS|GETMAXERRS> ioctls
  linux-user: Add support for FS_IOC32_<GET|SET>VERSION ioctls
  linux-user: Add support for FS_IOC32_<GET|SET>FLAGS ioctls
  linux-user: Add support for FS_IOC_<GET|SET>VERSION ioctls
  linux-user: Reserve space for brk
  linux-user:Fix align mistake when mmap guest space

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 7cea426c a7b09746
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -4761,6 +4761,12 @@ if compile_prog "" "" ; then
  syncfs=yes
fi

# check for kcov support (kernel must be 4.4+, compiled with certain options)
kcov=no
if check_include sys/kcov.h ; then
    kcov=yes
fi

# Check we have a new enough version of sphinx-build
has_sphinx_build() {
    # This is a bit awkward but works: create a trivial document and
@@ -6874,6 +6880,9 @@ fi
if test "$syncfs" = "yes" ; then
  echo "CONFIG_SYNCFS=y" >> $config_host_mak
fi
if test "$kcov" = "yes" ; then
  echo "CONFIG_KCOV=y" >> $config_host_mak
fi
if test "$inotify" = "yes" ; then
  echo "CONFIG_INOTIFY=y" >> $config_host_mak
fi
+57 −18
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@
#include "qemu/path.h"
#include "qemu/queue.h"
#include "qemu/guest-random.h"
#include "qemu/units.h"

#ifdef _ARCH_PPC64
#undef ARCH_DLINFO
@@ -2191,7 +2192,7 @@ unsigned long init_guest_space(unsigned long host_start,
             * to where we need to put the commpage.
             */
            munmap((void *)real_start, host_size);
            real_size = aligned_size + qemu_host_page_size;
            real_size = aligned_size + align;
            real_start = (unsigned long)
                mmap((void *)real_start, real_size, PROT_NONE, flags, -1, 0);
            if (real_start == (unsigned long)-1) {
@@ -2364,25 +2365,52 @@ static void load_elf_image(const char *image_name, int image_fd,
        }
    }

    load_addr = loaddr;
    if (ehdr->e_type == ET_DYN) {
        /* The image indicates that it can be loaded anywhere.  Find a
           location that can hold the memory space required.  If the
           image is pre-linked, LOADDR will be non-zero.  Since we do
           not supply MAP_FIXED here we'll use that address if and
           only if it remains available.  */
    if (pinterp_name != NULL) {
        /*
         * This is the main executable.
         *
         * Reserve extra space for brk.
         * We hold on to this space while placing the interpreter
         * and the stack, lest they be placed immediately after
         * the data segment and block allocation from the brk.
         *
         * 16MB is chosen as "large enough" without being so large
         * as to allow the result to not fit with a 32-bit guest on
         * a 32-bit host.
         */
        info->reserve_brk = 16 * MiB;
        hiaddr += info->reserve_brk;

        if (ehdr->e_type == ET_EXEC) {
            /*
             * Make sure that the low address does not conflict with
             * MMAP_MIN_ADDR or the QEMU application itself.
             */
            probe_guest_base(image_name, loaddr, hiaddr);
        }
    }

    /*
     * Reserve address space for all of this.
     *
     * In the case of ET_EXEC, we supply MAP_FIXED so that we get
     * exactly the address range that is required.
     *
     * Otherwise this is ET_DYN, and we are searching for a location
     * that can hold the memory space required.  If the image is
     * pre-linked, LOADDR will be non-zero, and the kernel should
     * honor that address if it happens to be free.
     *
     * In both cases, we will overwrite pages in this range with mappings
     * from the executable.
     */
    load_addr = target_mmap(loaddr, hiaddr - loaddr, PROT_NONE,
                                MAP_PRIVATE | MAP_ANON | MAP_NORESERVE,
                            MAP_PRIVATE | MAP_ANON | MAP_NORESERVE |
                            (ehdr->e_type == ET_EXEC ? MAP_FIXED : 0),
                            -1, 0);
    if (load_addr == -1) {
        goto exit_perror;
    }
    } else if (pinterp_name != NULL) {
        /* This is the main executable.  Make sure that the low
           address does not conflict with MMAP_MIN_ADDR or the
           QEMU application itself.  */
        probe_guest_base(image_name, loaddr, hiaddr);
    }
    load_bias = load_addr - loaddr;

    if (elf_is_fdpic(ehdr)) {
@@ -2860,6 +2888,17 @@ int load_elf_binary(struct linux_binprm *bprm, struct image_info *info)
    bprm->core_dump = &elf_core_dump;
#endif

    /*
     * If we reserved extra space for brk, release it now.
     * The implementation of do_brk in syscalls.c expects to be able
     * to mmap pages in this space.
     */
    if (info->reserve_brk) {
        abi_ulong start_brk = HOST_PAGE_ALIGN(info->brk);
        abi_ulong end_brk = HOST_PAGE_ALIGN(info->brk + info->reserve_brk);
        target_munmap(start_brk, end_brk - start_brk);
    }

    return 0;
}

+41 −0
Original line number Diff line number Diff line
@@ -69,6 +69,29 @@
     IOCTL(KDSETLED, 0, TYPE_INT)
     IOCTL_SPECIAL(KDSIGACCEPT, 0, do_ioctl_kdsigaccept, TYPE_INT)

     IOCTL(RTC_AIE_ON, 0, TYPE_NULL)
     IOCTL(RTC_AIE_OFF, 0, TYPE_NULL)
     IOCTL(RTC_UIE_ON, 0, TYPE_NULL)
     IOCTL(RTC_UIE_OFF, 0, TYPE_NULL)
     IOCTL(RTC_PIE_ON, 0, TYPE_NULL)
     IOCTL(RTC_PIE_OFF, 0, TYPE_NULL)
     IOCTL(RTC_WIE_ON, 0, TYPE_NULL)
     IOCTL(RTC_WIE_OFF, 0, TYPE_NULL)
     IOCTL(RTC_ALM_READ, IOC_R, MK_PTR(MK_STRUCT(STRUCT_rtc_time)))
     IOCTL(RTC_ALM_SET, IOC_W, MK_PTR(MK_STRUCT(STRUCT_rtc_time)))
     IOCTL(RTC_RD_TIME, IOC_R, MK_PTR(MK_STRUCT(STRUCT_rtc_time)))
     IOCTL(RTC_SET_TIME, IOC_W, MK_PTR(MK_STRUCT(STRUCT_rtc_time)))
     IOCTL(RTC_IRQP_READ, IOC_R, MK_PTR(TYPE_ULONG))
     IOCTL(RTC_IRQP_SET, IOC_W, TYPE_ULONG)
     IOCTL(RTC_EPOCH_READ, IOC_R, MK_PTR(TYPE_ULONG))
     IOCTL(RTC_EPOCH_SET, IOC_W, TYPE_ULONG)
     IOCTL(RTC_WKALM_RD, IOC_R, MK_PTR(MK_STRUCT(STRUCT_rtc_wkalrm)))
     IOCTL(RTC_WKALM_SET, IOC_W, MK_PTR(MK_STRUCT(STRUCT_rtc_wkalrm)))
     IOCTL(RTC_PLL_GET, IOC_R, MK_PTR(MK_STRUCT(STRUCT_rtc_pll_info)))
     IOCTL(RTC_PLL_SET, IOC_W, MK_PTR(MK_STRUCT(STRUCT_rtc_pll_info)))
     IOCTL(RTC_VL_READ, IOC_R, MK_PTR(TYPE_INT))
     IOCTL(RTC_VL_CLR, 0, TYPE_NULL)

     IOCTL(BLKROSET, IOC_W, MK_PTR(TYPE_INT))
     IOCTL(BLKROGET, IOC_R, MK_PTR(TYPE_INT))
     IOCTL(BLKRRPART, 0, TYPE_NULL)
@@ -114,7 +137,13 @@

     IOCTL(FDMSGON, 0, TYPE_NULL)
     IOCTL(FDMSGOFF, 0, TYPE_NULL)
     IOCTL(FDSETEMSGTRESH, 0, TYPE_NULL)
     IOCTL(FDFMTBEG, 0, TYPE_NULL)
     IOCTL(FDFMTTRK, IOC_W, MK_PTR(MK_STRUCT(STRUCT_format_descr)))
     IOCTL(FDFMTEND, 0, TYPE_NULL)
     IOCTL(FDFLUSH, 0, TYPE_NULL)
     IOCTL(FDSETMAXERRS, IOC_W, MK_PTR(MK_STRUCT(STRUCT_floppy_max_errors)))
     IOCTL(FDGETMAXERRS, IOC_R, MK_PTR(MK_STRUCT(STRUCT_floppy_max_errors)))
     IOCTL(FDRESET, 0, TYPE_NULL)
     IOCTL(FDRAWCMD, 0, TYPE_NULL)
     IOCTL(FDTWADDLE, 0, TYPE_NULL)
@@ -138,6 +167,12 @@

     IOCTL(FS_IOC_GETFLAGS, IOC_R, MK_PTR(TYPE_INT))
     IOCTL(FS_IOC_SETFLAGS, IOC_W, MK_PTR(TYPE_INT))
     IOCTL(FS_IOC_GETVERSION, IOC_R, MK_PTR(TYPE_INT))
     IOCTL(FS_IOC_SETVERSION, IOC_W, MK_PTR(TYPE_INT))
     IOCTL(FS_IOC32_GETFLAGS, IOC_R, MK_PTR(TYPE_INT))
     IOCTL(FS_IOC32_SETFLAGS, IOC_W, MK_PTR(TYPE_INT))
     IOCTL(FS_IOC32_GETVERSION, IOC_R, MK_PTR(TYPE_INT))
     IOCTL(FS_IOC32_SETVERSION, IOC_W, MK_PTR(TYPE_INT))

#ifdef CONFIG_USBFS
  /* USB ioctls */
@@ -522,3 +557,9 @@
  IOCTL_IGNORE(TIOCSTART)
  IOCTL_IGNORE(TIOCSTOP)
#endif

#ifdef CONFIG_KCOV
  IOCTL(KCOV_ENABLE, 0, TYPE_NULL)
  IOCTL(KCOV_DISABLE, 0, TYPE_NULL)
  IOCTL(KCOV_INIT_TRACE, IOC_R, TYPE_ULONG)
#endif
+1 −0
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ struct image_info {
        abi_ulong       end_data;
        abi_ulong       start_brk;
        abi_ulong       brk;
        abi_ulong       reserve_brk;
        abi_ulong       start_mmap;
        abi_ulong       start_stack;
        abi_ulong       stack_limit;
+6 −0
Original line number Diff line number Diff line
@@ -73,6 +73,9 @@
#ifdef CONFIG_SENDFILE
#include <sys/sendfile.h>
#endif
#ifdef CONFIG_KCOV
#include <sys/kcov.h>
#endif

#define termios host_termios
#define winsize host_winsize
@@ -107,6 +110,7 @@
#include <netpacket/packet.h>
#include <linux/netlink.h>
#include <linux/if_alg.h>
#include <linux/rtc.h>
#include "linux_loop.h"
#include "uname.h"

@@ -5175,6 +5179,8 @@ static abi_long do_ioctl(int fd, int cmd, abi_long arg)
        break;
    case TYPE_PTRVOID:
    case TYPE_INT:
    case TYPE_LONG:
    case TYPE_ULONG:
        ret = get_errno(safe_ioctl(fd, ie->host_cmd, arg));
        break;
    case TYPE_PTR:
Loading