1. 11 12月, 2018 6 次提交
  2. 23 11月, 2018 1 次提交
    • S
      iommu/vt-d: Handle domain agaw being less than iommu agaw · 3569dd07
      Sohil Mehta 提交于
      The Intel IOMMU driver opportunistically skips a few top level page
      tables from the domain paging directory while programming the IOMMU
      context entry. However there is an implicit assumption in the code that
      domain's adjusted guest address width (agaw) would always be greater
      than IOMMU's agaw.
      
      The IOMMU capabilities in an upcoming platform cause the domain's agaw
      to be lower than IOMMU's agaw. The issue is seen when the IOMMU supports
      both 4-level and 5-level paging. The domain builds a 4-level page table
      based on agaw of 2. However the IOMMU's agaw is set as 3 (5-level). In
      this case the code incorrectly tries to skip page page table levels.
      This causes the IOMMU driver to avoid programming the context entry. The
      fix handles this case and programs the context entry accordingly.
      
      Fixes: de24e553 ("iommu/vt-d: Simplify domain_context_mapping_one")
      Cc: <stable@vger.kernel.org>
      Cc: Ashok Raj <ashok.raj@intel.com>
      Cc: Jacob Pan <jacob.jun.pan@linux.intel.com>
      Cc: Lu Baolu <baolu.lu@linux.intel.com>
      Reviewed-by: NLu Baolu <baolu.lu@linux.intel.com>
      Reported-by: NRamos Falcon, Ernesto R <ernesto.r.ramos.falcon@intel.com>
      Tested-by: NRicardo Neri <ricardo.neri-calderon@linux.intel.com>
      Signed-off-by: NSohil Mehta <sohil.mehta@intel.com>
      Signed-off-by: NJoerg Roedel <jroedel@suse.de>
      3569dd07
  3. 25 9月, 2018 3 次提交
  4. 18 9月, 2018 2 次提交
  5. 18 8月, 2018 1 次提交
  6. 08 8月, 2018 1 次提交
  7. 20 7月, 2018 8 次提交
  8. 06 7月, 2018 3 次提交
  9. 13 6月, 2018 1 次提交
    • 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
  10. 15 5月, 2018 4 次提交
  11. 11 5月, 2018 1 次提交
    • G
      PCI: Add "pci=noats" boot parameter · cef74409
      Gil Kupfer 提交于
      Adds a "pci=noats" boot parameter.  When supplied, all ATS related
      functions fail immediately and the IOMMU is configured to not use
      device-IOTLB.
      
      Any function that checks for ATS capabilities directly against the devices
      should also check this flag.  Currently, such functions exist only in IOMMU
      drivers, and they are covered by this patch.
      
      The motivation behind this patch is the existence of malicious devices.
      Lots of research has been done about how to use the IOMMU as protection
      from such devices.  When ATS is supported, any I/O device can access any
      physical address by faking device-IOTLB entries.  Adding the ability to
      ignore these entries lets sysadmins enhance system security.
      Signed-off-by: NGil Kupfer <gilkup@cs.technion.ac.il>
      Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>
      Acked-by: NJoerg Roedel <jroedel@suse.de>
      cef74409
  12. 29 3月, 2018 1 次提交
  13. 20 3月, 2018 2 次提交
  14. 17 1月, 2018 2 次提交
    • S
      iommu/vt-d: Enable upto 57 bits of domain address width · 5e3b4a15
      Sohil Mehta 提交于
      Update the IOMMU default domain address width to 57 bits. This would
      enable the IOMMU to do upto 5-levels of paging for second level
      translations - IOVA translation requests without PASID.
      
      Even though the maximum supported address width is being increased to
      57, __iommu_calculate_agaw() would set the actual supported address
      width to the maximum support available in IOMMU hardware.
      Signed-off-by: NSohil Mehta <sohil.mehta@intel.com>
      Signed-off-by: NJoerg Roedel <jroedel@suse.de>
      5e3b4a15
    • P
      iommu/vt-d: Use domain instead of cache fetching · 9d2e6505
      Peter Xu 提交于
      after commit a1ddcbe9 ("iommu/vt-d: Pass dmar_domain directly into
      iommu_flush_iotlb_psi", 2015-08-12), we have domain pointer as parameter
      to iommu_flush_iotlb_psi(), so no need to fetch it from cache again.
      
      More importantly, a NULL reference pointer bug is reported on RHEL7 (and
      it can be reproduced on some old upstream kernels too, e.g., v4.13) by
      unplugging an 40g nic from a VM (hard to test unplug on real host, but
      it should be the same):
      
      https://bugzilla.redhat.com/show_bug.cgi?id=1531367
      
      [   24.391863] pciehp 0000:00:03.0:pcie004: Slot(0): Attention button pressed
      [   24.393442] pciehp 0000:00:03.0:pcie004: Slot(0): Powering off due to button press
      [   29.721068] i40evf 0000:01:00.0: Unable to send opcode 2 to PF, err I40E_ERR_QUEUE_EMPTY, aq_err OK
      [   29.783557] iommu: Removing device 0000:01:00.0 from group 3
      [   29.784662] BUG: unable to handle kernel NULL pointer dereference at 0000000000000304
      [   29.785817] IP: iommu_flush_iotlb_psi+0xcf/0x120
      [   29.786486] PGD 0
      [   29.786487] P4D 0
      [   29.786812]
      [   29.787390] Oops: 0000 [#1] SMP
      [   29.787876] Modules linked in: ip6t_rpfilter ip6t_REJECT nf_reject_ipv6 xt_conntrack ip_set nfnetlink ebtable_nat ebtable_broute bridge stp llc ip6table_ng
      [   29.795371] CPU: 0 PID: 156 Comm: kworker/0:2 Not tainted 4.13.0 #14
      [   29.796366] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.11.0-1.el7 04/01/2014
      [   29.797593] Workqueue: pciehp-0 pciehp_power_thread
      [   29.798328] task: ffff94f5745b4a00 task.stack: ffffb326805ac000
      [   29.799178] RIP: 0010:iommu_flush_iotlb_psi+0xcf/0x120
      [   29.799919] RSP: 0018:ffffb326805afbd0 EFLAGS: 00010086
      [   29.800666] RAX: ffff94f5bc56e800 RBX: 0000000000000000 RCX: 0000000200000025
      [   29.801667] RDX: ffff94f5bc56e000 RSI: 0000000000000082 RDI: 0000000000000000
      [   29.802755] RBP: ffffb326805afbf8 R08: 0000000000000000 R09: ffff94f5bc86bbf0
      [   29.803772] R10: ffffb326805afba8 R11: 00000000000ffdc4 R12: ffff94f5bc86a400
      [   29.804789] R13: 0000000000000000 R14: 00000000ffdc4000 R15: 0000000000000000
      [   29.805792] FS:  0000000000000000(0000) GS:ffff94f5bfc00000(0000) knlGS:0000000000000000
      [   29.806923] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
      [   29.807736] CR2: 0000000000000304 CR3: 000000003499d000 CR4: 00000000000006f0
      [   29.808747] Call Trace:
      [   29.809156]  flush_unmaps_timeout+0x126/0x1c0
      [   29.809800]  domain_exit+0xd6/0x100
      [   29.810322]  device_notifier+0x6b/0x70
      [   29.810902]  notifier_call_chain+0x4a/0x70
      [   29.812822]  __blocking_notifier_call_chain+0x47/0x60
      [   29.814499]  blocking_notifier_call_chain+0x16/0x20
      [   29.816137]  device_del+0x233/0x320
      [   29.817588]  pci_remove_bus_device+0x6f/0x110
      [   29.819133]  pci_stop_and_remove_bus_device+0x1a/0x20
      [   29.820817]  pciehp_unconfigure_device+0x7a/0x1d0
      [   29.822434]  pciehp_disable_slot+0x52/0xe0
      [   29.823931]  pciehp_power_thread+0x8a/0xa0
      [   29.825411]  process_one_work+0x18c/0x3a0
      [   29.826875]  worker_thread+0x4e/0x3b0
      [   29.828263]  kthread+0x109/0x140
      [   29.829564]  ? process_one_work+0x3a0/0x3a0
      [   29.831081]  ? kthread_park+0x60/0x60
      [   29.832464]  ret_from_fork+0x25/0x30
      [   29.833794] Code: 85 ed 74 0b 5b 41 5c 41 5d 41 5e 41 5f 5d c3 49 8b 54 24 60 44 89 f8 0f b6 c4 48 8b 04 c2 48 85 c0 74 49 45 0f b6 ff 4a 8b 3c f8 <80> bf
      [   29.838514] RIP: iommu_flush_iotlb_psi+0xcf/0x120 RSP: ffffb326805afbd0
      [   29.840362] CR2: 0000000000000304
      [   29.841716] ---[ end trace b10ec0d6900868d3 ]---
      
      This patch fixes that problem if applied to v4.13 kernel.
      
      The bug does not exist on latest upstream kernel since it's fixed as a
      side effect of commit 13cf0174 ("iommu/vt-d: Make use of iova
      deferred flushing", 2017-08-15).  But IMHO it's still good to have this
      patch upstream.
      
      CC: Alex Williamson <alex.williamson@redhat.com>
      Signed-off-by: NPeter Xu <peterx@redhat.com>
      Fixes: a1ddcbe9 ("iommu/vt-d: Pass dmar_domain directly into iommu_flush_iotlb_psi")
      Reviewed-by: NAlex Williamson <alex.williamson@redhat.com>
      Signed-off-by: NJoerg Roedel <jroedel@suse.de>
      9d2e6505
  15. 15 1月, 2018 1 次提交
  16. 18 11月, 2017 1 次提交
    • R
      iommu/vt-d: Fix scatterlist offset handling · 29a90b70
      Robin Murphy 提交于
      The intel-iommu DMA ops fail to correctly handle scatterlists where
      sg->offset is greater than PAGE_SIZE - the IOVA allocation is computed
      appropriately based on the page-aligned portion of the offset, but the
      mapping is set up relative to sg->page, which means it fails to actually
      cover the whole buffer (and in the worst case doesn't cover it at all):
      
          (sg->dma_address + sg->dma_len) ----+
          sg->dma_address ---------+          |
          iov_pfn------+           |          |
                       |           |          |
                       v           v          v
      iova:   a        b        c        d        e        f
              |--------|--------|--------|--------|--------|
                                <...calculated....>
                       [_____mapped______]
      pfn:    0        1        2        3        4        5
              |--------|--------|--------|--------|--------|
                       ^           ^          ^
                       |           |          |
          sg->page ----+           |          |
          sg->offset --------------+          |
          (sg->offset + sg->length) ----------+
      
      As a result, the caller ends up overrunning the mapping into whatever
      lies beyond, which usually goes badly:
      
      [  429.645492] DMAR: DRHD: handling fault status reg 2
      [  429.650847] DMAR: [DMA Write] Request device [02:00.4] fault addr f2682000 ...
      
      Whilst this is a fairly rare occurrence, it can happen from the result
      of intermediate scatterlist processing such as scatterwalk_ffwd() in the
      crypto layer. Whilst that particular site could be fixed up, it still
      seems worthwhile to bring intel-iommu in line with other DMA API
      implementations in handling this robustly.
      
      To that end, fix the intel_map_sg() path to line up the mapping
      correctly (in units of MM pages rather than VT-d pages to match the
      aligned_nrpages() calculation) regardless of the offset, and use
      sg_phys() consistently for clarity.
      Reported-by: NHarsh Jain <Harsh@chelsio.com>
      Signed-off-by: NRobin Murphy <robin.murphy@arm.com>
      Reviewed by: Ashok Raj <ashok.raj@intel.com>
      Tested by: Jacob Pan <jacob.jun.pan@intel.com>
      Cc: stable@vger.kernel.org
      Signed-off-by: NAlex Williamson <alex.williamson@redhat.com>
      29a90b70
  17. 12 10月, 2017 1 次提交
    • T
      iommu/iova: Make rcache flush optional on IOVA allocation failure · 538d5b33
      Tomasz Nowicki 提交于
      Since IOVA allocation failure is not unusual case we need to flush
      CPUs' rcache in hope we will succeed in next round.
      
      However, it is useful to decide whether we need rcache flush step because
      of two reasons:
      - Not scalability. On large system with ~100 CPUs iterating and flushing
        rcache for each CPU becomes serious bottleneck so we may want to defer it.
      - free_cpu_cached_iovas() does not care about max PFN we are interested in.
        Thus we may flush our rcaches and still get no new IOVA like in the
        commonly used scenario:
      
          if (dma_limit > DMA_BIT_MASK(32) && dev_is_pci(dev))
              iova = alloc_iova_fast(iovad, iova_len, DMA_BIT_MASK(32) >> shift);
      
          if (!iova)
              iova = alloc_iova_fast(iovad, iova_len, dma_limit >> shift);
      
         1. First alloc_iova_fast() call is limited to DMA_BIT_MASK(32) to get
            PCI devices a SAC address
         2. alloc_iova() fails due to full 32-bit space
         3. rcaches contain PFNs out of 32-bit space so free_cpu_cached_iovas()
            throws entries away for nothing and alloc_iova() fails again
         4. Next alloc_iova_fast() call cannot take advantage of rcache since we
            have just defeated caches. In this case we pick the slowest option
            to proceed.
      
      This patch reworks flushed_rcache local flag to be additional function
      argument instead and control rcache flush step. Also, it updates all users
      to do the flush as the last chance.
      Signed-off-by: NTomasz Nowicki <Tomasz.Nowicki@caviumnetworks.com>
      Reviewed-by: NRobin Murphy <robin.murphy@arm.com>
      Tested-by: NNate Watterson <nwatters@codeaurora.org>
      Signed-off-by: NJoerg Roedel <jroedel@suse.de>
      538d5b33
  18. 10 10月, 2017 1 次提交