TEGRA GART cleanup and new debug option
Subsystems (3)
v2 cover TEGRA GART cleanup and new debug option
This is a continuation of the "iommu/tegra: gart: Couple corrections" patchset that was send out quite some time ago and reviewed by Thierry Reding recently.
Change log:
v2:
- Dropped "Don't unnecessarily allocate registers context" patch as it is not entirely correct.
- Replaced "Correct number of unmapped bytes" and "Check whether page is already mapped" patches with a new GART debug Kconfig option patch.
Dmitry Osipenko (2):
iommu/tegra: gart: Optionally check for overwriting of page mappings iommu/tegra: gart: Move PFN validation out of spinlock
drivers/iommu/Kconfig | 9 +++++++++ drivers/iommu/tegra-gart.c | 20 +++++++++++++++++--- 2 files changed, 26 insertions(+), 3 deletions(-)
Signature · 1 line
2.14.1
A message that is not in the archive (sent off-list or not yet received): cover.1507078586.git.digetx-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
A message that is not in the archive (sent off-list or not yet received): cover.1507078770.git.digetx-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
PATCH v2 1/2 iommu/tegra: gart: Add optional debug checking for overwriting of page mappings
Due to a bug in IOVA allocator, page mapping could accidentally overwritten. We can catch this case by checking 'VALID' bit of GART's page entry prior to mapping of a page. Since that check introduces a noticeable performance impact, it should be enabled explicitly by a new CONFIG_TEGRA_IOMMU_GART_DEBUG option.
--- drivers/iommu/Kconfig | 9 +++++++++ drivers/iommu/tegra-gart.c | 16 +++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-)
drivers/iommu/Kconfig +9 -0
@@ -242,6 +242,15 @@ config TEGRA_IOMMU_GART space through the GART (Graphics Address Relocation Table) hardware included on Tegra SoCs. +config TEGRA_IOMMU_GART_DEBUG + bool "Debug Tegra GART IOMMU" + depends on TEGRA_IOMMU_GART + help + Properly unmap pages and check whether page is already mapped + during of mapping in expense of performance. This allows to + catch double page remappings, caused by a bug in the IOVA + allocator for example. + config TEGRA_IOMMU_SMMU bool "NVIDIA Tegra SMMU Support" depends on ARCH_TEGRA
drivers/iommu/tegra-gart.c +15 -1
@@ -271,6 +271,7 @@ static int gart_iommu_map(struct iommu_domain *domain, unsigned long iova,struct gart_device *gart = gart_domain->gart;unsigned long flags;unsigned long pfn; +unsigned long pte;if (!gart_iova_range_valid (gart, iova, bytes))return -EINVAL ;
@@ -282,6 +283,14 @@ static int gart_iommu_map(struct iommu_domain *domain, unsigned long iova,spin_unlock_irqrestore (&gart->pte_lock, flags);return -EINVAL ; } +if (IS_ENABLED (TEGRA_IOMMU_GART_DEBUG )) { + pte =gart_read_pte (gart, iova); +if (pte &GART_ENTRY_PHYS_ADDR_VALID ) { +spin_unlock_irqrestore (&gart->pte_lock, flags); +dev_err (gart->dev,"Page entry is used already\n" ); +return -EBUSY ; + } + }gart_set_pte (gart, iova,GART_PTE (pfn));FLUSH_GART_REGS (gart);spin_unlock_irqrestore (&gart->pte_lock, flags);
@@ -298,11 +307,16 @@ static size_t gart_iommu_unmap(struct iommu_domain *domain, unsigned long iova,if (!gart_iova_range_valid (gart, iova, bytes))return 0 ; +/* don't unmap page entries to achieve better performance */ +if (!IS_ENABLED (TEGRA_IOMMU_GART_DEBUG )) +return 0 ; +spin_lock_irqsave (&gart->pte_lock, flags);gart_set_pte (gart, iova,0 );FLUSH_GART_REGS (gart);spin_unlock_irqrestore (&gart->pte_lock, flags); -return 0 ; + +return bytes; } static phys_addr_t gart_iommu_iova_to_phys(struct iommu_domain *domain,
Signature · 1 line
2.14.1
A message that is not in the archive (sent off-list or not yet received): 2eadfde76987532354e419ffc98aae44e4af489a.1507078586.git.digetx-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
Re: [PATCH v2 1/2] iommu/tegra: gart: Add optional debug checking for overwriting of page mappings
Quoted 68 lines · Dmitry Osipenko
Due to a bug in IOVA allocator, page mapping could accidentally overwritten. We can catch this case by checking 'VALID' bit of GART's page entry prior to mapping of a page. Since that check introduces a noticeable performance impact, it should be enabled explicitly by a new
CONFIG_TEGRA_IOMMU_GART_DEBUGoption.Signed-off-by Dmitry Osipenko <[email protected]>--- drivers/iommu/Kconfig | 9 +++++++++ drivers/iommu/tegra-gart.c | 16 +++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-)drivers/iommu/Kconfig +9
-0@@ -242,6 +242,15 @@ config TEGRA_IOMMU_GART space through the GART (Graphics Address Relocation Table) hardware included on Tegra SoCs. +config TEGRA_IOMMU_GART_DEBUG + bool "Debug Tegra GART IOMMU" + depends on TEGRA_IOMMU_GART + help + Properly unmap pages and check whether page is already mapped + during of mapping in expense of performance. This allows to + catch double page remappings, caused by a bug in the IOVA + allocator for example. + config TEGRA_IOMMU_SMMU bool "NVIDIA Tegra SMMU Support" depends on ARCH_TEGRAdrivers/iommu/tegra-gart.c +13
-0@@ -271,6 +271,7 @@ static int gart_iommu_map(struct iommu_domain *domain, unsigned long iova,struct gart_device *gart = gart_domain->gart;unsigned long flags;unsigned long pfn; +unsigned long pte;if (!gart_iova_range_valid (gart, iova, bytes))return -EINVAL ;@@ -282,6 +283,14 @@ static int gart_iommu_map(struct iommu_domain *domain, unsigned long iova,spin_unlock_irqrestore (&gart->pte_lock, flags);return -EINVAL ; } +if (IS_ENABLED (TEGRA_IOMMU_GART_DEBUG )) { + pte =gart_read_pte (gart, iova); +if (pte &GART_ENTRY_PHYS_ADDR_VALID ) { +spin_unlock_irqrestore (&gart->pte_lock, flags); +dev_err (gart->dev,"Page entry is used already\n" ); +return -EBUSY ; + } + }gart_set_pte (gart, iova,GART_PTE (pfn));FLUSH_GART_REGS (gart);spin_unlock_irqrestore (&gart->pte_lock, flags);@@ -298,11 +307,16 @@ static size_t gart_iommu_unmap(struct iommu_domain *domain, unsigned long iova,if (!gart_iova_range_valid (gart, iova, bytes))return 0 ; +/* don't unmap page entries to achieve better performance */ +if (!IS_ENABLED (TEGRA_IOMMU_GART_DEBUG )) +return 0 ; +
drivers/iommu/tegra-gart.c static size_t gart_iommu_unmap(struct iommu_domain *domain, unsigned long iova, · line 322
Quoted 10 lines
drivers/iommu/tegra-gart.c +2
-1spin_lock_irqsave (&gart->pte_lock, flags);gart_set_pte (gart, iova,0 );FLUSH_GART_REGS (gart);spin_unlock_irqrestore (&gart->pte_lock, flags); -return 0 ; + +return bytes; } static phys_addr_t gart_iommu_iova_to_phys(struct iommu_domain *domain,
Please ignore this email, it was sent out by an accident. And please let me know if I should re-send the patchset.
PATCH v2 1/2 iommu/tegra: gart: Optionally check for overwriting of page mappings
In reply to a message not in the archiveDue to a bug in IOVA allocator, page mapping could accidentally overwritten. We can catch this case by checking 'VALID' bit of GART's page entry prior to mapping of a page. Since that check introduces a noticeable performance impact, it should be enabled explicitly by a new CONFIG_TEGRA_IOMMU_GART_DEBUG option.
--- drivers/iommu/Kconfig | 9 +++++++++ drivers/iommu/tegra-gart.c | 16 +++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-)
drivers/iommu/Kconfig +9 -0
@@ -242,6 +242,15 @@ config TEGRA_IOMMU_GART space through the GART (Graphics Address Relocation Table) hardware included on Tegra SoCs. +config TEGRA_IOMMU_GART_DEBUG + bool "Debug Tegra GART IOMMU" + depends on TEGRA_IOMMU_GART + help + Properly unmap pages and check whether page is already mapped + during of mapping in expense of performance. This allows to + catch double page remappings, caused by a bug in the IOVA + allocator for example. + config TEGRA_IOMMU_SMMU bool "NVIDIA Tegra SMMU Support" depends on ARCH_TEGRA
drivers/iommu/tegra-gart.c +15 -1
@@ -271,6 +271,7 @@ static int gart_iommu_map(struct iommu_domain *domain, unsigned long iova,struct gart_device *gart = gart_domain->gart;unsigned long flags;unsigned long pfn; +unsigned long pte;if (!gart_iova_range_valid (gart, iova, bytes))return -EINVAL ;
@@ -282,6 +283,14 @@ static int gart_iommu_map(struct iommu_domain *domain, unsigned long iova,spin_unlock_irqrestore (&gart->pte_lock, flags);return -EINVAL ; } +if (IS_ENABLED (TEGRA_IOMMU_GART_DEBUG )) { + pte =gart_read_pte (gart, iova); +if (pte &GART_ENTRY_PHYS_ADDR_VALID ) { +spin_unlock_irqrestore (&gart->pte_lock, flags); +dev_err (gart->dev,"Page entry is used already\n" ); +return -EBUSY ; + } + }gart_set_pte (gart, iova,GART_PTE (pfn));FLUSH_GART_REGS (gart);spin_unlock_irqrestore (&gart->pte_lock, flags);
@@ -295,6 +304,10 @@ static size_t gart_iommu_unmap(struct iommu_domain *domain, unsigned long iova,struct gart_device *gart = gart_domain->gart;unsigned long flags; +/* don't unmap page entries to achieve better performance */ +if (!IS_ENABLED (TEGRA_IOMMU_GART_DEBUG )) +return 0 ; +if (!gart_iova_range_valid (gart, iova, bytes))return 0 ;
@@ -302,7 +315,8 @@ static size_t gart_iommu_unmap(struct iommu_domain *domain, unsigned long iova,gart_set_pte (gart, iova,0 );FLUSH_GART_REGS (gart);spin_unlock_irqrestore (&gart->pte_lock, flags); -return 0 ; + +return bytes; } static phys_addr_t gart_iommu_iova_to_phys(struct iommu_domain *domain,
Signature · 1 line
2.14.1
A message that is not in the archive (sent off-list or not yet received): 7eea4a30b0f4fdbe14351cf2c6cf537365080d2d.1507078770.git.digetx-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
Re: [PATCH v2 1/2] iommu/tegra: gart: Optionally check for overwriting of page mappings
Quoted 5 lines · Dmitry Osipenko
Due to a bug in IOVA allocator, page mapping could accidentally overwritten. We can catch this case by checking 'VALID' bit of GART's page entry prior to mapping of a page. Since that check introduces a noticeable performance impact, it should be enabled explicitly by a new
CONFIG_TEGRA_IOMMU_GART_DEBUGoption.
Which bug in the IOVA allocator are you talking about?
Joerg
A message that is not in the archive (sent off-list or not yet received): 20171010095342.jyvzl2zex2pynqvv-zLv9SwRftAIdnm+yROfE0A@public.gmane.org
Re: [PATCH v2 1/2] iommu/tegra: gart: Optionally check for overwriting of page mappings
Quoted 9 lines · Joerg Roedel
Quoted 5 lines · Dmitry Osipenko
Due to a bug in IOVA allocator, page mapping could accidentally overwritten. We can catch this case by checking 'VALID' bit of GART's page entry prior to mapping of a page. Since that check introduces a noticeable performance impact, it should be enabled explicitly by a new
CONFIG_TEGRA_IOMMU_GART_DEBUGoption.Which bug in the IOVA allocator are you talking about?
I'm not talking about any specific bug, but in general if allocator re-maps already mapped region or unmaps the wrong-and-used region. I had those bug-cases during of development of the 'scattered' graphics allocations for Tegra20.
A message that is not in the archive (sent off-list or not yet received): 7dc66d59-3904-d1f8-3941-f9a534ff899a-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
Re: [PATCH v2 1/2] iommu/tegra: gart: Optionally check for overwriting of page mappings
Quoted 3 lines · Dmitry Osipenko
I'm not talking about any specific bug, but in general if allocator re-maps already mapped region or unmaps the wrong-and-used region. I had those bug-cases during of development of the 'scattered' graphics allocations for Tegra20.
The dma-iommu code does not re-map already mapped regions and it doesn't unmap wrong regions. If it does it should be reported and fixed.
So if you hit any bug there, please report it so that it can be fixed.
Thanks,
Joerg
A message that is not in the archive (sent off-list or not yet received): [email protected]
Re: [PATCH v2 1/2] iommu/tegra: gart: Optionally check for overwriting of page mappings
Quoted 8 lines · Joerg Roedel
Quoted 3 lines · Dmitry Osipenko
I'm not talking about any specific bug, but in general if allocator re-maps already mapped region or unmaps the wrong-and-used region. I had those bug-cases during of development of the 'scattered' graphics allocations for Tegra20.
The dma-iommu code does not re-map already mapped regions and it doesn't unmap wrong regions. If it does it should be reported and fixed.
Certainly iommu_map_sg doesn't perform itself any debug checks that I'm proposing to add to the GART.
Yet we don't use GART in the mainline, right now you may take a look at the WIP patches here:
https://github.com/grate-driver/linux/commit/9853371164a7f1b5698caee476e7cffe1b446afa
https://github.com/grate-driver/linux/commit/ea1fca4ac932464e7907a7ada8ea2698cab8db65
Quoted 2 lines
So if you hit any bug there, please report it so that it can be fixed.
PATCH v2 2/2 iommu/tegra: gart: Move PFN validation out of spinlock
In reply to a message not in the archiveValidation of page frame number doesn't require protection with a spinlock, let's move it out of spinlock for consistency.
--- drivers/iommu/tegra-gart.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/iommu/tegra-gart.c +2 -2
@@ -276,13 +276,13 @@ static int gart_iommu_map(struct iommu_domain *domain, unsigned long iova,if (!gart_iova_range_valid (gart, iova, bytes))return -EINVAL ; -spin_lock_irqsave (&gart->pte_lock, flags); pfn =__phys_to_pfn (pa);if (!pfn_valid (pfn)) {dev_err (gart->dev,"Invalid page: %pa\n" , &pa); -spin_unlock_irqrestore (&gart->pte_lock, flags);return -EINVAL ; } + +spin_lock_irqsave (&gart->pte_lock, flags);if (IS_ENABLED (TEGRA_IOMMU_GART_DEBUG )) { pte =gart_read_pte (gart, iova);if (pte &GART_ENTRY_PHYS_ADDR_VALID ) {
Signature · 1 line
2.14.1