Commit | Line | Data |
---|---|---|
8a94ade4 DW |
1 | /* |
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 | ||
18 | int 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 | ||
48 | int 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 | } |