Commit 42e76456 authored by Peter Maydell's avatar Peter Maydell
Browse files

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



Fix safe_syscall() on ppc64 host
Fix mmap() 0 length error case

# gpg: Signature made Tue 31 Jul 2018 09:41:07 BST
# gpg:                using RSA key F30C38BD3F2FBE3C
# 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-3.0-pull-request:
  linux-user: ppc64: don't use volatile register during safe_syscall
  tests: add check_invalid_maps to test-mmap
  linux-user/mmap.c: handle invalid len maps correctly

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 45a505d0 5d9f3ea0
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -49,7 +49,9 @@ safe_syscall_base:
	 *               and returns the result in r3
	 * Shuffle everything around appropriately.
	 */
	mr	11, 3	/* signal_pending */
	std     14, 16(1) /* Preserve r14 in SP+16 */
	.cfi_offset 14, 16
	mr	14, 3	/* signal_pending */
	mr	0, 4	/* syscall number */
	mr	3, 5	/* syscall arguments */
	mr	4, 6
@@ -67,12 +69,13 @@ safe_syscall_base:
	 */
safe_syscall_start:
	/* if signal_pending is non-zero, don't do the call */
	lwz	12, 0(11)
	lwz	12, 0(14)
	cmpwi	0, 12, 0
	bne-	0f
	sc
safe_syscall_end:
	/* code path when we did execute the syscall */
	ld 14, 16(1) /* restore r14 to its original value */
	bnslr+

	/* syscall failed; return negative errno */
@@ -81,6 +84,7 @@ safe_syscall_end:

	/* code path when we didn't execute the syscall */
0:	addi	3, 0, -TARGET_ERESTARTSYS
	ld 14, 16(1) /* restore r14 to its orginal value */
	blr
	.cfi_endproc

+12 −3
Original line number Diff line number Diff line
@@ -391,14 +391,23 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
    }
#endif

    if (offset & ~TARGET_PAGE_MASK) {
    if (!len) {
        errno = EINVAL;
        goto fail;
    }

    /* Also check for overflows... */
    len = TARGET_PAGE_ALIGN(len);
    if (len == 0)
        goto the_end;
    if (!len) {
        errno = ENOMEM;
        goto fail;
    }

    if (offset & ~TARGET_PAGE_MASK) {
        errno = EINVAL;
        goto fail;
    }

    real_start = start & qemu_host_page_mask;
    host_offset = offset & qemu_host_page_mask;

+21 −1
Original line number Diff line number Diff line
@@ -27,7 +27,7 @@
#include <stdint.h>
#include <string.h>
#include <unistd.h>

#include <errno.h>
#include <sys/mman.h>

#define D(x)
@@ -435,6 +435,25 @@ void checked_write(int fd, const void *buf, size_t count)
    fail_unless(rc == count);
}

void check_invalid_mmaps(void)
{
    unsigned char *addr;

    /* Attempt to map a zero length page.  */
    addr = mmap(NULL, 0, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    fprintf(stdout, "%s addr=%p", __func__, (void *)addr);
    fail_unless(addr == MAP_FAILED);
    fail_unless(errno == EINVAL);

    /* Attempt to map a over length page.  */
    addr = mmap(NULL, -4, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    fprintf(stdout, "%s addr=%p", __func__, (void *)addr);
    fail_unless(addr == MAP_FAILED);
    fail_unless(errno == ENOMEM);

    fprintf(stdout, " passed\n");
}

int main(int argc, char **argv)
{
	char tempname[] = "/tmp/.cmmapXXXXXX";
@@ -476,6 +495,7 @@ int main(int argc, char **argv)
	check_file_fixed_mmaps();
	check_file_fixed_eof_mmaps();
	check_file_unfixed_eof_mmaps();
	check_invalid_mmaps();

	/* Fails at the moment.  */
	/* check_aligned_anonymous_fixed_mmaps_collide_with_host(); */