From: Cho KyongHo <pullip.cho@samsung.com>
To: 'Linux ARM Kernel' <linux-arm-kernel@lists.infradead.org>,
'Linux IOMMU' <iommu@lists.linux-foundation.org>,
'Linux Kernel' <linux-kernel@vger.kernel.org>,
'Linux Samsung SOC' <linux-samsung-soc@vger.kernel.org>
Cc: 'Hyunwoong Kim' <khw0178.kim@samsung.com>,
'Joerg Roedel' <joro@8bytes.org>,
'Kukjin Kim' <kgene.kim@samsung.com>,
'Prathyush' <prathyush.k@samsung.com>,
'Rahul Sharma' <rahul.sharma@samsung.com>,
'Subash Patel' <supash.ramaswamy@linaro.org>,
'Keyyoung Park' <keyyoung.park@samsung.com>,
'Grant Grundler' <grundler@chromium.org>
Subject: [PATCH v7 3/9] iommu/exynos: fix page table maintenance
Date: Fri, 05 Jul 2013 21:29:18 +0900 [thread overview]
Message-ID: <002b01ce797b$44d4ad10$ce7e0730$@samsung.com> (raw)
This prevents allocating lv2 page table for the lv1 page table entry
that already has 1MB page mapping. In addition some BUG_ON() is
changed to WARN_ON().
Signed-off-by: Cho KyongHo <pullip.cho@samsung.com>
---
drivers/iommu/exynos-iommu.c | 34 ++++++++++++++++++++++++++--------
1 files changed, 26 insertions(+), 8 deletions(-)
diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index e3be3e5..2bfe9fa 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -862,12 +862,14 @@ static unsigned long *alloc_lv2entry(unsigned long *sent, unsigned long iova,
pent = kzalloc(LV2TABLE_SIZE, GFP_ATOMIC);
BUG_ON((unsigned long)pent & (LV2TABLE_SIZE - 1));
if (!pent)
- return NULL;
+ return ERR_PTR(-ENOMEM);
*sent = mk_lv1ent_page(__pa(pent));
*pgcounter = NUM_LV2ENTRIES;
pgtable_flush(pent, pent + NUM_LV2ENTRIES);
pgtable_flush(sent, sent + 1);
+ } else if (lv1ent_section(sent)) {
+ return ERR_PTR(-EADDRINUSE);
}
return page_entry(sent, iova);
@@ -944,16 +946,16 @@ static int exynos_iommu_map(struct iommu_domain *domain, unsigned long iova,
pent = alloc_lv2entry(entry, iova,
&priv->lv2entcnt[lv1ent_offset(iova)]);
- if (!pent)
- ret = -ENOMEM;
+ if (IS_ERR(pent))
+ ret = PTR_ERR(pent);
else
ret = lv2set_page(pent, paddr, size,
&priv->lv2entcnt[lv1ent_offset(iova)]);
}
if (ret) {
- pr_debug("%s: Failed to map iova 0x%lx/0x%x bytes\n",
- __func__, iova, size);
+ pr_err("%s: Failed(%d) to map iova 0x%#x bytes @ %#lx\n",
+ __func__, ret, size, iova);
}
spin_unlock_irqrestore(&priv->pgtablelock, flags);
@@ -968,6 +970,7 @@ static size_t exynos_iommu_unmap(struct iommu_domain *domain,
struct sysmmu_drvdata *data;
unsigned long flags;
unsigned long *ent;
+ size_t err_page;
BUG_ON(priv->pgtable == NULL);
@@ -976,7 +979,8 @@ static size_t exynos_iommu_unmap(struct iommu_domain *domain,
ent = section_entry(priv->pgtable, iova);
if (lv1ent_section(ent)) {
- BUG_ON(size < SECT_SIZE);
+ if (WARN_ON(size < SECT_SIZE))
+ goto err;
*ent = 0;
pgtable_flush(ent, ent + 1);
@@ -1008,7 +1012,8 @@ static size_t exynos_iommu_unmap(struct iommu_domain *domain,
}
/* lv1ent_large(ent) == true here */
- BUG_ON(size < LPAGE_SIZE);
+ if (WARN_ON(size < LPAGE_SIZE))
+ goto err;
memset(ent, 0, sizeof(*ent) * SPAGES_PER_LPAGE);
pgtable_flush(ent, ent + SPAGES_PER_LPAGE);
@@ -1023,8 +1028,21 @@ done:
sysmmu_tlb_invalidate_entry(data->dev, iova);
spin_unlock_irqrestore(&priv->lock, flags);
-
return size;
+err:
+ spin_unlock_irqrestore(&priv->pgtablelock, flags);
+
+ err_page = (
+ ((unsigned long)ent - (unsigned long)priv->pgtable)
+ < (NUM_LV1ENTRIES * sizeof(long))
+ ) ? SECT_SIZE : LPAGE_SIZE;
+
+ pr_err("%s: Failed due to size(%#lx) @ %#x is"\
+ " smaller than page size %#x\n",
+ __func__, iova, size, err_page);
+
+ return 0;
+
}
static phys_addr_t exynos_iommu_iova_to_phys(struct iommu_domain *domain,
--
1.7.2.5
WARNING: multiple messages have this Message-ID (diff)
From: pullip.cho@samsung.com (Cho KyongHo)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v7 3/9] iommu/exynos: fix page table maintenance
Date: Fri, 05 Jul 2013 21:29:18 +0900 [thread overview]
Message-ID: <002b01ce797b$44d4ad10$ce7e0730$@samsung.com> (raw)
This prevents allocating lv2 page table for the lv1 page table entry
that already has 1MB page mapping. In addition some BUG_ON() is
changed to WARN_ON().
Signed-off-by: Cho KyongHo <pullip.cho@samsung.com>
---
drivers/iommu/exynos-iommu.c | 34 ++++++++++++++++++++++++++--------
1 files changed, 26 insertions(+), 8 deletions(-)
diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index e3be3e5..2bfe9fa 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -862,12 +862,14 @@ static unsigned long *alloc_lv2entry(unsigned long *sent, unsigned long iova,
pent = kzalloc(LV2TABLE_SIZE, GFP_ATOMIC);
BUG_ON((unsigned long)pent & (LV2TABLE_SIZE - 1));
if (!pent)
- return NULL;
+ return ERR_PTR(-ENOMEM);
*sent = mk_lv1ent_page(__pa(pent));
*pgcounter = NUM_LV2ENTRIES;
pgtable_flush(pent, pent + NUM_LV2ENTRIES);
pgtable_flush(sent, sent + 1);
+ } else if (lv1ent_section(sent)) {
+ return ERR_PTR(-EADDRINUSE);
}
return page_entry(sent, iova);
@@ -944,16 +946,16 @@ static int exynos_iommu_map(struct iommu_domain *domain, unsigned long iova,
pent = alloc_lv2entry(entry, iova,
&priv->lv2entcnt[lv1ent_offset(iova)]);
- if (!pent)
- ret = -ENOMEM;
+ if (IS_ERR(pent))
+ ret = PTR_ERR(pent);
else
ret = lv2set_page(pent, paddr, size,
&priv->lv2entcnt[lv1ent_offset(iova)]);
}
if (ret) {
- pr_debug("%s: Failed to map iova 0x%lx/0x%x bytes\n",
- __func__, iova, size);
+ pr_err("%s: Failed(%d) to map iova 0x%#x bytes @ %#lx\n",
+ __func__, ret, size, iova);
}
spin_unlock_irqrestore(&priv->pgtablelock, flags);
@@ -968,6 +970,7 @@ static size_t exynos_iommu_unmap(struct iommu_domain *domain,
struct sysmmu_drvdata *data;
unsigned long flags;
unsigned long *ent;
+ size_t err_page;
BUG_ON(priv->pgtable == NULL);
@@ -976,7 +979,8 @@ static size_t exynos_iommu_unmap(struct iommu_domain *domain,
ent = section_entry(priv->pgtable, iova);
if (lv1ent_section(ent)) {
- BUG_ON(size < SECT_SIZE);
+ if (WARN_ON(size < SECT_SIZE))
+ goto err;
*ent = 0;
pgtable_flush(ent, ent + 1);
@@ -1008,7 +1012,8 @@ static size_t exynos_iommu_unmap(struct iommu_domain *domain,
}
/* lv1ent_large(ent) == true here */
- BUG_ON(size < LPAGE_SIZE);
+ if (WARN_ON(size < LPAGE_SIZE))
+ goto err;
memset(ent, 0, sizeof(*ent) * SPAGES_PER_LPAGE);
pgtable_flush(ent, ent + SPAGES_PER_LPAGE);
@@ -1023,8 +1028,21 @@ done:
sysmmu_tlb_invalidate_entry(data->dev, iova);
spin_unlock_irqrestore(&priv->lock, flags);
-
return size;
+err:
+ spin_unlock_irqrestore(&priv->pgtablelock, flags);
+
+ err_page = (
+ ((unsigned long)ent - (unsigned long)priv->pgtable)
+ < (NUM_LV1ENTRIES * sizeof(long))
+ ) ? SECT_SIZE : LPAGE_SIZE;
+
+ pr_err("%s: Failed due to size(%#lx) @ %#x is"\
+ " smaller than page size %#x\n",
+ __func__, iova, size, err_page);
+
+ return 0;
+
}
static phys_addr_t exynos_iommu_iova_to_phys(struct iommu_domain *domain,
--
1.7.2.5
next reply other threads:[~2013-07-05 12:29 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-07-05 12:29 Cho KyongHo [this message]
2013-07-05 12:29 ` [PATCH v7 3/9] iommu/exynos: fix page table maintenance Cho KyongHo
2013-07-11 17:37 ` Bartlomiej Zolnierkiewicz
2013-07-11 17:37 ` Bartlomiej Zolnierkiewicz
2013-07-15 11:21 ` Cho KyongHo
2013-07-15 11:21 ` Cho KyongHo
2013-07-15 16:18 ` Grant Grundler
2013-07-15 16:18 ` Grant Grundler
2013-07-16 13:07 ` Cho KyongHo
2013-07-16 13:07 ` Cho KyongHo
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='002b01ce797b$44d4ad10$ce7e0730$@samsung.com' \
--to=pullip.cho@samsung.com \
--cc=grundler@chromium.org \
--cc=iommu@lists.linux-foundation.org \
--cc=joro@8bytes.org \
--cc=keyyoung.park@samsung.com \
--cc=kgene.kim@samsung.com \
--cc=khw0178.kim@samsung.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-samsung-soc@vger.kernel.org \
--cc=prathyush.k@samsung.com \
--cc=rahul.sharma@samsung.com \
--cc=supash.ramaswamy@linaro.org \
/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.