All of lore.kernel.org
 help / color / mirror / Atom feed
From: <gregkh@linuxfoundation.org>
To: will.deacon@arm.com, brian.starkey@arm.com,
	gregkh@linuxfoundation.org, jroedel@suse.de
Cc: <stable@vger.kernel.org>, <stable-commits@vger.kernel.org>
Subject: Patch "iommu/io-pgtable-arm: Unmap and free table when overwriting with block" has been added to the 4.2-stable tree
Date: Sat, 26 Sep 2015 10:36:42 -0700	[thread overview]
Message-ID: <1443289002148199@kroah.com> (raw)


This is a note to let you know that I've just added the patch titled

    iommu/io-pgtable-arm: Unmap and free table when overwriting with block

to the 4.2-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     iommu-io-pgtable-arm-unmap-and-free-table-when-overwriting-with-block.patch
and it can be found in the queue-4.2 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@vger.kernel.org> know about it.


>From cf27ec930be906e142c752f9161197d69ca534d7 Mon Sep 17 00:00:00 2001
From: Will Deacon <will.deacon@arm.com>
Date: Tue, 11 Aug 2015 16:48:32 +0100
Subject: iommu/io-pgtable-arm: Unmap and free table when overwriting with block

From: Will Deacon <will.deacon@arm.com>

commit cf27ec930be906e142c752f9161197d69ca534d7 upstream.

When installing a block mapping, we unconditionally overwrite a non-leaf
PTE if we find one. However, this can cause a problem if the following
sequence of events occur:

  (1) iommu_map called for a 4k (i.e. PAGE_SIZE) mapping at some address
      - We initialise the page table all the way down to a leaf entry
      - No TLB maintenance is required, because we're going from invalid
        to valid.

  (2) iommu_unmap is called on the mapping installed in (1)
      - We walk the page table to the final (leaf) entry and zero it
      - We only changed a valid leaf entry, so we invalidate leaf-only

  (3) iommu_map is called on the same address as (1), but this time for
      a 2MB (i.e. BLOCK_SIZE) mapping)
      - We walk the page table down to the penultimate level, where we
        find a table entry
      - We overwrite the table entry with a block mapping and return
        without any TLB maintenance and without freeing the memory used
        by the now-orphaned table.

This last step can lead to a walk-cache caching the overwritten table
entry, causing unexpected faults when the new mapping is accessed by a
device. One way to fix this would be to collapse the page table when
freeing the last page at a given level, but this would require expensive
iteration on every map call. Instead, this patch detects the case when
we are overwriting a table entry and explicitly unmaps the table first,
which takes care of both freeing and TLB invalidation.

Reported-by: Brian Starkey <brian.starkey@arm.com>
Tested-by: Brian Starkey <brian.starkey@arm.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Joerg Roedel <jroedel@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

---
 drivers/iommu/io-pgtable-arm.c |   17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

--- a/drivers/iommu/io-pgtable-arm.c
+++ b/drivers/iommu/io-pgtable-arm.c
@@ -200,6 +200,10 @@ typedef u64 arm_lpae_iopte;
 
 static bool selftest_running = false;
 
+static int __arm_lpae_unmap(struct arm_lpae_io_pgtable *data,
+			    unsigned long iova, size_t size, int lvl,
+			    arm_lpae_iopte *ptep);
+
 static int arm_lpae_init_pte(struct arm_lpae_io_pgtable *data,
 			     unsigned long iova, phys_addr_t paddr,
 			     arm_lpae_iopte prot, int lvl,
@@ -207,10 +211,21 @@ static int arm_lpae_init_pte(struct arm_
 {
 	arm_lpae_iopte pte = prot;
 
-	/* We require an unmap first */
 	if (iopte_leaf(*ptep, lvl)) {
+		/* We require an unmap first */
 		WARN_ON(!selftest_running);
 		return -EEXIST;
+	} else if (iopte_type(*ptep, lvl) == ARM_LPAE_PTE_TYPE_TABLE) {
+		/*
+		 * We need to unmap and free the old table before
+		 * overwriting it with a block entry.
+		 */
+		arm_lpae_iopte *tblp;
+		size_t sz = ARM_LPAE_BLOCK_SIZE(lvl, data);
+
+		tblp = ptep - ARM_LPAE_LVL_IDX(iova, lvl, data);
+		if (WARN_ON(__arm_lpae_unmap(data, iova, sz, lvl, tblp) != sz))
+			return -EINVAL;
 	}
 
 	if (data->iop.cfg.quirks & IO_PGTABLE_QUIRK_ARM_NS)


Patches currently in stable-queue which might be from will.deacon@arm.com are

queue-4.2/arm64-head.s-initialise-mdcr_el2-in-el2_setup.patch
queue-4.2/arm64-set-max_memblock_addr-according-to-linear-region-size.patch
queue-4.2/arm64-kconfig-move-list_poison-to-a-safe-value.patch
queue-4.2/arm64-flush-fp-simd-state-correctly-after-execve.patch
queue-4.2/arm64-entry-always-restore-x0-from-the-stack-on-syscall-return.patch
queue-4.2/kvm-arm64-add-workaround-for-cortex-a57-erratum-852523.patch
queue-4.2/of-fdt-make-memblock-maximum-physical-address-arch-configurable.patch
queue-4.2/arm64-errata-add-module-build-workaround-for-erratum-843419.patch
queue-4.2/iommu-io-pgtable-arm-unmap-and-free-table-when-overwriting-with-block.patch
queue-4.2/arm64-compat-fix-vfp-save-restore-across-signal-handlers-in-big-endian.patch

                 reply	other threads:[~2015-09-26 17:36 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1443289002148199@kroah.com \
    --to=gregkh@linuxfoundation.org \
    --cc=brian.starkey@arm.com \
    --cc=jroedel@suse.de \
    --cc=stable-commits@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=will.deacon@arm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.