X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fpci%2Fintel-iommu.c;h=66c0fd21894b155e9db690b65a86bfddffca29c4;hb=7059d4b08eba2ad046395a04b02e34ca27304d8f;hp=301c68fab03befa1c10d60d8fe6d9d65fcd9583d;hpb=03b883840c630c7b571690577809754739ac773f;p=linux-2.6 diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index 301c68fab0..66c0fd2189 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c @@ -49,7 +49,7 @@ #define DEFAULT_DOMAIN_ADDRESS_WIDTH 48 -#define DMAR_OPERATION_TIMEOUT (HZ*60) /* 1m */ +#define DMAR_OPERATION_TIMEOUT ((cycles_t) tsc_khz*10*1000) /* 10sec */ #define DOMAIN_MAX_ADDR(gaw) ((((u64)1) << gaw) - 1) @@ -490,12 +490,12 @@ static int iommu_alloc_root_entry(struct intel_iommu *iommu) #define IOMMU_WAIT_OP(iommu, offset, op, cond, sts) \ {\ - unsigned long start_time = jiffies;\ + cycles_t start_time = get_cycles();\ while (1) {\ sts = op (iommu->reg + offset);\ if (cond)\ break;\ - if (time_after(jiffies, start_time + DMAR_OPERATION_TIMEOUT))\ + if (DMAR_OPERATION_TIMEOUT < (get_cycles() - start_time))\ panic("DMAR hardware is malfunctioning\n");\ cpu_relax();\ }\ @@ -1905,32 +1905,31 @@ get_valid_domain_for_dev(struct pci_dev *pdev) return domain; } -static dma_addr_t intel_map_single(struct device *hwdev, void *addr, - size_t size, int dir) +static dma_addr_t +intel_map_single(struct device *hwdev, phys_addr_t paddr, size_t size, int dir) { struct pci_dev *pdev = to_pci_dev(hwdev); - int ret; struct dmar_domain *domain; - unsigned long start_addr; + unsigned long start_paddr; struct iova *iova; int prot = 0; + int ret; BUG_ON(dir == DMA_NONE); if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO) - return virt_to_bus(addr); + return paddr; domain = get_valid_domain_for_dev(pdev); if (!domain) return 0; - addr = (void *)virt_to_phys(addr); - size = aligned_size((u64)addr, size); + size = aligned_size((u64)paddr, size); iova = __intel_alloc_iova(hwdev, domain, size); if (!iova) goto error; - start_addr = iova->pfn_lo << PAGE_SHIFT_4K; + start_paddr = iova->pfn_lo << PAGE_SHIFT_4K; /* * Check if DMAR supports zero-length reads on write only @@ -1942,33 +1941,33 @@ static dma_addr_t intel_map_single(struct device *hwdev, void *addr, if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL) prot |= DMA_PTE_WRITE; /* - * addr - (addr + size) might be partial page, we should map the whole + * paddr - (paddr + size) might be partial page, we should map the whole * page. Note: if two part of one page are separately mapped, we - * might have two guest_addr mapping to the same host addr, but this + * might have two guest_addr mapping to the same host paddr, but this * is not a big problem */ - ret = domain_page_mapping(domain, start_addr, - ((u64)addr) & PAGE_MASK_4K, size, prot); + ret = domain_page_mapping(domain, start_paddr, + ((u64)paddr) & PAGE_MASK_4K, size, prot); if (ret) goto error; pr_debug("Device %s request: %lx@%llx mapping: %lx@%llx, dir %d\n", - pci_name(pdev), size, (u64)addr, - size, (u64)start_addr, dir); + pci_name(pdev), size, (u64)paddr, + size, (u64)start_paddr, dir); /* it's a non-present to present mapping */ ret = iommu_flush_iotlb_psi(domain->iommu, domain->id, - start_addr, size >> PAGE_SHIFT_4K, 1); + start_paddr, size >> PAGE_SHIFT_4K, 1); if (ret) iommu_flush_write_buffer(domain->iommu); - return (start_addr + ((u64)addr & (~PAGE_MASK_4K))); + return (start_paddr + ((u64)paddr & (~PAGE_MASK_4K))); error: if (iova) __free_iova(&domain->iovad, iova); printk(KERN_ERR"Device %s request: %lx@%llx dir %d --- failed\n", - pci_name(pdev), size, (u64)addr, dir); + pci_name(pdev), size, (u64)paddr, dir); return 0; } @@ -2082,7 +2081,7 @@ static void * intel_alloc_coherent(struct device *hwdev, size_t size, return NULL; memset(vaddr, 0, size); - *dma_handle = intel_map_single(hwdev, vaddr, size, DMA_BIDIRECTIONAL); + *dma_handle = intel_map_single(hwdev, virt_to_bus(vaddr), size, DMA_BIDIRECTIONAL); if (*dma_handle) return vaddr; free_pages((unsigned long)vaddr, order);