Skip to content
  • Matthew R. Ochs's avatar
    cxlflash: Fix to avoid corrupting port selection mask · 1a47401b
    Matthew R. Ochs authored
    
    
    The port selection mask of a LUN can be corrupted when the manage LUN
    ioctl (DK_CXLFLASH_MANAGE_LUN) is issued more than once for any device.
    
    This mask indicates to the AFU which port[s] can be used for a data
    transfer to/from a particular LUN. The mask is critical to ensuring the
    correct behavior when using the virtual LUN function of this adapter.
    When the mask is configured for both ports, an I/O may be sent to either
    port as the AFU assumes that each port has access to the same physical
    device (specified by LUN ID in the port LUN table).
    
    In a situation where the mask becomes incorrectly configured to reflect
    access to both ports when in fact there is only access through a single
    port, an I/O can be targeted to the wrong physical device. This can lead
    to data corruption among other ill effects (e.g. security leaks).
    
    The cause for this corruption is the assumption that the ioctl will only
    be called a second time for a LUN when it is being configured for access
    via a second port. A boolean 'newly_created' variable is used to
    differentiate between a LUN that was created (and subsequently configured
    for single port access) and one that is destined for access across both
    ports. While initially set to 'true', this sticky boolean is toggled to
    the 'false' state during a lookup on any next ioctl performed on a device
    with a matching WWN/WWID. The code fails to realize that the match could
    in fact be the same device calling in again. From here, an assumption is
    made that any LUN with 'newly_created' set to 'false' is configured for
    access over both ports and the port selection mask is set to reflect this.
    Any future attempts to use this LUN for hosting a virtual LUN will result
    in the port LUN table being incorrectly programmed.
    
    As a remedy, the 'newly_created' concept was removed entirely and replaced
    with code that always constructs the port selection mask based upon the
    SCSI channel of the LUN being accessed. The bits remain sticky, therefore
    allowing for a device to be accessed over both ports when that is in fact
    the correct physical configuration.
    
    Also included in this commit are a few minor related changes to enhance
    the fix and provide better debug information for port selection mask and
    port LUN table bugs in the future. These include renaming refresh_local()
    to lookup_local(), tracing the WWN/WWID as a big-endian entity, and
    tracing the port selection mask, SCSI channel, and LUN ID each time the
    port LUN table is programmed.
    
    Signed-off-by: default avatarMatthew R. Ochs <mrochs@linux.vnet.ibm.com>
    Acked-by: default avatarManoj Kumar <manoj@linux.vnet.ibm.com>
    Reviewed-by: default avatarAndrew Donnellan <andrew.donnellan@au1.ibm.com>
    Signed-off-by: default avatarJames Bottomley <JBottomley@Odin.com>
    1a47401b