15 Jan, 2020

1 commit

  • commit 0e62395da2bd5166d7c9e14cbc7503b256a34cb0 upstream.

    In bfad_im_get_stats if bfa_port_get_stats fails, allocated memory needs to
    be released.

    Link: https://lore.kernel.org/r/20190910234417.22151-1-navid.emamdoost@gmail.com
    Signed-off-by: Navid Emamdoost
    Signed-off-by: Martin K. Petersen
    Cc: Ben Hutchings
    Signed-off-by: Greg Kroah-Hartman

    Navid Emamdoost
     

30 Aug, 2019

1 commit


05 Jun, 2019

1 commit

  • Based on 1 normalized pattern(s):

    this program is free software you can redistribute it and or modify
    it under the terms of the gnu general public license gpl version 2
    as published by the free software foundation this program is
    distributed in the hope that it will be useful but without any
    warranty without even the implied warranty of merchantability or
    fitness for a particular purpose see the gnu general public license
    for more details

    extracted by the scancode license scanner the SPDX license identifier

    GPL-2.0-only

    has been chosen to replace the boilerplate/reference in 66 file(s).

    Signed-off-by: Thomas Gleixner
    Reviewed-by: Allison Randal
    Reviewed-by: Alexios Zavras
    Cc: linux-spdx@vger.kernel.org
    Link: https://lkml.kernel.org/r/20190529141901.606369721@linutronix.de
    Signed-off-by: Greg Kroah-Hartman

    Thomas Gleixner
     

08 May, 2019

1 commit

  • …kernel/git/gustavoars/linux

    Pull Wimplicit-fallthrough updates from Gustavo A. R. Silva:
    "Mark switch cases where we are expecting to fall through.

    This is part of the ongoing efforts to enable -Wimplicit-fallthrough.

    Most of them have been baking in linux-next for a whole development
    cycle. And with Stephen Rothwell's help, we've had linux-next
    nag-emails going out for newly introduced code that triggers
    -Wimplicit-fallthrough to avoid gaining more of these cases while we
    work to remove the ones that are already present.

    We are getting close to completing this work. Currently, there are
    only 32 of 2311 of these cases left to be addressed in linux-next. I'm
    auditing every case; I take a look into the code and analyze it in
    order to determine if I'm dealing with an actual bug or a false
    positive, as explained here:

    https://lore.kernel.org/lkml/c2fad584-1705-a5f2-d63c-824e9b96cf50@embeddedor.com/

    While working on this, I've found and fixed the several missing
    break/return bugs, some of them introduced more than 5 years ago.

    Once this work is finished, we'll be able to universally enable
    "-Wimplicit-fallthrough" to avoid any of these kinds of bugs from
    entering the kernel again"

    * tag 'Wimplicit-fallthrough-5.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gustavoars/linux: (27 commits)
    memstick: mark expected switch fall-throughs
    drm/nouveau/nvkm: mark expected switch fall-throughs
    NFC: st21nfca: Fix fall-through warnings
    NFC: pn533: mark expected switch fall-throughs
    block: Mark expected switch fall-throughs
    ASN.1: mark expected switch fall-through
    lib/cmdline.c: mark expected switch fall-throughs
    lib: zstd: Mark expected switch fall-throughs
    scsi: sym53c8xx_2: sym_nvram: Mark expected switch fall-through
    scsi: sym53c8xx_2: sym_hipd: mark expected switch fall-throughs
    scsi: ppa: mark expected switch fall-through
    scsi: osst: mark expected switch fall-throughs
    scsi: lpfc: lpfc_scsi: Mark expected switch fall-throughs
    scsi: lpfc: lpfc_nvme: Mark expected switch fall-through
    scsi: lpfc: lpfc_nportdisc: Mark expected switch fall-through
    scsi: lpfc: lpfc_hbadisc: Mark expected switch fall-throughs
    scsi: lpfc: lpfc_els: Mark expected switch fall-throughs
    scsi: lpfc: lpfc_ct: Mark expected switch fall-throughs
    scsi: imm: mark expected switch fall-throughs
    scsi: csiostor: csio_wr: mark expected switch fall-through
    ...

    Linus Torvalds
     

09 Apr, 2019

1 commit

  • In preparation to enabling -Wimplicit-fallthrough, mark switch cases
    where we are expecting to fall through.

    Notice that I replaced "Fall through !!!" with a "fall through"
    annotation, which is what GCC is expecting to find.

    Addresses-Coverity-ID: 114971 ("Missing break in switch")
    Reviewed-by: Kees Cook
    Signed-off-by: Gustavo A. R. Silva

    Gustavo A. R. Silva
     

08 Apr, 2019

1 commit

  • mmiowb() is now implied by spin_unlock() on architectures that require
    it, so there is no reason to call it from driver code. This patch was
    generated using coccinelle:

    @mmiowb@
    @@
    - mmiowb();

    and invoked as:

    $ for d in drivers include/linux/qed sound; do \
    spatch --include-headers --sp-file mmiowb.cocci --dir $d --in-place; done

    NOTE: mmiowb() has only ever guaranteed ordering in conjunction with
    spin_unlock(). However, pairing each mmiowb() removal in this patch with
    the corresponding call to spin_unlock() is not at all trivial, so there
    is a small chance that this change may regress any drivers incorrectly
    relying on mmiowb() to order MMIO writes between CPUs using lock-free
    synchronisation. If you've ended up bisecting to this commit, you can
    reintroduce the mmiowb() calls using wmb() instead, which should restore
    the old behaviour on all architectures other than some esoteric ia64
    systems.

    Acked-by: Linus Torvalds
    Signed-off-by: Will Deacon

    Will Deacon
     

10 Mar, 2019

1 commit

  • Pull SCSI updates from James Bottomley:
    "This is mostly update of the usual drivers: arcmsr, qla2xxx, lpfc,
    hisi_sas, target/iscsi and target/core.

    Additionally Christoph refactored gdth as part of the dma changes. The
    major mid-layer change this time is the removal of bidi commands and
    with them the whole of the osd/exofs driver and filesystem. This is a
    major simplification for block and mq in particular"

    * tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (240 commits)
    scsi: cxgb4i: validate tcp sequence number only if chip version pf
    scsi: core: replace GFP_ATOMIC with GFP_KERNEL in scsi_scan.c
    scsi: mpt3sas: Add missing breaks in switch statements
    scsi: aacraid: Fix missing break in switch statement
    scsi: kill command serial number
    scsi: csiostor: drop serial_number usage
    scsi: mvumi: use request tag instead of serial_number
    scsi: dpt_i2o: remove serial number usage
    scsi: st: osst: Remove negative constant left-shifts
    scsi: ufs-bsg: Allow reading descriptors
    scsi: ufs: Allow reading descriptor via raw upiu
    scsi: ufs-bsg: Change the calling convention for write descriptor
    scsi: ufs: Remove unused device quirks
    Revert "scsi: ufs: disable vccq if it's not needed by UFS device"
    scsi: megaraid_sas: Remove a bunch of set but not used variables
    scsi: clean obsolete return values of eh_timed_out
    scsi: sd: Optimal I/O size should be a multiple of physical block size
    scsi: MAINTAINERS: SCSI initiator and target tweaks
    scsi: fcoe: make use of fip_mode enum complete
    ...

    Linus Torvalds
     

03 Mar, 2019

1 commit

  • Pull SCSI fixes from James Bottomley:
    "Nine small fixes.

    The resume fix is a cosmetic removal of a warning with an incorrect
    condition causing it to alarm people wrongly.

    The other eight patches correct a thinko in Christoph Hellwig's DMA
    conversion series. Without it all these drivers end up with 32 bit DMA
    masks meaning they bounce any page over 4GB before sending it to the
    controller.

    Nowadays, even laptops mostly have memory above 4GB, so this can lead
    to significant performance degradation with all the bouncing"

    * tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi:
    scsi: core: Avoid that system resume triggers a kernel warning
    scsi: hptiop: fix calls to dma_set_mask()
    scsi: hisi_sas: fix calls to dma_set_mask_and_coherent()
    scsi: csiostor: fix calls to dma_set_mask_and_coherent()
    scsi: bfa: fix calls to dma_set_mask_and_coherent()
    scsi: aic94xx: fix calls to dma_set_mask_and_coherent()
    scsi: 3w-sas: fix calls to dma_set_mask_and_coherent()
    scsi: 3w-9xxx: fix calls to dma_set_mask_and_coherent()
    scsi: lpfc: fix calls to dma_set_mask_and_coherent()

    Linus Torvalds
     

26 Feb, 2019

1 commit

  • The change to use dma_set_mask_and_coherent() incorrectly made a second
    call with the 32 bit DMA mask value when the call with the 64 bit DMA mask
    value succeeded.

    [mkp: fixed commit message]

    Fixes: a69b080025ea ("scsi: bfa: use dma_set_mask_and_coherent")
    Cc:
    Suggested-by: Ewan D. Milne
    Signed-off-by: Hannes Reinecke
    Reviewed-by: Christoph Hellwig
    Reviewed-by: Ewan D. Milne
    Signed-off-by: Martin K. Petersen

    Hannes Reinecke
     

29 Jan, 2019

1 commit

  • When calling debugfs functions, there is no need to ever check the return
    value. The function can work or not, but the code logic should never do
    something different based on this.

    [mkp: removed unused label]

    Cc: Anil Gurumurthy
    Cc: Sudarsana Kalluru
    Cc: "James E.J. Bottomley"
    Cc: "Martin K. Petersen"
    Cc: linux-scsi@vger.kernel.org
    Signed-off-by: Greg Kroah-Hartman
    Signed-off-by: Martin K. Petersen

    Greg Kroah-Hartman
     

12 Jan, 2019

3 commits

  • In preparation to enabling -Wimplicit-fallthrough, mark switch cases where
    we are expecting to fall through.

    Notice that, in this particular case, I replaced "!!! fall through !!!"
    comment with "fall through" annotations, which is what GCC is expecting to
    find.

    Addresses-Coverity-ID: 146155 ("Missing break in switch")
    Signed-off-by: Gustavo A. R. Silva
    Acked-by: Sudarsana Kalluru
    Signed-off-by: Martin K. Petersen

    Gustavo A. R. Silva
     
  • In preparation to enabling -Wimplicit-fallthrough, mark switch cases where
    we are expecting to fall through.

    Notice that I replaced "!! fall through !!" and "!!! fall through !!!"
    comments with "fall through" annotations, which is what GCC is expecting to
    find.

    Addresses-Coverity-ID: 744899 ("Missing break in switch")
    Addresses-Coverity-ID: 744900 ("Missing break in switch")
    Addresses-Coverity-ID: 744901 ("Missing break in switch")
    Signed-off-by: Gustavo A. R. Silva
    Acked-by: Sudarsana Kalluru
    Signed-off-by: Martin K. Petersen

    Gustavo A. R. Silva
     
  • In preparation to enabling -Wimplicit-fallthrough, mark switch cases where
    we are expecting to fall through.

    Notice that, in this particular case, I replaced "!!! fall through !!!"
    with a "fall through" annotation, which is what GCC is expecting to find.

    Signed-off-by: Gustavo A. R. Silva
    Acked-by: Sudarsana Kalluru
    Signed-off-by: Martin K. Petersen

    Gustavo A. R. Silva
     

08 Jan, 2019

1 commit

  • We already need to zero out memory for dma_alloc_coherent(), as such
    using dma_zalloc_coherent() is superflous. Phase it out.

    This change was generated with the following Coccinelle SmPL patch:

    @ replace_dma_zalloc_coherent @
    expression dev, size, data, handle, flags;
    @@

    -dma_zalloc_coherent(dev, size, handle, flags)
    +dma_alloc_coherent(dev, size, handle, flags)

    Suggested-by: Christoph Hellwig
    Signed-off-by: Luis Chamberlain
    [hch: re-ran the script on the latest tree]
    Signed-off-by: Christoph Hellwig

    Luis Chamberlain
     

20 Dec, 2018

1 commit


19 Dec, 2018

1 commit

  • Most SCSI drivers want to enable "clustering", that is merging of
    segments so that they might span more than a single page. Remove the
    ENABLE_CLUSTERING define, and require drivers to explicitly set
    DISABLE_CLUSTERING to disable this feature.

    Signed-off-by: Christoph Hellwig
    Signed-off-by: Martin K. Petersen

    Christoph Hellwig
     

16 Nov, 2018

1 commit

  • The driver currently uses pci_set_dma_mask despite otherwise using the
    generic DMA API. Switch it over to the better generic DMA API helper and
    also ensure we set the coherent mask as well in the resume path.

    Signed-off-by: Christoph Hellwig
    Signed-off-by: Martin K. Petersen

    Christoph Hellwig
     

25 Oct, 2018

1 commit

  • Pull SCSI updates from James Bottomley:
    "This is mostly updates of the usual drivers: UFS, esp_scsi, NCR5380,
    qla2xxx, lpfc, libsas, hisi_sas.

    In addition there's a set of mostly small updates to the target
    subsystem a set of conversions to the generic DMA API, which do have
    some potential for issues in the older drivers but we'll handle those
    as case by case fixes.

    A new myrs driver for the DAC960/mylex raid controllers to replace the
    block based DAC960 which is also being removed by Jens in this merge
    window.

    Plus the usual slew of trivial changes"

    [ "myrs" stands for "MYlex Raid Scsi". Obviously. Silly of me to even
    wonder. There's also a "myrb" driver, where the 'b' stands for
    'block'. Truly, somebody has got mad naming skillz. - Linus ]

    * tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (237 commits)
    scsi: myrs: Fix the processor absent message in processor_show()
    scsi: myrs: Fix a logical vs bitwise bug
    scsi: hisi_sas: Fix NULL pointer dereference
    scsi: myrs: fix build failure on 32 bit
    scsi: fnic: replace gross legacy tag hack with blk-mq hack
    scsi: mesh: switch to generic DMA API
    scsi: ips: switch to generic DMA API
    scsi: smartpqi: fully convert to the generic DMA API
    scsi: vmw_pscsi: switch to generic DMA API
    scsi: snic: switch to generic DMA API
    scsi: qla4xxx: fully convert to the generic DMA API
    scsi: qla2xxx: fully convert to the generic DMA API
    scsi: qla1280: switch to generic DMA API
    scsi: qedi: fully convert to the generic DMA API
    scsi: qedf: fully convert to the generic DMA API
    scsi: pm8001: switch to generic DMA API
    scsi: nsp32: switch to generic DMA API
    scsi: mvsas: fully convert to the generic DMA API
    scsi: mvumi: switch to generic DMA API
    scsi: mpt3sas: switch to generic DMA API
    ...

    Linus Torvalds
     

17 Oct, 2018

2 commits

  • Clang warns when one enumerated type is implicitly converted to another.

    drivers/scsi/bfa/bfa_fcs_lport.c:379:26: warning: implicit conversion
    from enumeration type 'enum bfa_lport_aen_event' to different
    enumeration type 'enum bfa_ioc_aen_event' [-Wenum-conversion]
    BFA_AEN_CAT_LPORT, event);
    ^~~~~

    The root cause of these warnings is the bfad_im_post_vendor_event
    function, which expects a value from enum bfa_ioc_aen_event but there
    are multiple instances of values from enums bfa_port_aen_event,
    bfa_audit_aen_event, and bfa_lport_aen_event being used in this
    function.

    Given that this doesn't appear to be a problem since cat helps with
    differentiating the events, just change evt's type to int so that no
    conversion needs to happen and Clang won't warn. Update aen_type's type
    in bfa_aen_entry_s as members that hold enumerated types should be int.

    Link: https://github.com/ClangBuiltLinux/linux/issues/147
    Signed-off-by: Nathan Chancellor
    Reviewed-by: Nick Desaulniers
    Signed-off-by: Martin K. Petersen

    Nathan Chancellor
     
  • Clang warns when a variable is assigned to itself.

    drivers/scsi/bfa/bfa_fcbuild.c:199:6: warning: explicitly assigning
    value of variable of type 'int' to itself [-Wself-assign]
    len = len;
    ~~~ ^ ~~~
    drivers/scsi/bfa/bfa_fcbuild.c:838:6: warning: explicitly assigning
    value of variable of type 'int' to itself [-Wself-assign]
    len = len;
    ~~~ ^ ~~~
    drivers/scsi/bfa/bfa_fcbuild.c:917:6: warning: explicitly assigning
    value of variable of type 'int' to itself [-Wself-assign]
    len = len;
    ~~~ ^ ~~~
    drivers/scsi/bfa/bfa_fcbuild.c:981:6: warning: explicitly assigning
    value of variable of type 'int' to itself [-Wself-assign]
    len = len;
    ~~~ ^ ~~~
    drivers/scsi/bfa/bfa_fcbuild.c:1008:6: warning: explicitly assigning
    value of variable of type 'int' to itself [-Wself-assign]
    len = len;
    ~~~ ^ ~~~
    5 warnings generated.

    This construct is usually used to avoid unused variable warnings, which
    I assume is the case here. -Wunused-parameter is hidden behind -Wextra
    with GCC 4.6, which is the minimum version to compile the kernel as of
    commit cafa0010cd51 ("Raise the minimum required gcc version to 4.6").

    However, upon further inspection, these functions aren't actually used
    anywhere; they're just defined. Rather than just removing the self
    assignments, remove all of this dead code.

    Link: https://github.com/ClangBuiltLinux/linux/issues/148
    Signed-off-by: Nathan Chancellor
    Signed-off-by: Martin K. Petersen

    Nathan Chancellor
     

03 Oct, 2018

1 commit

  • After bfcb79fca19d ("PCI/ERR: Run error recovery callbacks for all affected
    devices"), AER errors are always cleared by the PCI core and drivers don't
    need to do it themselves.

    Remove calls to pci_cleanup_aer_uncorrect_error_status() from device
    driver error recovery functions.

    Signed-off-by: Oza Pawandeep
    [bhelgaas: changelog, remove PCI core changes, remove unused variables]
    Signed-off-by: Bjorn Helgaas

    Oza Pawandeep
     

11 Jul, 2018

1 commit


13 Jun, 2018

1 commit

  • The kzalloc() function has a 2-factor argument form, kcalloc(). This
    patch replaces cases of:

    kzalloc(a * b, gfp)

    with:
    kcalloc(a * b, gfp)

    as well as handling cases of:

    kzalloc(a * b * c, gfp)

    with:

    kzalloc(array3_size(a, b, c), gfp)

    as it's slightly less ugly than:

    kzalloc_array(array_size(a, b), c, gfp)

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

    kzalloc(4 * 1024, gfp)

    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(
    - (sizeof(TYPE)) * E
    + sizeof(TYPE) * E
    , ...)
    |
    kzalloc(
    - (sizeof(THING)) * E
    + sizeof(THING) * E
    , ...)
    )

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

    (
    kzalloc(
    - sizeof(u8) * (COUNT)
    + COUNT
    , ...)
    |
    kzalloc(
    - sizeof(__u8) * (COUNT)
    + COUNT
    , ...)
    |
    kzalloc(
    - sizeof(char) * (COUNT)
    + COUNT
    , ...)
    |
    kzalloc(
    - sizeof(unsigned char) * (COUNT)
    + COUNT
    , ...)
    |
    kzalloc(
    - sizeof(u8) * COUNT
    + COUNT
    , ...)
    |
    kzalloc(
    - sizeof(__u8) * COUNT
    + COUNT
    , ...)
    |
    kzalloc(
    - sizeof(char) * COUNT
    + COUNT
    , ...)
    |
    kzalloc(
    - 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
    + kcalloc
    (
    - sizeof(TYPE) * (COUNT_ID)
    + COUNT_ID, sizeof(TYPE)
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - sizeof(TYPE) * COUNT_ID
    + COUNT_ID, sizeof(TYPE)
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - sizeof(TYPE) * (COUNT_CONST)
    + COUNT_CONST, sizeof(TYPE)
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - sizeof(TYPE) * COUNT_CONST
    + COUNT_CONST, sizeof(TYPE)
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - sizeof(THING) * (COUNT_ID)
    + COUNT_ID, sizeof(THING)
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - sizeof(THING) * COUNT_ID
    + COUNT_ID, sizeof(THING)
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - sizeof(THING) * (COUNT_CONST)
    + COUNT_CONST, sizeof(THING)
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - sizeof(THING) * COUNT_CONST
    + COUNT_CONST, sizeof(THING)
    , ...)
    )

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

    - kzalloc
    + kcalloc
    (
    - 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(
    - sizeof(TYPE) * (COUNT) * (STRIDE)
    + array3_size(COUNT, STRIDE, sizeof(TYPE))
    , ...)
    |
    kzalloc(
    - sizeof(TYPE) * (COUNT) * STRIDE
    + array3_size(COUNT, STRIDE, sizeof(TYPE))
    , ...)
    |
    kzalloc(
    - sizeof(TYPE) * COUNT * (STRIDE)
    + array3_size(COUNT, STRIDE, sizeof(TYPE))
    , ...)
    |
    kzalloc(
    - sizeof(TYPE) * COUNT * STRIDE
    + array3_size(COUNT, STRIDE, sizeof(TYPE))
    , ...)
    |
    kzalloc(
    - sizeof(THING) * (COUNT) * (STRIDE)
    + array3_size(COUNT, STRIDE, sizeof(THING))
    , ...)
    |
    kzalloc(
    - sizeof(THING) * (COUNT) * STRIDE
    + array3_size(COUNT, STRIDE, sizeof(THING))
    , ...)
    |
    kzalloc(
    - sizeof(THING) * COUNT * (STRIDE)
    + array3_size(COUNT, STRIDE, sizeof(THING))
    , ...)
    |
    kzalloc(
    - 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(
    - sizeof(TYPE1) * sizeof(TYPE2) * COUNT
    + array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
    , ...)
    |
    kzalloc(
    - sizeof(TYPE1) * sizeof(THING2) * (COUNT)
    + array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
    , ...)
    |
    kzalloc(
    - sizeof(THING1) * sizeof(THING2) * COUNT
    + array3_size(COUNT, sizeof(THING1), sizeof(THING2))
    , ...)
    |
    kzalloc(
    - sizeof(THING1) * sizeof(THING2) * (COUNT)
    + array3_size(COUNT, sizeof(THING1), sizeof(THING2))
    , ...)
    |
    kzalloc(
    - sizeof(TYPE1) * sizeof(THING2) * COUNT
    + array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
    , ...)
    |
    kzalloc(
    - 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(
    - (COUNT) * STRIDE * SIZE
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kzalloc(
    - COUNT * (STRIDE) * SIZE
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kzalloc(
    - COUNT * STRIDE * (SIZE)
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kzalloc(
    - (COUNT) * (STRIDE) * SIZE
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kzalloc(
    - COUNT * (STRIDE) * (SIZE)
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kzalloc(
    - (COUNT) * STRIDE * (SIZE)
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kzalloc(
    - (COUNT) * (STRIDE) * (SIZE)
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kzalloc(
    - 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(C1 * C2 * C3, ...)
    |
    kzalloc(
    - (E1) * E2 * E3
    + array3_size(E1, E2, E3)
    , ...)
    |
    kzalloc(
    - (E1) * (E2) * E3
    + array3_size(E1, E2, E3)
    , ...)
    |
    kzalloc(
    - (E1) * (E2) * (E3)
    + array3_size(E1, E2, E3)
    , ...)
    |
    kzalloc(
    - 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(sizeof(THING) * C2, ...)
    |
    kzalloc(sizeof(TYPE) * C2, ...)
    |
    kzalloc(C1 * C2 * C3, ...)
    |
    kzalloc(C1 * C2, ...)
    |
    - kzalloc
    + kcalloc
    (
    - sizeof(TYPE) * (E2)
    + E2, sizeof(TYPE)
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - sizeof(TYPE) * E2
    + E2, sizeof(TYPE)
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - sizeof(THING) * (E2)
    + E2, sizeof(THING)
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - sizeof(THING) * E2
    + E2, sizeof(THING)
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - (E1) * E2
    + E1, E2
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - (E1) * (E2)
    + E1, E2
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - E1 * E2
    + E1, E2
    , ...)
    )

    Signed-off-by: Kees Cook

    Kees Cook
     

15 Mar, 2018

1 commit

  • In preparation to enabling -Wvla, remove VLAs and replace them with
    fixed-length arrays instead.

    bfad_bsg.c uses a variable-length array declaration to measure the
    size of a putative array; this can be replaced by the product of the
    size of an element and the number of elements, avoiding the VLA
    altogether.

    This was prompted by https://lkml.org/lkml/2018/3/7/621

    Signed-off-by: Stephen Kitt
    Reviewed-by: Kees Cook
    Signed-off-by: Martin K. Petersen

    Stephen Kitt
     

01 Feb, 2018

1 commit

  • Pull SCSI updates from James Bottomley:
    "This is mostly updates of the usual driver suspects: arcmsr,
    scsi_debug, mpt3sas, lpfc, cxlflash, qla2xxx, aacraid, megaraid_sas,
    hisi_sas.

    We also have a rework of the libsas hotplug handling to make it more
    robust, a slew of 32 bit time conversions and fixes, and a host of the
    usual minor updates and style changes. The biggest potential for
    regressions is the libsas hotplug changes, but so far they seem stable
    under testing"

    * tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (313 commits)
    scsi: qla2xxx: Fix logo flag for qlt_free_session_done()
    scsi: arcmsr: avoid do_gettimeofday
    scsi: core: Add VENDOR_SPECIFIC sense code definitions
    scsi: qedi: Drop cqe response during connection recovery
    scsi: fas216: fix sense buffer initialization
    scsi: ibmvfc: Remove unneeded semicolons
    scsi: hisi_sas: fix a bug in hisi_sas_dev_gone()
    scsi: hisi_sas: directly attached disk LED feature for v2 hw
    scsi: hisi_sas: devicetree: bindings: add LED feature for v2 hw
    scsi: megaraid_sas: NVMe passthrough command support
    scsi: megaraid: use ktime_get_real for firmware time
    scsi: fnic: use 64-bit timestamps
    scsi: qedf: Fix error return code in __qedf_probe()
    scsi: devinfo: fix format of the device list
    scsi: qla2xxx: Update driver version to 10.00.00.05-k
    scsi: qla2xxx: Add XCB counters to debugfs
    scsi: qla2xxx: Fix queue ID for async abort with Multiqueue
    scsi: qla2xxx: Fix warning for code intentation in __qla24xx_handle_gpdb_event()
    scsi: qla2xxx: Fix warning during port_name debug print
    scsi: qla2xxx: Fix warning in qla2x00_async_iocb_timeout()
    ...

    Linus Torvalds
     

11 Jan, 2018

1 commit


04 Jan, 2018

1 commit


16 Dec, 2017

1 commit

  • Pull SCSI fixes from James Bottomley:
    "The most important one is the bfa fix because it's easy to oops the
    kernel with this driver (this includes the commit that corrects the
    compiler warning in the original), a regression in the new timespec
    conversion in aacraid and a regression in the Fibre Channel ELS
    handling patch.

    The other three are a theoretical problem with termination in the
    vendor/host matching code and a use after free in lpfc.

    The additional patches are a fix for an I/O hang in the mq code under
    certain circumstances and a rare oops in some debugging code"

    * tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi:
    scsi: core: Fix a scsi_show_rq() NULL pointer dereference
    scsi: MAINTAINERS: change FCoE list to linux-scsi
    scsi: libsas: fix length error in sas_smp_handler()
    scsi: bfa: fix type conversion warning
    scsi: core: run queue if SCSI device queue isn't ready and queue is idle
    scsi: scsi_devinfo: cleanly zero-pad devinfo strings
    scsi: scsi_devinfo: handle non-terminated strings
    scsi: bfa: fix access to bfad_im_port_s
    scsi: aacraid: address UBSAN warning regression
    scsi: libfc: fix ELS request handling
    scsi: lpfc: Use after free in lpfc_rq_buf_free()

    Linus Torvalds
     

12 Dec, 2017

1 commit

  • The bfa driver has a number of real issues with string termination
    that gcc-8 now points out:

    drivers/scsi/bfa/bfad_bsg.c: In function 'bfad_iocmd_port_get_attr':
    drivers/scsi/bfa/bfad_bsg.c:320:9: error: argument to 'sizeof' in 'strncpy' call is the same expression as the source; did you mean to use the size of the destination? [-Werror=sizeof-pointer-memaccess]
    drivers/scsi/bfa/bfa_fcs.c: In function 'bfa_fcs_fabric_psymb_init':
    drivers/scsi/bfa/bfa_fcs.c:775:9: error: argument to 'sizeof' in 'strncat' call is the same expression as the source; did you mean to use the size of the destination? [-Werror=sizeof-pointer-memaccess]
    drivers/scsi/bfa/bfa_fcs.c:781:9: error: argument to 'sizeof' in 'strncat' call is the same expression as the source; did you mean to use the size of the destination? [-Werror=sizeof-pointer-memaccess]
    drivers/scsi/bfa/bfa_fcs.c:788:9: error: argument to 'sizeof' in 'strncat' call is the same expression as the source; did you mean to use the size of the destination? [-Werror=sizeof-pointer-memaccess]
    drivers/scsi/bfa/bfa_fcs.c:801:10: error: argument to 'sizeof' in 'strncat' call is the same expression as the source; did you mean to use the size of the destination? [-Werror=sizeof-pointer-memaccess]
    drivers/scsi/bfa/bfa_fcs.c:808:10: error: argument to 'sizeof' in 'strncat' call is the same expression as the source; did you mean to use the size of the destination? [-Werror=sizeof-pointer-memaccess]
    drivers/scsi/bfa/bfa_fcs.c: In function 'bfa_fcs_fabric_nsymb_init':
    drivers/scsi/bfa/bfa_fcs.c:837:10: error: argument to 'sizeof' in 'strncat' call is the same expression as the source; did you mean to use the size of the destination? [-Werror=sizeof-pointer-memaccess]
    drivers/scsi/bfa/bfa_fcs.c:844:10: error: argument to 'sizeof' in 'strncat' call is the same expression as the source; did you mean to use the size of the destination? [-Werror=sizeof-pointer-memaccess]
    drivers/scsi/bfa/bfa_fcs.c:852:10: error: argument to 'sizeof' in 'strncat' call is the same expression as the source; did you mean to use the size of the destination? [-Werror=sizeof-pointer-memaccess]
    drivers/scsi/bfa/bfa_fcs.c: In function 'bfa_fcs_fabric_psymb_init':
    drivers/scsi/bfa/bfa_fcs.c:778:2: error: 'strncat' output may be truncated copying 10 bytes from a string of length 63 [-Werror=stringop-truncation]
    drivers/scsi/bfa/bfa_fcs.c:784:2: error: 'strncat' output may be truncated copying 30 bytes from a string of length 63 [-Werror=stringop-truncation]
    drivers/scsi/bfa/bfa_fcs.c:803:3: error: 'strncat' output may be truncated copying 44 bytes from a string of length 63 [-Werror=stringop-truncation]
    drivers/scsi/bfa/bfa_fcs.c:811:3: error: 'strncat' output may be truncated copying 16 bytes from a string of length 63 [-Werror=stringop-truncation]
    drivers/scsi/bfa/bfa_fcs.c: In function 'bfa_fcs_fabric_nsymb_init':
    drivers/scsi/bfa/bfa_fcs.c:840:2: error: 'strncat' output may be truncated copying 10 bytes from a string of length 63 [-Werror=stringop-truncation]
    drivers/scsi/bfa/bfa_fcs.c:847:2: error: 'strncat' output may be truncated copying 30 bytes from a string of length 63 [-Werror=stringop-truncation]
    drivers/scsi/bfa/bfa_fcs_lport.c: In function 'bfa_fcs_fdmi_get_hbaattr':
    drivers/scsi/bfa/bfa_fcs_lport.c:2657:10: error: argument to 'sizeof' in 'strncat' call is the same expression as the source; did you mean to use the size of the destination? [-Werror=sizeof-pointer-memaccess]
    drivers/scsi/bfa/bfa_fcs_lport.c:2659:11: error: argument to 'sizeof' in 'strncat' call is the same expression as the source; did you mean to use the size of the destination? [-Werror=sizeof-pointer-memaccess]
    drivers/scsi/bfa/bfa_fcs_lport.c: In function 'bfa_fcs_lport_ms_gmal_response':
    drivers/scsi/bfa/bfa_fcs_lport.c:3232:5: error: 'strncpy' output may be truncated copying 16 bytes from a string of length 247 [-Werror=stringop-truncation]
    drivers/scsi/bfa/bfa_fcs_lport.c: In function 'bfa_fcs_lport_ns_send_rspn_id':
    drivers/scsi/bfa/bfa_fcs_lport.c:4670:3: error: 'strncpy' output truncated before terminating nul copying as many bytes from a string as its length [-Werror=stringop-truncation]
    drivers/scsi/bfa/bfa_fcs_lport.c:4682:3: error: 'strncat' output truncated before terminating nul copying as many bytes from a string as its length [-Werror=stringop-truncation]
    drivers/scsi/bfa/bfa_fcs_lport.c: In function 'bfa_fcs_lport_ns_util_send_rspn_id':
    drivers/scsi/bfa/bfa_fcs_lport.c:5206:3: error: 'strncpy' output truncated before terminating nul copying as many bytes from a string as its length [-Werror=stringop-truncation]
    drivers/scsi/bfa/bfa_fcs_lport.c:5215:3: error: 'strncat' output truncated before terminating nul copying as many bytes from a string as its length [-Werror=stringop-truncation]
    drivers/scsi/bfa/bfa_fcs_lport.c: In function 'bfa_fcs_fdmi_get_portattr':
    drivers/scsi/bfa/bfa_fcs_lport.c:2751:2: error: 'strncpy' specified bound 128 equals destination size [-Werror=stringop-truncation]
    drivers/scsi/bfa/bfa_fcbuild.c: In function 'fc_rspnid_build':
    drivers/scsi/bfa/bfa_fcbuild.c:1254:2: error: 'strncpy' output truncated before terminating nul copying as many bytes from a string as its length [-Werror=stringop-truncation]
    drivers/scsi/bfa/bfa_fcbuild.c:1253:25: note: length computed here
    drivers/scsi/bfa/bfa_fcbuild.c: In function 'fc_rsnn_nn_build':
    drivers/scsi/bfa/bfa_fcbuild.c:1275:2: error: 'strncpy' output truncated before terminating nul copying as many bytes from a string as its length [-Werror=stringop-truncation]

    In most cases, this can be addressed by correctly calling strlcpy and
    strlcat instead of strncpy/strncat, with the size of the destination
    buffer as the last argument.

    For consistency, I'm changing the other callers of strncpy() in this
    driver the same way.

    Signed-off-by: Arnd Bergmann
    Reviewed-by: Johannes Thumshirn
    Acked-by: Sudarsana Kalluru
    Signed-off-by: Martin K. Petersen

    Arnd Bergmann
     

08 Dec, 2017

1 commit

  • A regression fix introduced a harmless type mismatch warning:

    drivers/scsi/bfa/bfad_bsg.c: In function 'bfad_im_bsg_vendor_request':
    drivers/scsi/bfa/bfad_bsg.c:3137:35: error: initialization of 'struct bfad_im_port_s *' from 'long unsigned int' makes pointer from integer without a cast [-Werror=int-conversion]
    struct bfad_im_port_s *im_port = shost->hostdata[0];
    ^~~~~
    drivers/scsi/bfa/bfad_bsg.c: In function 'bfad_im_bsg_els_ct_request':
    drivers/scsi/bfa/bfad_bsg.c:3353:35: error: initialization of 'struct bfad_im_port_s *' from 'long unsigned int' makes pointer from integer without a cast [-Werror=int-conversion]
    struct bfad_im_port_s *im_port = shost->hostdata[0];

    This changes the code back to shost_priv() once more, but encapsulates
    it in an inline function to document the rather unusual way of
    using the private data only as a pointer to the previously allocated
    structure.

    I did not try to get rid of the extra indirection level entirely,
    which would have been rather invasive and required reworking the entire
    initialization sequence.

    Fixes: 45349821ab3a ("scsi: bfa: fix access to bfad_im_port_s")
    Signed-off-by: Arnd Bergmann
    Reviewed-by: Johannes Thumshirn
    Reviewed-by: Hannes Reinecke
    Signed-off-by: Martin K. Petersen

    Arnd Bergmann
     

05 Dec, 2017

8 commits

  • The pointer 'port' is being assigned but it is never read, hence it is
    redundant and can be removed. Cleans up clang warning:

    drivers/scsi/bfa/bfad_attr.c:505:2: warning: Value stored to 'port' is
    never read.

    Signed-off-by: Colin Ian King
    Signed-off-by: Martin K. Petersen

    Colin Ian King
     
  • bfa_aen_entry_s is passed through a netlink socket that can be read by
    either 32-bit or 64-bit processes, but the data format is different
    between the two on current implementations.

    Originally, this was using a 'struct timeval', which also suffers from
    getting redefined with a new libc implementation.

    With this patch, the layout gets fixed to having two 64-bit members for
    the time, making it the same on 32-bit kernels and 64-bit kernels
    running either compat or native user space including x32.

    Provided that the new header file gets used to recompile any 32-bit
    application binaries, this will fix running those on a 64-bit kernel
    (with or without this patch) e.g. in a container environment, and it
    will make binaries work that will be built against a future 32-bit glibc
    that uses a 64-bit time_t, and avoid the y2038 overflow there.

    However, this also breaks compatibility with any existing 32-bit binary
    running on a native 32-bit kernel, those must be recompiled against the
    new header, which in turn makes them incompatible with older kernels
    unless the same change gets applied there.

    Obviously this patch should only be applied when the benefits outweigh
    the possible breakage. I'm posting it under the assumption that there
    are no open-source tools using the netlink interface, and that users of
    the binaries provided by qlogic for SLES10/11 and RHEL5/6 are not
    actually being used on new future systems with 32-bit x86 kernels.

    Signed-off-by: Arnd Bergmann
    Acked-by: Anil Gurumurthy
    Signed-off-by: Martin K. Petersen

    Arnd Bergmann
     
  • bfa_aen_entry_s is passed to user space in a netlink message, but is
    defined using a 'struct timeval' and an 'enum' that are not only
    different between architectures, but also between 32-bit user space and
    64-bit kernels they may run on, as well as depending on the particular C
    library that defines timeval.

    This changes the in-kernel definition to no longer use the timeval type
    directly but instead use two open-coded 'unsigned long' members. This
    keeps the existing ABI, but making the variable unsigned also helps make
    it work after y2038, until it overflows in 2106.

    Since the macro becomes overly complex at this point, I'm changing it to
    an inline function for readability.

    I'm not changing the 32-bit user-space ABI at this point, to keep the
    changes separate, I deally this would be defined using the same binary
    layout for all architectures.

    Signed-off-by: Arnd Bergmann
    Acked-by: Anil Gurumurthy
    Signed-off-by: Martin K. Petersen

    Arnd Bergmann
     
  • The bfa_get_log_time() returns a 64-bit timestamp that does not suffer
    from the y2038 overflow on 64-bit systems. However, on 32-bit
    architectures the timestamp will jump from 0x000000007fffffff to
    0xffffffff80000000 in y2038 and produce wrong results.

    The ktime_get_real_seconds() function does the same thing as
    bfa_get_log_time() without that problem, so we can simply remove the
    former use ktime_get_real_seconds() instead.

    Signed-off-by: Arnd Bergmann
    Acked-by: Anil Gurumurthy
    Signed-off-by: Martin K. Petersen

    Arnd Bergmann
     
  • io_profile_start_time() gets read using do_gettimeofday() and passed
    down as a 32-bit value through multiple functions. This will overflow in
    y2038 or y2106, depending on whether it gets interpreted as unsigned in
    the end.

    This changes do_gettimeofday() to ktime_get_real_seconds() and pushes
    the point at which it overflows to where we actually assign it to the
    bfa_fcpim_del_itn_stats_s structure, with an appropriate comment.

    Signed-off-by: Arnd Bergmann
    Acked-by: Anil Gurumurthy
    Signed-off-by: Martin K. Petersen

    Arnd Bergmann
     
  • In bfa_ioc_send_enable, we use the deprecated do_gettimeofday() function
    to read the current time. This is not a problem, since the firmware
    interface is already limited to 32-bit timestamps, but it's better to
    use ktime_get_seconds() and document what the limitation is.

    I noticed that I did the same change in commit a5af83925363 ("bna: avoid
    writing uninitialized data into hw registers") for the ethernet
    driver. That commit also changed the "disable" funtion to initialize the
    data we pass to the firmware properly, so I'm doing the same thing here.

    Signed-off-by: Arnd Bergmann
    Acked-by: Anil Gurumurthy
    Signed-off-by: Martin K. Petersen

    Arnd Bergmann
     
  • We use the deprecated do_gettimeofday() function to read the current
    time when resetting the statistics in both bfa_port and bfa_svc. This
    works fine because overflow is handled correctly, but we want to get rid
    of do_gettimeofday() and using a non-monotonic time suffers from
    concurrent settimeofday calls and other problems.

    This uses the ktime_get_seconds() function instead, which does what we
    need here.

    Signed-off-by: Arnd Bergmann
    Acked-by: Anil Gurumurthy
    Signed-off-by: Martin K. Petersen

    Arnd Bergmann
     
  • BFA_TRC_TS() calculates a 32-bit microsecond timestamp using the
    deprecated do_gettimeofday() function. This overflows roughly every 71
    minutes, so it's obviously not used as an absolute time stamp, but it
    seems wrong to use a time base for it that will jump during
    settimeofday() calls, leap seconds, or the y2038 overflow.

    This converts it to ktime_get_ts64(), which has none of those problems
    but is not synchronized to wall-clock time.

    Signed-off-by: Arnd Bergmann
    Acked-by: Anil Gurumurthy
    Signed-off-by: Martin K. Petersen

    Arnd Bergmann
     

29 Nov, 2017

1 commit

  • Commit 'cd21c605b2cf ("scsi: fc: provide fc_bsg_to_shost() helper")'
    changed access to bfa's 'struct bfad_im_port_s' by using shost_priv()
    instead of shost->hostdata[0].

    This lead to crashes like in the following back-trace:

    task: ffff880046375300 ti: ffff8800a2ef8000 task.ti: ffff8800a2ef8000
    RIP: e030:[] [] bfa_fcport_get_attr+0x82/0x260 [bfa]
    RSP: e02b:ffff8800a2efba10 EFLAGS: 00010046
    RAX: 575f415441536432 RBX: ffff8800a2efba28 RCX: 0000000000000000
    RDX: 0000000000000000 RSI: ffff8800a2efba28 RDI: ffff880004dc31d8
    RBP: ffff880004dc31d8 R08: 0000000000000000 R09: 0000000000000001
    R10: ffff88011fadc468 R11: 0000000000000001 R12: ffff880004dc31f0
    R13: 0000000000000200 R14: ffff880004dc61d0 R15: ffff880004947a10
    FS: 00007feb1e489700(0000) GS:ffff88011fac0000(0000) knlGS:0000000000000000
    CS: e033 DS: 0000 ES: 0000 CR0: 000000008005003b
    CR2: 00007ffe14e46c10 CR3: 00000000957b8000 CR4: 0000000000000660
    Stack:
    ffff88001d4da000 ffff880004dc31c0 ffffffffa048a9df ffffffff81e56380
    0000000000000000 0000000000000000 0000000000000000 0000000000000000
    [] bfad_iocmd_ioc_get_info+0x4f/0x220 [bfa]
    [] bfad_iocmd_handler+0xa00/0xd40 [bfa]
    [] bfad_im_bsg_request+0xee/0x1b0 [bfa]
    [] fc_bsg_dispatch+0x10b/0x1b0 [scsi_transport_fc]
    [] bsg_request_fn+0x11d/0x1c0
    [] __blk_run_queue+0x2f/0x40
    [] blk_execute_rq_nowait+0xa8/0x160
    [] blk_execute_rq+0x77/0x120
    [] bsg_ioctl+0x1b6/0x200
    [] do_vfs_ioctl+0x2cd/0x4a0
    [] SyS_ioctl+0x74/0x80
    [] entry_SYSCALL_64_fastpath+0x12/0x6d

    Fixes: cd21c605b2cf ("scsi: fc: provide fc_bsg_to_shost() helper")
    Signed-off-by: Johannes Thumshirn
    Cc: Michal Koutný
    Reviewed-by: Hannes Reinecke
    Signed-off-by: Martin K. Petersen

    Johannes Thumshirn
     

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