int intel_svm_alloc_pasid_tables(struct intel_iommu *iommu) { struct page *pages; int order; order = ecap_pss(iommu->ecap) + 7 - PAGE_SHIFT; if (order < 0) order = 0; pages = alloc_pages(GFP_KERNEL | __GFP_ZERO, order); if (!pages) { pr_warn("IOMMU: %s: Failed to allocate PASID table\n", iommu->name); return -ENOMEM; } iommu->pasid_table = page_address(pages); pr_info("%s: Allocated order %d PASID table.\n", iommu->name, order); if (ecap_dis(iommu->ecap)) { pages = alloc_pages(GFP_KERNEL | __GFP_ZERO, order); if (pages) iommu->pasid_state_table = page_address(pages); else pr_warn("IOMMU: %s: Failed to allocate PASID state table\n", iommu->name); } idr_init(&iommu->pasid_idr); return 0; }
int intel_svm_alloc_pasid_tables(struct intel_iommu *iommu) { struct page *pages; int order; /* Start at 2 because it's defined as 2^(1+PSS) */ iommu->pasid_max = 2 << ecap_pss(iommu->ecap); /* Eventually I'm promised we will get a multi-level PASID table * and it won't have to be physically contiguous. Until then, * limit the size because 8MiB contiguous allocations can be hard * to come by. The limit of 0x20000, which is 1MiB for each of * the PASID and PASID-state tables, is somewhat arbitrary. */ if (iommu->pasid_max > 0x20000) iommu->pasid_max = 0x20000; order = get_order(sizeof(struct pasid_entry) * iommu->pasid_max); pages = alloc_pages(GFP_KERNEL | __GFP_ZERO, order); if (!pages) { pr_warn("IOMMU: %s: Failed to allocate PASID table\n", iommu->name); return -ENOMEM; } iommu->pasid_table = page_address(pages); pr_info("%s: Allocated order %d PASID table.\n", iommu->name, order); if (ecap_dis(iommu->ecap)) { /* Just making it explicit... */ BUILD_BUG_ON(sizeof(struct pasid_entry) != sizeof(struct pasid_state_entry)); pages = alloc_pages(GFP_KERNEL | __GFP_ZERO, order); if (pages) iommu->pasid_state_table = page_address(pages); else pr_warn("IOMMU: %s: Failed to allocate PASID state table\n", iommu->name); } idr_init(&iommu->pasid_idr); return 0; }