qemu-devel
[Top][All Lists]
Advanced

[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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]