Browse Source

linux-user patches for qemu v11

-----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQS86RI+GtKfB8BJu973ErUQojoPXwUCaa7PQgAKCRD3ErUQojoP
 X1vmAP9xP/nu9TbgEn/75j6i/Id2vWAC3C5GGRVqFAIvtS7m0AEAor/4t50xQDvC
 yfrc2rGcV3cdoZe1jOlIPNbv6DvHIA4=
 =IkHG
 -----END PGP SIGNATURE-----

Merge tag 'linux-user-for-v11-pull-request' of https://github.com/hdeller/qemu-hppa into staging

linux-user patches for qemu v11

# -----BEGIN PGP SIGNATURE-----
#
# iHUEABYKAB0WIQS86RI+GtKfB8BJu973ErUQojoPXwUCaa7PQgAKCRD3ErUQojoP
# X1vmAP9xP/nu9TbgEn/75j6i/Id2vWAC3C5GGRVqFAIvtS7m0AEAor/4t50xQDvC
# yfrc2rGcV3cdoZe1jOlIPNbv6DvHIA4=
# =IkHG
# -----END PGP SIGNATURE-----
# gpg: Signature made Mon Mar  9 13:46:42 2026 GMT
# gpg:                using EDDSA key BCE9123E1AD29F07C049BBDEF712B510A23A0F5F
# gpg: Good signature from "Helge Deller <deller@gmx.de>" [unknown]
# gpg:                 aka "Helge Deller <deller@kernel.org>" [unknown]
# gpg:                 aka "Helge Deller <deller@debian.org>" [unknown]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 4544 8228 2CD9 10DB EF3D  25F8 3E5F 3D04 A7A2 4603
#      Subkey fingerprint: BCE9 123E 1AD2 9F07 C049  BBDE F712 B510 A23A 0F5F

* tag 'linux-user-for-v11-pull-request' of https://github.com/hdeller/qemu-hppa:
  linux-user: Improve formatting for mremap()
  tests/tcg/multiarch/test-mmap: Check mmaps beyond reserved_va
  tests/tcg/multiarch/test-mmap: Print more details
  bsd-user: Deal with mmap where start > reserved_va
  linux-user: Deal with mmap where start > reserved_va
  linux-user: fix TIOCGSID ioctl
  linux-user: fix matching ioctl numbers in print_ioctl
  linux-user: Check if RESOLVE_CACHED flag is defined before using it
  linux-user: properly check flags in openat2
  linux-user/strace: fix printing of file offsets

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
master
Peter Maydell 3 weeks ago
parent
commit
de61484ec3
  1. 8
      bsd-user/mmap.c
  2. 2
      linux-user/ioctls.h
  3. 9
      linux-user/mmap.c
  4. 51
      linux-user/strace.c
  5. 2
      linux-user/strace.list
  6. 4
      linux-user/syscall.c
  7. 27
      tests/tcg/multiarch/test-mmap.c

8
bsd-user/mmap.c

@ -258,12 +258,14 @@ abi_ulong mmap_next_start = TASK_UNMAPPED_BASE;
static abi_ulong mmap_find_vma_reserved(abi_ulong start, abi_ulong size,
abi_ulong alignment)
{
abi_ulong ret;
abi_ulong ret = -1;
ret = page_find_range_empty(start, reserved_va, size, alignment);
if (start <= reserved_va) {
ret = page_find_range_empty(start, reserved_va, size, alignment);
}
if (ret == -1 && start > TARGET_PAGE_SIZE) {
/* Restart at the beginning of the address space. */
ret = page_find_range_empty(TARGET_PAGE_SIZE, start - 1,
ret = page_find_range_empty(TARGET_PAGE_SIZE, MIN(start - 1, reserved_va),
size, alignment);
}

2
linux-user/ioctls.h

@ -26,7 +26,7 @@
IOCTL(TIOCSCTTY, 0, TYPE_INT)
IOCTL(TIOCGPGRP, IOC_R, MK_PTR(TYPE_INT))
IOCTL(TIOCSPGRP, IOC_W, MK_PTR(TYPE_INT))
IOCTL(TIOCGSID, IOC_W, MK_PTR(TYPE_INT))
IOCTL(TIOCGSID, IOC_R, MK_PTR(TYPE_INT))
IOCTL(TIOCOUTQ, IOC_R, MK_PTR(TYPE_INT))
IOCTL(TIOCSTI, IOC_W, MK_PTR(TYPE_INT))
IOCTL(TIOCMGET, IOC_R, MK_PTR(TYPE_INT))

9
linux-user/mmap.c

@ -423,12 +423,15 @@ abi_ulong mmap_next_start;
static abi_ulong mmap_find_vma_reserved(abi_ulong start, abi_ulong size,
abi_ulong align)
{
target_ulong ret;
target_ulong ret = -1;
ret = page_find_range_empty(start, reserved_va, size, align);
if (start <= reserved_va) {
ret = page_find_range_empty(start, reserved_va, size, align);
}
if (ret == -1 && start > mmap_min_addr) {
/* Restart at the beginning of the address space. */
ret = page_find_range_empty(mmap_min_addr, start - 1, size, align);
ret = page_find_range_empty(mmap_min_addr, MIN(start - 1, reserved_va),
size, align);
}
return ret;

51
linux-user/strace.c

@ -85,6 +85,10 @@ UNUSED static void print_enums(const struct enums *, abi_long, int);
UNUSED static void print_at_dirfd(abi_long, int);
UNUSED static void print_file_mode(abi_long, int);
UNUSED static void print_open_flags(abi_long, int);
UNUSED static void print_file_offset32(abi_long offset, bool last);
UNUSED static void print_file_offset64(abi_long word0,
abi_long word1,
bool last);
UNUSED static void print_syscall_prologue(const struct syscallname *);
UNUSED static void print_syscall_epilogue(const struct syscallname *);
UNUSED static void print_string(abi_long, int);
@ -1017,12 +1021,12 @@ print_syscall_ret_ioctl(CPUArchState *cpu_env, const struct syscallname *name,
int target_size;
for (ie = ioctl_entries; ie->target_cmd != 0; ie++) {
if (ie->target_cmd == arg1) {
if (ie->target_cmd == (int)arg1) {
break;
}
}
if (ie->target_cmd == arg1 &&
if (ie->target_cmd == (int)arg1 &&
(ie->access == IOC_R || ie->access == IOC_RW)) {
arg_type = ie->arg_type;
qemu_log(" (");
@ -1125,7 +1129,9 @@ UNUSED static const struct flags openat2_resolve_flags[] = {
FLAG_GENERIC(RESOLVE_NO_SYMLINKS),
FLAG_GENERIC(RESOLVE_BENEATH),
FLAG_GENERIC(RESOLVE_IN_ROOT),
#ifdef RESOLVE_CACHED
FLAG_GENERIC(RESOLVE_CACHED),
#endif
#endif
FLAG_END,
};
@ -1664,6 +1670,20 @@ print_open_flags(abi_long flags, int last)
print_flags(open_flags, flags, last);
}
/* Prints 32-bit file offset (off_t) */
static void
print_file_offset32(abi_long offset, bool last)
{
print_raw_param(TARGET_ABI_FMT_ld, offset, last);
}
/* Prints 64-bit file offset (loff_t) */
static void
print_file_offset64(abi_long word0, abi_long word1, bool last)
{
print_raw_param64("%" PRId64, target_offset64(word0, word1), last);
}
static void
print_syscall_prologue(const struct syscallname *sc)
{
@ -2256,11 +2276,13 @@ print_fallocate(CPUArchState *cpu_env, const struct syscallname *name,
print_raw_param("%d", arg0, 0);
print_flags(falloc_flags, arg1, 0);
#if TARGET_ABI_BITS == 32
print_raw_param("%" PRIu64, target_offset64(arg2, arg3), 0);
print_raw_param("%" PRIu64, target_offset64(arg4, arg5), 1);
/* On 32-bit targets, two registers are used for `loff_t` */
print_file_offset64(arg2, arg3, false);
print_file_offset64(arg4, arg5, true);
#else
print_raw_param(TARGET_ABI_FMT_ld, arg2, 0);
print_raw_param(TARGET_ABI_FMT_ld, arg3, 1);
/* On 64-bit targets, one register is used for `loff_t` */
print_file_offset64(arg2, 0, false);
print_file_offset64(arg3, 0, true);
#endif
print_syscall_epilogue(name);
}
@ -2666,8 +2688,7 @@ print__llseek(CPUArchState *cpu_env, const struct syscallname *name,
const char *whence = "UNKNOWN";
print_syscall_prologue(name);
print_raw_param("%d", arg0, 0);
print_raw_param("%ld", arg1, 0);
print_raw_param("%ld", arg2, 0);
print_file_offset64(arg1, arg2, false);
print_pointer(arg3, 0);
switch(arg4) {
case SEEK_SET: whence = "SEEK_SET"; break;
@ -2688,7 +2709,7 @@ print_lseek(CPUArchState *cpu_env, const struct syscallname *name,
{
print_syscall_prologue(name);
print_raw_param("%d", arg0, 0);
print_raw_param(TARGET_ABI_FMT_ld, arg1, 0);
print_file_offset32(arg1, false);
switch (arg2) {
case SEEK_SET:
qemu_log("SEEK_SET"); break;
@ -2719,7 +2740,7 @@ print_truncate(CPUArchState *cpu_env, const struct syscallname *name,
{
print_syscall_prologue(name);
print_string(arg0, 0);
print_raw_param(TARGET_ABI_FMT_ld, arg1, 1);
print_file_offset32(arg1, true);
print_syscall_epilogue(name);
}
#endif
@ -2736,7 +2757,7 @@ print_truncate64(CPUArchState *cpu_env, const struct syscallname *name,
arg1 = arg2;
arg2 = arg3;
}
print_raw_param("%" PRIu64, target_offset64(arg1, arg2), 1);
print_file_offset64(arg1, arg2, true);
print_syscall_epilogue(name);
}
#endif
@ -2753,7 +2774,7 @@ print_ftruncate64(CPUArchState *cpu_env, const struct syscallname *name,
arg1 = arg2;
arg2 = arg3;
}
print_raw_param("%" PRIu64, target_offset64(arg1, arg2), 1);
print_file_offset64(arg1, arg2, true);
print_syscall_epilogue(name);
}
#endif
@ -3308,7 +3329,7 @@ print_stat(CPUArchState *cpu_env, const struct syscallname *name,
print_syscall_epilogue(name);
}
#define print_lstat print_stat
#define print_stat64 print_stat
#define print_stat64 print_stat
#define print_lstat64 print_stat
#endif
@ -4302,7 +4323,7 @@ print_pread64(CPUArchState *cpu_env, const struct syscallname *name,
print_raw_param("%d", arg0, 0);
print_pointer(arg1, 0);
print_raw_param("%d", arg2, 0);
print_raw_param("%" PRIu64, target_offset64(arg3, arg4), 1);
print_file_offset64(arg3, arg4, true);
print_syscall_epilogue(name);
}
#endif
@ -4338,7 +4359,7 @@ print_ioctl(CPUArchState *cpu_env, const struct syscallname *name,
int target_size;
for (ie = ioctl_entries; ie->target_cmd != 0; ie++) {
if (ie->target_cmd == arg1) {
if (ie->target_cmd == (int)arg1) {
break;
}
}

2
linux-user/strace.list

@ -641,7 +641,7 @@
{ TARGET_NR_mq_unlink, "mq_unlink" , NULL, print_mq_unlink, NULL },
#endif
#ifdef TARGET_NR_mremap
{ TARGET_NR_mremap, "mremap" , NULL, NULL, NULL },
{ TARGET_NR_mremap, "mremap" , "%s(%#x,%u,%u,%d,%#x)", NULL, NULL },
#endif
#ifdef TARGET_NR_msgctl
{ TARGET_NR_msgctl, "msgctl" , NULL, NULL, NULL },

4
linux-user/syscall.c

@ -8831,6 +8831,10 @@ static int do_openat2(CPUArchState *cpu_env, abi_long dirfd,
}
return ret;
}
if (tswap64(how.flags) >> 32) {
return -TARGET_EINVAL;
}
pathname = lock_user_string(guest_pathname);
if (!pathname) {
return -TARGET_EFAULT;

27
tests/tcg/multiarch/test-mmap.c

@ -442,19 +442,19 @@ void check_invalid_mmaps(void)
/* 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);
fprintf(stdout, "%s addr=%p errno=%d\n", __func__, (void *)addr, errno);
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);
fprintf(stdout, "%s addr=%p errno=%d\n", __func__, (void *)addr, errno);
fail_unless(addr == MAP_FAILED);
fail_unless(errno == ENOMEM);
/* Attempt to remap a region which exceeds the bounds of memory. */
addr = mremap((void *)((uintptr_t)pagesize * 10), SIZE_MAX & ~(size_t)pagemask, pagesize, 0);
fprintf(stdout, "%s mremap addr=%p", __func__, (void *)addr);
fprintf(stdout, "%s mremap addr=%p errno=%d\n", __func__, (void *)addr, errno);
fail_unless(addr == MAP_FAILED);
fail_unless(errno == EFAULT);
@ -465,8 +465,11 @@ void check_shrink_mmaps(void)
{
unsigned char *a, *b, *c;
a = mmap(NULL, pagesize * 2, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
fprintf(stdout, "%s addr=%p errno=%d\n", __func__, (void *)a, errno);
b = mmap(NULL, pagesize * 2, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
fprintf(stdout, "%s addr=%p errno=%d\n", __func__, (void *)b, errno);
c = mmap(NULL, pagesize * 2, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
fprintf(stdout, "%s addr=%p errno=%d\n", __func__, (void *)c, errno);
fail_unless(a != MAP_FAILED);
fail_unless(b != MAP_FAILED);
@ -479,6 +482,7 @@ void check_shrink_mmaps(void)
/* Shrink the middle mapping in-place; the others should be unaffected */
b = mremap(b, pagesize * 2, pagesize, 0);
fprintf(stdout, "%s mremap addr=%p errno=%d\n", __func__, (void *)b, errno);
fail_unless(b != MAP_FAILED);
/* Ensure we can still access all valid mappings */
@ -489,6 +493,22 @@ void check_shrink_mmaps(void)
munmap(a, 2 * pagesize);
munmap(b, pagesize);
munmap(c, 2 * pagesize);
fprintf(stdout, " passed\n");
}
void check_mmaps_beyond_addr_space(void)
{
unsigned char *addr;
addr = mmap((void *)(-(unsigned long)pagesize * 10), pagesize * 2,
PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
fprintf(stdout, "%s addr=%p errno=%d", __func__, (void *)addr, errno);
fail_unless(addr != MAP_FAILED);
memcpy(dummybuf, addr, 2 * pagesize);
munmap(addr, 2 * pagesize);
fprintf(stdout, " passed\n");
}
int main(int argc, char **argv)
@ -534,6 +554,7 @@ int main(int argc, char **argv)
check_file_unfixed_eof_mmaps();
check_invalid_mmaps();
check_shrink_mmaps();
check_mmaps_beyond_addr_space();
/* Fails at the moment. */
/* check_aligned_anonymous_fixed_mmaps_collide_with_host(); */

Loading…
Cancel
Save