aboutsummaryrefslogtreecommitdiff
path: root/linux-user
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2021-06-22 16:07:53 +0100
committerPeter Maydell <peter.maydell@linaro.org>2021-06-22 16:07:53 +0100
commitb22726abdfa54592d6ad88f65b0297c0e8b363e2 (patch)
tree32f7589cd877a31509065ff6e2774916b2d3e0a1 /linux-user
parentbf7942e406cb5e96d2490909d2cb31c7625b087b (diff)
parent96ff758c6e9cd5a01443ee15afbd0df4f00c37a8 (diff)
Merge remote-tracking branch 'remotes/vivier2/tags/linux-user-for-6.1-pull-request' into staging
Linux-user pull request 20210621 # gpg: Signature made Mon 21 Jun 2021 12:03:53 BST # 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-6.1-pull-request: linux-user: Use public sigev_notify_thread_id member if available linux-user: Fix incorrect use of feature-test-macros linux-user: Check for ieee128 fpbits in PPC64 HWCAP2 feature list tests/tcg/linux-test: Check that sigaction can query SIGKILL/SIGSTOP linux-user: Let sigaction query SIGKILL/SIGSTOP linux-user: Implement pivot_root linux-user/trace-events: fix minor typo in format string linux-user: Disable static assert involving __SIGRTMAX if it is missing linux-user: Set CF_PARALLEL when mapping shared memory Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'linux-user')
-rw-r--r--linux-user/elfload.c2
-rw-r--r--linux-user/mmap.c14
-rw-r--r--linux-user/signal.c8
-rw-r--r--linux-user/syscall.c46
-rw-r--r--linux-user/trace-events2
5 files changed, 64 insertions, 8 deletions
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 4b0172339e..598ab8aa13 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -830,7 +830,7 @@ static uint32_t get_elf_hwcap2(void)
PPC2_ISA207S), QEMU_PPC_FEATURE2_ARCH_2_07 |
QEMU_PPC_FEATURE2_VEC_CRYPTO);
GET_FEATURE2(PPC2_ISA300, QEMU_PPC_FEATURE2_ARCH_3_00 |
- QEMU_PPC_FEATURE2_DARN);
+ QEMU_PPC_FEATURE2_DARN | QEMU_PPC_FEATURE2_HAS_IEEE128);
#undef GET_FEATURE
#undef GET_FEATURE2
diff --git a/linux-user/mmap.c b/linux-user/mmap.c
index 7e3b245036..0e103859fe 100644
--- a/linux-user/mmap.c
+++ b/linux-user/mmap.c
@@ -451,6 +451,20 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int target_prot,
goto fail;
}
+ /*
+ * If we're mapping shared memory, ensure we generate code for parallel
+ * execution and flush old translations. This will work up to the level
+ * supported by the host -- anything that requires EXCP_ATOMIC will not
+ * be atomic with respect to an external process.
+ */
+ if (flags & MAP_SHARED) {
+ CPUState *cpu = thread_cpu;
+ if (!(cpu->tcg_cflags & CF_PARALLEL)) {
+ cpu->tcg_cflags |= CF_PARALLEL;
+ tb_flush(cpu);
+ }
+ }
+
real_start = start & qemu_host_page_mask;
host_offset = offset & qemu_host_page_mask;
diff --git a/linux-user/signal.c b/linux-user/signal.c
index 9016896dcd..a8faea6f09 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -38,7 +38,9 @@ static void host_signal_handler(int host_signum, siginfo_t *info,
* Signal number 0 is reserved for use as kill(pid, 0), to test whether
* a process exists without sending it a signal.
*/
+#ifdef __SIGRTMAX
QEMU_BUILD_BUG_ON(__SIGRTMAX + 1 != _NSIG);
+#endif
static uint8_t host_to_target_signal_table[_NSIG] = {
[SIGHUP] = TARGET_SIGHUP,
[SIGINT] = TARGET_SIGINT,
@@ -851,7 +853,11 @@ int do_sigaction(int sig, const struct target_sigaction *act,
trace_signal_do_sigaction_guest(sig, TARGET_NSIG);
- if (sig < 1 || sig > TARGET_NSIG || sig == TARGET_SIGKILL || sig == TARGET_SIGSTOP) {
+ if (sig < 1 || sig > TARGET_NSIG) {
+ return -TARGET_EINVAL;
+ }
+
+ if (act && (sig == TARGET_SIGKILL || sig == TARGET_SIGSTOP)) {
return -TARGET_EINVAL;
}
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 974dd46c9a..64bbf331b2 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -4603,6 +4603,7 @@ static inline abi_ulong target_shmlba(CPUArchState *cpu_env)
static inline abi_ulong do_shmat(CPUArchState *cpu_env,
int shmid, abi_ulong shmaddr, int shmflg)
{
+ CPUState *cpu = env_cpu(cpu_env);
abi_long raddr;
void *host_raddr;
struct shmid_ds shm_info;
@@ -4633,6 +4634,17 @@ static inline abi_ulong do_shmat(CPUArchState *cpu_env,
mmap_lock();
+ /*
+ * We're mapping shared memory, so ensure we generate code for parallel
+ * execution and flush old translations. This will work up to the level
+ * supported by the host -- anything that requires EXCP_ATOMIC will not
+ * be atomic with respect to an external process.
+ */
+ if (!(cpu->tcg_cflags & CF_PARALLEL)) {
+ cpu->tcg_cflags |= CF_PARALLEL;
+ tb_flush(cpu);
+ }
+
if (shmaddr)
host_raddr = shmat(shmid, (void *)g2h_untagged(shmaddr), shmflg);
else {
@@ -7393,6 +7405,10 @@ static inline abi_long host_to_target_timex64(abi_long target_addr,
}
#endif
+#ifndef HAVE_SIGEV_NOTIFY_THREAD_ID
+#define sigev_notify_thread_id _sigev_un._tid
+#endif
+
static inline abi_long target_to_host_sigevent(struct sigevent *host_sevp,
abi_ulong target_addr)
{
@@ -7413,7 +7429,7 @@ static inline abi_long target_to_host_sigevent(struct sigevent *host_sevp,
host_sevp->sigev_signo =
target_to_host_signal(tswap32(target_sevp->sigev_signo));
host_sevp->sigev_notify = tswap32(target_sevp->sigev_notify);
- host_sevp->_sigev_un._tid = tswap32(target_sevp->_sigev_un._tid);
+ host_sevp->sigev_notify_thread_id = tswap32(target_sevp->_sigev_un._tid);
unlock_user_struct(target_sevp, target_addr, 1);
return 0;
@@ -7470,7 +7486,7 @@ static inline abi_long host_to_target_stat64(void *cpu_env,
__put_user(host_st->st_atime, &target_st->target_st_atime);
__put_user(host_st->st_mtime, &target_st->target_st_mtime);
__put_user(host_st->st_ctime, &target_st->target_st_ctime);
-#if _POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700
+#ifdef HAVE_STRUCT_STAT_ST_ATIM
__put_user(host_st->st_atim.tv_nsec, &target_st->target_st_atime_nsec);
__put_user(host_st->st_mtim.tv_nsec, &target_st->target_st_mtime_nsec);
__put_user(host_st->st_ctim.tv_nsec, &target_st->target_st_ctime_nsec);
@@ -7505,7 +7521,7 @@ static inline abi_long host_to_target_stat64(void *cpu_env,
__put_user(host_st->st_atime, &target_st->target_st_atime);
__put_user(host_st->st_mtime, &target_st->target_st_mtime);
__put_user(host_st->st_ctime, &target_st->target_st_ctime);
-#if _POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700
+#ifdef HAVE_STRUCT_STAT_ST_ATIM
__put_user(host_st->st_atim.tv_nsec, &target_st->target_st_atime_nsec);
__put_user(host_st->st_mtim.tv_nsec, &target_st->target_st_mtime_nsec);
__put_user(host_st->st_ctim.tv_nsec, &target_st->target_st_ctime_nsec);
@@ -8245,6 +8261,10 @@ static int host_to_target_cpu_mask(const unsigned long *host_mask,
return 0;
}
+#if defined(TARGET_NR_pivot_root) && defined(__NR_pivot_root)
+_syscall2(int, pivot_root, const char *, new_root, const char *, put_old)
+#endif
+
/* This is an internal helper for do_syscall so that it is easier
* to have a single return point, so that actions, such as logging
* of syscall results, can be performed.
@@ -10056,8 +10076,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
__put_user(st.st_atime, &target_st->target_st_atime);
__put_user(st.st_mtime, &target_st->target_st_mtime);
__put_user(st.st_ctime, &target_st->target_st_ctime);
-#if (_POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700) && \
- defined(TARGET_STAT_HAVE_NSEC)
+#if defined(HAVE_STRUCT_STAT_ST_ATIM) && defined(TARGET_STAT_HAVE_NSEC)
__put_user(st.st_atim.tv_nsec,
&target_st->target_st_atime_nsec);
__put_user(st.st_mtim.tv_nsec,
@@ -13208,6 +13227,23 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
return ret;
#endif
+#if defined(TARGET_NR_pivot_root)
+ case TARGET_NR_pivot_root:
+ {
+ void *p2;
+ p = lock_user_string(arg1); /* new_root */
+ p2 = lock_user_string(arg2); /* put_old */
+ if (!p || !p2) {
+ ret = -TARGET_EFAULT;
+ } else {
+ ret = get_errno(pivot_root(p, p2));
+ }
+ unlock_user(p2, arg2, 0);
+ unlock_user(p, arg1, 0);
+ }
+ return ret;
+#endif
+
default:
qemu_log_mask(LOG_UNIMP, "Unsupported syscall: %d\n", num);
return -TARGET_ENOSYS;
diff --git a/linux-user/trace-events b/linux-user/trace-events
index 1ec0d11ee3..e7d2f54e94 100644
--- a/linux-user/trace-events
+++ b/linux-user/trace-events
@@ -11,7 +11,7 @@ user_do_rt_sigreturn(void *env, uint64_t frame_addr) "env=%p frame_addr=0x%"PRIx
user_do_sigreturn(void *env, uint64_t frame_addr) "env=%p frame_addr=0x%"PRIx64
user_force_sig(void *env, int target_sig, int host_sig) "env=%p signal %d (host %d)"
user_handle_signal(void *env, int target_sig) "env=%p signal %d"
-user_host_signal(void *env, int host_sig, int target_sig) "env=%p signal %d (target %d("
+user_host_signal(void *env, int host_sig, int target_sig) "env=%p signal %d (target %d)"
user_queue_signal(void *env, int target_sig) "env=%p signal %d"
user_s390x_restore_sigregs(void *env, uint64_t sc_psw_addr, uint64_t env_psw_addr) "env=%p frame psw.addr 0x%"PRIx64 " current psw.addr 0x%"PRIx64