From 228168cbb7cc40bfb1621b0b6868c018b522276a Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 11 Jun 2021 23:08:28 -0700 Subject: linux-user: Set CF_PARALLEL when mapping shared memory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signal the translator to use host atomic instructions for guest operations, insofar as it is possible. This is the best we can do to allow the guest to interact atomically with other processes. Resolves: https://gitlab.com/qemu-project/qemu/-/issues/121 Signed-off-by: Richard Henderson Reviewed-by: Alex Bennée Message-Id: <20210612060828.695332-1-richard.henderson@linaro.org> Signed-off-by: Laurent Vivier --- linux-user/syscall.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'linux-user/syscall.c') diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 974dd46c9a..54037db8d6 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 { -- cgit 1.4.1 From e10fbe8f34843891b18f68f76320b43606f4df69 Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Mon, 31 May 2021 14:50:12 +0900 Subject: linux-user: Implement pivot_root Used by runc. Signed-off-by: YAMAMOTO Takashi Reviewed-by: Laurent Vivier Message-Id: <20210531055019.10149-6-yamamoto@midokura.com> Signed-off-by: Laurent Vivier --- linux-user/syscall.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'linux-user/syscall.c') diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 54037db8d6..723cb02d2a 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -8257,6 +8257,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. @@ -13220,6 +13224,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; -- cgit 1.4.1 From febf6fade63801ebca765797fa2ad9de8d9f2700 Mon Sep 17 00:00:00 2001 From: Michael Forney Date: Tue, 25 May 2021 20:55:31 -0700 Subject: linux-user: Fix incorrect use of feature-test-macros The _POSIX_C_SOURCE and _XOPEN_SOURCE macros are used by the application to indicate to libc which declarations it should expose. Since qemu does not define them anywhere, it does not make sense to check their value. Instead, since the intent is to determine whether the host struct stat supports the st_*tim fields, use the configure test result which does exactly that. Signed-off-by: Michael Forney Reviewed-by: Laurent Vivier Message-Id: <20210526035531.7871-1-mforney@mforney.org> Signed-off-by: Laurent Vivier --- linux-user/syscall.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'linux-user/syscall.c') diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 723cb02d2a..70ae8884ee 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -7482,7 +7482,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); @@ -7517,7 +7517,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); @@ -10072,8 +10072,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, -- cgit 1.4.1 From 96ff758c6e9cd5a01443ee15afbd0df4f00c37a8 Mon Sep 17 00:00:00 2001 From: Michael Forney Date: Tue, 25 May 2021 20:55:56 -0700 Subject: linux-user: Use public sigev_notify_thread_id member if available _sigev_un._tid is an internal glibc field and is not available on musl libc. The sigevent(7) man page and Linux UAPI headers both use sigev_notify_thread_id as a public way to access this field. musl libc supports this field since 1.2.2[0], and glibc plans to add support as well[1][2]. If sigev_notify_thread_id is not available, fall back to _sigev_un._tid as before. [0] http://git.musl-libc.org/cgit/musl/commit/?id=7c71792e87691451f2a6b76348e83ad1889f1dcb [1] https://www.openwall.com/lists/musl/2019/08/01/5 [2] https://sourceware.org/bugzilla/show_bug.cgi?id=27417 Signed-off-by: Michael Forney Reviewed-by: Laurent Vivier Message-Id: <20210526035556.7931-1-mforney@mforney.org> Signed-off-by: Laurent Vivier --- configure | 16 ++++++++++++++++ linux-user/syscall.c | 6 +++++- 2 files changed, 21 insertions(+), 1 deletion(-) (limited to 'linux-user/syscall.c') diff --git a/configure b/configure index 8dcb9965b2..942c531cce 100755 --- a/configure +++ b/configure @@ -4440,6 +4440,19 @@ if compile_prog "" "" ; then st_atim=yes fi +########################################## +# check if we have sigev_notify_thread_id + +sigev_notify_thread_id=no +cat > $TMPC << EOF +#include +#include +int main(void) { return offsetof(struct sigevent, sigev_notify_thread_id); } +EOF +if compile_prog "" "" ; then + sigev_notify_thread_id=yes +fi + ########################################## # check if trace backend exists @@ -5692,6 +5705,9 @@ fi if test "$st_atim" = "yes" ; then echo "HAVE_STRUCT_STAT_ST_ATIM=y" >> $config_host_mak fi +if test "$sigev_notify_thread_id" = "yes" ; then + echo "HAVE_SIGEV_NOTIFY_THREAD_ID=y" >> $config_host_mak +fi if test "$byteswap_h" = "yes" ; then echo "CONFIG_BYTESWAP_H=y" >> $config_host_mak fi diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 70ae8884ee..64bbf331b2 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -7405,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) { @@ -7425,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; -- cgit 1.4.1