blob: 5b42a95b3f80bc460687547b89b9db05fa766aca [file] [log] [blame]
David Woodhouse8a94ade2015-03-24 14:54:56 +00001/*
2 * Copyright © 2015 Intel Corporation.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * Authors: David Woodhouse <dwmw2@infradead.org>
14 */
15
16#include <linux/intel-iommu.h>
17
18int intel_svm_alloc_pasid_tables(struct intel_iommu *iommu)
19{
20 struct page *pages;
21 int order;
22
23 order = ecap_pss(iommu->ecap) + 7 - PAGE_SHIFT;
24 if (order < 0)
25 order = 0;
26
27 pages = alloc_pages(GFP_KERNEL | __GFP_ZERO, order);
28 if (!pages) {
29 pr_warn("IOMMU: %s: Failed to allocate PASID table\n",
30 iommu->name);
31 return -ENOMEM;
32 }
33 iommu->pasid_table = page_address(pages);
34 pr_info("%s: Allocated order %d PASID table.\n", iommu->name, order);
35
36 if (ecap_dis(iommu->ecap)) {
37 pages = alloc_pages(GFP_KERNEL | __GFP_ZERO, order);
38 if (pages)
39 iommu->pasid_state_table = page_address(pages);
40 else
41 pr_warn("IOMMU: %s: Failed to allocate PASID state table\n",
42 iommu->name);
43 }
44
45 return 0;
46}
47
48int intel_svm_free_pasid_tables(struct intel_iommu *iommu)
49{
50 int order;
51
52 order = ecap_pss(iommu->ecap) + 7 - PAGE_SHIFT;
53 if (order < 0)
54 order = 0;
55
56 if (iommu->pasid_table) {
57 free_pages((unsigned long)iommu->pasid_table, order);
58 iommu->pasid_table = NULL;
59 }
60 if (iommu->pasid_state_table) {
61 free_pages((unsigned long)iommu->pasid_state_table, order);
62 iommu->pasid_state_table = NULL;
63 }
64 return 0;
65}