• Roland Dreier's avatar
    IB/umad: Fix bit ordering and 32-on-64 problems on big endian systems · a394f83b
    Roland Dreier authored
    The declaration of struct ib_user_mad_reg_req.method_mask[] exported
    to userspace was an array of __u32, but the kernel internally treated
    it as a bitmap made up of longs.  This makes a difference for 64-bit
    big-endian kernels, where numbering the bits in an array of__u32 gives:
    
        |31.....0|63....31|95....64|127...96|
    
    while numbering the bits in an array of longs gives:
    
        |63..............0|127............64|
    
    64-bit userspace can handle this by just treating method_mask[] as an
    array of longs, but 32-bit userspace is really stuck: the meaning of
    the bits in method_mask[] depends on whether the kernel is 32-bit or
    64-bit, and there's no sane way for userspace to know that.
    
    Fix this by updating <rdma/ib_user_mad.h> to make it clear that
    method_mask[] is an array of longs, and using a compat_ioctl method to
    convert to an array of 64-bit longs to handle the 32-on-64 problem.
    This fixes the interface description to match existing behavior (so
    working binaries continue to work) in almost all situations, and gives
    consistent semantics in the case of 32-bit userspace that can run on
    either a 32-bit or 64-bit kernel, so that the same binary can work for
    both 32-on-32 and 32-on-64 systems.
    Signed-off-by: default avatarRoland Dreier <rolandd@cisco.com>
    a394f83b
user_mad.c 30.3 KB