Bug Fix drivers/pci/intel-iommu.c: convert paddr to correct DMA pfn
Subsystems (4)
PATCH 3/4 Bug Fix drivers/pci/intel-iommu.c: convert paddr to correct DMA pfn
In reply to a message not in the archiveWhen calling domain_pfn_mapping(), paddr should be converted to DMA pfn correctly instead just shift by VTD_PAGE_SHIFT.
This issue causes kernel panic on PAGE_SIZE>VTD_PAGE_SIZE platforms e.g. ia64 platforms.
---
drivers/pci/intel-iommu.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-)
drivers/pci/intel-iommu.c +2 -1
@@ -2558,6 +2564,7 @@ static dma_addr_t __intel_map_single(struct device *hwdev, phys_addr_t paddr,int prot =0 ;int ret;struct intel_iommu *iommu; +unsigned long paddr_pfn = paddr >>PAGE_SHIFT ;BUG_ON (dir =DMA_NONE );
@@ -2592,7 +2599,7 @@ static dma_addr_t __intel_map_single(struct device *hwdev, phys_addr_t paddr,* is not a big problem */ ret =domain_pfn_mapping (domain,mm_to_dma_pfn (iova->pfn_lo), - paddr >>VTD_PAGE_SHIFT , size, prot); +mm_to_dma_pfn (paddr_pfn), size, prot);if (ret) goto error;
PATCH 4/4 Bug Fix drivers/pci/intel-iommu.c: convert pfn_lo to VTD page address when calling iommu_flush_dev_iotlb()
In reply to a message not in the archiveThe iova->pfn_lo should be converted to VTD page address before it's passed to iommu_flush_dev_iotlb().
This issue may cause DMA failure on PAGE_SIZE>VTD_PAGE_SIZE platforms e.g. ia64 platforms.
---
drivers/pci/intel-iommu.c | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-)
drivers/pci/intel-iommu.c +1 -1
@@ -2647,7 +2654,7 @@ static void flush_unmaps(void) mask = (iova->pfn_hi - iova->pfn_lo +1 ) <<PAGE_SHIFT ; mask =ilog2 (mask >>VTD_PAGE_SHIFT );iommu_flush_dev_iotlb (deferred_flush[i].domain[j], - iova->pfn_lo <<PAGE_SHIFT , mask); + iova->pfn_lo <<VTD_PAGE_SHIFT , mask);__free_iova (&deferred_flush[i].domain[j]->iovad, iova); } deferred_flush[i].next =0 ;
Quoted 7 lines · Fenghua Yu
When calling
domain_pfn_mapping(), paddr should be converted to DMA pfn correctly instead just shift byVTD_PAGE_SHIFT.This issue causes kernel panic on PAGE_SIZE>VTD_PAGE_SIZE platforms e.g. ia64 platforms.
Signed-off-by Fenghua Yu <[email protected]>
Using the word 'alignment' somewhere in the above commit would have confused me a lot less -- I got most of the way through composing a mail asking how this patch wasn't a no-op, before I spotted it.
An alternative would be to align the size to DMA pages? Would that make the sg case easier?
(Thanks for fixing this, btw)
Signature · 1 line
dwmw2
Re: [PATCH 4/4] Bug Fix drivers/pci/intel-iommu.c: convert pfn_lo to VTD page address when calling iommu_flush_dev_iotlb()
In reply to Fenghua YuQuoted 7 lines · Fenghua Yu
The
iova->pfn_loshould be converted to VTD page address before it's passed toiommu_flush_dev_iotlb().This issue may cause DMA failure on PAGE_SIZE>VTD_PAGE_SIZE platforms e.g. ia64 platforms.
Signed-off-by Fenghua Yu <[email protected]>
I think this one is wrong. We allocate IOVA space in MM pages, not DMA pages -- so the pfn_lo is an MM page already, and shifting by PAGE_SHIFT is the right thing to do.
(I could be tempted to allocate it in DMA pages instead, but that's a different story).
Signature · 2 lines
David Woodhouse Open Source Technology Centre [email protected] Intel Corporation
PATCH 1/1 linux-next drm_cache.c: fix compilation error
In reply to Fenghua YuWhen compiling drm_cache.c on ia64, gcc reports undefined drm_clflush_ipi_handler() error. The problem is because drm_cache_ipi_handler is a typo.
One straightforward fix is changing drm_cache_ipi_handler to drm_clflush_ipi_handler.
But since drm_clflush_ipi_handler() does nothing on non-x86 platforms and ipi handling is costly, it would be better to just do nothing on non-x86 platforms and remove drm_clflush_ipi_handler() for those platforms.
---
The issue was introduced by commit c9c97b8c75019814d8c007059bc827bb475be917 in linux-next.
drm_cache.c | 7 ------- 1 files changed, 7 deletions(-)
drivers/gpu/drm/drm_cache.c +0 -7
@@ -62,10 +62,6 @@ drm_clflush_ipi_handler(void *null) {wbinvd (); } -#elif !defined(__powerpc__) -static void drm_cache_ipi_handler (void *dummy) -{ -}#endif void drm_clflush_pages (struct page *pages[],unsigned long num_pages)
@@ -94,9 +90,6 @@ drm_clflush_pages(struct page *pages[], unsigned long num_pages) (unsigned long)page_virtual + PAGE_SIZE); kunmap_atomic(page_virtual, KM_USER0); } -#else -if (on_each_cpu (drm_clflush_ipi_handler,NULL ,1 ) !=0 ) -printk (KERN_ERR "Timed out waiting for drm cache flush\n" );#endif }EXPORT_SYMBOL (drm_clflush_pages);