diff options
author | Joerg Roedel <joerg.roedel@amd.com> | 2008-12-03 08:43:34 -0500 |
---|---|---|
committer | Joerg Roedel <joerg.roedel@amd.com> | 2009-01-03 08:11:07 -0500 |
commit | 19de40a8472fa64693eab844911eec277d489f6c (patch) | |
tree | 502a8df560341ad715965ed39db33c720c657066 /virt/kvm | |
parent | 1aaf118352b85bb359ce28070bcc478f659a7031 (diff) |
KVM: change KVM to use IOMMU API
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Diffstat (limited to 'virt/kvm')
-rw-r--r-- | virt/kvm/iommu.c | 45 | ||||
-rw-r--r-- | virt/kvm/kvm_main.c | 2 |
2 files changed, 22 insertions, 25 deletions
diff --git a/virt/kvm/iommu.c b/virt/kvm/iommu.c index d46de9af838b..d0bebaa5bf0a 100644 --- a/virt/kvm/iommu.c +++ b/virt/kvm/iommu.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/kvm_host.h> | 25 | #include <linux/kvm_host.h> |
26 | #include <linux/pci.h> | 26 | #include <linux/pci.h> |
27 | #include <linux/dmar.h> | 27 | #include <linux/dmar.h> |
28 | #include <linux/iommu.h> | ||
28 | #include <linux/intel-iommu.h> | 29 | #include <linux/intel-iommu.h> |
29 | 30 | ||
30 | static int kvm_iommu_unmap_memslots(struct kvm *kvm); | 31 | static int kvm_iommu_unmap_memslots(struct kvm *kvm); |
@@ -37,7 +38,7 @@ int kvm_iommu_map_pages(struct kvm *kvm, | |||
37 | gfn_t gfn = base_gfn; | 38 | gfn_t gfn = base_gfn; |
38 | pfn_t pfn; | 39 | pfn_t pfn; |
39 | int i, r = 0; | 40 | int i, r = 0; |
40 | struct dmar_domain *domain = kvm->arch.intel_iommu_domain; | 41 | struct iommu_domain *domain = kvm->arch.iommu_domain; |
41 | 42 | ||
42 | /* check if iommu exists and in use */ | 43 | /* check if iommu exists and in use */ |
43 | if (!domain) | 44 | if (!domain) |
@@ -45,16 +46,15 @@ int kvm_iommu_map_pages(struct kvm *kvm, | |||
45 | 46 | ||
46 | for (i = 0; i < npages; i++) { | 47 | for (i = 0; i < npages; i++) { |
47 | /* check if already mapped */ | 48 | /* check if already mapped */ |
48 | if (intel_iommu_iova_to_phys(domain, | 49 | if (iommu_iova_to_phys(domain, gfn_to_gpa(gfn))) |
49 | gfn_to_gpa(gfn))) | ||
50 | continue; | 50 | continue; |
51 | 51 | ||
52 | pfn = gfn_to_pfn(kvm, gfn); | 52 | pfn = gfn_to_pfn(kvm, gfn); |
53 | r = intel_iommu_map_address(domain, | 53 | r = iommu_map_range(domain, |
54 | gfn_to_gpa(gfn), | 54 | gfn_to_gpa(gfn), |
55 | pfn_to_hpa(pfn), | 55 | pfn_to_hpa(pfn), |
56 | PAGE_SIZE, | 56 | PAGE_SIZE, |
57 | DMA_PTE_READ | DMA_PTE_WRITE); | 57 | IOMMU_READ | IOMMU_WRITE); |
58 | if (r) { | 58 | if (r) { |
59 | printk(KERN_ERR "kvm_iommu_map_address:" | 59 | printk(KERN_ERR "kvm_iommu_map_address:" |
60 | "iommu failed to map pfn=%lx\n", pfn); | 60 | "iommu failed to map pfn=%lx\n", pfn); |
@@ -88,7 +88,7 @@ int kvm_assign_device(struct kvm *kvm, | |||
88 | struct kvm_assigned_dev_kernel *assigned_dev) | 88 | struct kvm_assigned_dev_kernel *assigned_dev) |
89 | { | 89 | { |
90 | struct pci_dev *pdev = NULL; | 90 | struct pci_dev *pdev = NULL; |
91 | struct dmar_domain *domain = kvm->arch.intel_iommu_domain; | 91 | struct iommu_domain *domain = kvm->arch.iommu_domain; |
92 | int r; | 92 | int r; |
93 | 93 | ||
94 | /* check if iommu exists and in use */ | 94 | /* check if iommu exists and in use */ |
@@ -99,7 +99,7 @@ int kvm_assign_device(struct kvm *kvm, | |||
99 | if (pdev == NULL) | 99 | if (pdev == NULL) |
100 | return -ENODEV; | 100 | return -ENODEV; |
101 | 101 | ||
102 | r = intel_iommu_attach_device(domain, pdev); | 102 | r = iommu_attach_device(domain, &pdev->dev); |
103 | if (r) { | 103 | if (r) { |
104 | printk(KERN_ERR "assign device %x:%x.%x failed", | 104 | printk(KERN_ERR "assign device %x:%x.%x failed", |
105 | pdev->bus->number, | 105 | pdev->bus->number, |
@@ -119,7 +119,7 @@ int kvm_assign_device(struct kvm *kvm, | |||
119 | int kvm_deassign_device(struct kvm *kvm, | 119 | int kvm_deassign_device(struct kvm *kvm, |
120 | struct kvm_assigned_dev_kernel *assigned_dev) | 120 | struct kvm_assigned_dev_kernel *assigned_dev) |
121 | { | 121 | { |
122 | struct dmar_domain *domain = kvm->arch.intel_iommu_domain; | 122 | struct iommu_domain *domain = kvm->arch.iommu_domain; |
123 | struct pci_dev *pdev = NULL; | 123 | struct pci_dev *pdev = NULL; |
124 | 124 | ||
125 | /* check if iommu exists and in use */ | 125 | /* check if iommu exists and in use */ |
@@ -130,7 +130,7 @@ int kvm_deassign_device(struct kvm *kvm, | |||
130 | if (pdev == NULL) | 130 | if (pdev == NULL) |
131 | return -ENODEV; | 131 | return -ENODEV; |
132 | 132 | ||
133 | intel_iommu_detach_device(domain, pdev); | 133 | iommu_detach_device(domain, &pdev->dev); |
134 | 134 | ||
135 | printk(KERN_DEBUG "deassign device: host bdf = %x:%x:%x\n", | 135 | printk(KERN_DEBUG "deassign device: host bdf = %x:%x:%x\n", |
136 | assigned_dev->host_busnr, | 136 | assigned_dev->host_busnr, |
@@ -144,13 +144,13 @@ int kvm_iommu_map_guest(struct kvm *kvm) | |||
144 | { | 144 | { |
145 | int r; | 145 | int r; |
146 | 146 | ||
147 | if (!intel_iommu_found()) { | 147 | if (!iommu_found()) { |
148 | printk(KERN_ERR "%s: intel iommu not found\n", __func__); | 148 | printk(KERN_ERR "%s: iommu not found\n", __func__); |
149 | return -ENODEV; | 149 | return -ENODEV; |
150 | } | 150 | } |
151 | 151 | ||
152 | kvm->arch.intel_iommu_domain = intel_iommu_alloc_domain(); | 152 | kvm->arch.iommu_domain = iommu_domain_alloc(); |
153 | if (!kvm->arch.intel_iommu_domain) | 153 | if (!kvm->arch.iommu_domain) |
154 | return -ENOMEM; | 154 | return -ENOMEM; |
155 | 155 | ||
156 | r = kvm_iommu_map_memslots(kvm); | 156 | r = kvm_iommu_map_memslots(kvm); |
@@ -169,7 +169,7 @@ static void kvm_iommu_put_pages(struct kvm *kvm, | |||
169 | { | 169 | { |
170 | gfn_t gfn = base_gfn; | 170 | gfn_t gfn = base_gfn; |
171 | pfn_t pfn; | 171 | pfn_t pfn; |
172 | struct dmar_domain *domain = kvm->arch.intel_iommu_domain; | 172 | struct iommu_domain *domain = kvm->arch.iommu_domain; |
173 | unsigned long i; | 173 | unsigned long i; |
174 | u64 phys; | 174 | u64 phys; |
175 | 175 | ||
@@ -178,16 +178,13 @@ static void kvm_iommu_put_pages(struct kvm *kvm, | |||
178 | return; | 178 | return; |
179 | 179 | ||
180 | for (i = 0; i < npages; i++) { | 180 | for (i = 0; i < npages; i++) { |
181 | phys = intel_iommu_iova_to_phys(domain, | 181 | phys = iommu_iova_to_phys(domain, gfn_to_gpa(gfn)); |
182 | gfn_to_gpa(gfn)); | ||
183 | pfn = phys >> PAGE_SHIFT; | 182 | pfn = phys >> PAGE_SHIFT; |
184 | kvm_release_pfn_clean(pfn); | 183 | kvm_release_pfn_clean(pfn); |
185 | gfn++; | 184 | gfn++; |
186 | } | 185 | } |
187 | 186 | ||
188 | intel_iommu_unmap_address(domain, | 187 | iommu_unmap_range(domain, gfn_to_gpa(base_gfn), PAGE_SIZE * npages); |
189 | gfn_to_gpa(base_gfn), | ||
190 | PAGE_SIZE * npages); | ||
191 | } | 188 | } |
192 | 189 | ||
193 | static int kvm_iommu_unmap_memslots(struct kvm *kvm) | 190 | static int kvm_iommu_unmap_memslots(struct kvm *kvm) |
@@ -205,13 +202,13 @@ static int kvm_iommu_unmap_memslots(struct kvm *kvm) | |||
205 | 202 | ||
206 | int kvm_iommu_unmap_guest(struct kvm *kvm) | 203 | int kvm_iommu_unmap_guest(struct kvm *kvm) |
207 | { | 204 | { |
208 | struct dmar_domain *domain = kvm->arch.intel_iommu_domain; | 205 | struct iommu_domain *domain = kvm->arch.iommu_domain; |
209 | 206 | ||
210 | /* check if iommu exists and in use */ | 207 | /* check if iommu exists and in use */ |
211 | if (!domain) | 208 | if (!domain) |
212 | return 0; | 209 | return 0; |
213 | 210 | ||
214 | kvm_iommu_unmap_memslots(kvm); | 211 | kvm_iommu_unmap_memslots(kvm); |
215 | intel_iommu_free_domain(domain); | 212 | iommu_domain_free(domain); |
216 | return 0; | 213 | return 0; |
217 | } | 214 | } |
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 4ef0fb43d1f9..3a5a08298aab 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c | |||
@@ -504,7 +504,7 @@ static int kvm_vm_ioctl_assign_device(struct kvm *kvm, | |||
504 | list_add(&match->list, &kvm->arch.assigned_dev_head); | 504 | list_add(&match->list, &kvm->arch.assigned_dev_head); |
505 | 505 | ||
506 | if (assigned_dev->flags & KVM_DEV_ASSIGN_ENABLE_IOMMU) { | 506 | if (assigned_dev->flags & KVM_DEV_ASSIGN_ENABLE_IOMMU) { |
507 | if (!kvm->arch.intel_iommu_domain) { | 507 | if (!kvm->arch.iommu_domain) { |
508 | r = kvm_iommu_map_guest(kvm); | 508 | r = kvm_iommu_map_guest(kvm); |
509 | if (r) | 509 | if (r) |
510 | goto out_list_del; | 510 | goto out_list_del; |