Merge tag 'linux-user-for-7.2-pull-request' of https://gitlab.com/laurent_vivier/qemu into staging

linux-user pull request 20220928-v2

use 'max' instead of 'qemu32' / 'qemu64'
add  pidfd_open(), pidfd_send_signal() and pidfd_getfd()
Improve madvise(MADV_DONTNEED)
futex syscal rework
strace improvement
HP/PA fixes and improvement
Misc fixes

# -----BEGIN PGP SIGNATURE-----
#
# iQJGBAABCAAwFiEEzS913cjjpNwuT1Fz8ww4vT8vvjwFAmM0riISHGxhdXJlbnRA
# dml2aWVyLmV1AAoJEPMMOL0/L748gH4P/2wesXJKPMY2zQzP3Rld4iyefoPGG/Yp
# mdq59BbjO2jQMR8GBss/nl9l84cIzzkYRQIogaKsjljtZYm/OO5xRefqrzJY6apD
# eidxv20dAVjuaXHAIdGhbFlxot1ctExbZs9atB4uj5DWxfYGD6e/stoBy5/pSmr4
# M5EbGHhyrRI7tRbHGtVQVvG6AT6XGE0pT9tzT5JLaApF8UPMkgJwmez16PNWvcMm
# v8GEvKm/vEVS8CCpzLV4kfwVeo3f54VAOrEBDi29ph2Yo50IA21k8BvoRZaSp+Kn
# G6TMnnly/DkMspAs5EOVfat+kv3TziNNdDH7EnVU1vV1yTDdZgW/1204Uy/JY0Pw
# WotwAFuO9FYeHKmjY0CfnIIZZHYZpDYUOZ8M6dESD/O0EjoB8LMf5p9cbYlze4DE
# csJZCsVcz19HDv6QZXi5mvvDcJ83B2IDb8/PUAzSc0n62lXL9qjYD0wdb0QsLdAT
# I25qLDge1HCmQfCIKcaoHYvE0pDmvkF6ftuQUXLtIwtaV0Z/N5wDf2PEHikjOYHM
# gD2izz23/2wQx6KP/9ZNnCJ5QEBkEgm5wpHncsvjzSzi1uIdNlHyzJJwGTAcc5qZ
# hOeoJ7dT0D6g0BGnvOdg2W/bDx18KW65mNDxE4d+W0uzn0YmQtArk2YsnhKQNO46
# 12/0ltPFnSV/
# =DIzQ
# -----END PGP SIGNATURE-----
# gpg: Signature made Wed 28 Sep 2022 16:27:14 EDT
# 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

* tag 'linux-user-for-7.2-pull-request' of https://gitlab.com/laurent_vivier/qemu: (37 commits)
  linux-user: Add parameters of getrandom() syscall for strace
  linux-user: Lock log around strace
  linux-user: Update print_futex_op
  linux-user: Implement PI futexes
  linux-user: Convert signal number for FUTEX_FD
  linux-user: Implement FUTEX_WAKE_BITSET
  linux-user: Sink call to do_safe_futex
  linux-user: Combine do_futex and do_futex_time64
  linux-user: Set ELF_BASE_PLATFORM for MIPS
  linux-user: Introduce stubs for ELF AT_BASE_PLATFORM
  linux-user/s390x: Save/restore fpc when handling a signal
  linux-user: Don't assume 0 is not a valid host timer_t value
  linux-user: fix bug about missing signum convert of sigqueue
  linux-user/hppa: Fix setup_sigcontext()
  linux-user/hppa: Allow PROT_GROWSUP and PROT_GROWSDOWN in mprotect()
  linux-user/hppa: Increase guest stack size to 80MB for hppa target
  linux-user/hppa: Drop stack guard page on hppa target
  linux-user/hppa: Add signal trampoline for hppa target
  linux-user: Add proper strace format strings for getdents()/getdents64()
  linux-user: Fix TARGET_PROT_SEM for XTENSA
  ...

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
Stefan Hajnoczi
2022-09-28 17:03:54 -04:00
43 changed files with 795 additions and 260 deletions
+1 -1
View File
@@ -2258,7 +2258,7 @@ int page_get_flags(target_ulong address)
#ifndef PAGE_TARGET_STICKY
#define PAGE_TARGET_STICKY 0
#endif
#define PAGE_STICKY (PAGE_ANON | PAGE_TARGET_STICKY)
#define PAGE_STICKY (PAGE_ANON | PAGE_PASSTHROUGH | PAGE_TARGET_STICKY)
/* Modify the flags of a page and invalidate the code if necessary.
The flag PAGE_WRITE_ORG is positioned automatically depending
+6
View File
@@ -262,6 +262,12 @@ extern const TargetPageBits target_page;
#define PAGE_TARGET_1 0x0200
#define PAGE_TARGET_2 0x0400
/*
* For linux-user, indicates that the page is mapped with the same semantics
* in both guest and host.
*/
#define PAGE_PASSTHROUGH 0x0800
#if defined(CONFIG_USER_ONLY)
void page_dump(FILE *f);
+1
View File
@@ -0,0 +1 @@
#include "../generic/target_mman.h"
+8
View File
@@ -0,0 +1,8 @@
#ifndef ALPHA_TARGET_MMAN_H
#define ALPHA_TARGET_MMAN_H
#define TARGET_MADV_DONTNEED 6
#include "../generic/target_mman.h"
#endif
+1
View File
@@ -0,0 +1 @@
#include "../generic/target_mman.h"
+2
View File
@@ -27,9 +27,11 @@
do { \
CPUState *cs = env_cpu(env); \
fprintf(stderr, fmt , ## __VA_ARGS__); \
fprintf(stderr, "Failing executable: %s\n", exec_path); \
cpu_dump_state(cs, stderr, 0); \
if (qemu_log_separate()) { \
qemu_log(fmt, ## __VA_ARGS__); \
qemu_log("Failing executable: %s\n", exec_path); \
log_cpu_state(cs, 0); \
} \
} while (0)
+1
View File
@@ -0,0 +1 @@
#include "../generic/target_mman.h"
+67 -6
View File
@@ -1080,6 +1080,37 @@ static uint32_t get_elf_hwcap(void)
#define elf_check_abi(x) (!((x) & EF_MIPS_ABI2))
#endif
#define ELF_BASE_PLATFORM get_elf_base_platform()
#define MATCH_PLATFORM_INSN(_flags, _base_platform) \
do { if ((cpu->env.insn_flags & (_flags)) == _flags) \
{ return _base_platform; } } while (0)
static const char *get_elf_base_platform(void)
{
MIPSCPU *cpu = MIPS_CPU(thread_cpu);
/* 64 bit ISAs goes first */
MATCH_PLATFORM_INSN(CPU_MIPS64R6, "mips64r6");
MATCH_PLATFORM_INSN(CPU_MIPS64R5, "mips64r5");
MATCH_PLATFORM_INSN(CPU_MIPS64R2, "mips64r2");
MATCH_PLATFORM_INSN(CPU_MIPS64R1, "mips64");
MATCH_PLATFORM_INSN(CPU_MIPS5, "mips5");
MATCH_PLATFORM_INSN(CPU_MIPS4, "mips4");
MATCH_PLATFORM_INSN(CPU_MIPS3, "mips3");
/* 32 bit ISAs */
MATCH_PLATFORM_INSN(CPU_MIPS32R6, "mips32r6");
MATCH_PLATFORM_INSN(CPU_MIPS32R5, "mips32r5");
MATCH_PLATFORM_INSN(CPU_MIPS32R2, "mips32r2");
MATCH_PLATFORM_INSN(CPU_MIPS32R1, "mips32");
MATCH_PLATFORM_INSN(CPU_MIPS2, "mips2");
/* Fallback */
return "mips";
}
#undef MATCH_PLATFORM_INSN
static inline void init_thread(struct target_pt_regs *regs,
struct image_info *infop)
{
@@ -1776,6 +1807,10 @@ static inline void init_thread(struct target_pt_regs *regs,
#endif /* TARGET_HEXAGON */
#ifndef ELF_BASE_PLATFORM
#define ELF_BASE_PLATFORM (NULL)
#endif
#ifndef ELF_PLATFORM
#define ELF_PLATFORM (NULL)
#endif
@@ -2096,9 +2131,15 @@ static abi_ulong setup_arg_pages(struct linux_binprm *bprm,
if (size < STACK_LOWER_LIMIT) {
size = STACK_LOWER_LIMIT;
}
guard = TARGET_PAGE_SIZE;
if (guard < qemu_real_host_page_size()) {
guard = qemu_real_host_page_size();
if (STACK_GROWS_DOWN) {
guard = TARGET_PAGE_SIZE;
if (guard < qemu_real_host_page_size()) {
guard = qemu_real_host_page_size();
}
} else {
/* no guard page for hppa target where stack grows upwards. */
guard = 0;
}
prot = PROT_READ | PROT_WRITE;
@@ -2118,7 +2159,6 @@ static abi_ulong setup_arg_pages(struct linux_binprm *bprm,
info->stack_limit = error + guard;
return info->stack_limit + size - sizeof(void *);
} else {
target_mprotect(error + size, guard, PROT_NONE);
info->stack_limit = error + size;
return error;
}
@@ -2215,8 +2255,8 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
int i;
abi_ulong u_rand_bytes;
uint8_t k_rand_bytes[16];
abi_ulong u_platform;
const char *k_platform;
abi_ulong u_platform, u_base_platform;
const char *k_platform, *k_base_platform;
const int n = sizeof(elf_addr_t);
sp = p;
@@ -2238,6 +2278,22 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
}
}
u_base_platform = 0;
k_base_platform = ELF_BASE_PLATFORM;
if (k_base_platform) {
size_t len = strlen(k_base_platform) + 1;
if (STACK_GROWS_DOWN) {
sp -= (len + n - 1) & ~(n - 1);
u_base_platform = sp;
/* FIXME - check return value of memcpy_to_target() for failure */
memcpy_to_target(sp, k_base_platform, len);
} else {
memcpy_to_target(sp, k_base_platform, len);
u_base_platform = sp;
sp += len + 1;
}
}
u_platform = 0;
k_platform = ELF_PLATFORM;
if (k_platform) {
@@ -2279,6 +2335,8 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
}
size = (DLINFO_ITEMS + 1) * 2;
if (k_base_platform)
size += 2;
if (k_platform)
size += 2;
#ifdef DLINFO_ARCH_ITEMS
@@ -2356,6 +2414,9 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
NEW_AUX_ENT(AT_HWCAP2, (abi_ulong) ELF_HWCAP2);
#endif
if (u_base_platform) {
NEW_AUX_ENT(AT_BASE_PLATFORM, u_base_platform);
}
if (u_platform) {
NEW_AUX_ENT(AT_PLATFORM, u_platform);
}
+92
View File
@@ -0,0 +1,92 @@
#ifndef LINUX_USER_TARGET_MMAN_H
#define LINUX_USER_TARGET_MMAN_H
#ifndef TARGET_MADV_NORMAL
#define TARGET_MADV_NORMAL 0
#endif
#ifndef TARGET_MADV_RANDOM
#define TARGET_MADV_RANDOM 1
#endif
#ifndef TARGET_MADV_SEQUENTIAL
#define TARGET_MADV_SEQUENTIAL 2
#endif
#ifndef TARGET_MADV_WILLNEED
#define TARGET_MADV_WILLNEED 3
#endif
#ifndef TARGET_MADV_DONTNEED
#define TARGET_MADV_DONTNEED 4
#endif
#ifndef TARGET_MADV_FREE
#define TARGET_MADV_FREE 8
#endif
#ifndef TARGET_MADV_REMOVE
#define TARGET_MADV_REMOVE 9
#endif
#ifndef TARGET_MADV_DONTFORK
#define TARGET_MADV_DONTFORK 10
#endif
#ifndef TARGET_MADV_DOFORK
#define TARGET_MADV_DOFORK 11
#endif
#ifndef TARGET_MADV_MERGEABLE
#define TARGET_MADV_MERGEABLE 12
#endif
#ifndef TARGET_MADV_UNMERGEABLE
#define TARGET_MADV_UNMERGEABLE 13
#endif
#ifndef TARGET_MADV_HUGEPAGE
#define TARGET_MADV_HUGEPAGE 14
#endif
#ifndef TARGET_MADV_NOHUGEPAGE
#define TARGET_MADV_NOHUGEPAGE 15
#endif
#ifndef TARGET_MADV_DONTDUMP
#define TARGET_MADV_DONTDUMP 16
#endif
#ifndef TARGET_MADV_DODUMP
#define TARGET_MADV_DODUMP 17
#endif
#ifndef TARGET_MADV_WIPEONFORK
#define TARGET_MADV_WIPEONFORK 18
#endif
#ifndef TARGET_MADV_KEEPONFORK
#define TARGET_MADV_KEEPONFORK 19
#endif
#ifndef TARGET_MADV_COLD
#define TARGET_MADV_COLD 20
#endif
#ifndef TARGET_MADV_PAGEOUT
#define TARGET_MADV_PAGEOUT 21
#endif
#ifndef TARGET_MADV_POPULATE_READ
#define TARGET_MADV_POPULATE_READ 22
#endif
#ifndef TARGET_MADV_POPULATE_WRITE
#define TARGET_MADV_POPULATE_WRITE 23
#endif
#ifndef TARGET_MADV_DONTNEED_LOCKED
#define TARGET_MADV_DONTNEED_LOCKED 24
#endif
#endif
+1
View File
@@ -0,0 +1 @@
#include "../generic/target_mman.h"
+5 -1
View File
@@ -147,12 +147,15 @@ void cpu_loop(CPUHPPAState *env)
force_sig_fault(TARGET_SIGSEGV, TARGET_SEGV_MAPERR, env->iaoq_f);
break;
case EXCP_ILL:
EXCP_DUMP(env, "qemu: got CPU exception 0x%x - aborting\n", trapnr);
force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLOPN, env->iaoq_f);
break;
case EXCP_PRIV_OPR:
EXCP_DUMP(env, "qemu: got CPU exception 0x%x - aborting\n", trapnr);
force_sig_fault(TARGET_SIGILL, TARGET_ILL_PRVOPC, env->iaoq_f);
break;
case EXCP_PRIV_REG:
EXCP_DUMP(env, "qemu: got CPU exception 0x%x - aborting\n", trapnr);
force_sig_fault(TARGET_SIGILL, TARGET_ILL_PRVREG, env->iaoq_f);
break;
case EXCP_OVERFLOW:
@@ -171,7 +174,8 @@ void cpu_loop(CPUHPPAState *env)
/* just indicate that signals should be handled asap */
break;
default:
g_assert_not_reached();
EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n", trapnr);
abort();
}
process_pending_signals(env);
}
+34 -23
View File
@@ -41,7 +41,7 @@ struct target_ucontext {
};
struct target_rt_sigframe {
abi_uint tramp[9];
abi_uint tramp[2]; /* syscall restart return address */
target_siginfo_t info;
struct target_ucontext uc;
/* hidden location of upper halves of pa2.0 64-bit gregs */
@@ -49,23 +49,13 @@ struct target_rt_sigframe {
static void setup_sigcontext(struct target_sigcontext *sc, CPUArchState *env)
{
int flags = 0;
int i;
/* ??? if on_sig_stack, flags |= 1 (PARISC_SC_FLAG_ONSTACK). */
if (env->iaoq_f < TARGET_PAGE_SIZE) {
/* In the gateway page, executing a syscall. */
flags |= 2; /* PARISC_SC_FLAG_IN_SYSCALL */
__put_user(env->gr[31], &sc->sc_iaoq[0]);
__put_user(env->gr[31] + 4, &sc->sc_iaoq[1]);
} else {
__put_user(env->iaoq_f, &sc->sc_iaoq[0]);
__put_user(env->iaoq_b, &sc->sc_iaoq[1]);
}
__put_user(env->iaoq_f, &sc->sc_iaoq[0]);
__put_user(env->iaoq_b, &sc->sc_iaoq[1]);
__put_user(0, &sc->sc_iasq[0]);
__put_user(0, &sc->sc_iasq[1]);
__put_user(flags, &sc->sc_flags);
__put_user(0, &sc->sc_flags);
__put_user(cpu_hppa_get_psw(env), &sc->sc_gr[0]);
for (i = 1; i < 32; ++i) {
@@ -101,9 +91,15 @@ static void restore_sigcontext(CPUArchState *env, struct target_sigcontext *sc)
__get_user(env->cr[CR_SAR], &sc->sc_sar);
}
/* No, this doesn't look right, but it's copied straight from the kernel. */
#if TARGET_ABI_BITS == 32
#define SIGFRAME 64
#define FUNCTIONCALLFRAME 48
#else
#define SIGFRAME 128
#define FUNCTIONCALLFRAME 96
#endif
#define PARISC_RT_SIGFRAME_SIZE32 \
((sizeof(struct target_rt_sigframe) + 48 + 64) & -64)
((sizeof(struct target_rt_sigframe) + FUNCTIONCALLFRAME + SIGFRAME) & -SIGFRAME)
void setup_rt_frame(int sig, struct target_sigaction *ka,
target_siginfo_t *info,
@@ -118,7 +114,7 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
if ((ka->sa_flags & TARGET_SA_ONSTACK) && !sas_ss_flags(sp)) {
sp = (ts->sigaltstack_used.ss_sp + 0x7f) & ~0x3f;
}
frame_addr = QEMU_ALIGN_UP(sp, 64);
frame_addr = QEMU_ALIGN_UP(sp, SIGFRAME);
sp = frame_addr + PARISC_RT_SIGFRAME_SIZE32;
trace_user_setup_rt_frame(env, frame_addr);
@@ -139,14 +135,9 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
setup_sigcontext(&frame->uc.tuc_mcontext, env);
__put_user(0x34190000, frame->tramp + 0); /* ldi 0,%r25 */
__put_user(0x3414015a, frame->tramp + 1); /* ldi __NR_rt_sigreturn,%r20 */
__put_user(0xe4008200, frame->tramp + 2); /* be,l 0x100(%sr2,%r0) */
__put_user(0x08000240, frame->tramp + 3); /* nop */
unlock_user_struct(frame, frame_addr, 1);
env->gr[2] = h2g(frame->tramp);
env->gr[2] = default_rt_sigreturn;
env->gr[30] = sp;
env->gr[26] = sig;
env->gr[25] = h2g(&frame->info);
@@ -197,3 +188,23 @@ long do_rt_sigreturn(CPUArchState *env)
force_sig(TARGET_SIGSEGV);
return -QEMU_ESIGRETURN;
}
void setup_sigtramp(abi_ulong sigtramp_page)
{
uint32_t *tramp = lock_user(VERIFY_WRITE, sigtramp_page, 6*4, 0);
abi_ulong SIGFRAME_CONTEXT_REGS32;
assert(tramp != NULL);
SIGFRAME_CONTEXT_REGS32 = offsetof(struct target_rt_sigframe, uc.tuc_mcontext);
SIGFRAME_CONTEXT_REGS32 -= PARISC_RT_SIGFRAME_SIZE32;
__put_user(SIGFRAME_CONTEXT_REGS32, tramp + 0);
__put_user(0x08000240, tramp + 1); /* nop - b/c dwarf2 unwind routines */
__put_user(0x34190000, tramp + 2); /* ldi 0, %r25 (in_syscall=0) */
__put_user(0x3414015a, tramp + 3); /* ldi __NR_rt_sigreturn, %r20 */
__put_user(0xe4008200, tramp + 4); /* ble 0x100(%sr2, %r0) */
__put_user(0x08000240, tramp + 5); /* nop */
default_rt_sigreturn = (sigtramp_page + 8) | 3;
unlock_user(tramp, sigtramp_page, 6*4);
}
+15
View File
@@ -0,0 +1,15 @@
#ifndef HPPA_TARGET_MMAN_H
#define HPPA_TARGET_MMAN_H
#define TARGET_MADV_MERGEABLE 65
#define TARGET_MADV_UNMERGEABLE 66
#define TARGET_MADV_HUGEPAGE 67
#define TARGET_MADV_NOHUGEPAGE 68
#define TARGET_MADV_DONTDUMP 69
#define TARGET_MADV_DODUMP 70
#define TARGET_MADV_WIPEONFORK 71
#define TARGET_MADV_KEEPONFORK 72
#include "../generic/target_mman.h"
#endif
+1 -13
View File
@@ -70,18 +70,6 @@ typedef struct target_sigaltstack {
/* mask for all SS_xxx flags */
#define TARGET_SS_FLAG_BITS TARGET_SS_AUTODISARM
/*
* We cannot use a bare sigtramp page for hppa-linux.
*
* Unlike other guests where we use the instructions at PC to validate
* an offset from SP, the hppa libgcc signal frame fallback unwinding uses
* the PC address itself to find the frame. This is due to the fact that
* the hppa grows the stack upward, and the frame is of unknown size.
*
* TODO: We should be able to use a VDSO to address this, by providing
* proper unwind info for the sigtramp code, at which point the fallback
* unwinder will not be used.
*/
#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 0
#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1
#endif /* HPPA_TARGET_SIGNAL_H */
+2
View File
@@ -26,4 +26,6 @@ struct target_pt_regs {
#define TARGET_MCL_FUTURE 2
#define TARGET_MCL_ONFAULT 4
#define TARGET_DEFAULT_STACK_SIZE 80 * 1024 * 1024UL
#endif /* HPPA_TARGET_SYSCALL_H */
+1 -1
View File
@@ -9,6 +9,6 @@
#define I386_TARGET_ELF_H
static inline const char *cpu_get_model(uint32_t eflags)
{
return "qemu32";
return "max";
}
#endif
+1
View File
@@ -0,0 +1 @@
#include "../generic/target_mman.h"
+1
View File
@@ -0,0 +1 @@
#include "../generic/target_mman.h"
+1
View File
@@ -0,0 +1 @@
#include "../generic/target_mman.h"
+7 -2
View File
@@ -124,10 +124,14 @@ static void usage(int exitcode);
static const char *interp_prefix = CONFIG_QEMU_INTERP_PREFIX;
const char *qemu_uname_release;
#if !defined(TARGET_DEFAULT_STACK_SIZE)
/* XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so
we allocate a bigger stack. Need a better solution, for example
by remapping the process stack directly at the right place */
unsigned long guest_stack_size = 8 * 1024 * 1024UL;
#define TARGET_DEFAULT_STACK_SIZE 8 * 1024 * 1024UL
#endif
unsigned long guest_stack_size = TARGET_DEFAULT_STACK_SIZE;
/***********************************************************/
/* Helper routines for implementing atomic operations. */
@@ -668,7 +672,8 @@ int main(int argc, char **argv, char **envp)
struct rlimit lim;
if (getrlimit(RLIMIT_STACK, &lim) == 0
&& lim.rlim_cur != RLIM_INFINITY
&& lim.rlim_cur == (target_long)lim.rlim_cur) {
&& lim.rlim_cur == (target_long)lim.rlim_cur
&& lim.rlim_cur > guest_stack_size) {
guest_stack_size = lim.rlim_cur;
}
}

Some files were not shown because too many files have changed in this diff Show More