1. 08 11月, 2016 1 次提交
    • R
      iommu/arm-smmu: Don't inadvertently reject multiple SMMUv3s · ec615f43
      Robin Murphy 提交于
      We now delay installing our per-bus iommu_ops until we know an SMMU has
      successfully probed, as they don't serve much purpose beforehand, and
      doing so also avoids fights between multiple IOMMU drivers in a single
      kernel. However, the upshot of passing the return value of bus_set_iommu()
      back from our probe function is that if there happens to be more than
      one SMMUv3 device in a system, the second and subsequent probes will
      wind up returning -EBUSY to the driver core and getting torn down again.
      
      Avoid re-setting ops if ours are already installed, so that any genuine
      failures stand out.
      
      Fixes: 08d4ca2a ("iommu/arm-smmu: Support non-PCI devices with SMMUv3")
      CC: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
      CC: Hanjun Guo <hanjun.guo@linaro.org>
      Signed-off-by: NRobin Murphy <robin.murphy@arm.com>
      Signed-off-by: NJoerg Roedel <jroedel@suse.de>
      ec615f43
  2. 16 9月, 2016 8 次提交
    • R
      iommu/arm-smmu: Set domain geometry · 455eb7d3
      Robin Murphy 提交于
      For non-aperture-based IOMMUs, the domain geometry seems to have become
      the de-facto way of indicating the input address space size. That is
      quite a useful thing from the users' perspective, so let's do the same.
      Reviewed-by: NEric Auger <eric.auger@redhat.com>
      Tested-by: NLorenzo Pieralisi <lorenzo.pieralisi@arm.com>
      Signed-off-by: NRobin Murphy <robin.murphy@arm.com>
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      455eb7d3
    • R
      iommu/arm-smmu: Set PRIVCFG in stage 1 STEs · 95fa99aa
      Robin Murphy 提交于
      Implement the SMMUv3 equivalent of d346180e ("iommu/arm-smmu: Treat
      all device transactions as unprivileged"), so that once again those
      pesky DMA controllers with their privileged instruction fetches don't
      unexpectedly fault in stage 1 domains due to VMSAv8 rules.
      Acked-by: NWill Deacon <will.deacon@arm.com>
      Tested-by: NLorenzo Pieralisi <lorenzo.pieralisi@arm.com>
      Signed-off-by: NRobin Murphy <robin.murphy@arm.com>
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      95fa99aa
    • R
      iommu/arm-smmu: Support non-PCI devices with SMMUv3 · 08d4ca2a
      Robin Murphy 提交于
      With the device <-> stream ID relationship suitably abstracted and
      of_xlate() hooked up, the PCI dependency now looks, and is, entirely
      arbitrary. Any bus using the of_dma_configure() mechanism will work,
      so extend support to the platform and AMBA buses which do just that.
      Acked-by: NWill Deacon <will.deacon@arm.com>
      Tested-by: NLorenzo Pieralisi <lorenzo.pieralisi@arm.com>
      Signed-off-by: NRobin Murphy <robin.murphy@arm.com>
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      08d4ca2a
    • R
      iommu/arm-smmu: Implement of_xlate() for SMMUv3 · 8f785154
      Robin Murphy 提交于
      Now that we can properly describe the mapping between PCI RIDs and
      stream IDs via "iommu-map", and have it fed it to the driver
      automatically via of_xlate(), rework the SMMUv3 driver to benefit from
      that, and get rid of the current misuse of the "iommus" binding.
      
      Since having of_xlate wired up means that masters will now be given the
      appropriate DMA ops, we also need to make sure that default domains work
      properly. This necessitates dispensing with the "whole group at a time"
      notion for attaching to a domain, as devices which share a group get
      attached to the group's default domain one by one as they are initially
      probed.
      Signed-off-by: NRobin Murphy <robin.murphy@arm.com>
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      8f785154
    • R
      iommu/arm-smmu: Fall back to global bypass · dc87a98d
      Robin Murphy 提交于
      Unlike SMMUv2, SMMUv3 has no easy way to bypass unknown stream IDs,
      other than allocating and filling in the entire stream table with bypass
      entries, which for some configurations would waste *gigabytes* of RAM.
      Otherwise, all transactions on unknown stream IDs will simply be aborted
      with a C_BAD_STREAMID event.
      
      Rather than render the system unusable in the case of an invalid DT,
      avoid enabling the SMMU altogether such that everything bypasses
      (though letting the explicit disable_bypass option take precedence).
      Signed-off-by: NRobin Murphy <robin.murphy@arm.com>
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      dc87a98d
    • W
      iommu/arm-smmu: Disable interrupts whilst holding the cmdq lock · 8ded2909
      Will Deacon 提交于
      The cmdq lock is taken whenever we issue commands into the command queue,
      which can occur in IRQ context (as a result of unmap) or in process
      context (as a result of a threaded IRQ handler or device probe).
      
      This can lead to a theoretical deadlock if the interrupt handler
      performing the unmap hits whilst the lock is taken, so explicitly use
      the {irqsave,irqrestore} spin_lock accessors for the cmdq lock.
      Tested-by: NJean-Philippe Brucker <jean-philippe.brucker@arm.com>
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      8ded2909
    • J
      iommu/arm-smmu: Fix polling of command queue · bcfced15
      Jean-Philippe Brucker 提交于
      When the SMMUv3 driver attempts to send a command, it adds an entry to the
      command queue. This is a circular buffer, where both the producer and
      consumer have a wrap bit. When producer.index == consumer.index and
      producer.wrap == consumer.wrap, the list is empty. When producer.index ==
      consumer.index and producer.wrap != consumer.wrap, the list is full.
      
      If the list is full when the driver needs to add a command, it waits for
      the SMMU to consume one command, and advance the consumer pointer. The
      problem is that we currently rely on "X before Y" operation to know if
      entries have been consumed, which is a bit fiddly since it only makes
      sense when the distance between X and Y is less than or equal to the size
      of the queue. At the moment when the list is full, we use "Consumer before
      Producer + 1", which is out of range and returns a value opposite to what
      we expect: when the queue transitions to not full, we stay in the polling
      loop and time out, printing an error.
      
      Given that the actual bug was difficult to determine, simplify the polling
      logic by relying exclusively on queue_full and queue_empty, that don't
      have this range constraint. Polling the queue is now straightforward:
      
      * When we want to add a command and the list is full, wait until it isn't
        full and retry.
      * After adding a sync, wait for the list to be empty before returning.
      Suggested-by: NWill Deacon <will.deacon@arm.com>
      Signed-off-by: NJean-Philippe Brucker <jean-philippe.brucker@arm.com>
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      bcfced15
    • J
      iommu/arm-smmu: Fix event queues synchronization · b4163fb3
      Jean-Philippe Brucker 提交于
      SMMUv3 only sends interrupts for event queues (EVTQ and PRIQ) when they
      transition from empty to non-empty. At the moment, if the SMMU adds new
      items to a queue before the event thread finished consuming a previous
      batch, the driver ignores any new item. The queue is then stuck in
      non-empty state and all subsequent events will be lost.
      
      As an example, consider the following flow, where (P, C) is the SMMU view
      of producer/consumer indices, and (p, c) the driver view.
      
      						P C | p c
        1. SMMU appends a PPR to the PRI queue,	1 0 | 0 0
                sends an MSI
        2. PRIQ handler is called.			1 0 | 1 0
        3. SMMU appends a PPR to the PRI queue.	2 0 | 1 0
        4. PRIQ thread removes the first element.	2 1 | 1 1
      
        5. PRIQ thread believes that the queue is empty, goes into idle
           indefinitely.
      
      To avoid this, always synchronize the producer index and drain the queue
      once before leaving an event handler. In order to prevent races on the
      local producer index, move all event queue handling into the threads.
      Signed-off-by: NJean-Philippe Brucker <jean-philippe.brucker@arm.com>
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      b4163fb3
  3. 19 8月, 2016 2 次提交
    • W
      iommu/arm-smmu: Don't BUG() if we find aborting STEs with disable_bypass · 5bc0a116
      Will Deacon 提交于
      The disable_bypass cmdline option changes the SMMUv3 driver to put down
      faulting stream table entries by default, as opposed to bypassing
      transactions from unconfigured devices.
      
      In this mode of operation, it is entirely expected to see aborting
      entries in the stream table if and when we come to installing a valid
      translation, so don't trigger a BUG() as a result of misdiagnosing these
      entries as stream table corruption.
      
      Cc: <stable@vger.kernel.org>
      Fixes: 48ec83bc ("iommu/arm-smmu: Add initial driver support for ARM SMMUv3 devices")
      Tested-by: NRobin Murphy <robin.murphy@arm.com>
      Reported-by: NRobin Murphy <robin.murphy@arm.com>
      Reviewed-by: NRobin Murphy <robin.murphy@arm.com>
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      5bc0a116
    • W
      iommu/arm-smmu: Fix CMDQ error handling · aea2037e
      Will Deacon 提交于
      In the unlikely event of a global command queue error, the ARM SMMUv3
      driver attempts to convert the problematic command into a CMD_SYNC and
      resume the command queue. Unfortunately, this code is pretty badly
      broken:
      
        1. It uses the index into the error string table as the CMDQ index,
           so we probably read the wrong entry out of the queue
      
        2. The arguments to queue_write are the wrong way round, so we end up
           writing from the queue onto the stack.
      
      These happily cancel out, so the kernel is likely to stay alive, but
      the command queue will probably fault again when we resume.
      
      This patch fixes the error handling code to use the correct queue index
      and write back the CMD_SYNC to the faulting entry.
      
      Cc: <stable@vger.kernel.org>
      Fixes: 48ec83bc ("iommu/arm-smmu: Add initial driver support for ARM SMMUv3 devices")
      Reported-by: NDiwakar Subraveti <Diwakar.Subraveti@arm.com>
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      aea2037e
  4. 01 7月, 2016 1 次提交
    • W
      iommu/arm-smmu: request pcie devices to enable ACS · 112c898b
      Wei Chen 提交于
      The PCIe ACS capability will affect the layout of iommu groups.
      Generally speaking, if the path from root port to the PCIe device
      is ACS enabled, the iommu will create a single iommu group for this
      PCIe device. If all PCIe devices on the path are ACS enabled then
      Linux can determine this path is ACS enabled.
      
      Linux use two PCIe configuration registers to determine the ACS
      status of PCIe devices:
      ACS Capability Register and ACS Control Register.
      
      The first register is used to check the implementation of ACS function
      of a PCIe device, the second register is used to check the enable status
      of ACS function. If one PCIe device has implemented and enabled the ACS
      function then Linux will determine this PCIe device enabled ACS.
      
      From the Chapter:6.12 of PCI Express Base Specification Revision 3.1a,
      we can find that when a PCIe device implements ACS function, the enable
      status is set to disabled by default and can be enabled by ACS-aware
      software.
      
      ACS will affect the iommu groups topology, so, the iommu driver is
      ACS-aware software. This patch adds a call to pci_request_acs() to the
      arm-smmu driver to enable the ACS function in PCIe devices that support
      it, when they get probed.
      Reviewed-by: NRobin Murphy <robin.murphy@arm.com>
      Reviewed-by: NEric Auger <eric.auger@redhat.com>
      Signed-off-by: NWei Chen <Wei.Chen@arm.com>
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      112c898b
  5. 13 6月, 2016 1 次提交
  6. 28 5月, 2016 1 次提交
    • A
      remove lots of IS_ERR_VALUE abuses · 287980e4
      Arnd Bergmann 提交于
      Most users of IS_ERR_VALUE() in the kernel are wrong, as they
      pass an 'int' into a function that takes an 'unsigned long'
      argument. This happens to work because the type is sign-extended
      on 64-bit architectures before it gets converted into an
      unsigned type.
      
      However, anything that passes an 'unsigned short' or 'unsigned int'
      argument into IS_ERR_VALUE() is guaranteed to be broken, as are
      8-bit integers and types that are wider than 'unsigned long'.
      
      Andrzej Hajda has already fixed a lot of the worst abusers that
      were causing actual bugs, but it would be nice to prevent any
      users that are not passing 'unsigned long' arguments.
      
      This patch changes all users of IS_ERR_VALUE() that I could find
      on 32-bit ARM randconfig builds and x86 allmodconfig. For the
      moment, this doesn't change the definition of IS_ERR_VALUE()
      because there are probably still architecture specific users
      elsewhere.
      
      Almost all the warnings I got are for files that are better off
      using 'if (err)' or 'if (err < 0)'.
      The only legitimate user I could find that we get a warning for
      is the (32-bit only) freescale fman driver, so I did not remove
      the IS_ERR_VALUE() there but changed the type to 'unsigned long'.
      For 9pfs, I just worked around one user whose calling conventions
      are so obscure that I did not dare change the behavior.
      
      I was using this definition for testing:
      
       #define IS_ERR_VALUE(x) ((unsigned long*)NULL == (typeof (x)*)NULL && \
             unlikely((unsigned long long)(x) >= (unsigned long long)(typeof(x))-MAX_ERRNO))
      
      which ends up making all 16-bit or wider types work correctly with
      the most plausible interpretation of what IS_ERR_VALUE() was supposed
      to return according to its users, but also causes a compile-time
      warning for any users that do not pass an 'unsigned long' argument.
      
      I suggested this approach earlier this year, but back then we ended
      up deciding to just fix the users that are obviously broken. After
      the initial warning that caused me to get involved in the discussion
      (fs/gfs2/dir.c) showed up again in the mainline kernel, Linus
      asked me to send the whole thing again.
      
      [ Updated the 9p parts as per Al Viro  - Linus ]
      Signed-off-by: NArnd Bergmann <arnd@arndb.de>
      Cc: Andrzej Hajda <a.hajda@samsung.com>
      Cc: Andrew Morton <akpm@linux-foundation.org>
      Link: https://lkml.org/lkml/2016/1/7/363
      Link: https://lkml.org/lkml/2016/5/27/486
      Acked-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> # For nvmem part
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      287980e4
  7. 10 5月, 2016 1 次提交
  8. 18 2月, 2016 3 次提交
    • W
      iommu/arm-smmu: Treat IOMMU_DOMAIN_DMA as bypass for now · cbf8277e
      Will Deacon 提交于
      Until all upstream devices have their DMA ops swizzled to point at the
      SMMU, we need to treat the IOMMU_DOMAIN_DMA domain as bypass to avoid
      putting devices into an empty address space when detaching from VFIO.
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      cbf8277e
    • W
      iommu/arm-smmu: Don't fail device attach if already attached to a domain · bc7f2ce0
      Will Deacon 提交于
      The ARM SMMU attach_dev implementations returns -EEXIST if the device
      being attached is already attached to a domain. This doesn't play nicely
      with the default domain, resulting in splats such as:
      
        WARNING: at drivers/iommu/iommu.c:1257
        Modules linked in:
      
        CPU: 3 PID: 1939 Comm: virtio-net-tx Tainted: G S              4.5.0-rc4+ #1
        Hardware name: FVP Base (DT)
        task: ffffffc87a9d0000 ti: ffffffc07a278000 task.ti: ffffffc07a278000
        PC is at __iommu_detach_group+0x68/0xe8
        LR is at __iommu_detach_group+0x48/0xe8
      
      This patch fixes the problem by forcefully detaching the device from
      its old domain, if present, when attaching to a new one. The unused
      ->detach_dev callback is also removed the iommu_ops structures.
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      bc7f2ce0
    • R
      iommu/arm-smmu: Support DMA-API domains · 9adb9594
      Robin Murphy 提交于
      With DMA mapping ops provided by the iommu-dma code, only a minimal
      contribution from the IOMMU driver is needed to create a suitable
      DMA-API domain for them to use. Implement this for the ARM SMMUs.
      Signed-off-by: NRobin Murphy <robin.murphy@arm.com>
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      9adb9594
  9. 17 12月, 2015 9 次提交
    • P
      iommu/arm-smmu: Use STE.S1STALLD only when supported · 6380be05
      Prem Mallappa 提交于
      It is ILLEGAL to set STE.S1STALLD to 1 if stage 1 is enabled and
      either the stall or terminate models are not supported.
      
      This patch fixes the STALLD check and ensures that we don't set STALLD
      in the STE when it is not supported.
      Signed-off-by: NPrem Mallappa <pmallapp@broadcom.com>
      [will: consistently use IDR0_STALL_MODEL_* prefix]
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      6380be05
    • P
      iommu/arm-smmu: Fix write to GERRORN register · 324ba108
      Prem Mallappa 提交于
      When acknowledging global errors, the GERRORN register should be written
      with the original GERROR value so that active errors are toggled.
      
      This patch fixed the driver to write the original GERROR value to
      GERRORN, instead of an active error mask.
      Signed-off-by: NPrem Mallappa <pmallapp@broadcom.com>
      [will: reworked use of active bits and fixed commit log]
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      324ba108
    • R
      iommu/arm-smmu: Invalidate TLBs properly · 75df1386
      Robin Murphy 提交于
      When invalidating an IOVA range potentially spanning multiple pages,
      such as when removing an entire intermediate-level table, we currently
      only issue an invalidation for the first IOVA of that range. Since the
      architecture specifies that address-based TLB maintenance operations
      target a single entry, an SMMU could feasibly retain live entries for
      subsequent pages within that unmapped range, which is not good.
      
      Make sure we hit every possible entry by iterating over the whole range
      at the granularity provided by the pagetable implementation.
      Signed-off-by: NRobin Murphy <robin.murphy@arm.com>
      [will: added missing semicolons...]
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      75df1386
    • R
      iommu/io-pgtable: Indicate granule for TLB maintenance · 06c610e8
      Robin Murphy 提交于
      IOMMU hardware with range-based TLB maintenance commands can work
      happily with the iova and size arguments passed via the tlb_add_flush
      callback, but for IOMMUs which require separate commands per entry in
      the range, it is not straightforward to infer the necessary granularity
      when it comes to issuing the actual commands.
      
      Add an additional argument indicating the granularity for the benefit
      of drivers needing to know, and update the ARM LPAE code appropriately
      (for non-leaf invalidations we currently just assume the worst-case
      page granularity rather than walking the table to check).
      Signed-off-by: NRobin Murphy <robin.murphy@arm.com>
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      06c610e8
    • W
      iommu/arm-smmu: Handle unknown CERROR values gracefully · a0d5c04c
      Will Deacon 提交于
      Whilst the architecture only defines a few of the possible CERROR values,
      we should handle unknown values gracefully rather than go out of bounds
      trying to print out an error description.
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      a0d5c04c
    • P
      iommu/arm-smmu: Correct group reference count · 9a4a9d8c
      Peng Fan 提交于
      The basic flow for add a device:
       arm_smmu_add_device
              |->iommu_group_get_for_dev
                  |->iommu_group_get
                           return group;  (1)
                  |->ops->device_group : Init/increase reference count to/by 1.
                  |->iommu_group_add_device : Increase reference count by 1.
      		     return group   (2)
              |->return 0;
      
      Since we are adding one device, the flow is (2) and the group reference
      count will be increased by 2. So, we need to add iommu_group_put at the
      end of arm_smmu_add_device to decrease the count by 1.
      
      Also take the failure path into consideration when fail to add a device.
      Signed-off-by: NPeng Fan <van.freenix@gmail.com>
      Cc: Will Deacon <will.deacon@arm.com>
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      9a4a9d8c
    • W
      iommu/arm-smmu: Use incoming shareability attributes in bypass mode · a0eacd89
      Will Deacon 提交于
      When we initialise a bypass STE, we memset the structure to zero and
      set the Valid and Config fields to indicate that the stream should
      bypass the SMMU. Unfortunately, this results in an SHCFG field of 0
      which means that the shareability of any incoming transactions is
      overridden with non-shareable, leading to potential coherence problems
      down the line.
      
      This patch fixes the issue by initialising bypass STEs to use the
      incoming shareability attributes. When translation is in effect at
      either stage 1 or stage 2, the shareability is determined by the
      page tables.
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      a0eacd89
    • W
      iommu/arm-smmu: Convert DMA buffer allocations to the managed API · 04fa26c7
      Will Deacon 提交于
      The ARM SMMUv3 driver uses dma_{alloc,free}_coherent to manage its
      queues and configuration data structures.
      
      This patch converts the driver to the managed (dmam_*) API, so that
      resources are freed automatically on device teardown. This greatly
      simplifies the failure paths and allows us to remove a bunch of
      handcrafted freeing code.
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      04fa26c7
    • W
      iommu/arm-smmu: Remove #define for non-existent PRIQ_0_OF field · 89df3a96
      Will Deacon 提交于
      PRIQ_0_OF has been removed from the SMMUv3 architecture, so remove its
      corresponding (and unused) #define from the driver.
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      89df3a96
  10. 22 10月, 2015 1 次提交
  11. 15 10月, 2015 2 次提交
  12. 14 10月, 2015 1 次提交
  13. 23 9月, 2015 2 次提交
  14. 06 8月, 2015 3 次提交
  15. 31 7月, 2015 3 次提交
  16. 09 7月, 2015 1 次提交