1. 08 11月, 2016 3 次提交
  2. 16 9月, 2016 12 次提交
    • 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: Wire up generic configuration support · 021bb842
      Robin Murphy 提交于
      With everything else now in place, fill in an of_xlate callback and the
      appropriate registration to plumb into the generic configuration
      machinery, and watch everything just work.
      Signed-off-by: NRobin Murphy <robin.murphy@arm.com>
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      021bb842
    • R
      iommu/arm-smmu: Convert to iommu_fwspec · adfec2e7
      Robin Murphy 提交于
      In the final step of preparation for full generic configuration support,
      swap our fixed-size master_cfg for the generic iommu_fwspec. For the
      legacy DT bindings, the driver simply gets to act as its own 'firmware'.
      Farewell, arbitrary MAX_MASTER_STREAMIDS!
      Signed-off-by: NRobin Murphy <robin.murphy@arm.com>
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      adfec2e7
    • R
      iommu/arm-smmu: Intelligent SMR allocation · 588888a7
      Robin Murphy 提交于
      Stream Match Registers are one of the more awkward parts of the SMMUv2
      architecture; there are typically never enough to assign one to each
      stream ID in the system, and configuring them such that a single ID
      matches multiple entries is catastrophically bad - at best, every
      transaction raises a global fault; at worst, they go *somewhere*.
      
      To address the former issue, we can mask ID bits such that a single
      register may be used to match multiple IDs belonging to the same device
      or group, but doing so also heightens the risk of the latter problem
      (which can be nasty to debug).
      
      Tackle both problems at once by replacing the simple bitmap allocator
      with something much cleverer. Now that we have convenient in-memory
      representations of the stream mapping table, it becomes straightforward
      to properly validate new SMR entries against the current state, opening
      the door to arbitrary masking and SMR sharing.
      
      Another feature which falls out of this is that with IDs shared by
      separate devices being automatically accounted for, simply associating a
      group pointer with the S2CR offers appropriate group allocation almost
      for free, so hook that up in the process.
      Signed-off-by: NRobin Murphy <robin.murphy@arm.com>
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      588888a7
    • R
      iommu/arm-smmu: Add a stream map entry iterator · d3097e39
      Robin Murphy 提交于
      We iterate over the SMEs associated with a master config quite a lot in
      various places, and are about to do so even more. Let's wrap the idiom
      in a handy iterator macro before the repetition gets out of hand.
      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>
      d3097e39
    • R
      iommu/arm-smmu: Streamline SMMU data lookups · d6fc5d97
      Robin Murphy 提交于
      Simplify things somewhat by stashing our arm_smmu_device instance in
      drvdata, so that it's readily available to our driver model callbacks.
      Then we can excise the private list entirely, since the driver core
      already has a perfectly good list of SMMU devices we can use in the one
      instance we actually need to. Finally, make a further modest code saving
      with the relatively new of_device_get_match_data() helper.
      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>
      d6fc5d97
    • R
      iommu/arm-smmu: Refactor mmu-masters handling · f80cd885
      Robin Murphy 提交于
      To be able to support the generic bindings and handle of_xlate() calls,
      we need to be able to associate SMMUs and stream IDs directly with
      devices *before* allocating IOMMU groups. Furthermore, to support real
      default domains with multi-device groups we also have to handle domain
      attach on a per-device basis, as the "whole group at a time" assumption
      fails to properly handle subsequent devices added to a group after the
      first has already triggered default domain creation and attachment.
      
      To that end, use the now-vacant dev->archdata.iommu field for easy
      config and SMMU instance lookup, and unify config management by chopping
      down the platform-device-specific tree and probing the "mmu-masters"
      property on-demand instead. This may add a bit of one-off overhead to
      initially adding a new device, but we're about to deprecate that binding
      in favour of the inherently-more-efficient generic ones anyway.
      
      For the sake of simplicity, this patch does temporarily regress the case
      of aliasing PCI devices by losing the duplicate stream ID detection that
      the previous per-group config had. Stay tuned, because we'll be back to
      fix that in a better and more general way momentarily...
      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>
      f80cd885
    • R
      iommu/arm-smmu: Keep track of S2CR state · 8e8b203e
      Robin Murphy 提交于
      Making S2CRs first-class citizens within the driver with a high-level
      representation of their state offers a neat solution to a few problems:
      
      Firstly, the information about which context a device's stream IDs are
      associated with is already present by necessity in the S2CR. With that
      state easily accessible we can refer directly to it and obviate the need
      to track an IOMMU domain in each device's archdata (its earlier purpose
      of enforcing correct attachment of multi-device groups now being handled
      by the IOMMU core itself).
      
      Secondly, the core API now deprecates explicit domain detach and expects
      domain attach to move devices smoothly from one domain to another; for
      SMMUv2, this notion maps directly to simply rewriting the S2CRs assigned
      to the device. By giving the driver a suitable abstraction of those
      S2CRs to work with, we can massively reduce the overhead of the current
      heavy-handed "detach, free resources, reallocate resources, attach"
      approach.
      
      Thirdly, making the software state hardware-shaped and attached to the
      SMMU instance once again makes suspend/resume of this register group
      that much simpler to implement in future.
      Signed-off-by: NRobin Murphy <robin.murphy@arm.com>
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      8e8b203e
    • R
      iommu/arm-smmu: Consolidate stream map entry state · 1f3d5ca4
      Robin Murphy 提交于
      In order to consider SMR masking, we really want to be able to validate
      ID/mask pairs against existing SMR contents to prevent stream match
      conflicts, which at best would cause transactions to fault unexpectedly,
      and at worst lead to silent unpredictable behaviour. With our SMMU
      instance data holding only an allocator bitmap, and the SMR values
      themselves scattered across master configs hanging off devices which we
      may have no way of finding, there's essentially no way short of digging
      everything back out of the hardware. Similarly, the thought of power
      management ops to support suspend/resume faces the exact same problem.
      
      By massaging the software state into a closer shape to the underlying
      hardware, everything comes together quite nicely; the allocator and the
      high-level view of the data become a single centralised state which we
      can easily keep track of, and to which any updates can be validated in
      full before being synchronised to the hardware itself.
      Signed-off-by: NRobin Murphy <robin.murphy@arm.com>
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      1f3d5ca4
    • R
      iommu/arm-smmu: Handle stream IDs more dynamically · 21174240
      Robin Murphy 提交于
      Rather than assuming fixed worst-case values for stream IDs and SMR
      masks, keep track of whatever implemented bits the hardware actually
      reports. This also obviates the slightly questionable validation of SMR
      fields in isolation - rather than aborting the whole SMMU probe for a
      hardware configuration which is still architecturally valid, we can
      simply refuse masters later if they try to claim an unrepresentable ID
      or mask (which almost certainly implies a DT error anyway).
      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>
      21174240
    • R
      iommu/arm-smmu: Support v7s context format · 6070529b
      Robin Murphy 提交于
      Fill in the last bits of machinery required to drive a stage 1 context
      bank in v7 short descriptor format. By default we'll prefer to use it
      only when the CPUs are also using the same format, such that we're
      guaranteed that everything will be strictly 32-bit.
      Signed-off-by: NRobin Murphy <robin.murphy@arm.com>
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      6070529b
    • P
      iommu/arm-smmu: Drop devm_free_irq when driver detach · e2d42311
      Peng Fan 提交于
      There is no need to call devm_free_irq when driver detach.
      devres_release_all which is called after 'drv->remove' will
      release all managed resources.
      Signed-off-by: NPeng Fan <van.freenix@gmail.com>
      Reviewed-by: NRobin Murphy <robin.murphy@arm.com>
      Cc: Will Deacon <will.deacon@arm.com>
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      e2d42311
  3. 19 8月, 2016 1 次提交
    • W
      iommu/arm-smmu: Disable stalling faults for all endpoints · 3714ce1d
      Will Deacon 提交于
      Enabling stalling faults can result in hardware deadlock on poorly
      designed systems, particularly those with a PCI root complex upstream of
      the SMMU.
      
      Although it's not really Linux's job to save hardware integrators from
      their own misfortune, it *is* our job to stop userspace (e.g. VFIO
      clients) from hosing the system for everybody else, even if they might
      already be required to have elevated privileges.
      
      Given that the fault handling code currently executes entirely in IRQ
      context, there is nothing that can sensibly be done to recover from
      things like page faults anyway, so let's rip this code out for now and
      avoid the potential for deadlock.
      
      Cc: <stable@vger.kernel.org>
      Fixes: 48ec83bc ("iommu/arm-smmu: Add initial driver support for ARM SMMUv3 devices")
      Reported-by: NMatt Evans <matt.evans@arm.com>
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      3714ce1d
  4. 07 7月, 2016 1 次提交
  5. 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
  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. 04 5月, 2016 9 次提交
  9. 21 4月, 2016 2 次提交
  10. 20 4月, 2016 1 次提交
  11. 18 2月, 2016 5 次提交
    • 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: Allow disabling unmatched stream bypass · 25a1c96c
      Robin Murphy 提交于
      Borrow the disable_bypass parameter from the SMMUv3 driver as a handy
      debugging/security feature so that unmatched stream IDs (i.e. devices
      not attached to an IOMMU domain) may be configured to fault.
      
      Rather than introduce unsightly inconsistency, or repeat the existing
      unnecessary use of module_param_named(), fix that as well in passing.
      Signed-off-by: NRobin Murphy <robin.murphy@arm.com>
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      25a1c96c
    • 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
    • R
      iommu/arm-smmu: Treat all device transactions as unprivileged · d346180e
      Robin Murphy 提交于
      The IOMMU API has no concept of privilege so assumes all devices and
      mappings are equal, and indeed most non-CPU master devices on an AMBA
      interconnect make little use of the attribute bits on the bus thus by
      default perform unprivileged data accesses.
      
      Some devices, however, believe themselves more equal than others, such
      as programmable DMA controllers whose 'master' thread issues bus
      transactions marked as privileged instruction fetches, while the data
      accesses of its channel threads (under the control of Linux, at least)
      are marked as unprivileged. This poses a problem for implementing the
      DMA API on an IOMMU conforming to ARM VMSAv8, under which a page that is
      unprivileged-writeable is also implicitly privileged-execute-never.
      Given that, there is no one set of attributes with which iommu_map() can
      implement, say, dma_alloc_coherent() that will allow every possible type
      of access without something running into unexecepted permission faults.
      
      Fortunately the SMMU architecture provides a means to mitigate such
      issues by overriding the incoming attributes of a transaction; make use
      of that to strip the privileged/unprivileged status off incoming
      transactions, leaving just the instruction/data dichotomy which the
      IOMMU API does at least understand; Four states good, two states better.
      Signed-off-by: NRobin Murphy <robin.murphy@arm.com>
      Signed-off-by: NWill Deacon <will.deacon@arm.com>
      d346180e
  12. 17 12月, 2015 3 次提交
    • 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
    • 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