* [PATCH 0/4] iommu/tegra-smmu: A set of small fixes
@ 2019-12-20 0:29 Nicolin Chen
2019-12-20 0:29 ` [PATCH 1/4] memory: tegra: Correct reset value of xusb_hostr Nicolin Chen
` (3 more replies)
0 siblings, 4 replies; 6+ messages in thread
From: Nicolin Chen @ 2019-12-20 0:29 UTC (permalink / raw)
To: thierry.reding, joro; +Cc: linux-tegra, iommu, linux-kernel, jonathanh
Hi all,
This series of patches are some small fixes for tegra-smmu, mainly
tested Tegra210 with downstream kernel. As we only enabled limited
clients for Tegra210 on mainline tree, I am not sure how critical
these fixes are, so not CCing stable tree.
Nicolin Chen (4):
memory: tegra: Correct reset value of xusb_hostr
iommu/tegra-smmu: Do not use PAGE_SHIFT and PAGE_MASK
iommu/tegra-smmu: Fix iova->phy translation
iommu/tegra-smmu: Prevent race condition between map and unmap
drivers/iommu/tegra-smmu.c | 29 ++++++++++++++++++++++++-----
drivers/memory/tegra/tegra210.c | 2 +-
2 files changed, 25 insertions(+), 6 deletions(-)
--
2.17.1
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/4] memory: tegra: Correct reset value of xusb_hostr
2019-12-20 0:29 [PATCH 0/4] iommu/tegra-smmu: A set of small fixes Nicolin Chen
@ 2019-12-20 0:29 ` Nicolin Chen
2020-01-10 14:34 ` Thierry Reding
2019-12-20 0:29 ` [PATCH 2/4] iommu/tegra-smmu: Do not use PAGE_SHIFT and PAGE_MASK Nicolin Chen
` (2 subsequent siblings)
3 siblings, 1 reply; 6+ messages in thread
From: Nicolin Chen @ 2019-12-20 0:29 UTC (permalink / raw)
To: thierry.reding, joro; +Cc: linux-tegra, iommu, linux-kernel, jonathanh
According to Tegra X1 (Tegra210) TRM, the reset value of xusb_hostr
field (bit [7:0]) should be 0x7a. So this patch simply corrects it.
Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
---
drivers/memory/tegra/tegra210.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/memory/tegra/tegra210.c b/drivers/memory/tegra/tegra210.c
index a3918a96467f..eab4bc01c8bc 100644
--- a/drivers/memory/tegra/tegra210.c
+++ b/drivers/memory/tegra/tegra210.c
@@ -436,7 +436,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
.reg = 0x37c,
.shift = 0,
.mask = 0xff,
- .def = 0x39,
+ .def = 0x7a,
},
}, {
.id = 0x4b,
--
2.17.1
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/4] iommu/tegra-smmu: Do not use PAGE_SHIFT and PAGE_MASK
2019-12-20 0:29 [PATCH 0/4] iommu/tegra-smmu: A set of small fixes Nicolin Chen
2019-12-20 0:29 ` [PATCH 1/4] memory: tegra: Correct reset value of xusb_hostr Nicolin Chen
@ 2019-12-20 0:29 ` Nicolin Chen
2019-12-20 0:29 ` [PATCH 3/4] iommu/tegra-smmu: Fix iova->phys translation Nicolin Chen
2019-12-20 0:29 ` [PATCH 4/4] iommu/tegra-smmu: Prevent race condition between map and unmap Nicolin Chen
3 siblings, 0 replies; 6+ messages in thread
From: Nicolin Chen @ 2019-12-20 0:29 UTC (permalink / raw)
To: thierry.reding, joro; +Cc: linux-tegra, iommu, linux-kernel, jonathanh
PAGE_SHIFT and PAGE_MASK are defined corresponding to the page size
for CPU virtual addresses, which means PAGE_SHIFT could be a number
other than 12, but tegra-smmu maintains fixed 4KB IOVA pages and has
fixed [21:12] bit range for PTE entries.
So this patch replaces all PAGE_SHIFT/PAGE_MASK references with the
macros defined with SMMU_PTE_SHIFT.
Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
---
drivers/iommu/tegra-smmu.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index 63a147b623e6..5594b47a88bf 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -127,6 +127,11 @@ static inline u32 smmu_readl(struct tegra_smmu *smmu, unsigned long offset)
#define SMMU_PDE_SHIFT 22
#define SMMU_PTE_SHIFT 12
+#define SMMU_PAGE_MASK (~(SMMU_SIZE_PT-1))
+#define SMMU_OFFSET_IN_PAGE(x) ((unsigned long)(x) & ~SMMU_PAGE_MASK)
+#define SMMU_PFN_PHYS(x) ((phys_addr_t)(x) << SMMU_PTE_SHIFT)
+#define SMMU_PHYS_PFN(x) ((unsigned long)((x) >> SMMU_PTE_SHIFT))
+
#define SMMU_PD_READABLE (1 << 31)
#define SMMU_PD_WRITABLE (1 << 30)
#define SMMU_PD_NONSECURE (1 << 29)
@@ -644,7 +649,7 @@ static void tegra_smmu_set_pte(struct tegra_smmu_as *as, unsigned long iova,
u32 *pte, dma_addr_t pte_dma, u32 val)
{
struct tegra_smmu *smmu = as->smmu;
- unsigned long offset = offset_in_page(pte);
+ unsigned long offset = SMMU_OFFSET_IN_PAGE(pte);
*pte = val;
@@ -680,7 +685,7 @@ static int tegra_smmu_map(struct iommu_domain *domain, unsigned long iova,
pte_attrs |= SMMU_PTE_WRITABLE;
tegra_smmu_set_pte(as, iova, pte, pte_dma,
- __phys_to_pfn(paddr) | pte_attrs);
+ SMMU_PHYS_PFN(paddr) | pte_attrs);
return 0;
}
@@ -716,7 +721,7 @@ static phys_addr_t tegra_smmu_iova_to_phys(struct iommu_domain *domain,
pfn = *pte & as->smmu->pfn_mask;
- return PFN_PHYS(pfn);
+ return SMMU_PFN_PHYS(pfn);
}
static struct tegra_smmu *tegra_smmu_find(struct device_node *np)
@@ -1034,7 +1039,8 @@ struct tegra_smmu *tegra_smmu_probe(struct device *dev,
smmu->dev = dev;
smmu->mc = mc;
- smmu->pfn_mask = BIT_MASK(mc->soc->num_address_bits - PAGE_SHIFT) - 1;
+ smmu->pfn_mask =
+ BIT_MASK(mc->soc->num_address_bits - SMMU_PTE_SHIFT) - 1;
dev_dbg(dev, "address bits: %u, PFN mask: %#lx\n",
mc->soc->num_address_bits, smmu->pfn_mask);
smmu->tlb_mask = (smmu->soc->num_tlb_lines << 1) - 1;
--
2.17.1
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 3/4] iommu/tegra-smmu: Fix iova->phys translation
2019-12-20 0:29 [PATCH 0/4] iommu/tegra-smmu: A set of small fixes Nicolin Chen
2019-12-20 0:29 ` [PATCH 1/4] memory: tegra: Correct reset value of xusb_hostr Nicolin Chen
2019-12-20 0:29 ` [PATCH 2/4] iommu/tegra-smmu: Do not use PAGE_SHIFT and PAGE_MASK Nicolin Chen
@ 2019-12-20 0:29 ` Nicolin Chen
2019-12-20 0:29 ` [PATCH 4/4] iommu/tegra-smmu: Prevent race condition between map and unmap Nicolin Chen
3 siblings, 0 replies; 6+ messages in thread
From: Nicolin Chen @ 2019-12-20 0:29 UTC (permalink / raw)
To: thierry.reding, joro; +Cc: linux-tegra, iommu, linux-kernel, jonathanh
IOVA might not be always 4KB aligned. So tegra_smmu_iova_to_phys
function needs to add on the lower 12-bit offset from input iova.
Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
---
drivers/iommu/tegra-smmu.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index 5594b47a88bf..3999ecb63cfa 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -721,7 +721,7 @@ static phys_addr_t tegra_smmu_iova_to_phys(struct iommu_domain *domain,
pfn = *pte & as->smmu->pfn_mask;
- return SMMU_PFN_PHYS(pfn);
+ return SMMU_PFN_PHYS(pfn) + SMMU_OFFSET_IN_PAGE(iova);
}
static struct tegra_smmu *tegra_smmu_find(struct device_node *np)
--
2.17.1
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 4/4] iommu/tegra-smmu: Prevent race condition between map and unmap
2019-12-20 0:29 [PATCH 0/4] iommu/tegra-smmu: A set of small fixes Nicolin Chen
` (2 preceding siblings ...)
2019-12-20 0:29 ` [PATCH 3/4] iommu/tegra-smmu: Fix iova->phys translation Nicolin Chen
@ 2019-12-20 0:29 ` Nicolin Chen
3 siblings, 0 replies; 6+ messages in thread
From: Nicolin Chen @ 2019-12-20 0:29 UTC (permalink / raw)
To: thierry.reding, joro; +Cc: linux-tegra, iommu, linux-kernel, jonathanh
When testing with ethernet downloading, "EMEM address decode error"
happens due to race condition between map() and unmap() functions.
This patch adds a spin lock to protect content within as->[count]
and as->pts[pde] references, since a function call might be atomic.
Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
---
drivers/iommu/tegra-smmu.c | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index 3999ecb63cfa..236bc6d6d238 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -37,6 +37,7 @@ struct tegra_smmu {
unsigned long *asids;
struct mutex lock;
+ spinlock_t as_lock;
struct list_head list;
@@ -664,17 +665,23 @@ static int tegra_smmu_map(struct iommu_domain *domain, unsigned long iova,
phys_addr_t paddr, size_t size, int prot, gfp_t gfp)
{
struct tegra_smmu_as *as = to_smmu_as(domain);
+ struct tegra_smmu *smmu = as->smmu;
+ unsigned long flags;
dma_addr_t pte_dma;
u32 pte_attrs;
u32 *pte;
+ spin_lock_irqsave(&smmu->as_lock, flags);
pte = as_get_pte(as, iova, &pte_dma);
- if (!pte)
+ if (!pte) {
+ spin_unlock_irqrestore(&smmu->as_lock, flags);
return -ENOMEM;
+ }
/* If we aren't overwriting a pre-existing entry, increment use */
if (*pte == 0)
tegra_smmu_pte_get_use(as, iova);
+ spin_unlock_irqrestore(&smmu->as_lock, flags);
pte_attrs = SMMU_PTE_NONSECURE;
@@ -694,6 +701,8 @@ static size_t tegra_smmu_unmap(struct iommu_domain *domain, unsigned long iova,
size_t size, struct iommu_iotlb_gather *gather)
{
struct tegra_smmu_as *as = to_smmu_as(domain);
+ struct tegra_smmu *smmu = as->smmu;
+ unsigned long flags;
dma_addr_t pte_dma;
u32 *pte;
@@ -702,7 +711,10 @@ static size_t tegra_smmu_unmap(struct iommu_domain *domain, unsigned long iova,
return 0;
tegra_smmu_set_pte(as, iova, pte, pte_dma, 0);
+
+ spin_lock_irqsave(&smmu->as_lock, flags);
tegra_smmu_pte_put_use(as, iova);
+ spin_unlock_irqrestore(&smmu->as_lock, flags);
return size;
}
@@ -1033,6 +1045,7 @@ struct tegra_smmu *tegra_smmu_probe(struct device *dev,
INIT_LIST_HEAD(&smmu->groups);
mutex_init(&smmu->lock);
+ spin_lock_init(&smmu->as_lock);
smmu->regs = mc->regs;
smmu->soc = soc;
--
2.17.1
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 1/4] memory: tegra: Correct reset value of xusb_hostr
2019-12-20 0:29 ` [PATCH 1/4] memory: tegra: Correct reset value of xusb_hostr Nicolin Chen
@ 2020-01-10 14:34 ` Thierry Reding
0 siblings, 0 replies; 6+ messages in thread
From: Thierry Reding @ 2020-01-10 14:34 UTC (permalink / raw)
To: Nicolin Chen; +Cc: linux-tegra, linux-kernel, iommu, jonathanh
[-- Attachment #1.1: Type: text/plain, Size: 414 bytes --]
On Thu, Dec 19, 2019 at 04:29:11PM -0800, Nicolin Chen wrote:
> According to Tegra X1 (Tegra210) TRM, the reset value of xusb_hostr
> field (bit [7:0]) should be 0x7a. So this patch simply corrects it.
>
> Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
> ---
> drivers/memory/tegra/tegra210.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
Applied to for-5.6/memory, thanks.
Thierry
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
[-- Attachment #2: Type: text/plain, Size: 156 bytes --]
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2020-01-10 14:34 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-12-20 0:29 [PATCH 0/4] iommu/tegra-smmu: A set of small fixes Nicolin Chen
2019-12-20 0:29 ` [PATCH 1/4] memory: tegra: Correct reset value of xusb_hostr Nicolin Chen
2020-01-10 14:34 ` Thierry Reding
2019-12-20 0:29 ` [PATCH 2/4] iommu/tegra-smmu: Do not use PAGE_SHIFT and PAGE_MASK Nicolin Chen
2019-12-20 0:29 ` [PATCH 3/4] iommu/tegra-smmu: Fix iova->phys translation Nicolin Chen
2019-12-20 0:29 ` [PATCH 4/4] iommu/tegra-smmu: Prevent race condition between map and unmap Nicolin Chen
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).