1. 27 12月, 2019 3 次提交
  2. 10 11月, 2019 1 次提交
    • Z
      irqchip/gic-v3-its: Use the exact ITSList for VMOVP · 18e7fae3
      Zenghui Yu 提交于
      [ Upstream commit 8424312516e5d9baeeb0a95d0e4523579b7aa395 ]
      
      On a system without Single VMOVP support (say GITS_TYPER.VMOVP == 0),
      we will map vPEs only on ITSs that will actually control interrupts
      for the given VM.  And when moving a vPE, the VMOVP command will be
      issued only for those ITSs.
      
      But when issuing VMOVPs we seemed fail to present the exact ITSList
      to ITSs who are actually included in the synchronization operation.
      The its_list_map we're currently using includes all ITSs in the system,
      even though some of them don't have the corresponding vPE mapping at all.
      
      Introduce get_its_list() to get the per-VM its_list_map, to indicate
      which ITSs have vPE mappings for the given VM, and use this map as
      the expected ITSList when building VMOVP. This is hopefully a performance
      gain not to do some synchronization with those unsuspecting ITSs.
      And initialize the whole command descriptor to zero at beginning, since
      the seq_num and its_list should be RES0 when GITS_TYPER.VMOVP == 1.
      Signed-off-by: NZenghui Yu <yuzenghui@huawei.com>
      Signed-off-by: NMarc Zyngier <maz@kernel.org>
      Link: https://lore.kernel.org/r/1571802386-2680-1-git-send-email-yuzenghui@huawei.comSigned-off-by: NSasha Levin <sashal@kernel.org>
      18e7fae3
  3. 01 10月, 2019 1 次提交
  4. 25 8月, 2019 1 次提交
  5. 21 7月, 2019 1 次提交
    • H
      irqchip/gic-v3-its: Fix command queue pointer comparison bug · ff232a47
      Heyi Guo 提交于
      [ Upstream commit a050fa5476d418fc16b25abe168b3d38ba11e13c ]
      
      When we run several VMs with PCI passthrough and GICv4 enabled, not
      pinning vCPUs, we will occasionally see below warnings in dmesg:
      
      ITS queue timeout (65440 65504 480)
      ITS cmd its_build_vmovp_cmd failed
      
      The reason for the above issue is that in BUILD_SINGLE_CMD_FUNC:
      1. Post the write command.
      2. Release the lock.
      3. Start to read GITS_CREADR to get the reader pointer.
      4. Compare the reader pointer to the target pointer.
      5. If reader pointer does not reach the target, sleep 1us and continue
      to try.
      
      If we have several processors running the above concurrently, other
      CPUs will post write commands while the 1st CPU is waiting the
      completion. So we may have below issue:
      
      phase 1:
      ---rd_idx-----from_idx-----to_idx--0---------
      
      wait 1us:
      
      phase 2:
      --------------from_idx-----to_idx--0-rd_idx--
      
      That is the rd_idx may fly ahead of to_idx, and if in case to_idx is
      near the wrap point, rd_idx will wrap around. So the below condition
      will not be met even after 1s:
      
      if (from_idx < to_idx && rd_idx >= to_idx)
      
      There is another theoretical issue. For a slow and busy ITS, the
      initial rd_idx may fall behind from_idx a lot, just as below:
      
      ---rd_idx---0--from_idx-----to_idx-----------
      
      This will cause the wait function exit too early.
      
      Actually, it does not make much sense to use from_idx to judge if
      to_idx is wrapped, but we need a initial rd_idx when lock is still
      acquired, and it can be used to judge whether to_idx is wrapped and
      the current rd_idx is wrapped.
      
      We switch to a method of calculating the delta of two adjacent reads
      and accumulating it to get the sum, so that we can get the real rd_idx
      from the wrapped value even when the queue is almost full.
      
      Cc: Thomas Gleixner <tglx@linutronix.de>
      Cc: Jason Cooper <jason@lakedaemon.net>
      Signed-off-by: NHeyi Guo <guoheyi@huawei.com>
      Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
      Signed-off-by: NSasha Levin <sashal@kernel.org>
      ff232a47
  6. 27 3月, 2019 1 次提交
  7. 24 3月, 2019 1 次提交
  8. 14 3月, 2019 2 次提交
    • M
      irqchip/gic-v3-its: Gracefully fail on LPI exhaustion · 423869f8
      Marc Zyngier 提交于
      [ Upstream commit 45725e0fc3e7fe52fedb94f59806ec50e9618682 ]
      
      In the unlikely event that we cannot find any available LPI in the
      system, we should gracefully return an error instead of carrying
      on with no LPI allocated at all.
      
      Fixes: 38dd7c49 ("irqchip/gic-v3-its: Drop chunk allocation compatibility")
      Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
      Signed-off-by: NSasha Levin <sashal@kernel.org>
      423869f8
    • H
      irqchip/gic-v4: Fix occasional VLPI drop · dc81cfaf
      Heyi Guo 提交于
      [ Upstream commit 6479450f72c1391c03f08affe0d0110f41ae7ca0 ]
      
      1. In current implementation, every VLPI will temporarily be mapped to
      the first CPU in system (normally CPU0) and then moved to the real
      scheduled CPU later.
      
      2. So there is a time window and a VLPI may be sent to CPU0 instead of
      the real scheduled vCPU, in a multi-CPU virtual machine.
      
      3. However, CPU0 may have not been scheduled as a virtual CPU after
      system boots up, so the value of its GICR_VPROPBASER is unknown at
      that moment.
      
      4. If the INTID of VLPI is larger than 2^(GICR_VPROPBASER.IDbits+1),
      while IDbits is also in unknown state, GIC will behave as if the VLPI
      is out of range and simply drop it, which results in interrupt missing
      in Guest.
      
      As no code will clear GICR_VPROPBASER at runtime, we can safely
      initialize the IDbits field at boot time for each CPU to get rid of
      this issue.
      
      We also clear Valid bit of GICR_VPENDBASER in case any ancient
      programming gets left in and causes memory corrupting. A new function
      its_clear_vpend_valid() is added to reuse the code in
      its_vpe_deschedule().
      
      Fixes: e643d803 ("irqchip/gic-v3-its: Add VPE scheduling")
      Signed-off-by: NHeyi Guo <guoheyi@huawei.com>
      Signed-off-by: NHeyi Guo <heyi.guo@linaro.org>
      Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
      Signed-off-by: NSasha Levin <sashal@kernel.org>
      dc81cfaf
  9. 13 2月, 2019 1 次提交
    • M
      irqchip/gic-v3-its: Plug allocation race for devices sharing a DevID · 8459f1d6
      Marc Zyngier 提交于
      commit 9791ec7df0e7b4d80706ccea8f24b6542f6059e9 upstream.
      
      On systems or VMs where multiple devices share a single DevID
      (because they sit behind a PCI bridge, or because the HW is
      broken in funky ways), we reuse the save its_device structure
      in order to reflect this.
      
      It turns out that there is a distinct lack of locking when looking
      up the its_device, and two device being probed concurrently can result
      in double allocations. That's obviously not nice.
      
      A solution for this is to have a per-ITS mutex that serializes device
      allocation.
      
      A similar issue exists on the freeing side, which can run concurrently
      with the allocation. On top of now taking the appropriate lock, we
      also make sure that a shared device is never freed, as we have no way
      to currently track the life cycle of such object.
      Reported-by: NZheng Xiang <zhengxiang9@huawei.com>
      Tested-by: NZheng Xiang <zhengxiang9@huawei.com>
      Cc: stable@vger.kernel.org
      Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      8459f1d6
  10. 31 1月, 2019 1 次提交
  11. 07 9月, 2018 1 次提交
  12. 06 8月, 2018 1 次提交
  13. 16 7月, 2018 6 次提交
    • M
      irqchip/gic-v3-its: Honor hypervisor enforced LPI range · 12b2905a
      Marc Zyngier 提交于
      A recent extension to the GIC architecture allows a hypervisor to
      arbitrarily reduce the number of LPIs available to a guest, no
      matter what the GIC says about the valid range of IntIDs.
      
      Let's factor in this information when computing the number of
      available LPIs
      Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
      12b2905a
    • M
      irqchip/gic-v3: Expose GICD_TYPER in the rdist structure · a4f9edb2
      Marc Zyngier 提交于
      Instead of exposing the GIC distributor IntID field in the rdist
      structure that is passed to the ITS, let's replace it with a
      copy of the whole GICD_TYPER register. We are going to need
      some of this information at a later time.
      
      No functionnal change.
      Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
      a4f9edb2
    • M
      irqchip/gic-v3-its: Drop chunk allocation compatibility · 38dd7c49
      Marc Zyngier 提交于
      The chunk allocation system is now officially dead, so let's
      remove it.
      Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
      38dd7c49
    • M
      irqchip/gic-v3-its: Move minimum LPI requirements to individual busses · 147c8f37
      Marc Zyngier 提交于
      At the moment, the core ITS driver imposes the allocation to be
      in chunks of 32. As we want to relax this on a per bus basis, let's
      move the the the allocation constraints to each bus.
      
      No functionnal change.
      Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
      147c8f37
    • M
      irqchip/gic-v3-its: Use full range of LPIs · fe8e9350
      Marc Zyngier 提交于
      As we used to represent the LPI range using a bitmap, we were reducing
      the number of LPIs to at most 64k in order to preserve memory.
      
      With our new allocator, there is no such need, as dealing with 2^16
      or 2^32 LPIs takes the same amount of memory.
      
      So let's use the number of IntID bits reported by the GIC instead of
      an arbitrary limit.
      Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
      fe8e9350
    • M
      irqchip/gic-v3-its: Refactor LPI allocator · 880cb3cd
      Marc Zyngier 提交于
      Our current LPI allocator relies on a bitmap, each bit representing
      a chunk of 32 LPIs, meaning that each device gets allocated LPIs
      in multiple of 32. It served us well so far, but new use cases now
      require much more finer grain allocations, down the the individual
      LPI.
      
      Given the size of the IntID space (up to 32bit), it isn't practical
      to continue using a bitmap, so let's use a different data structure
      altogether.
      
      We switch to a list, where each element represent a contiguous range
      of LPIs. On allocation, we simply grab the first group big enough to
      satisfy the allocation, and substract what we need from it. If the
      group becomes empty, we just remove it. On freeing interrupts, we
      insert a new group of interrupt in the list, sort it and fuse the
      adjacent groups.
      
      This makes freeing interrupt much more expensive than allocating
      them (an unusual behaviour), but that's fine as long as we consider
      that freeing interrupts is an extremely rare event.
      
      We still allocate interrupts in blocks of 32 for the time being,
      but subsequent patches will relax this.
      Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
      880cb3cd
  14. 22 6月, 2018 4 次提交
  15. 13 6月, 2018 2 次提交
    • K
      treewide: kzalloc() -> kcalloc() · 6396bb22
      Kees Cook 提交于
      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: NKees Cook <keescook@chromium.org>
      6396bb22
    • K
      treewide: kmalloc() -> kmalloc_array() · 6da2ec56
      Kees Cook 提交于
      The kmalloc() function has a 2-factor argument form, kmalloc_array(). This
      patch replaces cases of:
      
              kmalloc(a * b, gfp)
      
      with:
              kmalloc_array(a * b, gfp)
      
      as well as handling cases of:
      
              kmalloc(a * b * c, gfp)
      
      with:
      
              kmalloc(array3_size(a, b, c), gfp)
      
      as it's slightly less ugly than:
      
              kmalloc_array(array_size(a, b), c, gfp)
      
      This does, however, attempt to ignore constant size factors like:
      
              kmalloc(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 tools/ directory was manually excluded, since it has its own
      implementation of kmalloc().
      
      The Coccinelle script used for this was:
      
      // Fix redundant parens around sizeof().
      @@
      type TYPE;
      expression THING, E;
      @@
      
      (
        kmalloc(
      -	(sizeof(TYPE)) * E
      +	sizeof(TYPE) * E
        , ...)
      |
        kmalloc(
      -	(sizeof(THING)) * E
      +	sizeof(THING) * E
        , ...)
      )
      
      // Drop single-byte sizes and redundant parens.
      @@
      expression COUNT;
      typedef u8;
      typedef __u8;
      @@
      
      (
        kmalloc(
      -	sizeof(u8) * (COUNT)
      +	COUNT
        , ...)
      |
        kmalloc(
      -	sizeof(__u8) * (COUNT)
      +	COUNT
        , ...)
      |
        kmalloc(
      -	sizeof(char) * (COUNT)
      +	COUNT
        , ...)
      |
        kmalloc(
      -	sizeof(unsigned char) * (COUNT)
      +	COUNT
        , ...)
      |
        kmalloc(
      -	sizeof(u8) * COUNT
      +	COUNT
        , ...)
      |
        kmalloc(
      -	sizeof(__u8) * COUNT
      +	COUNT
        , ...)
      |
        kmalloc(
      -	sizeof(char) * COUNT
      +	COUNT
        , ...)
      |
        kmalloc(
      -	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;
      @@
      
      (
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(TYPE) * (COUNT_ID)
      +	COUNT_ID, sizeof(TYPE)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(TYPE) * COUNT_ID
      +	COUNT_ID, sizeof(TYPE)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(TYPE) * (COUNT_CONST)
      +	COUNT_CONST, sizeof(TYPE)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(TYPE) * COUNT_CONST
      +	COUNT_CONST, sizeof(TYPE)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(THING) * (COUNT_ID)
      +	COUNT_ID, sizeof(THING)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(THING) * COUNT_ID
      +	COUNT_ID, sizeof(THING)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(THING) * (COUNT_CONST)
      +	COUNT_CONST, sizeof(THING)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(THING) * COUNT_CONST
      +	COUNT_CONST, sizeof(THING)
        , ...)
      )
      
      // 2-factor product, only identifiers.
      @@
      identifier SIZE, COUNT;
      @@
      
      - kmalloc
      + kmalloc_array
        (
      -	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;
      @@
      
      (
        kmalloc(
      -	sizeof(TYPE) * (COUNT) * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kmalloc(
      -	sizeof(TYPE) * (COUNT) * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kmalloc(
      -	sizeof(TYPE) * COUNT * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kmalloc(
      -	sizeof(TYPE) * COUNT * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kmalloc(
      -	sizeof(THING) * (COUNT) * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      |
        kmalloc(
      -	sizeof(THING) * (COUNT) * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      |
        kmalloc(
      -	sizeof(THING) * COUNT * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      |
        kmalloc(
      -	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;
      @@
      
      (
        kmalloc(
      -	sizeof(TYPE1) * sizeof(TYPE2) * COUNT
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
        , ...)
      |
        kmalloc(
      -	sizeof(TYPE1) * sizeof(THING2) * (COUNT)
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
        , ...)
      |
        kmalloc(
      -	sizeof(THING1) * sizeof(THING2) * COUNT
      +	array3_size(COUNT, sizeof(THING1), sizeof(THING2))
        , ...)
      |
        kmalloc(
      -	sizeof(THING1) * sizeof(THING2) * (COUNT)
      +	array3_size(COUNT, sizeof(THING1), sizeof(THING2))
        , ...)
      |
        kmalloc(
      -	sizeof(TYPE1) * sizeof(THING2) * COUNT
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
        , ...)
      |
        kmalloc(
      -	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;
      @@
      
      (
        kmalloc(
      -	(COUNT) * STRIDE * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kmalloc(
      -	COUNT * (STRIDE) * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kmalloc(
      -	COUNT * STRIDE * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kmalloc(
      -	(COUNT) * (STRIDE) * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kmalloc(
      -	COUNT * (STRIDE) * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kmalloc(
      -	(COUNT) * STRIDE * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kmalloc(
      -	(COUNT) * (STRIDE) * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kmalloc(
      -	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;
      @@
      
      (
        kmalloc(C1 * C2 * C3, ...)
      |
        kmalloc(
      -	(E1) * E2 * E3
      +	array3_size(E1, E2, E3)
        , ...)
      |
        kmalloc(
      -	(E1) * (E2) * E3
      +	array3_size(E1, E2, E3)
        , ...)
      |
        kmalloc(
      -	(E1) * (E2) * (E3)
      +	array3_size(E1, E2, E3)
        , ...)
      |
        kmalloc(
      -	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;
      @@
      
      (
        kmalloc(sizeof(THING) * C2, ...)
      |
        kmalloc(sizeof(TYPE) * C2, ...)
      |
        kmalloc(C1 * C2 * C3, ...)
      |
        kmalloc(C1 * C2, ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(TYPE) * (E2)
      +	E2, sizeof(TYPE)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(TYPE) * E2
      +	E2, sizeof(TYPE)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(THING) * (E2)
      +	E2, sizeof(THING)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(THING) * E2
      +	E2, sizeof(THING)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	(E1) * E2
      +	E1, E2
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	(E1) * (E2)
      +	E1, E2
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	E1 * E2
      +	E1, E2
        , ...)
      )
      Signed-off-by: NKees Cook <keescook@chromium.org>
      6da2ec56
  16. 23 3月, 2018 1 次提交
    • S
      irqchip/gic-v3: Ensure GICR_CTLR.EnableLPI=0 is observed before enabling · 6eb486b6
      Shanker Donthineni 提交于
      Booting with GICR_CTLR.EnableLPI=1 is usually a bad idea, and may
      result in subtle memory corruption. Detecting this is thus pretty
      important.
      
      On detecting that LPIs are still enabled, we taint the kernel (because
      we're not sure of anything anymore), and try to disable LPIs. This can
      fail, as implementations are allowed to implement GICR_CTLR.EnableLPI
      as a one-way enable, meaning the redistributors cannot be reprogrammed
      with new tables.
      
      Should this happen, we fail probing the redistributor and warn the user
      that things are pretty dire.
      Signed-off-by: NShanker Donthineni <shankerd@codeaurora.org>
      [maz: reworded changelog, minor comment and message changes]
      Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
      6eb486b6
  17. 14 3月, 2018 2 次提交
  18. 11 3月, 2018 1 次提交
    • A
      irqchip/gic-v3-its: Ensure nr_ites >= nr_lpis · 4f2c7583
      Ard Biesheuvel 提交于
      When struct its_device instances are created, the nr_ites member
      will be set to a power of 2 that equals or exceeds the requested
      number of MSIs passed to the msi_prepare() callback. At the same
      time, the LPI map is allocated to be some multiple of 32 in size,
      where the allocated size may be less than the requested size
      depending on whether a contiguous range of sufficient size is
      available in the global LPI bitmap.
      
      This may result in the situation where the nr_ites < nr_lpis, and
      since nr_ites is what we program into the hardware when we map the
      device, the additional LPIs will be non-functional.
      
      For bog standard hardware, this does not really matter. However,
      in cases where ITS device IDs are shared between different PCIe
      devices, we may end up allocating these additional LPIs without
      taking into account that they don't actually work.
      
      So let's make nr_ites at least 32. This ensures that all allocated
      LPIs are 'live', and that its_alloc_device_irq() will fail when
      attempts are made to allocate MSIs beyond what was allocated in
      the first place.
      Signed-off-by: NArd Biesheuvel <ard.biesheuvel@linaro.org>
      [maz: updated comment]
      Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
      4f2c7583
  19. 17 2月, 2018 1 次提交
  20. 16 2月, 2018 1 次提交
    • S
      irqchip/gic-v3: Ignore disabled ITS nodes · 95a25625
      Stephen Boyd 提交于
      On some platforms there's an ITS available but it's not enabled
      because reading or writing the registers is denied by the
      firmware. In fact, reading or writing them will cause the system
      to reset. We could remove the node from DT in such a case, but
      it's better to skip nodes that are marked as "disabled" in DT so
      that we can describe the hardware that exists and use the status
      property to indicate how the firmware has configured things.
      
      Cc: Stuart Yoder <stuyoder@gmail.com>
      Cc: Laurentiu Tudor <laurentiu.tudor@nxp.com>
      Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
      Cc: Marc Zyngier <marc.zyngier@arm.com>
      Cc: Rajendra Nayak <rnayak@codeaurora.org>
      Signed-off-by: NStephen Boyd <sboyd@codeaurora.org>
      Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
      95a25625
  21. 14 2月, 2018 1 次提交
  22. 30 12月, 2017 1 次提交
    • T
      genirq/irqdomain: Rename early argument of irq_domain_activate_irq() · 702cb0a0
      Thomas Gleixner 提交于
      The 'early' argument of irq_domain_activate_irq() is actually used to
      denote reservation mode. To avoid confusion, rename it before abuse
      happens.
      
      No functional change.
      
      Fixes: 72491643 ("genirq/irqdomain: Update irq_domain_ops.activate() signature")
      Signed-off-by: NThomas Gleixner <tglx@linutronix.de>
      Cc: Alexandru Chirvasitu <achirvasub@gmail.com>
      Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
      Cc: Dou Liyang <douly.fnst@cn.fujitsu.com>
      Cc: Pavel Machek <pavel@ucw.cz>
      Cc: Maciej W. Rozycki <macro@linux-mips.org>
      Cc: Mikael Pettersson <mikpelinux@gmail.com>
      Cc: Josh Poulson <jopoulso@microsoft.com>
      Cc: Mihai Costache <v-micos@microsoft.com>
      Cc: Stephen Hemminger <sthemmin@microsoft.com>
      Cc: Marc Zyngier <marc.zyngier@arm.com>
      Cc: linux-pci@vger.kernel.org
      Cc: Haiyang Zhang <haiyangz@microsoft.com>
      Cc: Dexuan Cui <decui@microsoft.com>
      Cc: Simon Xiao <sixiao@microsoft.com>
      Cc: Saeed Mahameed <saeedm@mellanox.com>
      Cc: Jork Loeser <Jork.Loeser@microsoft.com>
      Cc: Bjorn Helgaas <bhelgaas@google.com>
      Cc: devel@linuxdriverproject.org
      Cc: KY Srinivasan <kys@microsoft.com>
      Cc: Alan Cox <alan@linux.intel.com>
      Cc: Sakari Ailus <sakari.ailus@intel.com>,
      Cc: linux-media@vger.kernel.org
      702cb0a0
  23. 07 11月, 2017 1 次提交
  24. 02 11月, 2017 1 次提交
  25. 19 10月, 2017 3 次提交