提交 42e76456 编写于 作者: P Peter Maydell

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: NPeter Maydell <peter.maydell@linaro.org>
......@@ -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
......
......@@ -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;
......
......@@ -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(); */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册