LINUX.ORG.RU

История изменений

Исправление vel, (текущая версия) :

Проклятые дефайны в С!

#define PAGE_MASK (~(PAGE_SIZE-1))
для x86 это целое 32бит, а с PAE phys_addr_t 64 бита! по сему
pteval = (sg_phys(sg) & PAGE_MASK) | prot;
не позволял через DMA писать выше 4G

Автору коммита написал, если не откликнется, то придется самому патч постить. Весь патч 2 строки,

diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index f1042da..f9a7ebc 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -2159,7 +2159,7 @@ static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
                        sg_res = aligned_nrpages(sg->offset, sg->length);
                        sg->dma_address = ((dma_addr_t)iov_pfn << VTD_PAGE_SHIFT) + sg->offset;
                        sg->dma_length = sg->length;
-                       pteval = (sg_phys(sg) & PAGE_MASK) | prot;
+                       pteval = (sg_phys(sg) & (~(phys_addr_t)(PAGE_SIZE - 1)) | prot;
                        phys_pfn = pteval >> VTD_PAGE_SHIFT;
                }

А проблему создал коммит db0fa0cb015794dd19f664933d49c6ce902ec1e1 еще в августе

Исходная версия vel, :

Проклятые дефайны в С!

#define PAGE_MASK (~(PAGE_SIZE-1))
для x86 это целое 32бит, а с PAE phys_addr_t 64 бита! по сему
pteval = (sg_phys(sg) & PAGE_MASK) | prot;
не позволял через DMA писать выше 4G

Автору коммита написал, если не откликнется, то придется самому патч постить. Весь патч 2 строки,

diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index f1042da..f9a7ebc 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -2159,7 +2159,7 @@ static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
                        sg_res = aligned_nrpages(sg->offset, sg->length);
                        sg->dma_address = ((dma_addr_t)iov_pfn << VTD_PAGE_SHIFT) + sg->offset;
                        sg->dma_length = sg->length;
-                       pteval = (sg_phys(sg) & PAGE_MASK) | prot;
+                       pteval = (sg_phys(sg) & (~(phys_addr_t)(PAGE_SIZE - 1)) | prot;
                        phys_pfn = pteval >> VTD_PAGE_SHIFT;
                }