Re: [PATCH 2/2] KVM: Device Assignment with VT-d
Han, Weidong wrote: This patch only can work on x86, it breaks build on other architectures. It is caused by kvm_irq_ack_notifier and kvm_assigned_dev_kernel are defined under x86, while they are always used in include/linux/kvm_host.h whether CONFIG_DMAR is set or not. I move these two definitions to include/linux/kvm_host.h, and attached the updated patch. Thanks. I replaced the old patch with your new version. -- I have a truly marvellous patch that fixes the bug which this signature is too narrow to contain. -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 2/2] KVM: Device Assignment with VT-d
This patch only can work on x86, it breaks build on other architectures. It is caused by kvm_irq_ack_notifier and kvm_assigned_dev_kernel are defined under x86, while they are always used in include/linux/kvm_host.h whether CONFIG_DMAR is set or not. I move these two definitions to include/linux/kvm_host.h, and attached the updated patch. Randy (Weidong) Amit Shah wrote: > From: Ben-Ami Yassour <[EMAIL PROTECTED]> > > Based on a patch by: Kay, Allen M <[EMAIL PROTECTED]> > > This patch enables PCI device assignment based on VT-d support. > When a device is assigned to the guest, the guest memory is pinned and > the mapping is updated in the VT-d IOMMU. > > [Amit: Expose KVM_CAP_IOMMU so we can check if an IOMMU is present > and also control enable/disable from userspace] > > Signed-off-by: Kay, Allen M <[EMAIL PROTECTED]> > Signed-off-by: Weidong Han <[EMAIL PROTECTED]> > Signed-off-by: Ben-Ami Yassour <[EMAIL PROTECTED]> > Signed-off-by: Amit Shah <[EMAIL PROTECTED]> > > Acked-by: Mark Gross <[EMAIL PROTECTED]> > --- > arch/x86/kvm/Makefile |3 + > arch/x86/kvm/vtd.c | 198 > arch/x86/kvm/x86.c > | 14 +++ include/asm-x86/kvm_host.h |3 + > include/linux/kvm.h|3 + > include/linux/kvm_host.h | 32 +++ > virt/kvm/kvm_main.c|9 ++- > 7 files changed, 261 insertions(+), 1 deletions(-) > create mode 100644 arch/x86/kvm/vtd.c > > diff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile > index d0e940b..3072b17 100644 > --- a/arch/x86/kvm/Makefile > +++ b/arch/x86/kvm/Makefile > @@ -12,6 +12,9 @@ EXTRA_CFLAGS += -Ivirt/kvm -Iarch/x86/kvm > > kvm-objs := $(common-objs) x86.o mmu.o x86_emulate.o i8259.o irq.o > lapic.o \ i8254.o > +ifeq ($(CONFIG_DMAR),y) > +kvm-objs += vtd.o > +endif > obj-$(CONFIG_KVM) += kvm.o > kvm-intel-objs = vmx.o > obj-$(CONFIG_KVM_INTEL) += kvm-intel.o > diff --git a/arch/x86/kvm/vtd.c b/arch/x86/kvm/vtd.c > new file mode 100644 > index 000..667bf3f > --- /dev/null > +++ b/arch/x86/kvm/vtd.c > @@ -0,0 +1,198 @@ > +/* > + * Copyright (c) 2006, Intel Corporation. > + * > + * This program is free software; you can redistribute it and/or > modify it + * under the terms and conditions of the GNU General > Public License, + * version 2, as published by the Free Software > Foundation. + * > + * This program is distributed in the hope it will be useful, but > WITHOUT + * ANY WARRANTY; without even the implied warranty of > MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU > General Public License for + * more details. > + * > + * You should have received a copy of the GNU General Public License > along with + * this program; if not, write to the Free Software > Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA > 02111-1307 USA. + * > + * Copyright (C) 2006-2008 Intel Corporation > + * Copyright IBM Corporation, 2008 > + * Author: Allen M. Kay <[EMAIL PROTECTED]> > + * Author: Weidong Han <[EMAIL PROTECTED]> > + * Author: Ben-Ami Yassour <[EMAIL PROTECTED]> > + */ > + > +#include > +#include > +#include > +#include > +#include > + > +static int kvm_iommu_unmap_memslots(struct kvm *kvm); > +static void kvm_iommu_put_pages(struct kvm *kvm, > + gfn_t base_gfn, unsigned long npages); > + > +int kvm_iommu_map_pages(struct kvm *kvm, > + gfn_t base_gfn, unsigned long npages) > +{ > + gfn_t gfn = base_gfn; > + pfn_t pfn; > + int i, r; > + struct dmar_domain *domain = kvm->arch.intel_iommu_domain; > + > + /* check if iommu exists and in use */ > + if (!domain) > + return 0; > + > + r = -EINVAL; > + for (i = 0; i < npages; i++) { > + /* check if already mapped */ > + pfn = (pfn_t)intel_iommu_iova_to_pfn(domain, > + gfn_to_gpa(gfn)); > + if (pfn && !is_mmio_pfn(pfn)) > + continue; > + > + pfn = gfn_to_pfn(kvm, gfn); > + if (!is_mmio_pfn(pfn)) { > + r = intel_iommu_page_mapping(domain, > + gfn_to_gpa(gfn), > + pfn_to_hpa(pfn), > + PAGE_SIZE, > + DMA_PTE_READ | > + DMA_PTE_WRITE); > + if (r) { > + printk(KERN_DEBUG "kvm_iommu_map_pages:" > +"iommu failed to map pfn=%lx\n", pfn); > + goto unmap_pages; > + } > + } else { > + printk(KERN_DEBUG "kvm_iommu_map_page:" > +"invalid pfn=%lx\n", pfn); > + goto unmap_pages; > + } > + gfn++; > +
RE: [PATCH 2/2] KVM: Device Assignment with VT-d
Amit, Thanks for your quick fixing. Randy (Weidong) Amit Shah wrote: > * On Tuesday 09 September 2008 19:21:20 Han, Weidong wrote: > >> +static int kvm_iommu_map_memslots(struct kvm *kvm) +{ >> +int i, rc; >> + >> +down_read(&kvm->slots_lock); >> +for (i = 0; i < kvm->nmemslots; i++) { >> +rc = kvm_iommu_map_pages(kvm, kvm->memslots[i].base_gfn, >> + kvm->memslots[i].npages); >> +if (rc) { >> +up_read(&kvm->slots_lock); >> +return rc; >> +} >> +} >> +up_read(&kvm->slots_lock); >> +return 0; >> +} > > I simplified this to: > > static int kvm_iommu_map_memslots(struct kvm *kvm) > { > int i, r; > > down_read(&kvm->slots_lock); > for (i = 0; i < kvm->nmemslots; i++) { > r = kvm_iommu_map_pages(kvm, kvm->memslots[i].base_gfn, > kvm->memslots[i].npages); > if (r) > break; > } > up_read(&kvm->slots_lock); > return r; > } > > Also cleaned up some whitespace. > > I'll send out the patchset soon. -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2] KVM: Device Assignment with VT-d
* On Tuesday 09 September 2008 19:21:20 Han, Weidong wrote: > +static int kvm_iommu_map_memslots(struct kvm *kvm) > +{ > + int i, rc; > + > + down_read(&kvm->slots_lock); > + for (i = 0; i < kvm->nmemslots; i++) { > + rc = kvm_iommu_map_pages(kvm, kvm->memslots[i].base_gfn, > + kvm->memslots[i].npages); > + if (rc) { > + up_read(&kvm->slots_lock); > + return rc; > + } > + } > + up_read(&kvm->slots_lock); > + return 0; > +} I simplified this to: static int kvm_iommu_map_memslots(struct kvm *kvm) { int i, r; down_read(&kvm->slots_lock); for (i = 0; i < kvm->nmemslots; i++) { r = kvm_iommu_map_pages(kvm, kvm->memslots[i].base_gfn, kvm->memslots[i].npages); if (r) break; } up_read(&kvm->slots_lock); return r; } Also cleaned up some whitespace. I'll send out the patchset soon. -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 2/2] KVM: Device Assignment with VT-d
Amit Shah wrote: > There are a couple of things here that might need some error handling: > > * On Tuesday 26 August 2008 14:25:35 Amit Shah wrote: >> From: Ben-Ami Yassour <[EMAIL PROTECTED]> >> >> Based on a patch by: Kay, Allen M <[EMAIL PROTECTED]> >> >> This patch enables PCI device assignment based on VT-d support. >> When a device is assigned to the guest, the guest memory is pinned >> and >> the mapping is updated in the VT-d IOMMU. >> >> [Amit: Expose KVM_CAP_IOMMU so we can check if an IOMMU is present >> and also control enable/disable from userspace] >> >> Signed-off-by: Kay, Allen M <[EMAIL PROTECTED]> >> Signed-off-by: Weidong Han <[EMAIL PROTECTED]> >> Signed-off-by: Ben-Ami Yassour <[EMAIL PROTECTED]> >> Signed-off-by: Amit Shah <[EMAIL PROTECTED]> > > >> +#include >> +#include >> +#include >> +#include >> +#include >> + >> +static int kvm_iommu_unmap_memslots(struct kvm *kvm); + >> +int kvm_iommu_map_pages(struct kvm *kvm, >> + gfn_t base_gfn, unsigned long npages) >> +{ >> +gfn_t gfn = base_gfn; >> +pfn_t pfn; >> +int i, rc; >> +struct dmar_domain *domain = kvm->arch.intel_iommu_domain; + >> +/* check if iommu exists and in use */ >> +if (!domain) >> +return 0; >> + >> +for (i = 0; i < npages; i++) { >> +/* check if already mapped */ >> +pfn = (pfn_t)intel_iommu_iova_to_pfn(domain, >> + gfn_to_gpa(gfn)); >> +if (pfn && !is_mmio_pfn(pfn)) >> +continue; >> + >> +pfn = gfn_to_pfn(kvm, gfn); >> +if (!is_mmio_pfn(pfn)) { >> +rc = intel_iommu_page_mapping(domain, >> + gfn_to_gpa(gfn), >> + pfn_to_hpa(pfn), >> + PAGE_SIZE, >> + DMA_PTE_READ | >> + DMA_PTE_WRITE); >> +if (rc) { >> +kvm_release_pfn_clean(pfn); >> +printk(KERN_DEBUG "kvm_iommu_map_pages:" >> + "iommu failed to map pfn=%lx\n", pfn); >> +return rc; >> +} >> +} else { >> +printk(KERN_DEBUG "kvm_iommu_map_page:" >> + "invalid pfn=%lx\n", pfn); >> +return 0; >> +} > > In the error case, this function should itself call unmap_pages so > that either all pages are mapped or none are. Also makes it easier to > bail out in the two places this function gets called. > Good catch. Will fix it. >> + >> +gfn++; >> +} >> +return 0; >> +} >> + >> +static int kvm_iommu_map_memslots(struct kvm *kvm) +{ >> +int i, rc; >> + >> +down_read(&kvm->slots_lock); >> +for (i = 0; i < kvm->nmemslots; i++) { >> +rc = kvm_iommu_map_pages(kvm, kvm->memslots[i].base_gfn, >> + kvm->memslots[i].npages); >> +if (rc) { >> +up_read(&kvm->slots_lock); >> +return rc; >> +} >> +} >> +up_read(&kvm->slots_lock); >> +return 0; >> +} >> + >> +int kvm_iommu_map_guest(struct kvm *kvm, >> +struct kvm_assigned_dev_kernel *assigned_dev) >> +{ >> +struct pci_dev *pdev = NULL; >> +int rc; >> + >> +if (!intel_iommu_found()) { >> +printk(KERN_ERR "intel iommu not found\n"); >> +return -ENODEV; >> +} >> + >> +printk(KERN_DEBUG "VT-d direct map: host bdf = %x:%x:%x\n", >> + assigned_dev->host_busnr, >> + PCI_SLOT(assigned_dev->host_devfn), >> + PCI_FUNC(assigned_dev->host_devfn)); >> + >> +pdev = assigned_dev->dev; >> + >> +if (pdev == NULL) { >> +if (kvm->arch.intel_iommu_domain) { >> + intel_iommu_domain_exit(kvm->arch.intel_iommu_domain); >> +kvm->arch.intel_iommu_domain = NULL; >> +} >> +return -ENODEV; >> +} >> + >> +kvm->arch.intel_iommu_domain = intel_iommu_domain_alloc(pdev); > > check if we really got the domain yes, need a check here. > >> + >> +rc = kvm_iommu_map_memslots(kvm); >> +if (rc) >> +goto out_unmap; >> + >> +intel_iommu_detach_dev(kvm->arch.intel_iommu_domain, >> + pdev->bus->number, pdev->devfn); >> + >> +rc = intel_iommu_context_mapping(kvm->arch.intel_iommu_domain, >> + pdev); > > This function name (as Mark points out) doesn't make much sense; can > this be changed? This function name keeps consistent with original name in vtd driver. do you want to add a verb in the name? > >> +if (rc) { >> +printk(KERN_ERR "Domain context map f
Re: [PATCH 2/2] KVM: Device Assignment with VT-d
There are a couple of things here that might need some error handling: * On Tuesday 26 August 2008 14:25:35 Amit Shah wrote: > From: Ben-Ami Yassour <[EMAIL PROTECTED]> > > Based on a patch by: Kay, Allen M <[EMAIL PROTECTED]> > > This patch enables PCI device assignment based on VT-d support. > When a device is assigned to the guest, the guest memory is pinned and > the mapping is updated in the VT-d IOMMU. > > [Amit: Expose KVM_CAP_IOMMU so we can check if an IOMMU is present > and also control enable/disable from userspace] > > Signed-off-by: Kay, Allen M <[EMAIL PROTECTED]> > Signed-off-by: Weidong Han <[EMAIL PROTECTED]> > Signed-off-by: Ben-Ami Yassour <[EMAIL PROTECTED]> > Signed-off-by: Amit Shah <[EMAIL PROTECTED]> > +#include > +#include > +#include > +#include > +#include > + > +static int kvm_iommu_unmap_memslots(struct kvm *kvm); > + > +int kvm_iommu_map_pages(struct kvm *kvm, > + gfn_t base_gfn, unsigned long npages) > +{ > + gfn_t gfn = base_gfn; > + pfn_t pfn; > + int i, rc; > + struct dmar_domain *domain = kvm->arch.intel_iommu_domain; > + > + /* check if iommu exists and in use */ > + if (!domain) > + return 0; > + > + for (i = 0; i < npages; i++) { > + /* check if already mapped */ > + pfn = (pfn_t)intel_iommu_iova_to_pfn(domain, > + gfn_to_gpa(gfn)); > + if (pfn && !is_mmio_pfn(pfn)) > + continue; > + > + pfn = gfn_to_pfn(kvm, gfn); > + if (!is_mmio_pfn(pfn)) { > + rc = intel_iommu_page_mapping(domain, > + gfn_to_gpa(gfn), > + pfn_to_hpa(pfn), > + PAGE_SIZE, > + DMA_PTE_READ | > + DMA_PTE_WRITE); > + if (rc) { > + kvm_release_pfn_clean(pfn); > + printk(KERN_DEBUG "kvm_iommu_map_pages:" > +"iommu failed to map pfn=%lx\n", pfn); > + return rc; > + } > + } else { > + printk(KERN_DEBUG "kvm_iommu_map_page:" > +"invalid pfn=%lx\n", pfn); > + return 0; > + } In the error case, this function should itself call unmap_pages so that either all pages are mapped or none are. Also makes it easier to bail out in the two places this function gets called. > + > + gfn++; > + } > + return 0; > +} > + > +static int kvm_iommu_map_memslots(struct kvm *kvm) > +{ > + int i, rc; > + > + down_read(&kvm->slots_lock); > + for (i = 0; i < kvm->nmemslots; i++) { > + rc = kvm_iommu_map_pages(kvm, kvm->memslots[i].base_gfn, > + kvm->memslots[i].npages); > + if (rc) { > + up_read(&kvm->slots_lock); > + return rc; > + } > + } > + up_read(&kvm->slots_lock); > + return 0; > +} > + > +int kvm_iommu_map_guest(struct kvm *kvm, > + struct kvm_assigned_dev_kernel *assigned_dev) > +{ > + struct pci_dev *pdev = NULL; > + int rc; > + > + if (!intel_iommu_found()) { > + printk(KERN_ERR "intel iommu not found\n"); > + return -ENODEV; > + } > + > + printk(KERN_DEBUG "VT-d direct map: host bdf = %x:%x:%x\n", > +assigned_dev->host_busnr, > +PCI_SLOT(assigned_dev->host_devfn), > +PCI_FUNC(assigned_dev->host_devfn)); > + > + pdev = assigned_dev->dev; > + > + if (pdev == NULL) { > + if (kvm->arch.intel_iommu_domain) { > + intel_iommu_domain_exit(kvm->arch.intel_iommu_domain); > + kvm->arch.intel_iommu_domain = NULL; > + } > + return -ENODEV; > + } > + > + kvm->arch.intel_iommu_domain = intel_iommu_domain_alloc(pdev); check if we really got the domain > + > + rc = kvm_iommu_map_memslots(kvm); > + if (rc) > + goto out_unmap; > + > + intel_iommu_detach_dev(kvm->arch.intel_iommu_domain, > +pdev->bus->number, pdev->devfn); > + > + rc = intel_iommu_context_mapping(kvm->arch.intel_iommu_domain, > + pdev); This function name (as Mark points out) doesn't make much sense; can this be changed? > + if (rc) { > + printk(KERN_ERR "Domain context map for %s failed", > +pci_name(pdev)); > + goto out_unmap; > + } > + return 0; > + > +out_unmap: > + kvm_iommu_unmap_memslots(kvm); > + return rc; > +} > + > +static void kvm_iommu_put_pages(stru
RE: [PATCH 2/2] KVM: Device Assignment with VT-d
Avi Kivity wrote: > Zhang, Xiantao wrote: >> Amit Shah wrote: >> >>> * On Tuesday 26 Aug 2008 15:58:42 Zhang, Xiantao wrote: >>> Maybe vtd.c should be put @ virt/kvm so that ia64 can share it to avoid future code move. >>> As of now, device assignment resides inside the x86 directory and is >>> only tested in x86 environment. Once we support ia64, we'll have a >>> lot of files moving anyway. >>> >> >> Just a suggestion. Even if put it @ virt/kvm, we still can make it >> only >> > > I'm fine with keeping it in x86 and moving it later, since the code is > late already. However if someone is willing to do the work to move it > to virt/kvm/, I'm happy with that as well. I think we'd better keep it in x86 at this moment. Making VT-d code arch-independent is our goal. Moving that file is not enough, let's do it cleanly after merging VT-d patches into upstream. Randy (Weidong) -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2] KVM: Device Assignment with VT-d
Zhang, Xiantao wrote: Amit Shah wrote: * On Tuesday 26 Aug 2008 15:58:42 Zhang, Xiantao wrote: Maybe vtd.c should be put @ virt/kvm so that ia64 can share it to avoid future code move. As of now, device assignment resides inside the x86 directory and is only tested in x86 environment. Once we support ia64, we'll have a lot of files moving anyway. Just a suggestion. Even if put it @ virt/kvm, we still can make it only I'm fine with keeping it in x86 and moving it later, since the code is late already. However if someone is willing to do the work to move it to virt/kvm/, I'm happy with that as well. -- error compiling committee.c: too many arguments to function -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 2/2] KVM: Device Assignment with VT-d
Amit Shah wrote: > * On Tuesday 26 Aug 2008 16:12:56 Zhang, Xiantao wrote: >> Amit Shah wrote: >>> * On Tuesday 26 Aug 2008 15:58:42 Zhang, Xiantao wrote: Maybe vtd.c should be put @ virt/kvm so that ia64 can share it to avoid future code move. >>> >>> As of now, device assignment resides inside the x86 directory and is >>> only tested in x86 environment. Once we support ia64, we'll have a >>> lot of files moving anyway. >> >> Just a suggestion. Even if put it @ virt/kvm, we still can make it >> only compiled with x86 before eanbling it for ia64. :) > > Sure; I'm fine with that :-) >> Have you considered the cross-arch support in the current code? > > I've not, since I don't know much about ia64, but Allen had mentioned > that it shouldn't take much effort to port the current code to ia64. Okay. Thanks for your explanation! Xiantao -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2] KVM: Device Assignment with VT-d
* On Tuesday 26 Aug 2008 16:12:56 Zhang, Xiantao wrote: > Amit Shah wrote: > > * On Tuesday 26 Aug 2008 15:58:42 Zhang, Xiantao wrote: > >> Maybe vtd.c should be put @ virt/kvm so that ia64 can share it to > >> avoid future code move. > > > > As of now, device assignment resides inside the x86 directory and is > > only tested in x86 environment. Once we support ia64, we'll have a > > lot of files moving anyway. > > Just a suggestion. Even if put it @ virt/kvm, we still can make it only > compiled with x86 before eanbling it for ia64. :) Sure; I'm fine with that :-) > Have you considered the cross-arch support in the current code? I've not, since I don't know much about ia64, but Allen had mentioned that it shouldn't take much effort to port the current code to ia64. Amit -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 2/2] KVM: Device Assignment with VT-d
Amit Shah wrote: > * On Tuesday 26 Aug 2008 15:58:42 Zhang, Xiantao wrote: >> Maybe vtd.c should be put @ virt/kvm so that ia64 can share it to >> avoid future code move. > > As of now, device assignment resides inside the x86 directory and is > only tested in x86 environment. Once we support ia64, we'll have a > lot of files moving anyway. Just a suggestion. Even if put it @ virt/kvm, we still can make it only compiled with x86 before eanbling it for ia64. :) Have you considered the cross-arch support in the current code? > However, I don't have any preference for the location of vtd.c; > depends on what Avi thinks. -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2] KVM: Device Assignment with VT-d
* On Tuesday 26 Aug 2008 15:58:42 Zhang, Xiantao wrote: > Maybe vtd.c should be put @ virt/kvm so that ia64 can share it to avoid > future code move. As of now, device assignment resides inside the x86 directory and is only tested in x86 environment. Once we support ia64, we'll have a lot of files moving anyway. However, I don't have any preference for the location of vtd.c; depends on what Avi thinks. Amit -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 2/2] KVM: Device Assignment with VT-d
Maybe vtd.c should be put @ virt/kvm so that ia64 can share it to avoid future code move. Thanks Xiantao Amit Shah wrote: > From: Ben-Ami Yassour <[EMAIL PROTECTED]> > > Based on a patch by: Kay, Allen M <[EMAIL PROTECTED]> > > This patch enables PCI device assignment based on VT-d support. > When a device is assigned to the guest, the guest memory is pinned and > the mapping is updated in the VT-d IOMMU. > > [Amit: Expose KVM_CAP_IOMMU so we can check if an IOMMU is present > and also control enable/disable from userspace] > > Signed-off-by: Kay, Allen M <[EMAIL PROTECTED]> > Signed-off-by: Weidong Han <[EMAIL PROTECTED]> > Signed-off-by: Ben-Ami Yassour <[EMAIL PROTECTED]> > Signed-off-by: Amit Shah <[EMAIL PROTECTED]> > --- > arch/x86/kvm/Makefile |3 + > arch/x86/kvm/vtd.c | 203 > arch/x86/kvm/x86.c > | 14 +++ include/asm-x86/kvm_host.h |3 + > include/linux/kvm.h|3 + > include/linux/kvm_host.h | 32 +++ > virt/kvm/kvm_main.c|9 ++- > 7 files changed, 266 insertions(+), 1 deletions(-) > create mode 100644 arch/x86/kvm/vtd.c > > diff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile > index d0e940b..3072b17 100644 > --- a/arch/x86/kvm/Makefile > +++ b/arch/x86/kvm/Makefile > @@ -12,6 +12,9 @@ EXTRA_CFLAGS += -Ivirt/kvm -Iarch/x86/kvm > > kvm-objs := $(common-objs) x86.o mmu.o x86_emulate.o i8259.o irq.o > lapic.o \ i8254.o > +ifeq ($(CONFIG_DMAR),y) > +kvm-objs += vtd.o > +endif > obj-$(CONFIG_KVM) += kvm.o > kvm-intel-objs = vmx.o > obj-$(CONFIG_KVM_INTEL) += kvm-intel.o > diff --git a/arch/x86/kvm/vtd.c b/arch/x86/kvm/vtd.c > new file mode 100644 > index 000..4336769 > --- /dev/null > +++ b/arch/x86/kvm/vtd.c > @@ -0,0 +1,203 @@ > +/* > + * Copyright (c) 2006, Intel Corporation. > + * > + * This program is free software; you can redistribute it and/or > modify it + * under the terms and conditions of the GNU General > Public License, + * version 2, as published by the Free Software > Foundation. + * > + * This program is distributed in the hope it will be useful, but > WITHOUT + * ANY WARRANTY; without even the implied warranty of > MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU > General Public License for + * more details. > + * > + * You should have received a copy of the GNU General Public License > along with + * this program; if not, write to the Free Software > Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA > 02111-1307 USA. + * > + * Copyright (C) 2006-2008 Intel Corporation > + * Copyright IBM Corporation, 2008 > + * Author: Allen M. Kay <[EMAIL PROTECTED]> > + * Author: Weidong Han <[EMAIL PROTECTED]> > + * Author: Ben-Ami Yassour <[EMAIL PROTECTED]> > + */ > + > +#include > +#include > +#include > +#include > +#include > + > +static int kvm_iommu_unmap_memslots(struct kvm *kvm); > + > +int kvm_iommu_map_pages(struct kvm *kvm, > + gfn_t base_gfn, unsigned long npages) > +{ > + gfn_t gfn = base_gfn; > + pfn_t pfn; > + int i, rc; > + struct dmar_domain *domain = kvm->arch.intel_iommu_domain; > + > + /* check if iommu exists and in use */ > + if (!domain) > + return 0; > + > + for (i = 0; i < npages; i++) { > + /* check if already mapped */ > + pfn = (pfn_t)intel_iommu_iova_to_pfn(domain, > + gfn_to_gpa(gfn)); > + if (pfn && !is_mmio_pfn(pfn)) > + continue; > + > + pfn = gfn_to_pfn(kvm, gfn); > + if (!is_mmio_pfn(pfn)) { > + rc = intel_iommu_page_mapping(domain, > + gfn_to_gpa(gfn), > + pfn_to_hpa(pfn), > + PAGE_SIZE, > + DMA_PTE_READ | > + DMA_PTE_WRITE); > + if (rc) { > + kvm_release_pfn_clean(pfn); > + printk(KERN_DEBUG "kvm_iommu_map_pages:" > +"iommu failed to map pfn=%lx\n", pfn); > + return rc; > + } > + } else { > + printk(KERN_DEBUG "kvm_iommu_map_page:" > +"invalid pfn=%lx\n", pfn); > + return 0; > + } > + > + gfn++; > + } > + return 0; > +} > + > +static int kvm_iommu_map_memslots(struct kvm *kvm) > +{ > + int i, rc; > + > + down_read(&kvm->slots_lock); > + for (i = 0; i < kvm->nmemslots; i++) { > + rc = kvm_iommu_map_pages(kvm, kvm->memslots[i].base_gfn, > + kvm->memslots[i].npages); > + if (rc) { > +