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 | |
parent | 1aaf118352b85bb359ce28070bcc478f659a7031 (diff) |
KVM: change KVM to use IOMMU API
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
-rw-r--r-- | arch/ia64/include/asm/kvm_host.h | 2 | ||||
-rw-r--r-- | arch/ia64/kvm/Makefile | 2 | ||||
-rw-r--r-- | arch/ia64/kvm/kvm-ia64.c | 3 | ||||
-rw-r--r-- | arch/x86/include/asm/kvm_host.h | 2 | ||||
-rw-r--r-- | arch/x86/kvm/Makefile | 2 | ||||
-rw-r--r-- | arch/x86/kvm/x86.c | 3 | ||||
-rw-r--r-- | include/linux/kvm_host.h | 6 | ||||
-rw-r--r-- | virt/kvm/iommu.c | 45 | ||||
-rw-r--r-- | virt/kvm/kvm_main.c | 2 |
9 files changed, 33 insertions, 34 deletions
diff --git a/arch/ia64/include/asm/kvm_host.h b/arch/ia64/include/asm/kvm_host.h index 0560f3fae538..348663661659 100644 --- a/arch/ia64/include/asm/kvm_host.h +++ b/arch/ia64/include/asm/kvm_host.h | |||
@@ -467,7 +467,7 @@ struct kvm_arch { | |||
467 | struct kvm_sal_data rdv_sal_data; | 467 | struct kvm_sal_data rdv_sal_data; |
468 | 468 | ||
469 | struct list_head assigned_dev_head; | 469 | struct list_head assigned_dev_head; |
470 | struct dmar_domain *intel_iommu_domain; | 470 | struct iommu_domain *iommu_domain; |
471 | struct hlist_head irq_ack_notifier_list; | 471 | struct hlist_head irq_ack_notifier_list; |
472 | 472 | ||
473 | unsigned long irq_sources_bitmap; | 473 | unsigned long irq_sources_bitmap; |
diff --git a/arch/ia64/kvm/Makefile b/arch/ia64/kvm/Makefile index cb69dfcfb1a6..0bb99b732908 100644 --- a/arch/ia64/kvm/Makefile +++ b/arch/ia64/kvm/Makefile | |||
@@ -51,7 +51,7 @@ EXTRA_AFLAGS += -Ivirt/kvm -Iarch/ia64/kvm/ | |||
51 | common-objs = $(addprefix ../../../virt/kvm/, kvm_main.o ioapic.o \ | 51 | common-objs = $(addprefix ../../../virt/kvm/, kvm_main.o ioapic.o \ |
52 | coalesced_mmio.o irq_comm.o) | 52 | coalesced_mmio.o irq_comm.o) |
53 | 53 | ||
54 | ifeq ($(CONFIG_DMAR),y) | 54 | ifeq ($(CONFIG_IOMMU_API),y) |
55 | common-objs += $(addprefix ../../../virt/kvm/, iommu.o) | 55 | common-objs += $(addprefix ../../../virt/kvm/, iommu.o) |
56 | endif | 56 | endif |
57 | 57 | ||
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c index 0f5ebd948437..4e586f6110aa 100644 --- a/arch/ia64/kvm/kvm-ia64.c +++ b/arch/ia64/kvm/kvm-ia64.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/bitops.h> | 31 | #include <linux/bitops.h> |
32 | #include <linux/hrtimer.h> | 32 | #include <linux/hrtimer.h> |
33 | #include <linux/uaccess.h> | 33 | #include <linux/uaccess.h> |
34 | #include <linux/iommu.h> | ||
34 | #include <linux/intel-iommu.h> | 35 | #include <linux/intel-iommu.h> |
35 | 36 | ||
36 | #include <asm/pgtable.h> | 37 | #include <asm/pgtable.h> |
@@ -188,7 +189,7 @@ int kvm_dev_ioctl_check_extension(long ext) | |||
188 | r = KVM_COALESCED_MMIO_PAGE_OFFSET; | 189 | r = KVM_COALESCED_MMIO_PAGE_OFFSET; |
189 | break; | 190 | break; |
190 | case KVM_CAP_IOMMU: | 191 | case KVM_CAP_IOMMU: |
191 | r = intel_iommu_found(); | 192 | r = iommu_found(); |
192 | break; | 193 | break; |
193 | default: | 194 | default: |
194 | r = 0; | 195 | r = 0; |
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 97215a458e5f..730843d1d2fb 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h | |||
@@ -360,7 +360,7 @@ struct kvm_arch{ | |||
360 | struct list_head active_mmu_pages; | 360 | struct list_head active_mmu_pages; |
361 | struct list_head assigned_dev_head; | 361 | struct list_head assigned_dev_head; |
362 | struct list_head oos_global_pages; | 362 | struct list_head oos_global_pages; |
363 | struct dmar_domain *intel_iommu_domain; | 363 | struct iommu_domain *iommu_domain; |
364 | struct kvm_pic *vpic; | 364 | struct kvm_pic *vpic; |
365 | struct kvm_ioapic *vioapic; | 365 | struct kvm_ioapic *vioapic; |
366 | struct kvm_pit *vpit; | 366 | struct kvm_pit *vpit; |
diff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile index 00f46c2d14bd..d3ec292f00f2 100644 --- a/arch/x86/kvm/Makefile +++ b/arch/x86/kvm/Makefile | |||
@@ -7,7 +7,7 @@ common-objs = $(addprefix ../../../virt/kvm/, kvm_main.o ioapic.o \ | |||
7 | ifeq ($(CONFIG_KVM_TRACE),y) | 7 | ifeq ($(CONFIG_KVM_TRACE),y) |
8 | common-objs += $(addprefix ../../../virt/kvm/, kvm_trace.o) | 8 | common-objs += $(addprefix ../../../virt/kvm/, kvm_trace.o) |
9 | endif | 9 | endif |
10 | ifeq ($(CONFIG_DMAR),y) | 10 | ifeq ($(CONFIG_IOMMU_API),y) |
11 | common-objs += $(addprefix ../../../virt/kvm/, iommu.o) | 11 | common-objs += $(addprefix ../../../virt/kvm/, iommu.o) |
12 | endif | 12 | endif |
13 | 13 | ||
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 0e6aa8141dcd..cc17546a2406 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/module.h> | 34 | #include <linux/module.h> |
35 | #include <linux/mman.h> | 35 | #include <linux/mman.h> |
36 | #include <linux/highmem.h> | 36 | #include <linux/highmem.h> |
37 | #include <linux/iommu.h> | ||
37 | #include <linux/intel-iommu.h> | 38 | #include <linux/intel-iommu.h> |
38 | 39 | ||
39 | #include <asm/uaccess.h> | 40 | #include <asm/uaccess.h> |
@@ -989,7 +990,7 @@ int kvm_dev_ioctl_check_extension(long ext) | |||
989 | r = !tdp_enabled; | 990 | r = !tdp_enabled; |
990 | break; | 991 | break; |
991 | case KVM_CAP_IOMMU: | 992 | case KVM_CAP_IOMMU: |
992 | r = intel_iommu_found(); | 993 | r = iommu_found(); |
993 | break; | 994 | break; |
994 | default: | 995 | default: |
995 | r = 0; | 996 | r = 0; |
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index e62a4629e51c..ec49d0be7f52 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h | |||
@@ -328,7 +328,7 @@ void kvm_unregister_irq_ack_notifier(struct kvm_irq_ack_notifier *kian); | |||
328 | int kvm_request_irq_source_id(struct kvm *kvm); | 328 | int kvm_request_irq_source_id(struct kvm *kvm); |
329 | void kvm_free_irq_source_id(struct kvm *kvm, int irq_source_id); | 329 | void kvm_free_irq_source_id(struct kvm *kvm, int irq_source_id); |
330 | 330 | ||
331 | #ifdef CONFIG_DMAR | 331 | #ifdef CONFIG_IOMMU_API |
332 | int kvm_iommu_map_pages(struct kvm *kvm, gfn_t base_gfn, | 332 | int kvm_iommu_map_pages(struct kvm *kvm, gfn_t base_gfn, |
333 | unsigned long npages); | 333 | unsigned long npages); |
334 | int kvm_iommu_map_guest(struct kvm *kvm); | 334 | int kvm_iommu_map_guest(struct kvm *kvm); |
@@ -337,7 +337,7 @@ int kvm_assign_device(struct kvm *kvm, | |||
337 | struct kvm_assigned_dev_kernel *assigned_dev); | 337 | struct kvm_assigned_dev_kernel *assigned_dev); |
338 | int kvm_deassign_device(struct kvm *kvm, | 338 | int kvm_deassign_device(struct kvm *kvm, |
339 | struct kvm_assigned_dev_kernel *assigned_dev); | 339 | struct kvm_assigned_dev_kernel *assigned_dev); |
340 | #else /* CONFIG_DMAR */ | 340 | #else /* CONFIG_IOMMU_API */ |
341 | static inline int kvm_iommu_map_pages(struct kvm *kvm, | 341 | static inline int kvm_iommu_map_pages(struct kvm *kvm, |
342 | gfn_t base_gfn, | 342 | gfn_t base_gfn, |
343 | unsigned long npages) | 343 | unsigned long npages) |
@@ -366,7 +366,7 @@ static inline int kvm_deassign_device(struct kvm *kvm, | |||
366 | { | 366 | { |
367 | return 0; | 367 | return 0; |
368 | } | 368 | } |
369 | #endif /* CONFIG_DMAR */ | 369 | #endif /* CONFIG_IOMMU_API */ |
370 | 370 | ||
371 | static inline void kvm_guest_enter(void) | 371 | static inline void kvm_guest_enter(void) |
372 | { | 372 | { |
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; |