30 Jun, 2018

1 commit

  • Move the Microsemi Switchtec PCI Vendor ID (same as
    PCI_VENDOR_ID_PMC_Sierra) to pci_ids.h. Also, replace Microsemi class
    constants with the standard PCI definitions.

    Signed-off-by: Doug Meyer
    [bhelgaas: restore SPDX (I assume it was removed by mistake), remove
    device ID definitions]
    Signed-off-by: Bjorn Helgaas
    Reviewed-by: Logan Gunthorpe

    Doug Meyer
     

13 Jun, 2018

2 commits

  • Pull more overflow updates from Kees Cook:
    "The rest of the overflow changes for v4.18-rc1.

    This includes the explicit overflow fixes from Silvio, further
    struct_size() conversions from Matthew, and a bug fix from Dan.

    But the bulk of it is the treewide conversions to use either the
    2-factor argument allocators (e.g. kmalloc(a * b, ...) into
    kmalloc_array(a, b, ...) or the array_size() macros (e.g. vmalloc(a *
    b) into vmalloc(array_size(a, b)).

    Coccinelle was fighting me on several fronts, so I've done a bunch of
    manual whitespace updates in the patches as well.

    Summary:

    - Error path bug fix for overflow tests (Dan)

    - Additional struct_size() conversions (Matthew, Kees)

    - Explicitly reported overflow fixes (Silvio, Kees)

    - Add missing kvcalloc() function (Kees)

    - Treewide conversions of allocators to use either 2-factor argument
    variant when available, or array_size() and array3_size() as needed
    (Kees)"

    * tag 'overflow-v4.18-rc1-part2' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux: (26 commits)
    treewide: Use array_size in f2fs_kvzalloc()
    treewide: Use array_size() in f2fs_kzalloc()
    treewide: Use array_size() in f2fs_kmalloc()
    treewide: Use array_size() in sock_kmalloc()
    treewide: Use array_size() in kvzalloc_node()
    treewide: Use array_size() in vzalloc_node()
    treewide: Use array_size() in vzalloc()
    treewide: Use array_size() in vmalloc()
    treewide: devm_kzalloc() -> devm_kcalloc()
    treewide: devm_kmalloc() -> devm_kmalloc_array()
    treewide: kvzalloc() -> kvcalloc()
    treewide: kvmalloc() -> kvmalloc_array()
    treewide: kzalloc_node() -> kcalloc_node()
    treewide: kzalloc() -> kcalloc()
    treewide: kmalloc() -> kmalloc_array()
    mm: Introduce kvcalloc()
    video: uvesafb: Fix integer overflow in allocation
    UBIFS: Fix potential integer overflow in allocation
    leds: Use struct_size() in allocation
    Convert intel uncore to struct_size
    ...

    Linus Torvalds
     
  • The kzalloc_node() function has a 2-factor argument form, kcalloc_node(). This
    patch replaces cases of:

    kzalloc_node(a * b, gfp, node)

    with:
    kcalloc_node(a * b, gfp, node)

    as well as handling cases of:

    kzalloc_node(a * b * c, gfp, node)

    with:

    kzalloc_node(array3_size(a, b, c), gfp, node)

    as it's slightly less ugly than:

    kcalloc_node(array_size(a, b), c, gfp, node)

    This does, however, attempt to ignore constant size factors like:

    kzalloc_node(4 * 1024, gfp, node)

    though any constants defined via macros get caught up in the conversion.

    Any factors with a sizeof() of "unsigned char", "char", and "u8" were
    dropped, since they're redundant.

    The Coccinelle script used for this was:

    // Fix redundant parens around sizeof().
    @@
    type TYPE;
    expression THING, E;
    @@

    (
    kzalloc_node(
    - (sizeof(TYPE)) * E
    + sizeof(TYPE) * E
    , ...)
    |
    kzalloc_node(
    - (sizeof(THING)) * E
    + sizeof(THING) * E
    , ...)
    )

    // Drop single-byte sizes and redundant parens.
    @@
    expression COUNT;
    typedef u8;
    typedef __u8;
    @@

    (
    kzalloc_node(
    - sizeof(u8) * (COUNT)
    + COUNT
    , ...)
    |
    kzalloc_node(
    - sizeof(__u8) * (COUNT)
    + COUNT
    , ...)
    |
    kzalloc_node(
    - sizeof(char) * (COUNT)
    + COUNT
    , ...)
    |
    kzalloc_node(
    - sizeof(unsigned char) * (COUNT)
    + COUNT
    , ...)
    |
    kzalloc_node(
    - sizeof(u8) * COUNT
    + COUNT
    , ...)
    |
    kzalloc_node(
    - sizeof(__u8) * COUNT
    + COUNT
    , ...)
    |
    kzalloc_node(
    - sizeof(char) * COUNT
    + COUNT
    , ...)
    |
    kzalloc_node(
    - sizeof(unsigned char) * COUNT
    + COUNT
    , ...)
    )

    // 2-factor product with sizeof(type/expression) and identifier or constant.
    @@
    type TYPE;
    expression THING;
    identifier COUNT_ID;
    constant COUNT_CONST;
    @@

    (
    - kzalloc_node
    + kcalloc_node
    (
    - sizeof(TYPE) * (COUNT_ID)
    + COUNT_ID, sizeof(TYPE)
    , ...)
    |
    - kzalloc_node
    + kcalloc_node
    (
    - sizeof(TYPE) * COUNT_ID
    + COUNT_ID, sizeof(TYPE)
    , ...)
    |
    - kzalloc_node
    + kcalloc_node
    (
    - sizeof(TYPE) * (COUNT_CONST)
    + COUNT_CONST, sizeof(TYPE)
    , ...)
    |
    - kzalloc_node
    + kcalloc_node
    (
    - sizeof(TYPE) * COUNT_CONST
    + COUNT_CONST, sizeof(TYPE)
    , ...)
    |
    - kzalloc_node
    + kcalloc_node
    (
    - sizeof(THING) * (COUNT_ID)
    + COUNT_ID, sizeof(THING)
    , ...)
    |
    - kzalloc_node
    + kcalloc_node
    (
    - sizeof(THING) * COUNT_ID
    + COUNT_ID, sizeof(THING)
    , ...)
    |
    - kzalloc_node
    + kcalloc_node
    (
    - sizeof(THING) * (COUNT_CONST)
    + COUNT_CONST, sizeof(THING)
    , ...)
    |
    - kzalloc_node
    + kcalloc_node
    (
    - sizeof(THING) * COUNT_CONST
    + COUNT_CONST, sizeof(THING)
    , ...)
    )

    // 2-factor product, only identifiers.
    @@
    identifier SIZE, COUNT;
    @@

    - kzalloc_node
    + kcalloc_node
    (
    - SIZE * COUNT
    + COUNT, SIZE
    , ...)

    // 3-factor product with 1 sizeof(type) or sizeof(expression), with
    // redundant parens removed.
    @@
    expression THING;
    identifier STRIDE, COUNT;
    type TYPE;
    @@

    (
    kzalloc_node(
    - sizeof(TYPE) * (COUNT) * (STRIDE)
    + array3_size(COUNT, STRIDE, sizeof(TYPE))
    , ...)
    |
    kzalloc_node(
    - sizeof(TYPE) * (COUNT) * STRIDE
    + array3_size(COUNT, STRIDE, sizeof(TYPE))
    , ...)
    |
    kzalloc_node(
    - sizeof(TYPE) * COUNT * (STRIDE)
    + array3_size(COUNT, STRIDE, sizeof(TYPE))
    , ...)
    |
    kzalloc_node(
    - sizeof(TYPE) * COUNT * STRIDE
    + array3_size(COUNT, STRIDE, sizeof(TYPE))
    , ...)
    |
    kzalloc_node(
    - sizeof(THING) * (COUNT) * (STRIDE)
    + array3_size(COUNT, STRIDE, sizeof(THING))
    , ...)
    |
    kzalloc_node(
    - sizeof(THING) * (COUNT) * STRIDE
    + array3_size(COUNT, STRIDE, sizeof(THING))
    , ...)
    |
    kzalloc_node(
    - sizeof(THING) * COUNT * (STRIDE)
    + array3_size(COUNT, STRIDE, sizeof(THING))
    , ...)
    |
    kzalloc_node(
    - sizeof(THING) * COUNT * STRIDE
    + array3_size(COUNT, STRIDE, sizeof(THING))
    , ...)
    )

    // 3-factor product with 2 sizeof(variable), with redundant parens removed.
    @@
    expression THING1, THING2;
    identifier COUNT;
    type TYPE1, TYPE2;
    @@

    (
    kzalloc_node(
    - sizeof(TYPE1) * sizeof(TYPE2) * COUNT
    + array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
    , ...)
    |
    kzalloc_node(
    - sizeof(TYPE1) * sizeof(THING2) * (COUNT)
    + array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
    , ...)
    |
    kzalloc_node(
    - sizeof(THING1) * sizeof(THING2) * COUNT
    + array3_size(COUNT, sizeof(THING1), sizeof(THING2))
    , ...)
    |
    kzalloc_node(
    - sizeof(THING1) * sizeof(THING2) * (COUNT)
    + array3_size(COUNT, sizeof(THING1), sizeof(THING2))
    , ...)
    |
    kzalloc_node(
    - sizeof(TYPE1) * sizeof(THING2) * COUNT
    + array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
    , ...)
    |
    kzalloc_node(
    - sizeof(TYPE1) * sizeof(THING2) * (COUNT)
    + array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
    , ...)
    )

    // 3-factor product, only identifiers, with redundant parens removed.
    @@
    identifier STRIDE, SIZE, COUNT;
    @@

    (
    kzalloc_node(
    - (COUNT) * STRIDE * SIZE
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kzalloc_node(
    - COUNT * (STRIDE) * SIZE
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kzalloc_node(
    - COUNT * STRIDE * (SIZE)
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kzalloc_node(
    - (COUNT) * (STRIDE) * SIZE
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kzalloc_node(
    - COUNT * (STRIDE) * (SIZE)
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kzalloc_node(
    - (COUNT) * STRIDE * (SIZE)
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kzalloc_node(
    - (COUNT) * (STRIDE) * (SIZE)
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kzalloc_node(
    - COUNT * STRIDE * SIZE
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    )

    // Any remaining multi-factor products, first at least 3-factor products,
    // when they're not all constants...
    @@
    expression E1, E2, E3;
    constant C1, C2, C3;
    @@

    (
    kzalloc_node(C1 * C2 * C3, ...)
    |
    kzalloc_node(
    - (E1) * E2 * E3
    + array3_size(E1, E2, E3)
    , ...)
    |
    kzalloc_node(
    - (E1) * (E2) * E3
    + array3_size(E1, E2, E3)
    , ...)
    |
    kzalloc_node(
    - (E1) * (E2) * (E3)
    + array3_size(E1, E2, E3)
    , ...)
    |
    kzalloc_node(
    - E1 * E2 * E3
    + array3_size(E1, E2, E3)
    , ...)
    )

    // And then all remaining 2 factors products when they're not all constants,
    // keeping sizeof() as the second factor argument.
    @@
    expression THING, E1, E2;
    type TYPE;
    constant C1, C2, C3;
    @@

    (
    kzalloc_node(sizeof(THING) * C2, ...)
    |
    kzalloc_node(sizeof(TYPE) * C2, ...)
    |
    kzalloc_node(C1 * C2 * C3, ...)
    |
    kzalloc_node(C1 * C2, ...)
    |
    - kzalloc_node
    + kcalloc_node
    (
    - sizeof(TYPE) * (E2)
    + E2, sizeof(TYPE)
    , ...)
    |
    - kzalloc_node
    + kcalloc_node
    (
    - sizeof(TYPE) * E2
    + E2, sizeof(TYPE)
    , ...)
    |
    - kzalloc_node
    + kcalloc_node
    (
    - sizeof(THING) * (E2)
    + E2, sizeof(THING)
    , ...)
    |
    - kzalloc_node
    + kcalloc_node
    (
    - sizeof(THING) * E2
    + E2, sizeof(THING)
    , ...)
    |
    - kzalloc_node
    + kcalloc_node
    (
    - (E1) * E2
    + E1, E2
    , ...)
    |
    - kzalloc_node
    + kcalloc_node
    (
    - (E1) * (E2)
    + E1, E2
    , ...)
    |
    - kzalloc_node
    + kcalloc_node
    (
    - E1 * E2
    + E1, E2
    , ...)
    )

    Signed-off-by: Kees Cook

    Kees Cook
     

12 Jun, 2018

6 commits


29 Jan, 2018

26 commits

  • Sparse is whining about the u32 and __le32 mixed usage in the driver

    drivers/ntb/test/ntb_perf.c:288:21: warning: cast to restricted __le32
    drivers/ntb/test/ntb_perf.c:295:37: warning: incorrect type in argument 4 (different base types)
    drivers/ntb/test/ntb_perf.c:295:37: expected unsigned int [unsigned] [usertype] val
    drivers/ntb/test/ntb_perf.c:295:37: got restricted __le32 [usertype]
    ...

    NTB hardware drivers shall accept CPU-endian data and translate it to
    the portable formate by internal means, so the explicit conversions
    are not necessary before Scratchpad/Messages API usage anymore.

    Fixes: b83003b3fdc1 ("NTB: ntb_perf: Add full multi-port NTB API support")
    Signed-off-by: Serge Semin
    Acked-by: Arnd Bergmann
    Signed-off-by: Jon Mason

    Serge Semin
     
  • We accidentally return success if dmaengine_submit() fails. The fix is
    to preserve the error code from dma_submit_error().

    Signed-off-by: Dan Carpenter
    Acked-by: Serge Semin
    Signed-off-by: Jon Mason

    Dan Carpenter
     
  • Fixes the following sparse warnings:

    drivers/ntb/hw/mscc/ntb_hw_switchtec.c:1552:6: warning:
    symbol 'switchtec_ntb_remove' was not declared. Should it be static?

    Signed-off-by: Wei Yongjun
    Reviewed-by: Logan Gunthorpe
    Signed-off-by: Jon Mason

    Wei Yongjun
     
  • Currently there is a memory leak on buf when the call to ntb_mw_get_align
    fails. Add an exit err label and jump to this so that kfree on buf frees
    the memory.

    Detected by CoverityScan, CID#1464286 ("Resource leak")

    Fixes: d637628ce00c ("NTB: ntb_tool: Add full multi-port NTB API support")
    Signed-off-by: Colin Ian King
    Acked-by: Serge Semin
    Signed-off-by: Jon Mason

    Colin Ian King
     
  • On 32-bit architectures, resource_size_t is usually 'unsigned int' or
    'unsigned long' but not 'unsigned long long', so we get a warning
    about printing the wrong data:

    drivers/ntb/test/ntb_perf.c: In function 'perf_setup_peer_mw':
    drivers/ntb/test/ntb_perf.c:1390:35: error: format '%llx' expects argument of type 'long long unsigned int', but argument 4 has type 'resource_size_t {aka unsigned int}' [-Werror=format=]

    This changes the format string to the special %pa that is already
    used elsewhere in the same file.

    Fixes: b83003b3fdc1 ("NTB: ntb_perf: Add full multi-port NTB API support")
    Signed-off-by: Arnd Bergmann
    Signed-off-by: Jon Mason

    Arnd Bergmann
     
  • Since Switchtec patch there has been a new topology added to
    the NTB API. It's called NTB_TOPO_SWITCH and dedicated for
    PCIe switch chips. Even though topo field isn't used within the
    IDT driver much, lets set it for the sake of unification.

    Signed-off-by: Serge Semin
    Signed-off-by: Jon Mason

    Serge Semin
     
  • Former NTB Performance driver could only work with NTB devices, which
    got Scratchpads available and had just two ports. Since there are
    devices, which don't have Scratchpads and got more than two peer
    ports, the performance measuring tool needs to be rewritten. This
    patch adds the ability to test any available NTB peer.
    Additionally it allows to set NTB memory windows up using any
    available data exchange interface: Scratchpad or Message registers.
    Some cleanups are also added here.

    Signed-off-by: Serge Semin
    Signed-off-by: Jon Mason

    Serge Semin
     
  • Former NTB Debugging tool driver supported only the limited
    functionality of the recently updated NTB API, which is now available
    to work with the truly NTB multi-port devices and devices, which
    got NTB Message registers instead of Scratchpads. This patch
    fully rewrites the driver so one would fully expose all the new
    NTB API interfaces. Particularly it concerns the Message registers,
    peer ports API, NTB link settings. Additional cleanups are also added
    here.

    Signed-off-by: Serge Semin
    Signed-off-by: Jon Mason

    Serge Semin
     
  • Current Ping Pong driver can't truly work with multi-port devices.
    Additionally it requires the Scratchpad registers being available
    on NTB device. This patches rewrites the driver so one would
    perform the cyclic Ping-Pong algorithm around all the available
    NTB peers and makes it working with NTB hardware, which doesn't
    support Scratchpads, but such alternative as NTB Message register.
    Additional cleanups are also added here.

    Signed-off-by: Serge Semin
    Signed-off-by: Jon Mason

    Serge Semin
     
  • The dma_mask and dma_coherent_mask fields of the NTB struct device
    weren't initialized in hardware drivers. In fact it should be done
    instead of PCIe interface usage, since NTB clients are supposed to
    use NTB API and left unaware of real hardware implementation.
    In addition to that ntb_device_register() method shouldn't clear
    the passed ntb_dev structure, since it dma_mask is initialized
    by hardware drivers.

    Signed-off-by: Serge Semin
    Signed-off-by: Jon Mason

    Serge Semin
     
  • There is a common methods signature form used over all the NTB API
    like functions naming scheme, arguments names and order, etc.
    Recently added NTB messaging API IO callbacks were named a bit
    different so should be renamed to be in compliance with the rest
    of the API.

    Signed-off-by: Serge Semin
    Signed-off-by: Jon Mason

    Serge Semin
     
  • Newer gcc (version 7 and 8 presumably) warn about a statement mixing
    the << operator with logical and:

    drivers/ntb/hw/mscc/ntb_hw_switchtec.c: In function 'switchtec_ntb_init_sndev':
    drivers/ntb/hw/mscc/ntb_hw_switchtec.c:888:24: error: '<
    Signed-off-by: Arnd Bergmann
    Signed-off-by: Jon Mason

    Arnd Bergmann
     
  • With Switchtec hardware, the buffer used for a memory window must be
    aligned to its size (the hardware only replaces the lower bits). In
    certain circumstances dma_alloc_coherent() will not provide a buffer
    that adheres to this requirement like when using the CMA and
    CONFIG_CMA_ALIGNMENT is set lower than the buffer size.

    When we get an unaligned buffer mw_set_trans() should return an error.
    We also log an error so we know the cause of the problem.

    Signed-off-by: Logan Gunthorpe
    Signed-off-by: Jon Mason

    Logan Gunthorpe
     
  • When using the max_mw_size parameter of ntb_transport to limit the size of
    the Memory windows, communication cannot be established and the queues
    freeze.

    This is because the mw_size that's reported to the peer is correctly
    limited but the size used locally is not. So the MW is initialized
    with a buffer smaller than the window but the TX side is using the
    full window. This means the TX side will be writing to a region of the
    window that points nowhere.

    This is easily fixed by applying the same limit to tx_size in
    ntb_transport_init_queue().

    Fixes: e26a5843f7f5 ("NTB: Split ntb_hw_intel and ntb_transport drivers")
    Signed-off-by: Logan Gunthorpe
    Acked-by: Allen Hubbe
    Cc: Dave Jiang
    Signed-off-by: Jon Mason

    Logan Gunthorpe
     
  • If one host crashes and soft reboots, the other host may not see a
    link down event. Then when the crashed host comes back up, the
    surviving host may not know the link was reset and the NTB clients
    may not work without being reset.

    To solve this, we send a LINK_FORCE_DOWN message to each peer every
    time we come up, before we register the NTB device. If a surviving
    host still thinks the link is up it will take it down immediately.
    In this way, once the crashed host comes up fully, it will send a
    regular link up event as per usual and the link will be properly
    restarted.

    While we are in the area, this also fixes the MSG_LINK_UP message that
    was in the link down function that was reported by Doug Meyers.

    Signed-off-by: Logan Gunthorpe
    Reported-by: ThanhTuThai
    Signed-off-by: Jon Mason

    Logan Gunthorpe
     
  • In a crosslink configuration doorbells and messages largely work the
    same but the NTB registers must be accessed through the reserved LUT
    window. Also, as a bonus, seeing there are now two independent sets of
    NTB links, both partitions can actually use all 60 doorbell registers
    instead of them having to be split into two for each partition.

    Signed-off-by: Logan Gunthorpe
    Signed-off-by: Jon Mason

    Logan Gunthorpe
     
  • Crosslink is a feature of the Switchtec switches that is similar to
    the B2B mode of other NTB devices. It allows a system to be designed
    that is perfectly symmetric with two identical switches that link
    two hosts together.

    In order for the system to be symmetric, there is an empty host-less
    partition between the two switches which the host must enumerate and
    assign BAR addresses to. The firmware in the switch manages this
    specially so that the BAR addresses on both sides of the empty
    partition will be identical despite being in the same partition with
    the same address space.

    The driver determines whether crosslink is enabled by a flag set in
    the NTB partition info registers which are set by the switch's
    configuration file.

    When crosslink is enabled, a reserved LUT window is setup to point to
    the peer's switch's NTB registers and the local MWs are set to forward
    to the host-less partition's BARs. (Yes, this hurts my brain too.)
    Once this is setup, largely the same NTB infrastructure is used to
    communicate between the two hosts.

    Signed-off-by: Logan Gunthorpe
    Signed-off-by: Jon Mason

    Logan Gunthorpe
     
  • This is a prep patch in order to support the crosslink feature which
    will require the driver to setup the requester ID table in another
    partition as well as it's own. To aid this, create a helper function
    which sets up the requester IDs from an array.

    Signed-off-by: Logan Gunthorpe
    Signed-off-by: Jon Mason

    Logan Gunthorpe
     
  • This is a prep patch in order to support the crosslink feature which
    will require the driver to use another reserved LUT window. To
    simplify this we move the code which sets up the reserved LUT window
    into a helper function which will be used by the crosslink
    initialization.

    Signed-off-by: Logan Gunthorpe
    Signed-off-by: Jon Mason

    Logan Gunthorpe
     
  • This is a prep patch in order to support the crosslink feature which will
    require the driver to use another reserved LUT window. To simplify this,
    we add some code to track the number of reserved LUT windows in use
    instead of assuming this is always 1.

    Signed-off-by: Logan Gunthorpe
    Signed-off-by: Jon Mason

    Logan Gunthorpe
     
  • Allow using Switchtec NTB in setups that have more than two partitions.
    Note: this does not enable having multi-host communication, it only
    allows for a single NTB link between two hosts in a network that might
    have more than two.

    Use following logic to determine the NT peer partition:

    1) If there are 2 partitions, and the target vector is set in
    the Switchtec configuration, use the partition specified in target
    vector.
    2) If there are 2 partitions and target vector is unset
    use the only other partition as specified in the NT EP map.
    3) If there are more than 2 partitions and target vector is set
    use the other partition specified in target vector.
    4) If there are more than 2 partitions and target vector is unset,
    this is invalid and report an error.

    Signed-off-by: Kelvin Cao
    [logang@deltatee.com: commit message fleshed out]
    Signed-off-by: Logan Gunthorpe
    Reviewed-by: Logan Gunthorpe
    Signed-off-by: Jon Mason

    Kelvin Cao
     
  • Trivial addition of "\n" to the dev_* prints where necessary

    Signed-off-by: Joe Perches
    Signed-off-by: Jon Mason

    Jon Mason
     
  • Trivial fix to spelling mistake in dev_err error message

    Signed-off-by: Colin Ian King
    Reviewed-By: Logan Gunthorpe
    Signed-off-by: Jon Mason

    Colin Ian King
     
  • Removing dead code since this is not being used.

    Signed-off-by: Dave Jiang
    Signed-off-by: Jon Mason

    Dave Jiang
     
  • There is no need to #define the license of the driver, just put it in
    the MODULE_LICENSE() line directly as a text string.

    This allows tools that check that the module license matches the source
    code license to work properly, as there is no need to unwind the
    unneeded dereference, especially when the string is defined just a few
    lines above the usage of it.

    Reported-and-reviewed-by: Philippe Ombredanne
    Signed-off-by: Greg Kroah-Hartman
    Cc: Dave Jiang
    Cc: Allen Hubbe
    Cc: Gary R Hook
    Cc: Serge Semin
    Signed-off-by: Jon Mason

    Greg Kroah-Hartman
     
  • This resolves a bug which may incorrectly configure the peer host's
    LUT for shared memory window access. The code was using the local
    host's first BAR number, rather than the peer hosts's first BAR
    number, to determine what peer NT control register to program.

    The bug will cause the Switchtec NTB link to work only if both peers
    have the same first NTB BAR configured. In all other configurations,
    the link will not come up, failing silently.

    When both hosts have the same first BAR, the configuration works only
    because the first BAR numbers happent to be the same. When the hosts
    do not have the same first BAR, then the LUT translation will not be
    configured in the correct peer LUT and will not give the peer the
    shared memory window access required for the link to operate.

    Signed-off-by: Doug Meyer
    Reviewed-by: Logan Gunthorpe
    Fixes: 678784a44ae8 ("NTB: switchtec_ntb: Initialize hardware for memory windows")
    Signed-off-by: Jon Mason

    Doug Meyer
     

22 Nov, 2017

1 commit

  • This converts all remaining cases of the old setup_timer() API into using
    timer_setup(), where the callback argument is the structure already
    holding the struct timer_list. These should have no behavioral changes,
    since they just change which pointer is passed into the callback with
    the same available pointers after conversion. It handles the following
    examples, in addition to some other variations.

    Casting from unsigned long:

    void my_callback(unsigned long data)
    {
    struct something *ptr = (struct something *)data;
    ...
    }
    ...
    setup_timer(&ptr->my_timer, my_callback, ptr);

    and forced object casts:

    void my_callback(struct something *ptr)
    {
    ...
    }
    ...
    setup_timer(&ptr->my_timer, my_callback, (unsigned long)ptr);

    become:

    void my_callback(struct timer_list *t)
    {
    struct something *ptr = from_timer(ptr, t, my_timer);
    ...
    }
    ...
    timer_setup(&ptr->my_timer, my_callback, 0);

    Direct function assignments:

    void my_callback(unsigned long data)
    {
    struct something *ptr = (struct something *)data;
    ...
    }
    ...
    ptr->my_timer.function = my_callback;

    have a temporary cast added, along with converting the args:

    void my_callback(struct timer_list *t)
    {
    struct something *ptr = from_timer(ptr, t, my_timer);
    ...
    }
    ...
    ptr->my_timer.function = (TIMER_FUNC_TYPE)my_callback;

    And finally, callbacks without a data assignment:

    void my_callback(unsigned long data)
    {
    ...
    }
    ...
    setup_timer(&ptr->my_timer, my_callback, 0);

    have their argument renamed to verify they're unused during conversion:

    void my_callback(struct timer_list *unused)
    {
    ...
    }
    ...
    timer_setup(&ptr->my_timer, my_callback, 0);

    The conversion is done with the following Coccinelle script:

    spatch --very-quiet --all-includes --include-headers \
    -I ./arch/x86/include -I ./arch/x86/include/generated \
    -I ./include -I ./arch/x86/include/uapi \
    -I ./arch/x86/include/generated/uapi -I ./include/uapi \
    -I ./include/generated/uapi --include ./include/linux/kconfig.h \
    --dir . \
    --cocci-file ~/src/data/timer_setup.cocci

    @fix_address_of@
    expression e;
    @@

    setup_timer(
    -&(e)
    +&e
    , ...)

    // Update any raw setup_timer() usages that have a NULL callback, but
    // would otherwise match change_timer_function_usage, since the latter
    // will update all function assignments done in the face of a NULL
    // function initialization in setup_timer().
    @change_timer_function_usage_NULL@
    expression _E;
    identifier _timer;
    type _cast_data;
    @@

    (
    -setup_timer(&_E->_timer, NULL, _E);
    +timer_setup(&_E->_timer, NULL, 0);
    |
    -setup_timer(&_E->_timer, NULL, (_cast_data)_E);
    +timer_setup(&_E->_timer, NULL, 0);
    |
    -setup_timer(&_E._timer, NULL, &_E);
    +timer_setup(&_E._timer, NULL, 0);
    |
    -setup_timer(&_E._timer, NULL, (_cast_data)&_E);
    +timer_setup(&_E._timer, NULL, 0);
    )

    @change_timer_function_usage@
    expression _E;
    identifier _timer;
    struct timer_list _stl;
    identifier _callback;
    type _cast_func, _cast_data;
    @@

    (
    -setup_timer(&_E->_timer, _callback, _E);
    +timer_setup(&_E->_timer, _callback, 0);
    |
    -setup_timer(&_E->_timer, &_callback, _E);
    +timer_setup(&_E->_timer, _callback, 0);
    |
    -setup_timer(&_E->_timer, _callback, (_cast_data)_E);
    +timer_setup(&_E->_timer, _callback, 0);
    |
    -setup_timer(&_E->_timer, &_callback, (_cast_data)_E);
    +timer_setup(&_E->_timer, _callback, 0);
    |
    -setup_timer(&_E->_timer, (_cast_func)_callback, _E);
    +timer_setup(&_E->_timer, _callback, 0);
    |
    -setup_timer(&_E->_timer, (_cast_func)&_callback, _E);
    +timer_setup(&_E->_timer, _callback, 0);
    |
    -setup_timer(&_E->_timer, (_cast_func)_callback, (_cast_data)_E);
    +timer_setup(&_E->_timer, _callback, 0);
    |
    -setup_timer(&_E->_timer, (_cast_func)&_callback, (_cast_data)_E);
    +timer_setup(&_E->_timer, _callback, 0);
    |
    -setup_timer(&_E._timer, _callback, (_cast_data)_E);
    +timer_setup(&_E._timer, _callback, 0);
    |
    -setup_timer(&_E._timer, _callback, (_cast_data)&_E);
    +timer_setup(&_E._timer, _callback, 0);
    |
    -setup_timer(&_E._timer, &_callback, (_cast_data)_E);
    +timer_setup(&_E._timer, _callback, 0);
    |
    -setup_timer(&_E._timer, &_callback, (_cast_data)&_E);
    +timer_setup(&_E._timer, _callback, 0);
    |
    -setup_timer(&_E._timer, (_cast_func)_callback, (_cast_data)_E);
    +timer_setup(&_E._timer, _callback, 0);
    |
    -setup_timer(&_E._timer, (_cast_func)_callback, (_cast_data)&_E);
    +timer_setup(&_E._timer, _callback, 0);
    |
    -setup_timer(&_E._timer, (_cast_func)&_callback, (_cast_data)_E);
    +timer_setup(&_E._timer, _callback, 0);
    |
    -setup_timer(&_E._timer, (_cast_func)&_callback, (_cast_data)&_E);
    +timer_setup(&_E._timer, _callback, 0);
    |
    _E->_timer@_stl.function = _callback;
    |
    _E->_timer@_stl.function = &_callback;
    |
    _E->_timer@_stl.function = (_cast_func)_callback;
    |
    _E->_timer@_stl.function = (_cast_func)&_callback;
    |
    _E._timer@_stl.function = _callback;
    |
    _E._timer@_stl.function = &_callback;
    |
    _E._timer@_stl.function = (_cast_func)_callback;
    |
    _E._timer@_stl.function = (_cast_func)&_callback;
    )

    // callback(unsigned long arg)
    @change_callback_handle_cast
    depends on change_timer_function_usage@
    identifier change_timer_function_usage._callback;
    identifier change_timer_function_usage._timer;
    type _origtype;
    identifier _origarg;
    type _handletype;
    identifier _handle;
    @@

    void _callback(
    -_origtype _origarg
    +struct timer_list *t
    )
    {
    (
    ... when != _origarg
    _handletype *_handle =
    -(_handletype *)_origarg;
    +from_timer(_handle, t, _timer);
    ... when != _origarg
    |
    ... when != _origarg
    _handletype *_handle =
    -(void *)_origarg;
    +from_timer(_handle, t, _timer);
    ... when != _origarg
    |
    ... when != _origarg
    _handletype *_handle;
    ... when != _handle
    _handle =
    -(_handletype *)_origarg;
    +from_timer(_handle, t, _timer);
    ... when != _origarg
    |
    ... when != _origarg
    _handletype *_handle;
    ... when != _handle
    _handle =
    -(void *)_origarg;
    +from_timer(_handle, t, _timer);
    ... when != _origarg
    )
    }

    // callback(unsigned long arg) without existing variable
    @change_callback_handle_cast_no_arg
    depends on change_timer_function_usage &&
    !change_callback_handle_cast@
    identifier change_timer_function_usage._callback;
    identifier change_timer_function_usage._timer;
    type _origtype;
    identifier _origarg;
    type _handletype;
    @@

    void _callback(
    -_origtype _origarg
    +struct timer_list *t
    )
    {
    + _handletype *_origarg = from_timer(_origarg, t, _timer);
    +
    ... when != _origarg
    - (_handletype *)_origarg
    + _origarg
    ... when != _origarg
    }

    // Avoid already converted callbacks.
    @match_callback_converted
    depends on change_timer_function_usage &&
    !change_callback_handle_cast &&
    !change_callback_handle_cast_no_arg@
    identifier change_timer_function_usage._callback;
    identifier t;
    @@

    void _callback(struct timer_list *t)
    { ... }

    // callback(struct something *handle)
    @change_callback_handle_arg
    depends on change_timer_function_usage &&
    !match_callback_converted &&
    !change_callback_handle_cast &&
    !change_callback_handle_cast_no_arg@
    identifier change_timer_function_usage._callback;
    identifier change_timer_function_usage._timer;
    type _handletype;
    identifier _handle;
    @@

    void _callback(
    -_handletype *_handle
    +struct timer_list *t
    )
    {
    + _handletype *_handle = from_timer(_handle, t, _timer);
    ...
    }

    // If change_callback_handle_arg ran on an empty function, remove
    // the added handler.
    @unchange_callback_handle_arg
    depends on change_timer_function_usage &&
    change_callback_handle_arg@
    identifier change_timer_function_usage._callback;
    identifier change_timer_function_usage._timer;
    type _handletype;
    identifier _handle;
    identifier t;
    @@

    void _callback(struct timer_list *t)
    {
    - _handletype *_handle = from_timer(_handle, t, _timer);
    }

    // We only want to refactor the setup_timer() data argument if we've found
    // the matching callback. This undoes changes in change_timer_function_usage.
    @unchange_timer_function_usage
    depends on change_timer_function_usage &&
    !change_callback_handle_cast &&
    !change_callback_handle_cast_no_arg &&
    !change_callback_handle_arg@
    expression change_timer_function_usage._E;
    identifier change_timer_function_usage._timer;
    identifier change_timer_function_usage._callback;
    type change_timer_function_usage._cast_data;
    @@

    (
    -timer_setup(&_E->_timer, _callback, 0);
    +setup_timer(&_E->_timer, _callback, (_cast_data)_E);
    |
    -timer_setup(&_E._timer, _callback, 0);
    +setup_timer(&_E._timer, _callback, (_cast_data)&_E);
    )

    // If we fixed a callback from a .function assignment, fix the
    // assignment cast now.
    @change_timer_function_assignment
    depends on change_timer_function_usage &&
    (change_callback_handle_cast ||
    change_callback_handle_cast_no_arg ||
    change_callback_handle_arg)@
    expression change_timer_function_usage._E;
    identifier change_timer_function_usage._timer;
    identifier change_timer_function_usage._callback;
    type _cast_func;
    typedef TIMER_FUNC_TYPE;
    @@

    (
    _E->_timer.function =
    -_callback
    +(TIMER_FUNC_TYPE)_callback
    ;
    |
    _E->_timer.function =
    -&_callback
    +(TIMER_FUNC_TYPE)_callback
    ;
    |
    _E->_timer.function =
    -(_cast_func)_callback;
    +(TIMER_FUNC_TYPE)_callback
    ;
    |
    _E->_timer.function =
    -(_cast_func)&_callback
    +(TIMER_FUNC_TYPE)_callback
    ;
    |
    _E._timer.function =
    -_callback
    +(TIMER_FUNC_TYPE)_callback
    ;
    |
    _E._timer.function =
    -&_callback;
    +(TIMER_FUNC_TYPE)_callback
    ;
    |
    _E._timer.function =
    -(_cast_func)_callback
    +(TIMER_FUNC_TYPE)_callback
    ;
    |
    _E._timer.function =
    -(_cast_func)&_callback
    +(TIMER_FUNC_TYPE)_callback
    ;
    )

    // Sometimes timer functions are called directly. Replace matched args.
    @change_timer_function_calls
    depends on change_timer_function_usage &&
    (change_callback_handle_cast ||
    change_callback_handle_cast_no_arg ||
    change_callback_handle_arg)@
    expression _E;
    identifier change_timer_function_usage._timer;
    identifier change_timer_function_usage._callback;
    type _cast_data;
    @@

    _callback(
    (
    -(_cast_data)_E
    +&_E->_timer
    |
    -(_cast_data)&_E
    +&_E._timer
    |
    -_E
    +&_E->_timer
    )
    )

    // If a timer has been configured without a data argument, it can be
    // converted without regard to the callback argument, since it is unused.
    @match_timer_function_unused_data@
    expression _E;
    identifier _timer;
    identifier _callback;
    @@

    (
    -setup_timer(&_E->_timer, _callback, 0);
    +timer_setup(&_E->_timer, _callback, 0);
    |
    -setup_timer(&_E->_timer, _callback, 0L);
    +timer_setup(&_E->_timer, _callback, 0);
    |
    -setup_timer(&_E->_timer, _callback, 0UL);
    +timer_setup(&_E->_timer, _callback, 0);
    |
    -setup_timer(&_E._timer, _callback, 0);
    +timer_setup(&_E._timer, _callback, 0);
    |
    -setup_timer(&_E._timer, _callback, 0L);
    +timer_setup(&_E._timer, _callback, 0);
    |
    -setup_timer(&_E._timer, _callback, 0UL);
    +timer_setup(&_E._timer, _callback, 0);
    |
    -setup_timer(&_timer, _callback, 0);
    +timer_setup(&_timer, _callback, 0);
    |
    -setup_timer(&_timer, _callback, 0L);
    +timer_setup(&_timer, _callback, 0);
    |
    -setup_timer(&_timer, _callback, 0UL);
    +timer_setup(&_timer, _callback, 0);
    |
    -setup_timer(_timer, _callback, 0);
    +timer_setup(_timer, _callback, 0);
    |
    -setup_timer(_timer, _callback, 0L);
    +timer_setup(_timer, _callback, 0);
    |
    -setup_timer(_timer, _callback, 0UL);
    +timer_setup(_timer, _callback, 0);
    )

    @change_callback_unused_data
    depends on match_timer_function_unused_data@
    identifier match_timer_function_unused_data._callback;
    type _origtype;
    identifier _origarg;
    @@

    void _callback(
    -_origtype _origarg
    +struct timer_list *unused
    )
    {
    ... when != _origarg
    }

    Signed-off-by: Kees Cook

    Kees Cook
     

19 Nov, 2017

4 commits

  • The workaround code is never used because Skylake NTB does not need it.

    Reported-by: Allen Hubbe
    Signed-off-by: Dave Jiang
    Signed-off-by: Jon Mason

    Dave Jiang
     
  • Make these const as they are only used during a copy operation.
    Done using Coccinelle.

    Signed-off-by: Bhumika Goyal
    Signed-off-by: Jon Mason

    Bhumika Goyal
     
  • The Switchtec hardware has two types of memory windows: LUTs and Direct.
    The first area in each BAR is for LUT windows and the remaining area is
    for the direct region. The total number of LUT entries is set by a
    configuration setting in hardware and they all must be the same
    size. (This is fixed by switchtec_ntb to be 64K.)

    switchtec_ntb enables the LUTs only for the first BAR and enables the
    highest power of two possible. Seeing the LUTs are at the beginning of
    the BAR, the direct memory window's alignment is affected. Therefore,
    the maximum direct memory window size can not be greater than the number
    of LUTs times 64K. The direct window in other BARs will not have this
    restriction as the LUTs will not be enabled there. LUTs will only be
    exposed through the NTB API if the use_lut_mw parameter is set.

    Seeing the Switchtec hardware, by default, configures BARs to be 4G a
    module parameter is given to limit the size of the advertised memory
    windows. Higher layers tend to allocate the maximum BAR size and this
    has a tendency to fail when they try to allocate 4GB of contiguous
    memory.

    Signed-off-by: Logan Gunthorpe
    Reviewed-by: Stephen Bates
    Reviewed-by: Kurt Schwemmer
    Acked-by: Allen Hubbe
    Signed-off-by: Jon Mason

    Logan Gunthorpe
     
  • Seeing there is no dedicated hardware for this, we simply add
    these as entries in the shared memory window. Thus, we could support
    any number of them but 128 seems like enough, for now.

    Signed-off-by: Logan Gunthorpe
    Reviewed-by: Stephen Bates
    Reviewed-by: Kurt Schwemmer
    Acked-by: Allen Hubbe
    Signed-off-by: Jon Mason

    Logan Gunthorpe