diff --git a/src/kernel_abi.h b/src/kernel_abi.h index ce7704b228f..744623f9746 100644 --- a/src/kernel_abi.h +++ b/src/kernel_abi.h @@ -1666,6 +1666,55 @@ struct BaseArch : public wordsize, ptr r_map; // More fields we don't need (and are potentially libc specific) }; + + /* Based on: + * - https://github.com/linux-rdma/rdma-core/blob/e336086ec6649fbcace511b54419dcac0ae040b7/libibverbs/cmd_ioctl.h + * - https://github.com/torvalds/linux/blob/494c5580aa6721874a6d9d62dac1c94e83e79302/include/uapi/rdma/rdma_user_ioctl_cmds.h + * + * TODO: Is it possible to use `using` to expose kernel structs in this namespace? + */ + struct ib_uverbs_attr { + uint16_t attr_id; /* command specific type attribute */ + uint16_t len; /* only for pointers and IDRs array */ + uint16_t flags; /* combination of UVERBS_ATTR_F_XXXX */ + union { + struct { + uint8_t elem_id; + uint8_t reserved; + } enum_data; + uint16_t reserved; + } attr_data; + union { + /* + * ptr to command, inline data, idr/fd or + * ptr to __u32 array of IDRs + */ + uint64_t __attribute__((aligned(8))) data; + /* Used by FD_IN and FD_OUT */ + int64_t data_s64; + }; + }; + + /* Argument object passed to RDMA_VERBS_IOCTL ioctl request. + * NOTE: sizeof(T) will return an incorrect value because of VLA at the end + * of the struct. + * + * Based on: + * - https://github.com/linux-rdma/rdma-core/blob/e336086ec6649fbcace511b54419dcac0ae040b7/libibverbs/cmd_ioctl.h + * - https://github.com/torvalds/linux/blob/494c5580aa6721874a6d9d62dac1c94e83e79302/include/uapi/rdma/rdma_user_ioctl_cmds.h + * + * TODO: Is it possible to use `using` to expose kernel structs in this namespace? + */ + struct ib_uverbs_ioctl_hdr { + uint16_t length; + uint16_t object_id; + uint16_t method_id; + uint16_t num_attrs; + uint64_t __attribute__((aligned(8))) reserved1; + uint32_t driver_id; + uint32_t reserved2; + struct ib_uverbs_attr attrs[0]; + }; }; struct X64Arch : public BaseArch { diff --git a/src/record_syscall.cc b/src/record_syscall.cc index 4872f1f69ea..4e40a1d5f3e 100644 --- a/src/record_syscall.cc +++ b/src/record_syscall.cc @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -1570,6 +1571,14 @@ template void prepare_ethtool_ioctl(RecordTask* t, TaskSyscallSt case ETHTOOL_SPAUSEPARAM: case ETHTOOL_SFEATURES: break; + // Expected EINVAL for 'ioctl' but got result 0 (errno SUCCESS); unknown ETHTOOL command 76 + case ETHTOOL_GLINKSETTINGS: + // TODO(sodar): Handle it somehow? + break; + // Expected EINVAL for 'ioctl' but got result 0 (errno SUCCESS); unknown ETHTOOL command 29 + case ETHTOOL_GSTATS: + // TODO(sodar): Handle it somehow? + break; default: LOG(debug) << "Unknown ETHTOOL cmd " << cmd; syscall_state.expect_errno = EINVAL; @@ -1746,6 +1755,15 @@ static Switchable prepare_ioctl(RecordTask* t, syscall_state.reg_parameter(3); return PREVENT_SWITCH; + /* RDMA_VERBS_IOCTL ioctl request used in libibverbs. + * net_mlx5 PMD is linked against libibverbs and these ioctls + * are called during probing. + */ + case RDMA_VERBS_IOCTL: + // TODO: ioctl argument size is dynamically calculated. How to do this in rr? + syscall_state.reg_parameter(3); + return PREVENT_SWITCH; + case SG_IO: auto argsp = syscall_state.reg_parameter(3, IN_OUT); auto args = t->read_mem(argsp); diff --git a/src/syscalls.py b/src/syscalls.py index 7b008e0d57c..231b8ababc3 100644 --- a/src/syscalls.py +++ b/src/syscalls.py @@ -570,7 +570,7 @@ def __init__(self, **kwargs): lstat = EmulatedSyscall(x86=107, x64=6, arg2="struct Arch::stat") fstat = EmulatedSyscall(x86=108, x64=5, generic=80, arg2="struct Arch::stat") olduname = UnsupportedSyscall(x86=109) -iopl = UnsupportedSyscall(x86=110, x64=172) +iopl = EmulatedSyscall(x86=110, x64=172) vhangup = UnsupportedSyscall(x86=111, x64=153, generic=58) idle = UnsupportedSyscall(x86=112) vm86old = UnsupportedSyscall(x86=113)