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 <laur...@vivier.eu> > --- > > 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