[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v2] linux-user: emulate msgsnd(), msgrcv() and s
From: |
Laurent Vivier |
Subject: |
Re: [Qemu-devel] [PATCH v2] linux-user: emulate msgsnd(), msgrcv() and semtimedop() |
Date: |
Mon, 24 Jun 2019 23:00:54 +0200 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.7.0 |
Le 29/05/2019 à 10:48, Laurent Vivier a écrit :
> When we have updated kernel headers to 5.2-rc1 we have introduced
> new syscall numbers that can be not supported by older kernels
> and fail with ENOSYS while the guest emulation succeeded before
> because the syscalls were emulated with ipc().
>
> This patch fixes the problem by using ipc() if the new syscall
> returns ENOSYS.
>
> Fixes: 86e636951ddc ("linux-user: fix __NR_semtimedop undeclared error")
> Signed-off-by: Laurent Vivier <address@hidden>
> ---
>
> Notes:
> v2: replace ENOSYS by TARGET_ENOSYS
>
> linux-user/syscall.c | 61 +++++++++++++++++++--------------------
> linux-user/syscall_defs.h | 1 +
> 2 files changed, 31 insertions(+), 31 deletions(-)
>
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 5e29e675e9cf..9ecbac463385 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -763,50 +763,21 @@ safe_syscall2(int, nanosleep, const struct timespec *,
> req,
> safe_syscall4(int, clock_nanosleep, const clockid_t, clock, int, flags,
> const struct timespec *, req, struct timespec *, rem)
> #endif
> -#if !defined(__NR_msgsnd) || !defined(__NR_msgrcv) ||
> !defined(__NR_semtimedop)
> -/* This host kernel architecture uses a single ipc syscall; fake up
> - * wrappers for the sub-operations to hide this implementation detail.
> - * Annoyingly we can't include linux/ipc.h to get the constant definitions
> - * for the call parameter because some structs in there conflict with the
> - * sys/ipc.h ones. So we just define them here, and rely on them being
> - * the same for all host architectures.
> - */
> -#define Q_SEMTIMEDOP 4
> -#define Q_MSGSND 11
> -#define Q_MSGRCV 12
> -#define Q_IPCCALL(VERSION, OP) ((VERSION) << 16 | (OP))
> -
> +#ifdef __NR_ipc
> safe_syscall6(int, ipc, int, call, long, first, long, second, long, third,
> void *, ptr, long, fifth)
> #endif
> #ifdef __NR_msgsnd
> safe_syscall4(int, msgsnd, int, msgid, const void *, msgp, size_t, sz,
> int, flags)
> -#else
> -static int safe_msgsnd(int msgid, const void *msgp, size_t sz, int flags)
> -{
> - return safe_ipc(Q_IPCCALL(0, Q_MSGSND), msgid, sz, flags, (void *)msgp,
> 0);
> -}
> #endif
> #ifdef __NR_msgrcv
> safe_syscall5(int, msgrcv, int, msgid, void *, msgp, size_t, sz,
> long, msgtype, int, flags)
> -#else
> -static int safe_msgrcv(int msgid, void *msgp, size_t sz, long type, int
> flags)
> -{
> - return safe_ipc(Q_IPCCALL(1, Q_MSGRCV), msgid, sz, flags, msgp, type);
> -}
> #endif
> #ifdef __NR_semtimedop
> safe_syscall4(int, semtimedop, int, semid, struct sembuf *, tsops,
> unsigned, nsops, const struct timespec *, timeout)
> -#else
> -static int safe_semtimedop(int semid, struct sembuf *tsops, unsigned nsops,
> - const struct timespec *timeout)
> -{
> - return safe_ipc(Q_IPCCALL(0, Q_SEMTIMEDOP), semid, nsops, 0, tsops,
> - (long)timeout);
> -}
> #endif
> #if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
> safe_syscall5(int, mq_timedsend, int, mqdes, const char *, msg_ptr,
> @@ -3530,11 +3501,21 @@ static inline abi_long target_to_host_sembuf(struct
> sembuf *host_sembuf,
> static inline abi_long do_semop(int semid, abi_long ptr, unsigned nsops)
> {
> struct sembuf sops[nsops];
> + abi_long ret;
>
> if (target_to_host_sembuf(sops, ptr, nsops))
> return -TARGET_EFAULT;
>
> - return get_errno(safe_semtimedop(semid, sops, nsops, NULL));
> + ret = -TARGET_ENOSYS;
> +#ifdef __NR_semtimedop
> + ret = get_errno(safe_semtimedop(semid, sops, nsops, NULL));
> +#endif
> +#ifdef __NR_ipc
> + if (ret == -TARGET_ENOSYS) {
> + ret = get_errno(safe_ipc(IPCOP_semtimedop, semid, nsops, 0, sops,
> 0));
> + }
> +#endif
> + return ret;
> }
>
> struct target_msqid_ds
> @@ -3689,7 +3670,16 @@ static inline abi_long do_msgsnd(int msqid, abi_long
> msgp,
> }
> host_mb->mtype = (abi_long) tswapal(target_mb->mtype);
> memcpy(host_mb->mtext, target_mb->mtext, msgsz);
> + ret = -TARGET_ENOSYS;
> +#ifdef __NR_msgsnd
> ret = get_errno(safe_msgsnd(msqid, host_mb, msgsz, msgflg));
> +#endif
> +#ifdef __NR_ipc
> + if (ret == -TARGET_ENOSYS) {
> + ret = get_errno(safe_ipc(IPCOP_msgsnd, msqid, msgsz, msgflg,
> + host_mb, 0));
> + }
> +#endif
> g_free(host_mb);
> unlock_user_struct(target_mb, msgp, 0);
>
> @@ -3717,7 +3707,16 @@ static inline abi_long do_msgrcv(int msqid, abi_long
> msgp,
> ret = -TARGET_ENOMEM;
> goto end;
> }
> + ret = -TARGET_ENOSYS;
> +#ifdef __NR_msgrcv
> ret = get_errno(safe_msgrcv(msqid, host_mb, msgsz, msgtyp, msgflg));
> +#endif
> +#ifdef __NR_ipc
> + if (ret == -TARGET_ENOSYS) {
> + ret = get_errno(safe_ipc(IPCOP_CALL(1, IPCOP_msgrcv), msqid, msgsz,
> + msgflg, host_mb, msgtyp));
> + }
> +#endif
>
> if (ret > 0) {
> abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
> diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
> index 7f141f699c1a..3175440e9dd9 100644
> --- a/linux-user/syscall_defs.h
> +++ b/linux-user/syscall_defs.h
> @@ -32,6 +32,7 @@
> #define TARGET_SYS_RECVMMSG 19 /* recvmmsg() */
> #define TARGET_SYS_SENDMMSG 20 /* sendmmsg() */
>
> +#define IPCOP_CALL(VERSION, OP) ((VERSION) << 16 | (OP))
> #define IPCOP_semop 1
> #define IPCOP_semget 2
> #define IPCOP_semctl 3
>
Applied to my linux-user branch.
Thanks,
Laurent
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Re: [Qemu-devel] [PATCH v2] linux-user: emulate msgsnd(), msgrcv() and semtimedop(),
Laurent Vivier <=