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.1-stable tree
Date: Sat, 26 Sep 2015 10:35:43 -0700 [thread overview]
Message-ID: <144328894361184@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.1-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.1 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.1/arm64-head.s-initialise-mdcr_el2-in-el2_setup.patch
queue-4.1/arm64-set-max_memblock_addr-according-to-linear-region-size.patch
queue-4.1/arm64-kconfig-move-list_poison-to-a-safe-value.patch
queue-4.1/arm64-flush-fp-simd-state-correctly-after-execve.patch
queue-4.1/kvm-arm64-add-workaround-for-cortex-a57-erratum-852523.patch
queue-4.1/of-fdt-make-memblock-maximum-physical-address-arch-configurable.patch
queue-4.1/arm64-errata-add-module-build-workaround-for-erratum-843419.patch
queue-4.1/iommu-io-pgtable-arm-unmap-and-free-table-when-overwriting-with-block.patch
queue-4.1/arm64-compat-fix-vfp-save-restore-across-signal-handlers-in-big-endian.patch
reply other threads:[~2015-09-26 17:35 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=144328894361184@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).