1. 21 9月, 2018 4 次提交
    • M
      IB/hfi1: Fix destroy_qp hang after a link down · b4a4957d
      Michael J. Ruhl 提交于
      rvt_destroy_qp() cannot complete until all in process packets have
      been released from the underlying hardware.  If a link down event
      occurs, an application can hang with a kernel stack similar to:
      
      cat /proc/<app PID>/stack
       quiesce_qp+0x178/0x250 [hfi1]
       rvt_reset_qp+0x23d/0x400 [rdmavt]
       rvt_destroy_qp+0x69/0x210 [rdmavt]
       ib_destroy_qp+0xba/0x1c0 [ib_core]
       nvme_rdma_destroy_queue_ib+0x46/0x80 [nvme_rdma]
       nvme_rdma_free_queue+0x3c/0xd0 [nvme_rdma]
       nvme_rdma_destroy_io_queues+0x88/0xd0 [nvme_rdma]
       nvme_rdma_error_recovery_work+0x52/0xf0 [nvme_rdma]
       process_one_work+0x17a/0x440
       worker_thread+0x126/0x3c0
       kthread+0xcf/0xe0
       ret_from_fork+0x58/0x90
       0xffffffffffffffff
      
      quiesce_qp() waits until all outstanding packets have been freed.
      This wait should be momentary.  During a link down event, the cleanup
      handling does not ensure that all packets caught by the link down are
      flushed properly.
      
      This is caused by the fact that the freeze path and the link down
      event is handled the same.  This is not correct.  The freeze path
      waits until the HFI is unfrozen and then restarts PIO.  A link down
      is not a freeze event.  The link down path cannot restart the PIO
      until link is restored.  If the PIO path is restarted before the link
      comes up, the application (QP) using the PIO path will hang (until
      link is restored).
      
      Fix by separating the linkdown path from the freeze path and use the
      link down path for link down events.
      
      Close a race condition sc_disable() by acquiring both the progress
      and release locks.
      
      Close a race condition in sc_stop() by moving the setting of the flag
      bits under the alloc lock.
      
      Cc: <stable@vger.kernel.org> # 4.9.x+
      Fixes: 77241056 ("IB/hfi1: add driver files")
      Reviewed-by: NMike Marciniszyn <mike.marciniszyn@intel.com>
      Signed-off-by: NMichael J. Ruhl <michael.j.ruhl@intel.com>
      Signed-off-by: NDennis Dalessandro <dennis.dalessandro@intel.com>
      Signed-off-by: NJason Gunthorpe <jgg@mellanox.com>
      b4a4957d
    • M
      IB/hfi1: Fix context recovery when PBC has an UnsupportedVL · d623500b
      Michael J. Ruhl 提交于
      If a packet stream uses an UnsupportedVL (virtual lane), the send
      engine will not send the packet, and it will not indicate that an
      error has occurred.  This will cause the packet stream to block.
      
      HFI has 8 virtual lanes available for packet streams.  Each lane can
      be enabled or disabled using the UnsupportedVL mask.  If a lane is
      disabled, adding a packet to the send context must be disallowed.
      
      The current mask for determining unsupported VLs defaults to 0 (allow
      all).  This is incorrect.  Only the VLs that are defined should be
      allowed.
      
      Determine which VLs are disabled (mtu == 0), and set the appropriate
      unsupported bit in the mask.  The correct mask will allow the send
      engine to error on the invalid VL, and error recovery will work
      correctly.
      
      Cc: <stable@vger.kernel.org> # 4.9.x+
      Fixes: 77241056 ("IB/hfi1: add driver files")
      Reviewed-by: NMike Marciniszyn <mike.marciniszyn@intel.com>
      Reviewed-by: NLukasz Odzioba <lukasz.odzioba@intel.com>
      Signed-off-by: NMichael J. Ruhl <michael.j.ruhl@intel.com>
      Signed-off-by: NDennis Dalessandro <dennis.dalessandro@intel.com>
      Signed-off-by: NJason Gunthorpe <jgg@mellanox.com>
      d623500b
    • M
      IB/hfi1: Invalid user input can result in crash · 94694d18
      Michael J. Ruhl 提交于
      If the number of packets in a user sdma request does not match
      the actual iovectors being sent, sdma_cleanup can be called on
      an uninitialized request structure, resulting in a crash similar
      to this:
      
      BUG: unable to handle kernel NULL pointer dereference at 0000000000000008
      IP: [<ffffffffc0ae8bb7>] __sdma_txclean+0x57/0x1e0 [hfi1]
      PGD 8000001044f61067 PUD 1052706067 PMD 0
      Oops: 0000 [#1] SMP
      CPU: 30 PID: 69912 Comm: upsm Kdump: loaded Tainted: G           OE
      ------------   3.10.0-862.el7.x86_64 #1
      Hardware name: Intel Corporation S2600KPR/S2600KPR, BIOS
      SE5C610.86B.01.01.0019.101220160604 10/12/2016
      task: ffff8b331c890000 ti: ffff8b2ed1f98000 task.ti: ffff8b2ed1f98000
      RIP: 0010:[<ffffffffc0ae8bb7>]  [<ffffffffc0ae8bb7>] __sdma_txclean+0x57/0x1e0
      [hfi1]
      RSP: 0018:ffff8b2ed1f9bab0  EFLAGS: 00010286
      RAX: 0000000000008b2b RBX: ffff8b2adf6e0000 RCX: 0000000000000000
      RDX: 00000000000000a0 RSI: ffff8b2e9eedc540 RDI: ffff8b2adf6e0000
      RBP: ffff8b2ed1f9bad8 R08: 0000000000000000 R09: ffffffffc0b04a06
      R10: ffff8b331c890190 R11: ffffe6ed00bf1840 R12: ffff8b3315480000
      R13: ffff8b33154800f0 R14: 00000000fffffff2 R15: ffff8b2e9eedc540
      FS:  00007f035ac47740(0000) GS:ffff8b331e100000(0000) knlGS:0000000000000000
      CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
      CR2: 0000000000000008 CR3: 0000000c03fe6000 CR4: 00000000001607e0
      Call Trace:
       [<ffffffffc0b0570d>] user_sdma_send_pkts+0xdcd/0x1990 [hfi1]
       [<ffffffff9fe75fb0>] ? gup_pud_range+0x140/0x290
       [<ffffffffc0ad3105>] ? hfi1_mmu_rb_insert+0x155/0x1b0 [hfi1]
       [<ffffffffc0b0777b>] hfi1_user_sdma_process_request+0xc5b/0x11b0 [hfi1]
       [<ffffffffc0ac193a>] hfi1_aio_write+0xba/0x110 [hfi1]
       [<ffffffffa001a2bb>] do_sync_readv_writev+0x7b/0xd0
       [<ffffffffa001bede>] do_readv_writev+0xce/0x260
       [<ffffffffa022b089>] ? tty_ldisc_deref+0x19/0x20
       [<ffffffffa02268c0>] ? n_tty_ioctl+0xe0/0xe0
       [<ffffffffa001c105>] vfs_writev+0x35/0x60
       [<ffffffffa001c2bf>] SyS_writev+0x7f/0x110
       [<ffffffffa051f7d5>] system_call_fastpath+0x1c/0x21
      Code: 06 49 c7 47 18 00 00 00 00 0f 87 89 01 00 00 5b 41 5c 41 5d 41 5e 41 5f
      5d c3 66 2e 0f 1f 84 00 00 00 00 00 48 8b 4e 10 48 89 fb <48> 8b 51 08 49 89 d4
      83 e2 0c 41 81 e4 00 e0 00 00 48 c1 ea 02
      RIP  [<ffffffffc0ae8bb7>] __sdma_txclean+0x57/0x1e0 [hfi1]
       RSP <ffff8b2ed1f9bab0>
      CR2: 0000000000000008
      
      There are two exit points from user_sdma_send_pkts().  One (free_tx)
      merely frees the slab entry and one (free_txreq) cleans the sdma_txreq
      prior to freeing the slab entry.   The free_txreq variation can only be
      called after one of the sdma_init*() variations has been called.
      
      In the panic case, the slab entry had been allocated but not inited.
      
      Fix the issue by exiting through free_tx thus avoiding sdma_clean().
      
      Cc: <stable@vger.kernel.org> # 4.9.x+
      Fixes: 77241056 ("IB/hfi1: add driver files")
      Reviewed-by: NMike Marciniszyn <mike.marciniszyn@intel.com>
      Reviewed-by: NLukasz Odzioba <lukasz.odzioba@intel.com>
      Signed-off-by: NMichael J. Ruhl <michael.j.ruhl@intel.com>
      Signed-off-by: NDennis Dalessandro <dennis.dalessandro@intel.com>
      Signed-off-by: NJason Gunthorpe <jgg@mellanox.com>
      94694d18
    • I
      IB/hfi1: Fix SL array bounds check · 0dbfaa9f
      Ira Weiny 提交于
      The SL specified by a user needs to be a valid SL.
      
      Add a range check to the user specified SL value which protects from
      running off the end of the SL to SC table.
      
      CC: stable@vger.kernel.org
      Fixes: 77241056 ("IB/hfi1: add driver files")
      Signed-off-by: NIra Weiny <ira.weiny@intel.com>
      Signed-off-by: NDennis Dalessandro <dennis.dalessandro@intel.com>
      Signed-off-by: NJason Gunthorpe <jgg@mellanox.com>
      0dbfaa9f
  2. 12 9月, 2018 1 次提交
  3. 23 8月, 2018 1 次提交
    • M
      mm, oom: distinguish blockable mode for mmu notifiers · 93065ac7
      Michal Hocko 提交于
      There are several blockable mmu notifiers which might sleep in
      mmu_notifier_invalidate_range_start and that is a problem for the
      oom_reaper because it needs to guarantee a forward progress so it cannot
      depend on any sleepable locks.
      
      Currently we simply back off and mark an oom victim with blockable mmu
      notifiers as done after a short sleep.  That can result in selecting a new
      oom victim prematurely because the previous one still hasn't torn its
      memory down yet.
      
      We can do much better though.  Even if mmu notifiers use sleepable locks
      there is no reason to automatically assume those locks are held.  Moreover
      majority of notifiers only care about a portion of the address space and
      there is absolutely zero reason to fail when we are unmapping an unrelated
      range.  Many notifiers do really block and wait for HW which is harder to
      handle and we have to bail out though.
      
      This patch handles the low hanging fruit.
      __mmu_notifier_invalidate_range_start gets a blockable flag and callbacks
      are not allowed to sleep if the flag is set to false.  This is achieved by
      using trylock instead of the sleepable lock for most callbacks and
      continue as long as we do not block down the call chain.
      
      I think we can improve that even further because there is a common pattern
      to do a range lookup first and then do something about that.  The first
      part can be done without a sleeping lock in most cases AFAICS.
      
      The oom_reaper end then simply retries if there is at least one notifier
      which couldn't make any progress in !blockable mode.  A retry loop is
      already implemented to wait for the mmap_sem and this is basically the
      same thing.
      
      The simplest way for driver developers to test this code path is to wrap
      userspace code which uses these notifiers into a memcg and set the hard
      limit to hit the oom.  This can be done e.g.  after the test faults in all
      the mmu notifier managed memory and set the hard limit to something really
      small.  Then we are looking for a proper process tear down.
      
      [akpm@linux-foundation.org: coding style fixes]
      [akpm@linux-foundation.org: minor code simplification]
      Link: http://lkml.kernel.org/r/20180716115058.5559-1-mhocko@kernel.orgSigned-off-by: NMichal Hocko <mhocko@suse.com>
      Acked-by: Christian König <christian.koenig@amd.com> # AMD notifiers
      Acked-by: Leon Romanovsky <leonro@mellanox.com> # mlx and umem_odp
      Reported-by: NDavid Rientjes <rientjes@google.com>
      Cc: "David (ChunMing) Zhou" <David1.Zhou@amd.com>
      Cc: Paolo Bonzini <pbonzini@redhat.com>
      Cc: Alex Deucher <alexander.deucher@amd.com>
      Cc: David Airlie <airlied@linux.ie>
      Cc: Jani Nikula <jani.nikula@linux.intel.com>
      Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
      Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
      Cc: Doug Ledford <dledford@redhat.com>
      Cc: Jason Gunthorpe <jgg@ziepe.ca>
      Cc: Mike Marciniszyn <mike.marciniszyn@intel.com>
      Cc: Dennis Dalessandro <dennis.dalessandro@intel.com>
      Cc: Sudeep Dutt <sudeep.dutt@intel.com>
      Cc: Ashutosh Dixit <ashutosh.dixit@intel.com>
      Cc: Dimitri Sivanich <sivanich@sgi.com>
      Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
      Cc: Juergen Gross <jgross@suse.com>
      Cc: "Jérôme Glisse" <jglisse@redhat.com>
      Cc: Andrea Arcangeli <aarcange@redhat.com>
      Cc: Felix Kuehling <felix.kuehling@amd.com>
      Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      93065ac7
  4. 21 8月, 2018 1 次提交
    • M
      IB/hfi1: Invalid NUMA node information can cause a divide by zero · c513de49
      Michael J. Ruhl 提交于
      If the system BIOS does not supply NUMA node information to the
      PCI devices, the NUMA node is selected by choosing the current
      node.
      
      This can lead to the following crash:
      
      divide error: 0000 SMP
      CPU: 0 PID: 4 Comm: kworker/0:0 Tainted: G          IOE
      ------------   3.10.0-693.21.1.el7.x86_64 #1
      Hardware name: Intel Corporation S2600KP/S2600KP, BIOS
      SE5C610.86B.01.01.0005.101720141054 10/17/2014
      Workqueue: events work_for_cpu_fn
      task: ffff880174480fd0 ti: ffff880174488000 task.ti: ffff880174488000
      RIP: 0010: [<ffffffffc020ac69>] hfi1_dev_affinity_init+0x129/0x6a0 [hfi1]
      RSP: 0018:ffff88017448bbf8  EFLAGS: 00010246
      RAX: 0000000000000011 RBX: ffff88107ffba6c0 RCX: ffff88085c22e130
      RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffff880824ad0000
      RBP: ffff88017448bc48 R08: 0000000000000011 R09: 0000000000000002
      R10: ffff8808582b6ca0 R11: 0000000000003151 R12: ffff8808582b6ca0
      R13: ffff8808582b6518 R14: ffff8808582b6010 R15: 0000000000000012
      FS:  0000000000000000(0000) GS:ffff88085ec00000(0000) knlGS:0000000000000000
      CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
      CR2: 00007efc707404f0 CR3: 0000000001a02000 CR4: 00000000001607f0
      DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
      DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
      Call Trace:
       hfi1_init_dd+0x14b3/0x27a0 [hfi1]
       ? pcie_capability_write_word+0x46/0x70
       ? hfi1_pcie_init+0xc0/0x200 [hfi1]
       do_init_one+0x153/0x4c0 [hfi1]
       ? sched_clock_cpu+0x85/0xc0
       init_one+0x1b5/0x260 [hfi1]
       local_pci_probe+0x4a/0xb0
       work_for_cpu_fn+0x1a/0x30
       process_one_work+0x17f/0x440
       worker_thread+0x278/0x3c0
       ? manage_workers.isra.24+0x2a0/0x2a0
       kthread+0xd1/0xe0
       ? insert_kthread_work+0x40/0x40
       ret_from_fork+0x77/0xb0
       ? insert_kthread_work+0x40/0x40
      
      If the BIOS is not supplying NUMA information:
        - set the default table count to 1 for all possible nodes
        - select node 0 (instead of current NUMA) node to get consistent
          performance
        - generate an error indicating that the BIOS should be upgraded
      Reviewed-by: NGary Leshner <gary.s.leshner@intel.com>
      Reviewed-by: NMike Marciniszyn <mike.marciniszyn@intel.com>
      Signed-off-by: NMichael J. Ruhl <michael.j.ruhl@intel.com>
      Signed-off-by: NDennis Dalessandro <dennis.dalessandro@intel.com>
      Signed-off-by: NJason Gunthorpe <jgg@mellanox.com>
      c513de49
  5. 20 7月, 2018 3 次提交
  6. 12 7月, 2018 1 次提交
  7. 11 7月, 2018 1 次提交
  8. 10 7月, 2018 1 次提交
  9. 04 7月, 2018 2 次提交
  10. 27 6月, 2018 1 次提交
  11. 22 6月, 2018 7 次提交
  12. 20 6月, 2018 4 次提交
  13. 19 6月, 2018 1 次提交
  14. 13 6月, 2018 1 次提交
    • K
      treewide: Use array_size() in kvzalloc_node() · 84ca176b
      Kees Cook 提交于
      The kvzalloc_node() function has no 2-factor argument form, so
      multiplication factors need to be wrapped in array_size(). This patch
      replaces cases of:
      
              kvzalloc_node(a * b, gfp, node)
      
      with:
              kvzalloc_node(array_size(a, b), gfp, node)
      
      as well as handling cases of:
      
              kvzalloc_node(a * b * c, gfp, node)
      
      with:
      
              kvzalloc_node(array3_size(a, b, c), gfp, node)
      
      This does, however, attempt to ignore constant size factors like:
      
              kvzalloc_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;
      @@
      
      (
        kvzalloc_node(
      -	(sizeof(TYPE)) * E
      +	sizeof(TYPE) * E
        , ...)
      |
        kvzalloc_node(
      -	(sizeof(THING)) * E
      +	sizeof(THING) * E
        , ...)
      )
      
      // Drop single-byte sizes and redundant parens.
      @@
      expression COUNT;
      typedef u8;
      typedef __u8;
      @@
      
      (
        kvzalloc_node(
      -	sizeof(u8) * (COUNT)
      +	COUNT
        , ...)
      |
        kvzalloc_node(
      -	sizeof(__u8) * (COUNT)
      +	COUNT
        , ...)
      |
        kvzalloc_node(
      -	sizeof(char) * (COUNT)
      +	COUNT
        , ...)
      |
        kvzalloc_node(
      -	sizeof(unsigned char) * (COUNT)
      +	COUNT
        , ...)
      |
        kvzalloc_node(
      -	sizeof(u8) * COUNT
      +	COUNT
        , ...)
      |
        kvzalloc_node(
      -	sizeof(__u8) * COUNT
      +	COUNT
        , ...)
      |
        kvzalloc_node(
      -	sizeof(char) * COUNT
      +	COUNT
        , ...)
      |
        kvzalloc_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;
      @@
      
      (
        kvzalloc_node(
      -	sizeof(TYPE) * (COUNT_ID)
      +	array_size(COUNT_ID, sizeof(TYPE))
        , ...)
      |
        kvzalloc_node(
      -	sizeof(TYPE) * COUNT_ID
      +	array_size(COUNT_ID, sizeof(TYPE))
        , ...)
      |
        kvzalloc_node(
      -	sizeof(TYPE) * (COUNT_CONST)
      +	array_size(COUNT_CONST, sizeof(TYPE))
        , ...)
      |
        kvzalloc_node(
      -	sizeof(TYPE) * COUNT_CONST
      +	array_size(COUNT_CONST, sizeof(TYPE))
        , ...)
      |
        kvzalloc_node(
      -	sizeof(THING) * (COUNT_ID)
      +	array_size(COUNT_ID, sizeof(THING))
        , ...)
      |
        kvzalloc_node(
      -	sizeof(THING) * COUNT_ID
      +	array_size(COUNT_ID, sizeof(THING))
        , ...)
      |
        kvzalloc_node(
      -	sizeof(THING) * (COUNT_CONST)
      +	array_size(COUNT_CONST, sizeof(THING))
        , ...)
      |
        kvzalloc_node(
      -	sizeof(THING) * COUNT_CONST
      +	array_size(COUNT_CONST, sizeof(THING))
        , ...)
      )
      
      // 2-factor product, only identifiers.
      @@
      identifier SIZE, COUNT;
      @@
      
        kvzalloc_node(
      -	SIZE * COUNT
      +	array_size(COUNT, SIZE)
        , ...)
      
      // 3-factor product with 1 sizeof(type) or sizeof(expression), with
      // redundant parens removed.
      @@
      expression THING;
      identifier STRIDE, COUNT;
      type TYPE;
      @@
      
      (
        kvzalloc_node(
      -	sizeof(TYPE) * (COUNT) * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kvzalloc_node(
      -	sizeof(TYPE) * (COUNT) * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kvzalloc_node(
      -	sizeof(TYPE) * COUNT * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kvzalloc_node(
      -	sizeof(TYPE) * COUNT * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kvzalloc_node(
      -	sizeof(THING) * (COUNT) * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      |
        kvzalloc_node(
      -	sizeof(THING) * (COUNT) * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      |
        kvzalloc_node(
      -	sizeof(THING) * COUNT * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      |
        kvzalloc_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;
      @@
      
      (
        kvzalloc_node(
      -	sizeof(TYPE1) * sizeof(TYPE2) * COUNT
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
        , ...)
      |
        kvzalloc_node(
      -	sizeof(TYPE1) * sizeof(THING2) * (COUNT)
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
        , ...)
      |
        kvzalloc_node(
      -	sizeof(THING1) * sizeof(THING2) * COUNT
      +	array3_size(COUNT, sizeof(THING1), sizeof(THING2))
        , ...)
      |
        kvzalloc_node(
      -	sizeof(THING1) * sizeof(THING2) * (COUNT)
      +	array3_size(COUNT, sizeof(THING1), sizeof(THING2))
        , ...)
      |
        kvzalloc_node(
      -	sizeof(TYPE1) * sizeof(THING2) * COUNT
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
        , ...)
      |
        kvzalloc_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;
      @@
      
      (
        kvzalloc_node(
      -	(COUNT) * STRIDE * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kvzalloc_node(
      -	COUNT * (STRIDE) * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kvzalloc_node(
      -	COUNT * STRIDE * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kvzalloc_node(
      -	(COUNT) * (STRIDE) * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kvzalloc_node(
      -	COUNT * (STRIDE) * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kvzalloc_node(
      -	(COUNT) * STRIDE * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kvzalloc_node(
      -	(COUNT) * (STRIDE) * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kvzalloc_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;
      @@
      
      (
        kvzalloc_node(C1 * C2 * C3, ...)
      |
        kvzalloc_node(
      -	E1 * E2 * E3
      +	array3_size(E1, E2, E3)
        , ...)
      )
      
      // And then all remaining 2 factors products when they're not all constants.
      @@
      expression E1, E2;
      constant C1, C2;
      @@
      
      (
        kvzalloc_node(C1 * C2, ...)
      |
        kvzalloc_node(
      -	E1 * E2
      +	array_size(E1, E2)
        , ...)
      )
      Signed-off-by: NKees Cook <keescook@chromium.org>
      84ca176b
  15. 05 6月, 2018 6 次提交
  16. 24 5月, 2018 5 次提交